📄 snort_stream5_session.c
字号:
/* $Id$ *//*** Copyright (C) 2005-2008 Sourcefire, Inc.** AUTHOR: Steven Sturges <ssturges@sourcefire.com>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License Version 2 as** published by the Free Software Foundation. You may not use, modify or** distribute this program under any other version of the GNU General** Public License.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//* snort_stream5_session.c * * Purpose: Hash Table implementation of session management functions for * Stream5 preprocessor. * * Arguments: * * Effect: * * Comments: * * Any comments? * */#include "decode.h"#include "debug.h"#include "log.h"#include "util.h"#include "snort_stream5_session.h"#include "sf_types.h"#include "sfhashfcn.h"#ifndef WIN32#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif#include "bitop_funcs.h"extern unsigned int giFlowbitSize;#ifdef MPLS#include "snort.h"#endifvoid PrintSessionKey(SessionKey *skey){ LogMessage("SessionKey:\n"); LogMessage(" ip_l = 0x%08X\n", skey->ip_l); LogMessage(" ip_h = 0x%08X\n", skey->ip_h); LogMessage(" prt_l = %d\n", skey->port_l); LogMessage(" prt_h = %d\n", skey->port_h); LogMessage(" vlan_tag = %d\n", skey->vlan_tag); #ifdef MPLS LogMessage(" mpls label = 0x%08X\n", skey->mplsLabel);#endif}int GetLWSessionCount(Stream5SessionCache *sessionCache){ if (sessionCache && sessionCache->hashTable) return sessionCache->hashTable->count; else return 0;}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 */}Stream5LWSession *GetLWSession(Stream5SessionCache *sessionCache, Packet *p, SessionKey *key){ Stream5LWSession *returned = NULL; SFXHASH_NODE *hnode; if (!sessionCache) return NULL; if (!GetLWSessionKey(p, key)) { return NULL; } hnode = sfxhash_find_node(sessionCache->hashTable, key); if (hnode && hnode->data) { /* This is a unique hnode, since the sfxhash finds the * same key before returning this node. */ returned = (Stream5LWSession *)hnode->data; if (returned && (returned->last_data_seen < p->pkth->ts.tv_sec)) { returned->last_data_seen = p->pkth->ts.tv_sec; } } return returned;}Stream5LWSession *GetLWSessionFromKey(Stream5SessionCache *sessionCache, SessionKey *key){ Stream5LWSession *returned = NULL; SFXHASH_NODE *hnode; if (!sessionCache) return NULL; hnode = sfxhash_find_node(sessionCache->hashTable, key);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -