萨塞克斯大学硕士预科:首部校验以及解包程序
来源:百度文库 编辑:九乡新闻网 时间: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; }