萨塞克斯大学硕士预科:首部校验以及解包程序

来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 09:03:37

1、 //计算TCP校验和    

                        memcpy(   SendBuff[n],   &PsdHeader,   sizeof(PsdHeader)   );    

                        memcpy(   SendBuff[n]   +   sizeof(PsdHeader),   &TcpHeader,   sizeof(TcpHeader)   );    

                        TcpHeader.th_sum   =   checksum(   (USHORT   *)   SendBuff[n],   sizeof(PsdHeader)   +   sizeof(TcpHeader)   );    

   

   

                        //计算IP检验和    

                        memcpy(   SendBuff[n],   &IpHeader,   sizeof(IpHeader)   );    

                        memcpy(   SendBuff[n]   +   sizeof(IpHeader),   &TcpHeader,   sizeof(TcpHeader)   );    

                        memset(   SendBuff[n]   +   sizeof(IpHeader)   +   sizeof(TcpHeader),   0,   4   );    

                        IpHeader.checksum   =   checksum(   (USHORT   *)   SendBuff,   sizeof(IpHeader)   +   sizeof(TcpHeader)   );    

 

 /* 下面是首部校验和的算法 */ 

unsigned short in_cksum(unsigned short *addr, int len) /* function is from ping.c */ 

{ register int nleft = len; 

 register u_short *w = addr; 

 register int sum = 0; 

 u_short answer =0; 

 while (nleft > 1)  //16位依次相加

 { 

     sum += *w++; 

     nleft -= 2; 

 } 

 if (nleft == 1) { //对于tcp或者是udp来说需要检验整个数据包,当有包长不是偶数的时候,剩下那个字节要添加一个字节0。这是为了校验和计算。

     *(u_char *)(&answer) = *(u_char *)w; 

     sum += answer; 

 } 

//把高16位中的数据与低16位数据相加

while(sum>>16)

{

    sum = (sum >> 16) + (sum & 0xffff);

}

 answer = ~sum; 

 return(answer); 

}


2  //IP解包程序  

  int   DecodeIpPack(char   *buf,   int   iBufSize)  

  {  

  IP_HEADER   *pIpheader;  

  SOCKADDR_IN   saSource,   saDest;  

  pIpheader   =   (IP_HEADER   *)buf;  

  //协议甄别  

  iProtocol   =   pIpheader->proto;  

  strncpy(szProtocol,   CheckProtocol(iProtocol),   MAX_PROTO_TEXT_LEN);  

  if((iProtocol==IPPROTO_TCP)   &&   (!ParamTcp))   return   true;  

  if((iProtocol==IPPROTO_UDP)   &&   (!ParamUdp))   return   true;  

  if((iProtocol==IPPROTO_ICMP)   &&   (!ParamIcmp))   return   true;  

  //源地址  

  saSource.sin_addr.s_addr   =   pIpheader->sourceIP;  

  strncpy(szSourceIP,   inet_ntoa(saSource.sin_addr),   MAX_ADDR_LEN);  

  if   (strFromIpFilter)  

  if   (strcmp(strFromIpFilter,szSourceIP))   return   true;  

  //目的地址  

  saDest.sin_addr.s_addr   =   pIpheader->destIP;  

  strncpy(szDestIP,   inet_ntoa(saDest.sin_addr),   MAX_ADDR_LEN);  

  if   (strDestIpFilter)  

  if   (strcmp(strDestIpFilter,szDestIP))   return   true;  

  iTTL   =   pIpheader->ttl;  

  //计算IP首部的长度  

  int   iIphLen   =   sizeof(unsigned   long)   *   (pIpheader->h_lenver   &   0xf);  

  //根据协议类型分别调用相应的函数  

  switch(iProtocol)  

  {  

  case   IPPROTO_TCP:DecodeTcpPack(buf+iIphLen,   iBufSize);break;  

  case   IPPROTO_UDP:DecodeUdpPack(buf+iIphLen,   iBufSize);break;  

  case   IPPROTO_ICMP:DecodeIcmpPack(buf+iIphLen,   iBufSize);break;  

  default:break;  

  }  

  //printf("\n");  

  return   true;  

  }  

   

  //协议识别程序  

  char   *   CheckProtocol(int   iProtocol)  

  {  

  for(int   i=0;   i

  if(ProtoMap[i].ProtoNum==iProtocol)    

  return   ProtoMap[i].ProtoText;  

  return   "";  

  }  

   

  //TCP解包程序  

  int   DecodeTcpPack(char   *   TcpBuf,   int   iBufSize)  

  {  

  TCP_HEADER   *   pTcpHeader;  

  int   i;  

  int   iSourcePort,iDestPort;  

   

  pTcpHeader   =   (TCP_HEADER   *   )TcpBuf;  

  //计算TCP首部长度  

  int   TcpHeaderLen   =     pTcpHeader->th_lenres>>4;  

  TcpHeaderLen   *=   sizeof(unsigned   long);  

  char   *   TcpData=TcpBuf+TcpHeaderLen;  

  //如果过滤敏感字符串则判断是否包含  

  if   (strSensitive)    

  if   ((strstr(TcpData,   strSensitive))==NULL)   return   true;  

  //对端口进行过滤  

  iSourcePort   =   ntohs(pTcpHeader->th_sport);  

  iDestPort   =   ntohs(pTcpHeader->th_dport);  

  if   ((iPortFilter)   &&   (iSourcePort!=iPortFilter)   &&   (iDestPort!=iPortFilter))  

  return   true;  

  //输出  

  printf("%s   ",   szProtocol);  

  printf("%15s:%5d   ->%15s:%5d     ",   szSourceIP,   iSourcePort,   szDestIP,   iDestPort);  

  printf("TTL=%3d     ",   iTTL);  

  //判断TCP标志位  

  unsigned   char   FlagMask   =   1;  

  for(   i=0;   i<6;   i++   )  

  {  

  if((pTcpHeader->th_flag)   &   FlagMask)   printf("%c",TcpFlag[i]);  

  else   printf("-");  

  FlagMask=FlagMask<<1;  

  }  

  printf("     bytes=%4d",   iBufSize);  

  printf("\n");  

  //对于长度大于40字节的包进行数据分析(IP_HEADER+TCP_HEADER=40)  

  if   ((ParamDecode)   &&   (iBufSize>40))  

  {  

  //分析TCP数据段  

  if   ((!strSensitive)   ||   (strstr(TcpData,strSensitive)))  

  {  

  printf("   [DATA]\n");  

  printf("%s",TcpData);  

  printf("\n   [DATA   END]\n\n\n");  

  }  

  }  

  return   true;  

  }  

   

   

   

   

  //UDP解包程序  

  int   DecodeUdpPack(char   *   UdpBuf,   int   iBufSize)  

  {  

  UDP_HEADER   *pUdpHeader;  

  pUdpHeader   =   (UDP_HEADER   *   )UdpBuf;  

  int   iSourcePort   =   ntohs(pUdpHeader->uh_sport);  

  int   iDestPort   =   ntohs(pUdpHeader->uh_dport);  

  //对端口进行过滤  

  if(iPortFilter)  

  if   ((iSourcePort!=iPortFilter)   &&   (iDestPort!=iPortFilter))  

  return   true;  

  printf("%s   ",   szProtocol);  

  printf("%15s:%5d   ->%15s:%5d     ",   szSourceIP,   iSourcePort,   szDestIP,   iDestPort);  

  printf("TTL=%3d   ",   iTTL);  

  printf("Len=%4d   ",   ntohs(pUdpHeader->uh_len));  

  printf("bytes=%4d",   iBufSize);  

  printf("\n");  

  //对于长度大于28字节的包进行数据分析(IP_HEADER+UDP_HEADER>28)  

  if   ((ParamDecode)   &&   (iBufSize>28))  

  {  

  printf("   [DATA]\n");  

  //UDP首部长度为8  

  char   *   UdpData=UdpBuf+8;  

  //分析UDP数据段  

  for(unsigned   int   i=0;i<(iBufSize-sizeof(UDP_HEADER));i++)    

  {  

  if   (!(i%8))   printf("\n");    

  if   (   (UdpData[i]>33)   &&   (UdpData[i]<122)   )  

  printf("%3c   [%3x]",   UdpData[i],   UdpData[i]);  

  else   printf("         [%3x]",   abs(UdpData[i]));  

  }  

  printf("\n   [DATA   END]\n\n\n");  

  }  

  return   true;  

  }  

   

  //ICMP解包程序  

  int   DecodeIcmpPack(char   *   IcmpBuf,   int   iBufSize)  

  {  

  ICMP_HEADER   *   pIcmpHeader;  

  pIcmpHeader   =   (ICMP_HEADER   *   )IcmpBuf;  

  int   iIcmpType   =   pIcmpHeader->i_type;  

  int   iIcmpCode   =   pIcmpHeader->i_code;  

  //对类型进行过滤  

  if   ((iPortFilter)   &&   (iIcmpType!=iPortFilter))   return   true;  

  printf("%s   ",   szProtocol);  

  //printf("%15s   Type%d   ->%15s   Code%d     ",   szSourceIP,   iIcmpType,   szDestIP,   iIcmpCode);  

  printf("%15s               ->%15s                 ",   szSourceIP,   szDestIP);  

  printf("TTL=%3d   ",   iTTL);  

  printf("Type%2d,%d   ",iIcmpType,iIcmpCode);  

  printf("bytes=%4d",   iBufSize);  

  printf("\n");  

  //对于包含数据段的包进行数据分析  

  if   ((ParamDecode)   &&   (iBufSize>28))  

  {  

  char   *   IcmpData=IcmpBuf+4;  

  //分析ICMP数据段  

  printf("   [DATA]");  

  for(unsigned   int   i=0;i<(iBufSize-sizeof(ICMP_HEADER));i++)    

  {  

  if   (!(i%8))   printf("\n");    

  if   (   (IcmpData[i]>33)   &&   (IcmpData[i]<122)   )  

  printf("%3c   [%3x]",   IcmpData[i],   IcmpData[i]);  

  else   printf("         [%3x]",   abs(IcmpData[i]));  

  }  

  printf("\n   [DATA   END]\n\n\n");  

  }  

  return   true;  

  }