一个适用于windows和linux的抓包程序

程序的精髓不在于抓包,而在于对数据包的处理,可以很方便的扩展。
程序如下:

/******************************************************************
windows:g++ -o process process.cpp -lws2_32 -DWIN
linux  :g++  -o process process.cpp
all right reserve
*******************************************************************/
#include <iostream>
#include <vector>
#ifdef WIN
#include <windows.h>
#include <winsock2.h>
#else
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if_ether.h>
#include <net/if.h>
#endif


#include "head_ip.h"
#ifdef WIN
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#endif
 
using namespace std;
#ifdef WIN
int ioct(SOCKET sniffer);
#else
int do_promisc(char *nif, int sock ) ;
void die(char *why, int n);
#endif

int print_ip(const char * ip_hdr);
struct iphdr * char_to_ip(const char * pkg);
struct tcphdr * char_to_tcp(const char * pkg);
struct udphdr * char_to_udp(const char * pkg);

class processor
{
public:
     virtual void  print(const char * pkg) const =0;

};


class protocol
{
public:
     virtual bool  judge(const char* pkg) const =0;
     virtual processor* create_processor() const =0;
};


char  processor_buffer[sizeof(processor)];

/********************************tcp***************************************************/
class processor_tcp:public processor
{
public:
     virtual void print(const char * pkg) const
     {
      cout<<"-----------------------------------------------------------------"<<endl;
      cout<<"this is a tcp packet"<<endl;
     print_ip(pkg);
     
     
     cout<<"source port:"<<ntohs(char_to_tcp(pkg+20)->source)<<endl;
     cout<<"dest port:"<<ntohs(char_to_tcp(pkg+20)->dest)<<endl;
     cout<<"seq:"<<char_to_tcp(pkg+20)->seq<<endl;
     cout<<"ack seq:"<<char_to_tcp(pkg+20)->ack_seq<<endl;
     cout<<"ack:"<<char_to_tcp(pkg+20)->ack<<endl;
     cout<<"syn:"<<char_to_tcp(pkg+20)->syn<<endl;
     cout<<"fin:"<<char_to_tcp(pkg+20)->fin<<endl;


      
      };

};


class protocol_tcp :public protocol
{
public:    
    virtual bool judge(const  char * pkg) const
    {     

           if( char_to_ip(pkg)->protocol==6)
           return true;
           else
           return false;
    }
   
    virtual processor* create_processor() const
    {
         return new(processor_buffer) processor_tcp;
        
    }
};

 

/*********************************udp*************************************************/
class processor_udp:public processor
{
public:
     virtual void print(const char * pkg) const
     {
      cout<<"-----------------------------------------------------------------"<<endl;
      cout<<"this is a udp packet"<<endl;
     print_ip(pkg);
     
     cout<<"source port:"<<ntohs(char_to_udp(pkg+20)->source)<<endl;
     cout<<"dest port:"<<ntohs(char_to_udp(pkg+20)->dest)<<endl;
     cout<<"length:"<<char_to_udp(pkg+20)->len<<endl;
      
      };

};


class protocol_udp :public protocol
{
public:    
    virtual bool judge(const  char * pkg) const
    {     
        if( char_to_ip(pkg)->protocol==17)
        return true;
           else
           return false;
    }
   
    virtual processor* create_processor() const
    {
         return new(processor_buffer) processor_udp;
    }
};


/*********************************udp*************************************************/
class processor_icmp:public processor
{
public:
     virtual void print(const char * pkg) const
     {
      cout<<"-----------------------------------------------------------------"<<endl;
      cout<<"this is a icmp packet"<<endl;
     print_ip(pkg);
     
      };

};


class protocol_icmp :public protocol
{
public:    
    virtual bool judge(const  char * pkg) const
    {     
        if( char_to_ip(pkg)->protocol==1)
        return true;
           else
           return false;
    }
   
    virtual processor* create_processor() const
    {
         return new(processor_buffer) processor_icmp;
    }
};

 

 

 

 

 

class manager
{
    vector<protocol*>  container_;

public:
    ~manager()
   {
     
   }
    template<typename _Proctocol>
    void install_protocol()
    {
         container_.push_back( new _Proctocol());
    }
  
   int create_process(const char * pkg) const
    {
              for(vector<protocol*>::const_iterator it = container_.begin(); it != container_.end(); it++)
               {         
                 if((*it)->judge(pkg) == true)
                   {
                 
                processor * xx=(*it)->create_processor();
                return 1;
                  }
            
       }
        return 0;
    }
};

 

 

int main(int argc,char *argv[])
{
    manager mgr;
#ifdef WIN
    WSADATA wsaData;
    SOCKADDR_IN saddr;
    SOCKET sniffer;
    int len;
    struct sockaddr_in addr;
#else

int sniffer;

#endif
    int err;
    char *buf1=(char *)malloc(1518);
    char *buf=buf1+14;
    int num;
   
 if(argc!=2)
 {
  cout<<"Input error,such as:/n"<<argv[0]<<" 192.168.0.1"<<endl;;
  return -1;
 }

#ifdef WIN   
    err = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
    if ( err != 0 ) {
        cout<<"error!WSAStartup failed!"<<endl;;
        return -1;
    }

    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr(argv[1]);    
    saddr.sin_port = htons(555);
   
    if((sniffer=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==SOCKET_ERROR)
    {
        cout<<"socket failed!"<<endl;
        return -1;
    }
    if(bind(sniffer,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
    {
        cout<<"bind failed!"<<endl;
        return -1;
    }
    ioct(sniffer);
    len = sizeof(addr); 
#else
if((sniffer=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)))==-1)


{
        die("socket", 1); 
}
do_promisc("eth0", sniffer); 

#endif

mgr.install_protocol<protocol_tcp>();
mgr.install_protocol<protocol_udp>();
mgr.install_protocol<protocol_icmp>();
while(1)
   {
#ifndef WIN
num = recv(sniffer,buf1,1518,0);
#else

num = recvfrom(sniffer,buf,1500, 0, (struct sockaddr *)&addr,&len);

#endif
        if(num>0)
        {

        if(mgr.create_process(buf)==1)
        {
      
    ( reinterpret_cast<processor*>(processor_buffer))->print(buf);
     }
        }
   
   }
#ifdef WIN
    closesocket(sniffer);
    WSACleanup();
#endif
    return 0;

}

#ifdef WIN
int ioct(SOCKET sniffer)
{
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
WSAIoctl(sniffer, SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen),&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );
}
#else
int do_promisc(char *nif, int sock ) 

struct ifreq ifr; 
               
strncpy(ifr.ifr_name, nif,strlen(nif)+1); 
   if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1))  //..flag
   {        
     die("ioctl", 2); 
   } 
  
   ifr.ifr_flags |= IFF_PROMISC;  //..flag..
 
   if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 )  //....
   {
     die("ioctl", 3); 
   } 
}

void die(char *why, int n) 

  perror(why); 
  exit(n); 
}  
#endif


int print_ip(const char * ip_hdr)
{
cout<<"version:"<<char_to_ip(ip_hdr)->version<<endl;
cout<<"TTL:"<<char_to_ip(ip_hdr)->ttl<<endl;
cout<<"tot_len:"<<char_to_ip(ip_hdr)->tot_len<<endl;
cout<<"ID:"<<char_to_ip(ip_hdr)->id<<endl;
cout<<"source ip:"<<char_to_ip(ip_hdr)->saddr_u.ip_str_saddr.ip1<<"."<<char_to_ip(ip_hdr)->saddr_u.ip_str_saddr.ip2<<"."<<char_to_ip(ip_hdr)->saddr_u.ip_str_saddr.ip3<<"."<<char_to_ip(ip_hdr)->saddr_u.ip_str_saddr.ip4<<endl;
cout<<"dest ip:"<<char_to_ip(ip_hdr)->daddr_u.ip_str_daddr.ip1<<"."<<char_to_ip(ip_hdr)->daddr_u.ip_str_daddr.ip2<<"."<<char_to_ip(ip_hdr)->daddr_u.ip_str_daddr.ip3<<"."<<char_to_ip(ip_hdr)->daddr_u.ip_str_daddr.ip4<<endl; 

return 0;
}

inline struct iphdr * char_to_ip(const char * pkg)

{
 
return reinterpret_cast<struct iphdr *>(const_cast<char *>(pkg));

}
inline struct udphdr * char_to_udp(const char * pkg)

{
 
return reinterpret_cast<struct udphdr *>(const_cast<char *>(pkg));

}
inline struct tcphdr * char_to_tcp(const char * pkg)

{
 
return reinterpret_cast<struct tcphdr *>(const_cast<char *>(pkg));

}


 

程序里面有一个很奇怪的问题,如果linux下面如果用recvfrom()这种形式

会吧mgr的结构破坏,被迫使用recv()函数了,那位大虾找到原因了可以给我

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值