/* * Initialize key for dynamic channel and call daq api method to notify firmware * of the expected dynamic channel. */ void DAQ_Add_Dynamic_Protocol_Channel(const Packet *ctrlPkt, snort_ip_p cliIP, uint16_t cliPort, snort_ip_p srvIP, uint16_t srvPort, uint8_t protocol ) { DAQ_DP_key_t dp_key; dp_key.af = cliIP->family; if( dp_key.af == AF_INET ) { memcpy( &dp_key.sa.src_ip4, &cliIP->ip32[0], 4 ); memcpy( &dp_key.da.dst_ip4, &srvIP->ip32[0], 4 ); } else { memcpy( &dp_key.sa.src_ip6, &cliIP->ip32[0], sizeof( u_int32_t ) * 4 ); memcpy( &dp_key.da.dst_ip6, &srvIP->ip32[0], sizeof( u_int32_t ) * 4 ); } dp_key.protocol = protocol; dp_key.src_port = cliPort; dp_key.dst_port = srvPort; dp_key.vlan_cnots = 1; if( ctrlPkt->vh ) dp_key.vlan_id = VTH_VLAN( ctrlPkt->vh ); else dp_key.vlan_id = 0xFFFF; if( ctrlPkt->GTPencapsulated ) dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_GTP_TUNNEL; else if ( ctrlPkt->encapsulated ) dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_OTHER_TUNNEL; else dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_NON_TUNNEL; // notify the firmware to add expected flow for this dynamic channel daq_dp_add_dc( daq_mod, daq_hand, ctrlPkt->pkth, &dp_key, ctrlPkt->pkt ); }
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; }
static int ProcessIcmpUnreach(Packet *p) { /* Handle ICMP unreachable */ SessionKey skey; Stream5LWSession *ssn = NULL; u_int16_t sport; u_int16_t dport; /* No "orig" IP Header */ if (!p->orig_iph) return 0; /* Get TCP/UDP/ICMP session from original protocol/port info * embedded in the ICMP Unreach message. This is already decoded * in p->orig_foo. TCP/UDP ports are decoded as p->orig_sp/dp. */ skey.protocol = p->orig_iph->ip_proto; sport = p->orig_sp; dport = p->orig_dp; if (p->orig_iph->ip_src.s_addr < p->orig_iph->ip_dst.s_addr) { skey.ip_l = p->orig_iph->ip_src.s_addr; skey.port_l = sport; skey.ip_h = p->orig_iph->ip_dst.s_addr; skey.port_h = dport; } else if (p->orig_iph->ip_dst.s_addr == p->orig_iph->ip_src.s_addr) { skey.ip_l = p->orig_iph->ip_src.s_addr; skey.ip_h = p->orig_iph->ip_src.s_addr; if (sport < dport) { skey.port_l = sport; skey.port_h = dport; } else { skey.port_l = dport; skey.port_h = sport; } } else { skey.ip_l = p->orig_iph->ip_dst.s_addr; skey.port_l = dport; skey.ip_h = p->orig_iph->ip_src.s_addr; skey.port_h = sport; } if (p->vh) skey.vlan_tag = VTH_VLAN(p->vh); else skey.vlan_tag = 0; switch (skey.protocol) { case IPPROTO_TCP: /* Lookup a TCP session */ ssn = GetLWTcpSession(&skey); break; case IPPROTO_UDP: /* Lookup a UDP session */ ssn = GetLWUdpSession(&skey); break; case IPPROTO_ICMP: /* Lookup a ICMP session */ ssn = GetLWSessionFromKey(icmp_lws_cache, &skey); break; } if (ssn) { /* Mark this session as dead. */ DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Marking session as dead, per ICMP Unreachable!\n");); ssn->session_flags |= STREAM5_STATE_DROP_CLIENT; ssn->session_flags |= STREAM5_STATE_DROP_SERVER; ssn->session_flags |= STREAM5_STATE_UNREACH; }
static int ProcessIcmpUnreach(Packet *p) { /* Handle ICMP unreachable */ SessionKey skey; SessionControlBlock *ssn = NULL; uint16_t sport; uint16_t dport; sfip_t *src; sfip_t *dst; /* No "orig" IP Header */ if (!p->orig_iph) return 0; /* Get TCP/UDP/ICMP session from original protocol/port info * embedded in the ICMP Unreach message. This is already decoded * in p->orig_foo. TCP/UDP ports are decoded as p->orig_sp/dp. */ skey.protocol = GET_ORIG_IPH_PROTO(p); sport = p->orig_sp; dport = p->orig_dp; src = GET_ORIG_SRC(p); dst = GET_ORIG_DST(p); if (sfip_fast_lt6(src, dst)) { COPY4(skey.ip_l, src->ip32); skey.port_l = sport; COPY4(skey.ip_h, dst->ip32); skey.port_h = dport; } else if (IP_EQUALITY(GET_ORIG_SRC(p), GET_ORIG_DST(p))) { COPY4(skey.ip_l, src->ip32); COPY4(skey.ip_h, skey.ip_l); if (sport < dport) { skey.port_l = sport; skey.port_h = dport; } else { skey.port_l = dport; skey.port_h = sport; } } else { COPY4(skey.ip_l, dst->ip32); COPY4(skey.ip_h, src->ip32); skey.port_l = dport; skey.port_h = sport; } if (p->vh) skey.vlan_tag = (uint16_t)VTH_VLAN(p->vh); else skey.vlan_tag = 0; switch (skey.protocol) { case IPPROTO_TCP: /* Lookup a TCP session */ ssn = GetLWTcpSession(&skey); break; case IPPROTO_UDP: /* Lookup a UDP session */ ssn = GetLWUdpSession(&skey); break; case IPPROTO_ICMP: /* Lookup a ICMP session */ ssn = session_api->get_session_by_key(icmp_lws_cache, &skey); break; } if (ssn) { /* Mark this session as dead. */ DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Marking session as dead, per ICMP Unreachable!\n");); ssn->ha_state.session_flags |= SSNFLAG_DROP_CLIENT; ssn->ha_state.session_flags |= SSNFLAG_DROP_SERVER; ssn->session_state |= STREAM_STATE_UNREACH; }
/* * Initialize key for dynamic channel and call daq api method to notify firmware * of the expected dynamic channel. */ void DAQ_Add_Dynamic_Protocol_Channel(const Packet *ctrlPkt, sfaddr_t* cliIP, uint16_t cliPort, sfaddr_t* srvIP, uint16_t srvPort, uint8_t protocol, DAQ_DC_Params* params) { DAQ_DP_key_t dp_key; #ifdef HAVE_DAQ_DATA_CHANNEL_SEPARATE_IP_VERSIONS dp_key.src_af = sfaddr_family(cliIP); if (AF_INET == dp_key.src_af) { dp_key.sa.src_ip4.s_addr = sfaddr_get_ip4_value(cliIP); } else { memcpy(&dp_key.sa.src_ip6, sfaddr_get_ip6_ptr(cliIP), sizeof(dp_key.sa.src_ip6)); } dp_key.dst_af = sfaddr_family(srvIP); if (AF_INET == dp_key.dst_af) { dp_key.da.dst_ip4.s_addr = sfaddr_get_ip4_value(srvIP); } else { memcpy(&dp_key.da.dst_ip6, sfaddr_get_ip6_ptr(srvIP), sizeof(dp_key.da.dst_ip6)); } #else dp_key.af = sfaddr_family(cliIP); if( dp_key.af == AF_INET ) { dp_key.sa.src_ip4.s_addr = sfaddr_get_ip4_value(cliIP); dp_key.da.dst_ip4.s_addr = sfaddr_get_ip4_value(srvIP); } else { memcpy( &dp_key.sa.src_ip6, sfaddr_get_ip6_ptr(cliIP), sizeof( dp_key.sa.src_ip6 ) ); memcpy( &dp_key.da.dst_ip6, sfaddr_get_ip6_ptr(srvIP), sizeof( dp_key.da.dst_ip6 ) ); } #endif dp_key.protocol = protocol; dp_key.src_port = cliPort; dp_key.dst_port = srvPort; dp_key.vlan_cnots = 1; if( ctrlPkt->vh ) dp_key.vlan_id = VTH_VLAN( ctrlPkt->vh ); else dp_key.vlan_id = 0xFFFF; if( ctrlPkt->GTPencapsulated ) dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_GTP_TUNNEL; #ifdef DAQ_DP_TUNNEL_TYPE_MPLS_TUNNEL else if ( ctrlPkt->mpls ) dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_MPLS_TUNNEL; #endif else if ( ctrlPkt->encapsulated ) dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_OTHER_TUNNEL; else dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_NON_TUNNEL; // notify the firmware to add expected flow for this dynamic channel #ifdef HAVE_DAQ_DATA_CHANNEL_PARAMS { DAQ_Data_Channel_Params_t daq_params; memset(&daq_params, 0, sizeof(daq_params)); daq_params.timeout_ms = params->timeout_ms; if (params->flags & DAQ_DC_FLOAT) daq_params.flags |= DAQ_DATA_CHANNEL_FLOAT; if (params->flags & DAQ_DC_ALLOW_MULTIPLE) daq_params.flags |= DAQ_DATA_CHANNEL_ALLOW_MULTIPLE; if (params->flags & DAQ_DC_PERSIST) daq_params.flags |= DAQ_DATA_CHANNEL_PERSIST; daq_dp_add_dc(daq_mod, daq_hand, ctrlPkt->pkth, &dp_key, ctrlPkt->pkt, &daq_params); } #else daq_dp_add_dc( daq_mod, daq_hand, ctrlPkt->pkth, &dp_key, ctrlPkt->pkt ); #endif }
int GetVlanId(void* p) { Packet *packet = (Packet *)p; return (VTH_VLAN(packet->vh)); }