GENERIC sfrt_search(sfaddr_t* ip, table_t *table) { uint32_t* adr; int numAdrDwords; tuple_t tuple; void *rt = NULL; if ((ip == NULL) || (table == NULL)) return NULL; if (sfaddr_family(ip) == AF_INET) { adr = sfaddr_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfaddr_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } tuple = table->lookup(adr, numAdrDwords, rt); if(tuple.index >= table->max_size) return NULL; return table->data[tuple.index]; }
/* Perform a lookup on value contained in "ip" */ GENERIC sfrt_flat_lookup(sfaddr_t *ip, table_flat_t *table) { tuple_flat_t tuple; uint32_t* adr; int numAdrDwords; INFO *data; TABLE_PTR rt; uint8_t *base; if(!ip) { return NULL; } if(!table) { return NULL; } if (sfaddr_family(ip) == AF_INET) { adr = sfaddr_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfaddr_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } tuple = sfrt_dir_flat_lookup(adr, numAdrDwords, rt); if(tuple.index >= table->num_ent) { return NULL; } base = (uint8_t *)segment_basePtr(); data = (INFO *)(&base[table->data]); if (data[tuple.index]) return (GENERIC) &base[data[tuple.index]]; else return NULL; }
/* Perform a lookup on value contained in "ip" */ GENERIC sfrt_lookup(sfaddr_t* ip, table_t* table) { tuple_t tuple; uint32_t* adr; int numAdrDwords; void *rt; if(!ip) { return NULL; } if(!table || !table->lookup) { return NULL; } if (sfaddr_family(ip) == AF_INET) { adr = sfaddr_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfaddr_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } tuple = table->lookup(adr, numAdrDwords, rt); if(tuple.index >= table->max_size) { return NULL; } return table->data[tuple.index]; }
/* * 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 }
static int ProcessIcmpUnreach(Packet *p) { /* Handle ICMP unreachable */ SessionKey skey; SessionControlBlock *ssn = NULL; uint16_t sport; uint16_t dport; sfaddr_t *src; sfaddr_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, sfaddr_get_ip6_ptr(src)); skey.port_l = sport; COPY4(skey.ip_h, sfaddr_get_ip6_ptr(dst)); skey.port_h = dport; } else if (IP_EQUALITY(src, dst)) { COPY4(skey.ip_l, sfaddr_get_ip6_ptr(src)); 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, sfaddr_get_ip6_ptr(dst)); COPY4(skey.ip_h, sfaddr_get_ip6_ptr(src)); 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; }