当前位置:编程学习 > VC++ >>

VC++实现数据包嗅探

 
嗅探器 可以窃听网络上流经的数据包。 用集线器hub组建的网络是基于共享的原理的, 局域网内所有的计算机都接收相同的数据包, 而网卡构造了硬件的“过滤器“ 通过识别MAC地址过滤掉和自己无关的信息, 嗅探程序只需关闭这个过滤器, 将网卡设置为“混杂模式“就可以进行嗅探 用交换机switch组建的网络是基于“交换“原理的 ,交换机不是把数据包发到所有的端口上, 而是发到目的网卡所在的端口。
嗅探 sniff。嗅探器可以窃听网络上流经的数据包。用集线器hub组建的网络是基于共享的原理的,局域网内所有的计算机都接收相同的数据包,而网卡构造了硬件的“过滤器“通过识别MAC地址过滤掉和自己无关的信息,嗅探程序只需关闭这个过滤器,将网卡设置为“混杂模式“就可以进行嗅探用交换机switch组建的网络是基于“交换“原理的,交换机不是把数据包发到所有的端口上,而是发到目的网卡所在的端口。这样嗅探起来会麻烦一些,嗅探程序一般利用“ARP欺骗“的方法,通过改变MAC地址等手段,欺骗交换机将数据包发给自己,嗅探分析完毕再转发出去。
 
[cpp] 
#include <stdio.h>  
#include <winsock2.h>  
#include <ws2tcpip.h>  
  
#pragma comment (lib,"ws2_32.lib")  
  
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)  
  
struct IPHEAD  
{  
    unsigned char h_len:4;//4位首部长度+4位IP版本号  
    unsigned char ver:4;  
    unsigned char tos;//8位服务类型TOS  
    unsigned short total_len;//16位总长度(字节)  
    unsigned short ident;//16位标识  
    unsigned short frag_and_flags;//3位标志位  
    unsigned char ttl;//8位生存时间 TTL  
    unsigned char proto;//8位协议 (TCP, UDP 或其他)  
    unsigned short checksum;//16位IP首部校验和  
    unsigned int sourceip;//32位源IP地址  
    unsigned int destip;//32位目的IP地址  
};  
  
struct TCPHEAD //定义TCP首部  
{  
USHORT th_sport; //16位源端口  
USHORT th_dport; //16位目的端口  
unsigned int th_seq; //32位序列号  
unsigned int th_ack; //32位确认号  
unsigned char th_lenres; //4位首部长度/6位保留字  
unsigned char th_flag; //6位标志位  
USHORT th_win; //16位窗口大小  
USHORT th_sum; //16位校验和  
USHORT th_urp; //16位紧急数据偏移量  
};  
  
  
char *phostlist[10];//列举主机网卡的数组  
  
DWORD _stdcall listen(void *p)  
{  
    SOCKET s;  
    struct sockaddr_in addr;  
    int itimeout=1000;  
    int ret;  
    char cbuf[1500];//接收数据缓冲区  
    struct IPHEAD *piphd;//定义IP头结构  
    struct TCPHEAD *ptcphd;//定义TCP头结构  
   
    s=socket(AF_INET,SOCK_RAW,IPPROTO_RAW); //创建一个原始套接字  
    setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char*)&itimeout,sizeof(itimeout));  
  
    memset(&addr,0,sizeof(addr));  
    addr.sin_family=AF_INET;  
    addr.sin_addr.S_un.S_addr=inet_addr((char *)p);  
    addr.sin_port=htons(6000);//设置本地端口号  
    bind(s,(struct sockaddr *)&addr,sizeof(addr));//绑定端口  
    //设置sock_raw为sio_rcvall,以便接收所有IP包  
    DWORD dwin=1;  
    DWORD dwout[10];  
    DWORD dwret;  
    WSAIoctl(s,SIO_RCVALL,&dwin,sizeof(dwin),&dwout,sizeof(dwout),&dwret,NULL,NULL);  
  
    for(;;)  
    {  
        ret=recv(s,cbuf,sizeof(cbuf),0);//接收数据  
        if(ret==SOCKET_ERROR)  
        {  
            if(WSAGetLastError()==WSAETIMEDOUT)continue;  
            closesocket(s);  
            return 0;  
        }  
  
        piphd=(struct IPHEAD *)cbuf;//取得IP头数据的地址  
        int iIphLen = sizeof(unsigned long) * (piphd->h_len  & 0xf);  
        ptcphd=(struct TCPHEAD *)(cbuf+iIphLen);//取得TCP头数据的地址  
  
  
        printf("From : %s \t port %d\t",inet_ntoa(*(struct in_addr*)&piphd->sourceip),ntohs(ptcphd->th_sport) );  
        printf("To : %s \t port %d  ",inet_ntoa(*(struct in_addr*)&piphd->destip),ntohs(ptcphd->th_dport));  
      
        switch(piphd->proto)//根据IP头的协议判断数据包协议类型  
        {  
        case 1:  
            printf("ICMP\n");  
            break;  
        case 2:  
            printf("IGMP\n");  
            break;  
        case 6:  
            printf("TCP\n");  
            break;  
        case 17:  
            printf("UDP\n");  
            break;  
        default:  
            printf("unknow:%d\n",piphd->proto);  
        }  
    }  
  
    return 1;  
}  
  
void main()  
{  
    //初始化sock  
    WSADATA wsa;  
    int i=0;  
    DWORD dwtid;  
    char chname[128];  
    hostent *host;  
  
    WSAStartup(MAKEWORD(2,1),&wsa);  
    gethostname(chname,sizeof(chname));  
    host=gethostbyname(chname);  
    while(host->h_addr_list[i]!=NULL)//取所有网卡序号,为每个网卡开启一个监听线程  
    {  
        phostlist[i]=(char *)malloc(16);  
        sprintf(phostlist[i],"%s",inet_ntoa(*(struct in_addr *)host->h_addr_list[i]));  
      &n
补充:软件开发 , Vc ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,