Пример #1
0
/*
 * 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;
}
Пример #3
0
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;
    }
Пример #4
0
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;
    }
Пример #5
0
/*
 * 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
}
Пример #6
0
int GetVlanId(void* p)
{
   Packet *packet = (Packet *)p;
   return (VTH_VLAN(packet->vh));
}