VC++实现ip数据包解包TCP解包HTTP

来源:互联网 发布:python网络课程 编辑:程序博客网 时间:2024/05/21 07:50

我们需要监控用户的互联网行为,则需要检测HTTP

如何在网络层截取HTTP呢,众所周知,网站是80号端口

代码实现如下

[cpp] view plaincopyprint?
  1. CInitSock theSock;    
  2.     
  3.     
  4.     
  5. void GetFtp(char *pData, DWORD dwDestIp)    
  6. {    
  7.     char szBuf[256];    
  8.     static char szUserName[21];    
  9.     static char szPassword[21];    
  10.     
  11.     if(strnicmp(pData, "USER ", 5) == 0)    
  12.     {    
  13.         sscanf(pData + 4, "%*[ ]%s", szUserName);       
  14.     }    
  15.     else if(strnicmp(pData, "PASS ", 5) == 0)    
  16.     {    
  17.         sscanf(pData + 4, "%*[ ]%s", szPassword);    
  18.     
  19.         wsprintf(szBuf, " Server Address: %s; User Name: %s; Password: %s; \n\n",     
  20.                                 ::inet_ntoa(*(in_addr*)&dwDestIp), szUserName, szPassword);    
  21.     
  22.         printf(szBuf);  // 这里您可以将它保存到文件中     
  23.     }    
  24. }    
  25.     
  26.     
  27. void DecodeIPPacket(char *pData)    
  28. {    
  29.     IPHeader *pIPHdr = (IPHeader*)pData;    
  30.     
  31.     
  32.     int nHeaderLen = (pIPHdr->iphVerLen & 0xf) * sizeof(ULONG);    
  33.     
  34.     switch(pIPHdr->ipProtocol)    
  35.     {    
  36.     case IPPROTO_TCP:    
  37.         {    
  38.             TCPHeader *pTCPHdr = (TCPHeader *)(pData + nHeaderLen);    
  39.             switch(::ntohs(pTCPHdr->destinationPort))    
  40.             {    
  41.             case 21:    // ftp协议     
  42.                 {    
  43.                     GetFtp((char*)pTCPHdr + sizeof(TCPHeader), pIPHdr->ipDestination);    
  44.                 }    
  45.                 break;    
  46.     
  47.             case 80:    // http协议...     
  48.             case 8080:    
  49.                     
  50.                 break;    
  51.             }    
  52.         }    
  53.         break;    
  54.     case IPPROTO_UDP:    
  55.         break;    
  56.     case IPPROTO_ICMP:    
  57.         break;     
  58.     }    
  59. }    
  60.     
  61.     
  62. void main()    
  63. {    
  64.     // 创建原始套节字     
  65.     SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP);    
  66.     
  67.     // 获取本地IP地址     
  68.     char szHostName[56];    
  69.     SOCKADDR_IN addr_in;    
  70.     struct  hostent *pHost;    
  71.     gethostname(szHostName, 56);    
  72.     if((pHost = gethostbyname((char*)szHostName)) == NULL)      
  73.         return ;    
  74.     
  75.     // 在调用ioctl之前,套节字必须绑定     
  76.     addr_in.sin_family  = AF_INET;    
  77.     addr_in.sin_port    = htons(0);    
  78.     memcpy(&addr_in.sin_addr.S_un.S_addr, pHost->h_addr_list[0], pHost->h_length);    
  79.     
  80.     printf(" Binding to interface : %s \n", ::inet_ntoa(addr_in.sin_addr));    
  81.     if(bind(sRaw, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR)    
  82.         return;    
  83.     
  84.     // 设置SIO_RCVALL控制代码,以便接收所有的IP包       
  85.     DWORD dwValue = 1;    
  86.     if(ioctlsocket(sRaw, SIO_RCVALL, &dwValue) != 0)        
  87.         return ;    
  88.         
  89.     // 开始接收封包     
  90.     printf(" \n\n begin to monitor ftp password... \n\n");    
  91.     char buff[1024];    
  92.     int nRet;    
  93.     while(TRUE)    
  94.     {    
  95.         nRet = recv(sRaw, buff, 1024, 0);    
  96.         if(nRet > 0)    
  97.         {    
  98.             DecodeIPPacket(buff);    
  99.         }    
  100.     }    
  101.     closesocket(sRaw);    
  102. }