int AnalyzeIp(u_char *data, int size) { u_char *ptr = NULL; int lest = 0; struct iphdr *iphdr = NULL; // IPヘッダ u_char *option = NULL; // ヘッダオプション int optionLen = 0; // ヘッダオプションサイズ int len = 0; unsigned short sum = 0; ptr = data; // IPヘッダの先頭ポインタ lest = size; if (lest < sizeof(struct iphdr)) { ExitWithTooLittleLengthError("iphdr", lest); } iphdr = (struct iphdr *) ptr; // IPヘッダの先頭ポインタ ptr += sizeof(struct iphdr); // IPヘッダオプションの先頭ポインタ lest -= sizeof(struct iphdr); // ヘッダオプションサイズを求める(パディングを含む) optionLen = iphdr->ihl * 4 - sizeof(struct iphdr); if (optionLen > 0) { if (optionLen >= 1500) { fprintf(stderr, "IP optionLen(%d):too big\n", optionLen); } option = ptr; // IPヘッダオプションの先頭ポインタ ptr += optionLen; // ペイロードの先頭ポインタ lest -= optionLen; } if (checkIPchecksum(iphdr, option, optionLen) == 0) { ExitWithBadChecksumError("ip"); } PrintIpHeader(iphdr, option, optionLen, stdout); if (iphdr->protocol == IPPROTO_ICMP) { // ペイロードサイズを取得する // tot_lenはペイロードを含めたIPヘッダのサイズ len = ntohs(iphdr->tot_len) - iphdr->ihl * 4; sum = checksum(ptr, len); // ペイロードのチェックサムを取得する if (sum != 0 && sum != 0xFFFF) { ExitWithBadChecksumError("icmp"); } AnalyzeIcmp(ptr, lest); } else if (iphdr->protocol == IPPROTO_TCP) { // ペイロードサイズを取得する len = ntohs(iphdr->tot_len) - iphdr->ihl * 4; if (checkIPDATAchecksum(iphdr, ptr, len) == 0) { ExitWithBadChecksumError("tcp"); } AnalyzeTcp(ptr, lest); } else if (iphdr->protocol == IPPROTO_UDP) { struct udphdr *udphdr; udphdr = (struct udphdr *) ptr; len = ntohs(iphdr->tot_len) - iphdr->ihl * 4; if (udphdr->check != 0 && checkIPDATAchecksum(iphdr, ptr, len) == 0) { ExitWithBadChecksumError("udp"); } AnalyzeUdp(ptr, lest); } return 0; }
int AnalyzeIp(u_char *data,int size) { u_char *ptr; int lest; struct iphdr *iphdr; u_char *option; int optionLen,len; unsigned short sum; ptr=data; lest=size; if(lest<sizeof(struct iphdr)){ if(fil[2] == 1 || fil[3] == 1 || fil[4] == 1 || fil [6] == 1){ fprintf(stderr,"lest(%d)<sizeof(struct iphdr)\n",lest); } return(-1); } iphdr=(struct iphdr *)ptr; ptr+=sizeof(struct iphdr); lest-=sizeof(struct iphdr); optionLen=iphdr->ihl*4-sizeof(struct iphdr); if(optionLen>0){ if(optionLen>=1500){ if(fil[2] == 1 || fil[3] == 1 || fil[4] == 1 || fil[6] == 1){ fprintf(stderr,"IP optionLen(%d):too big\n",optionLen); } return(-1); } option=ptr; ptr+=optionLen; lest-=optionLen; } if(checkIPchecksum(iphdr,option,optionLen)==0){ fprintf(stderr,"bad ip checksum\n"); return(-1); } if(fil[6] == 1){ PrintIpHeader(iphdr,option,optionLen,stdout); } if(iphdr->protocol==IPPROTO_ICMP){ len=ntohs(iphdr->tot_len)-iphdr->ihl*4; sum=checksum(ptr,len); if(sum!=0&&sum!=0xFFFF){ fprintf(stderr,"bad icmp checksum\n"); return(-1); } AnalyzeIcmp(ptr,lest); } else if(iphdr->protocol==IPPROTO_TCP){ len=ntohs(iphdr->tot_len)-iphdr->ihl*4; if(checkIPDATAchecksum(iphdr,ptr,len)==0){ fprintf(stderr,"bad tcp checksum\n"); return(-1); } AnalyzeTcp(ptr,lest); } else if(iphdr->protocol==IPPROTO_UDP){ struct udphdr *udphdr; udphdr=(struct udphdr *)ptr; len=ntohs(iphdr->tot_len)-iphdr->ihl*4; if(udphdr->check!=0&&checkIPDATAchecksum(iphdr,ptr,len)==0){ fprintf(stderr,"bad udp checksum\n"); return(-1); } AnalyzeUdp(ptr,lest); } return(0); }