u_int32_t Checksum(Packet *iPkt,u_int32_t pktlen) { if( (iPkt == NULL) || pktlen == 0) { /* XXX */ return 1; } if(iPkt->iph) { if(IS_IP4(iPkt)) { ip_checksum((void *)iPkt->iph, (pktlen - ((void *) iPkt->iph - (void *)iPkt->pkt))); } else if(IS_IP6(iPkt)) { ip6_checksum((void *)iPkt->iph, (pktlen - ((void *) iPkt->iph - (void *)iPkt->pkt))); } else { goto cksum_err; } } return 0; cksum_err: printf("[%s()]: Encountered an error while running checksum against a packet \n", __FUNCTION__); return 1; }
int GetLWSessionKey(Packet *p, SessionKey *key) { u_int16_t sport; u_int16_t dport; int proto; /* Because the key is going to be used for hash lookups, * the lower of the values of the IP address field is * stored in the key->ip_l and the port for that ip is * stored in key->port_l. */ if (!key) return 0; #ifdef SUP_IP6 if (IS_IP4(p)) { u_int32_t *src; u_int32_t *dst; proto = p->iph->ip_proto; switch (proto) { case IPPROTO_TCP: case IPPROTO_UDP: sport = p->sp; dport = p->dp; break; case IPPROTO_ICMP: default: sport = dport = 0; break; } src = p->ip4h.ip_src.ip32; dst = p->ip4h.ip_dst.ip32; /* These comparisons are done in this fashion for performance reasons */ if (*src < *dst) { COPY4(key->ip_l, src); COPY4(key->ip_h, dst); key->port_l = sport; key->port_h = dport; } else if (*src == *dst) { COPY4(key->ip_l, src); COPY4(key->ip_h, dst); if (sport < dport) { key->port_l = sport; key->port_h = dport; } else { key->port_l = dport; key->port_h = sport; } } else { COPY4(key->ip_l, dst); key->port_l = dport; COPY4(key->ip_h, src); key->port_h = sport; } #ifdef MPLS if(pv.overlapping_IP && (p->mpls) && isPrivateIP(*src) && isPrivateIP(*dst) ) { key->mplsLabel = p->mplsHdr.label; } else { key->mplsLabel = 0; } #endif } else { /* IPv6 */ sfip_t *src; sfip_t *dst; proto = p->ip6h.next; switch (proto) { case IPPROTO_TCP: case IPPROTO_UDP: sport = p->sp; dport = p->dp; break; case IPPROTO_ICMP: default: sport = dport = 0; break; } src = &p->ip6h.ip_src; dst = &p->ip6h.ip_dst; if (sfip_fast_lt6(src, dst)) { COPY4(key->ip_l, src->ip32); key->port_l = sport; COPY4(key->ip_h, dst->ip32); key->port_h = dport; } else if (sfip_fast_eq6(src, dst)) { COPY4(key->ip_l, src->ip32); COPY4(key->ip_h, dst->ip32); if (sport < dport) { key->port_l = sport; key->port_h = dport; } else { key->port_l = dport; key->port_h = sport; } } else { COPY4(key->ip_l, dst->ip32); key->port_l = dport; COPY4(key->ip_h, src->ip32); key->port_h = sport; } #ifdef MPLS if(pv.overlapping_IP && (p->mpls)) { key->mplsLabel = p->mplsHdr.label; } else { key->mplsLabel = 0; } #endif } #else proto = p->iph->ip_proto; switch (proto) { case IPPROTO_TCP: case IPPROTO_UDP: sport = p->sp; dport = p->dp; break; case IPPROTO_ICMP: default: sport = dport = 0; break; } /* These comparisons are done in this fashion for performance reasons */ if (IP_LESSER(GET_SRC_IP(p), GET_DST_IP(p))) { IP_COPY_VALUE(key->ip_l, GET_SRC_IP(p)); key->port_l = sport; IP_COPY_VALUE(key->ip_h, GET_DST_IP(p)); key->port_h = dport; } else if (IP_EQUALITY(GET_SRC_IP(p), GET_DST_IP(p))) { IP_COPY_VALUE(key->ip_l, GET_SRC_IP(p)); IP_COPY_VALUE(key->ip_h, GET_DST_IP(p)); if (sport < dport) { key->port_l = sport; key->port_h = dport; } else { key->port_l = dport; key->port_h = sport; } } else { IP_COPY_VALUE(key->ip_l, GET_DST_IP(p)); key->port_l = dport; IP_COPY_VALUE(key->ip_h, GET_SRC_IP(p)); key->port_h = sport; } #ifdef MPLS if(pv.overlapping_IP && (p->mpls) && isPrivateIP(key->ip_l) && isPrivateIP(key->ip_h)) { key->mplsLabel = p->mplsHdr.label; } else { key->mplsLabel = 0; } #endif #endif key->protocol = proto; if (p->vh) key->vlan_tag = (u_int16_t)VTH_VLAN(p->vh); else key->vlan_tag = 0; key->pad = 0; #ifdef MPLS key->mplsPad = 0; #endif return 1; }
void GetLWPacketDirection(Packet *p, Stream5LWSession *ssn) { #ifndef SUP_IP6 if (p->iph->ip_src.s_addr == ssn->client_ip) { if (p->iph->ip_proto == IPPROTO_TCP) { if (p->tcph->th_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->iph->ip_proto == IPPROTO_UDP) { if (p->udph->uh_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->iph->ip_proto == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->iph->ip_dst.s_addr == ssn->client_ip) { if (p->iph->ip_proto == IPPROTO_TCP) { if (p->tcph->th_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->iph->ip_proto == IPPROTO_UDP) { if (p->udph->uh_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->iph->ip_proto == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } else { /* Uh, no match of the packet to the session. */ /* Probably should log an error */ } #else if(IS_IP4(p)) { if (p->iph->ip_src.s_addr == *ssn->client_ip.ip32) { if (p->iph->ip_proto == IPPROTO_TCP) { if (p->tcph->th_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->iph->ip_proto == IPPROTO_UDP) { if (p->udph->uh_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->iph->ip_proto == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->iph->ip_dst.s_addr == *ssn->client_ip.ip32) { if (p->iph->ip_proto == IPPROTO_TCP) { if (p->tcph->th_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->iph->ip_proto == IPPROTO_UDP) { if (p->udph->uh_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->iph->ip_proto == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } } else /* IS_IP6(p) */ { if (sfip_fast_eq6(&p->ip6h.ip_src, &ssn->client_ip)) { if (p->ip6h.next == IPPROTO_TCP) { if (p->tcph->th_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->ip6h.next == IPPROTO_UDP) { if (p->udph->uh_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->ip6h.next == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } else if (sfip_fast_eq6(&p->ip6h.ip_dst, &ssn->client_ip)) { if (p->ip6h.next == IPPROTO_TCP) { if (p->tcph->th_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->ip6h.next == IPPROTO_UDP) { if (p->udph->uh_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->ip6h.next == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } } #endif /* SUP_IP6 */ }
/*-------------------------------------------------------------------- * Function: LogIPHeader(TextLog* ) * * Purpose: Dump the IP header info to the given TextLog * * Arguments: log => TextLog to print to * * Returns: void function *-------------------------------------------------------------------- */ void LogIPHeader(TextLog* log, Packet * p) { if(!IPH_IS_VALID(p)) { TextLog_Print(log, "IP header truncated\n"); return; } if(p->frag_flag) { /* just print the straight IP header */ TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p))); TextLog_Puts(log, " -> "); TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p))); } else { if(GET_IPH_PROTO(p) != IPPROTO_TCP && GET_IPH_PROTO(p) != IPPROTO_UDP) { /* just print the straight IP header */ TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p))); TextLog_Puts(log, " -> "); TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p))); } else { if (!BcObfuscate()) { /* print the header complete with port information */ TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p))); TextLog_Print(log, ":%d -> ", p->sp); TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p))); TextLog_Print(log, ":%d", p->dp); } else { /* print the header complete with port information */ if(IS_IP4(p)) TextLog_Print(log, "xxx.xxx.xxx.xxx:%d -> xxx.xxx.xxx.xxx:%d", p->sp, p->dp); else if(IS_IP6(p)) TextLog_Print(log, "x:x:x:x:x:x:x:x:%d -> x:x:x:x:x:x:x:x:%d", p->sp, p->dp); } } } if(!BcOutputDataLink()) { TextLog_NewLine(log); } else { TextLog_Putc(log, ' '); } TextLog_Print(log, "%s TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u", protocol_names[GET_IPH_PROTO(p)], GET_IPH_TTL(p), GET_IPH_TOS(p), IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p)), GET_IPH_HLEN(p) << 2, GET_IP_DGMLEN(p)); /* print the reserved bit if it's set */ if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x8000) >> 15) == 1) TextLog_Puts(log, " RB"); /* printf more frags/don't frag bits */ if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x4000) >> 14) == 1) TextLog_Puts(log, " DF"); if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x2000) >> 13) == 1) TextLog_Puts(log, " MF"); TextLog_NewLine(log); /* print IP options */ if(p->ip_option_count != 0) { LogIpOptions(log, p); } /* print fragment info if necessary */ if(p->frag_flag) { TextLog_Print(log, "Frag Offset: 0x%04X Frag Size: 0x%04X\n", (p->frag_offset & 0x1FFF), GET_IP_PAYLEN(p)); } }