zoukankan      html  css  js  c++  java
  • VC++实现数据包嗅探


    嗅探器 可以窃听网络上流经的数据包。 用集线器hub组建的网络是基于共享的原理的, 局域网内所有的计算机都接收相同的数据包, 而网卡构造了硬件的“过滤器“ 通过识别MAC地址过滤掉和自己无关的信息, 嗅探程序只需关闭这个过滤器, 将网卡设置为“混杂模式“就可以进行嗅探 用交换机switch组建的网络是基于“交换“原理的 ,交换机不是把数据包发到所有的端口上, 而是发到目的网卡所在的端口。
    嗅探 sniff。嗅探器可以窃听网络上流经的数据包。用集线器hub组建的网络是基于共享的原理的,局域网内所有的计算机都接收相同的数据包,而网卡构造了硬件的“过滤器“通过识别MAC地址过滤掉和自己无关的信息,嗅探程序只需关闭这个过滤器,将网卡设置为“混杂模式“就可以进行嗅探用交换机switch组建的网络是基于“交换“原理的,交换机不是把数据包发到所有的端口上,而是发到目的网卡所在的端口。这样嗅探起来会麻烦一些,嗅探程序一般利用“ARP欺骗“的方法,通过改变MAC地址等手段,欺骗交换机将数据包发给自己,嗅探分析完毕再转发出去。


    #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]));
            printf("Bind to %s\n",phostlist[i]);
            CreateThread(NULL,0,listen,phostlist[i],0,&dwtid);
            i++;
        }
    
        for(;;)//为每个网卡创建监听线程后要用一个循环防止主线程退出
        {
            Sleep(10);
        }
    } 


  • 相关阅读:
    [转]SVN服务器搭建和使用(二)
    [转]SVN服务器搭建和使用(一)
    BZOJ 2049 Sdoi2008 Cave 洞穴勘测
    BZOJ 1589 Usaco2008 Dec Trick or Treat on the Farm 采集糖果
    BZOJ 2796 POI2012 Fibonacci Representation
    BZOJ 2115 Wc2011 Xor
    BZOJ 3105 CQOI2013 新Nim游戏
    BZOJ 2460 Beijing2011 元素
    BZOJ 3687 简单题
    BZOJ 1068 SCOI2008 压缩
  • 原文地址:https://www.cnblogs.com/new0801/p/6177617.html
Copyright © 2011-2022 走看看