Windows下利用原始套接字实现的一个抓包程序Demo

早就学过了套接字编程,但是原始套接字还没用过。最近听了网络安全老师的课,心血来潮,写了个抓包程序Demo,把代码分享给大家,感兴趣的可以看看。引用一句网络安全老师的话:“你们要本着技术的心态去实践,哎,一部分人,写着写着就成黑客了”。


  1. #define _CRT_SECURE_NO_WARNINGS   
  2. #include <stdio.h>  
  3. #include <WinSock2.h>  
  4. #include <WS2tcpip.h>  
  5. #include <stdlib.h>  
  6. #include <Windows.h>  
  7. #include <string.h>  
  8.   
  9.   
  10. #pragma comment(lib,"Ws2_32.lib")  
  11.   
  12. #define SOURCE_PORT 7234  
  13. #define MAX_RECEIVEBYTE 255  
  14. #define MAX_ADDR_LEN 32  
  15. #define SIO_RCVALL  (IOC_IN|IOC_VENDOR|1)//定义网卡为混杂模式  
  16.   
  17. typedef struct ip_hdr//定义IP首部  
  18. {  
  19.     unsigned char h_verlen;//4位首部长度,4位IP版本号  
  20.     unsigned char tos;//8位服务类型TOS  
  21.     unsigned short tatal_len;//16位总长度  
  22.     unsigned short ident;//16位标示  
  23.     unsigned short frag_and_flags;//偏移量和3位标志位  
  24.     unsigned char ttl;//8位生存时间TTL  
  25.     unsigned char proto;//8位协议(TCP,UDP或其他)  
  26.     unsigned short checksum;//16位IP首部检验和  
  27.     unsigned int sourceIP;//32位源IP地址  
  28.     unsigned int destIP;//32位目的IP地址  
  29. }IPHEADER;  
  30.   
  31. typedef struct tsd_hdr//定义TCP伪首部  
  32. {  
  33.     unsigned long saddr;//源地址  
  34.     unsigned long daddr;//目的地址  
  35.     char mbz;  
  36.     char ptcl;//协议类型  
  37.     unsigned short tcpl;//TCP长度  
  38. }PSDHEADER;  
  39.   
  40. typedef struct tcp_hdr//定义TCP首部  
  41. {  
  42.     unsigned short sport;//16位源端口  
  43.     unsigned short dport;//16位目的端口  
  44.     unsigned int seq;//32位序列号  
  45.     unsigned int ack;//32位确认号  
  46.     unsigned char lenres;//4位首部长度/6位保留字  
  47.     unsigned char flag;//6位标志位  
  48.     unsigned short win;//16位窗口大小  
  49.     unsigned short sum;//16位检验和  
  50.     unsigned short urp;//16位紧急数据偏移量  
  51. }TCPHEADER;  
  52.   
  53. typedef struct udp_hdr//定义UDP首部  
  54. {  
  55.     unsigned short sport;//16位源端口  
  56.     unsigned short dport;//16位目的端口  
  57.     unsigned short len;//UDP 长度  
  58.     unsigned short cksum;//检查和  
  59. }UDPHEADER;  
  60.   
  61. typedef struct icmp_hdr//定义ICMP首部  
  62. {  
  63.     unsigned short sport;  
  64.     unsigned short dport;  
  65.     unsigned char type;  
  66.     unsigned char code;  
  67.     unsigned short cksum;  
  68.     unsigned short id;  
  69.     unsigned short seq;  
  70.     unsigned long timestamp;  
  71. }ICMPHEADER;  
  72.   
  73. int main(int argc, char **argv)  
  74. {  
  75.     SOCKET sock;  
  76.     WSADATA wsd;  
  77.     char recvBuf[65535] = { 0 };  
  78.     char temp[65535] = { 0 };  
  79.     DWORD dwBytesRet;  
  80.       
  81.     int pCount = 0;  
  82.     unsigned int optval = 1;  
  83.     unsigned char* dataip = nullptr;  
  84.     unsigned char* datatcp = nullptr;  
  85.     unsigned char* dataudp = nullptr;  
  86.     unsigned char* dataicmp = nullptr;  
  87.   
  88.     int lentcp, lenudp, lenicmp, lenip;  
  89.     char TcpFlag[6] = { 'F''S''R''A''U' };//定义TCP标志位  
  90.     WSAStartup(MAKEWORD(2, 1), &wsd);  
  91.       
  92.     if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == SOCKET_ERROR)//创建一个原始套接字  
  93.     {  
  94.         exit(0);  
  95.     }  
  96.   
  97.     char FAR name[MAXBYTE];  
  98.     gethostname(name, MAXBYTE);  
  99.     struct hostent FAR* pHostent;  
  100.   
  101.     pHostent = (struct hostent*)malloc(sizeof(struct hostent));  
  102.     pHostent = gethostbyname(name);  
  103.     SOCKADDR_IN sa;  
  104.     sa.sin_family = AF_INET;  
  105.     sa.sin_port = htons(1);//原始套接字没有端口的概念,所以这个值随便设置  
  106.     memcpy(&sa.sin_addr,pHostent->h_addr_list[0],pHostent->h_length);//设置本机地址  
  107.   
  108.     bind(sock, (SOCKADDR*)&sa, sizeof(sa));//绑定  
  109.     if (WSAGetLastError() == 10013)  
  110.     {  
  111.         exit(0);  
  112.     }  
  113.   
  114.     //设置网卡为混杂模式,也叫泛听模式。可以侦听经过的所有的包。  
  115.     WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), nullptr, 0, &dwBytesRet,nullptr,nullptr);  
  116.   
  117.     UDPHEADER * pUdpheader;//UDP头结构体指针  
  118.     IPHEADER * pIpheader;//IP头结构体指针  
  119.     TCPHEADER * pTcpheader;//TCP头结构体指针  
  120.     ICMPHEADER * pIcmpheader;//ICMP头结构体指针  
  121.     char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN];//源IP和目的IP  
  122.     SOCKADDR_IN saSource, saDest;//源地址结构体,目的地址结构体  
  123.   
  124.     //设置各种头指针  
  125.     pIpheader = (IPHEADER*)recvBuf;  
  126.     pTcpheader = (TCPHEADER*)(recvBuf + sizeof(IPHEADER));  
  127.     pUdpheader = (UDPHEADER*)(recvBuf + sizeof(IPHEADER));  
  128.     pIcmpheader = (ICMPHEADER*)(recvBuf + sizeof(IPHEADER));  
  129.     int iIphLen = sizeof(unsigned long)*(pIpheader->h_verlen & 0x0f);  
  130.     while (1)  
  131.     {  
  132.           
  133.         memset(recvBuf, 0, sizeof(recvBuf));//清空缓冲区  
  134.         recv(sock, recvBuf, sizeof(recvBuf), 0);//接收包  
  135.   
  136.         //获得源地址和目的地址  
  137.         saSource.sin_addr.s_addr = pIpheader->sourceIP;  
  138.         strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);  
  139.         saDest.sin_addr.s_addr = pIpheader->destIP;  
  140.         strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);  
  141.   
  142.         //计算各种包的长度(只有判断是否是该包后才有意义,先计算出来)  
  143.         lenip = ntohs(pIpheader->tatal_len);  
  144.         lentcp = ntohs(pIpheader->tatal_len) - (sizeof(IPHEADER) + sizeof(TCPHEADER));  
  145.         lenudp = ntohs(pIpheader->tatal_len) - (sizeof(IPHEADER) + sizeof(UDPHEADER));  
  146.         lenicmp = ntohs(pIpheader->tatal_len) - (sizeof(IPHEADER) + sizeof(ICMPHEADER));  
  147.   
  148.         //判断是否是TCP包  
  149.         if (pIpheader->proto == IPPROTO_TCP&&lentcp != 0)  
  150.         {  
  151.             pCount++;//计数加一  
  152.             dataip = (unsigned char *)recvBuf;  
  153.             datatcp = (unsigned char *)recvBuf + sizeof(IPHEADER) + sizeof(TCPHEADER);  
  154.             system("cls");  
  155.   
  156.             printf("\n#################数据包[%i]=%d字节数据#############", pCount,   
  157.   
  158. lentcp);  
  159.             printf("\n**********IP协议头部***********");  
  160.             printf("\n标示:%i", ntohs(pIpheader->ident));  
  161.             printf("\n总长度:%i", ntohs(pIpheader->tatal_len));  
  162.             printf("\n偏移量:%i", ntohs(pIpheader->frag_and_flags));  
  163.             printf("\n生存时间:%d",pIpheader->ttl);  
  164.             printf("\n服务类型:%d",pIpheader->tos);  
  165.             printf("\n协议类型:%d",pIpheader->proto);  
  166.             printf("\n检验和:%i", ntohs(pIpheader->checksum));  
  167.             printf("\n源IP:%s", szSourceIP);  
  168.             printf("\n目的IP:%s", szDestIP);  
  169.             printf("\n**********TCP协议头部***********");  
  170.             printf("\n源端口:%i", ntohs(pTcpheader->sport));  
  171.             printf("\n目的端口:%i", ntohs(pTcpheader->dport));  
  172.             printf("\n序列号:%i", ntohs(pTcpheader->seq));  
  173.             printf("\n应答号:%i", ntohs(pTcpheader->ack));  
  174.             printf("\n检验和:%i", ntohs(pTcpheader->sum));  
  175.             printf("\n标志位:");  
  176.       
  177.             unsigned char FlagMask = 1;  
  178.             int k;  
  179.               
  180.             //打印标志位  
  181.             for (k = 0; k < 6; k++)  
  182.             {  
  183.                 if ((pTcpheader->flag)&FlagMask)  
  184.                     printf("%c", TcpFlag[k]);  
  185.                 else  
  186.                     printf(" ");  
  187.                 FlagMask = FlagMask << 1;  
  188.             }  
  189.             //打印出前100个字节的十六进制数据  
  190.             printf("\n数据:\n");  
  191.             for (int i = 0; i < 100; i++)  
  192.             {  
  193.                 printf("%x", datatcp[i]);  
  194.             }  
  195.         }         
  196.         //+++++++++++++++++++++++++++++  
  197.         //在这里可以加入其它封包的判断和处理  
  198.         //+++++++++++++++++++++++++++++  
  199.     }  
  200. }  

运行效果



  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值