$NetBSD: patch-ak,v 1.2 2012/03/31 08:31:06 dholland Exp $ - use standard headers - unclear other changes from a long time back --- sn_packets.c.orig 1997-04-18 09:33:58.000000000 +0000 +++ sn_packets.c @@ -4,6 +4,7 @@ #include "sn_config.h" #include "sn_defines.h" #include "sn_structs.h" +#include #include extern int PROTO_HEAD; @@ -43,6 +44,7 @@ int unwrap_packet (unsigned char *sp, st struct UDP_header UDPhead; int i; + short int dummy; /* 2 bytes, important */ memcpy(&IPhead,(sp+PROTO_HEAD),sizeof(struct IP_header)); /* IP header Conversion */ @@ -51,6 +53,7 @@ int unwrap_packet (unsigned char *sp, st unwrapped->TCP_len = 0; /* Reset structure NEEDED!!! */ unwrapped->UDP_len = 0; unwrapped->DATA_len = 0; + unwrapped->FRAG_nf = 0; if(NO_CHKSUM == 0) { @@ -75,32 +78,74 @@ int unwrap_packet (unsigned char *sp, st /* restore orig buffer */ /* general programming rule */ } + +#ifdef DEBUG_ONSCREEN + printf("IPheadlen: %d total length: %d\n", unwrapped->IP_len, + ntohs(IPhead.length)); +#endif + + dummy=ntohs(IPhead.flag_offset); dummy<<=3; + if( dummy!=0 ) /* we have offset */ + { + unwrapped->FRAG_nf = 1; + } + if(IPhead.protocol == TCP ) /* TCP */ { - memcpy(&TCPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)), + if(unwrapped->FRAG_nf == 0) + { + if( (ntohs(IPhead.length)-(unwrapped->IP_len))<20 ) + {return CORRUPT_IP;}; + + memcpy(&TCPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)), sizeof(struct TCP_header)); - unwrapped->TCP_len = ntohs(TCPhead.offset_flag) & 0xF000; - unwrapped->TCP_len >>= 10; - unwrapped->DATA_len = ntohs(IPhead.length) - + unwrapped->TCP_len = ntohs(TCPhead.offset_flag) & 0xF000; + unwrapped->TCP_len >>= 10; + unwrapped->DATA_len = ntohs(IPhead.length) - (unwrapped->IP_len) - (unwrapped->TCP_len); + } + else + { + unwrapped->DATA_len = ntohs(IPhead.length) - (unwrapped->IP_len); + } return TCP; } if(IPhead.protocol == ICMP ) /* ICMP */ { - memcpy(&ICMPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)), + if(unwrapped->FRAG_nf == 0) + { + if( (ntohs(IPhead.length)-(unwrapped->IP_len))<4 ) + {return CORRUPT_IP;}; + + memcpy(&ICMPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)), sizeof(struct ICMP_header)); - unwrapped->ICMP_len = ICMP_HEADLENGTH; - unwrapped->DATA_len = ntohs(IPhead.length) - + unwrapped->ICMP_len = ICMP_HEADLENGTH; + unwrapped->DATA_len = ntohs(IPhead.length) - (unwrapped->IP_len) - (unwrapped->ICMP_len); - return ICMP; + return ICMP; + } + else + { + return -1; /* don't handle fragmented ICMP */ + } } if(IPhead.protocol == UDP ) /* UDP */ { - memcpy(&UDPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)), + if(unwrapped->FRAG_nf == 0) + { + if( (ntohs(IPhead.length)-(unwrapped->IP_len))<8 ) + {return CORRUPT_IP;}; + + memcpy(&UDPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)), sizeof(struct UDP_header)); - unwrapped->UDP_len = UDP_HEADLENGTH; - unwrapped->DATA_len = ntohs(IPhead.length) - + unwrapped->UDP_len = UDP_HEADLENGTH; + unwrapped->DATA_len = ntohs(IPhead.length) - (unwrapped->IP_len) - (unwrapped->UDP_len); + } + else + { + unwrapped->DATA_len = ntohs(IPhead.length)-(unwrapped->IP_len); + } return UDP; } return -1;