📄 snort_stream5_udp.c
字号:
{ udp_ports[dport] |= UDP_SESSION; } } } } else { /* any -> any rule */ if (any_any_flow == 0) { any_any_flow = Stream5UdpAnyAnyFlow(rtn, any_any_flow); } }#endif /* PORTLISTS */ } /* for (rtn=...) */ } } /* for (rule=...) */ /* If portscan is tracking UDP, need to create * sessions for all UDP ports */ if (ps_get_protocols() & PS_PROTO_UDP) { int j; for (j=0; j<MAX_PORTS; j++) { udp_ports[j] |= UDP_SESSION; } } if (any_any_flow == 1) { LogMessage("Warning: 'ignore_any_rules' option for Stream5 UDP " "disabled because of UDP rule with flow or flowbits option\n"); } else if (ignored_udp_rules) { LogMessage("Warning: Rules (GID:SID) effectively ignored because of " "'ignore_any_rules' option for Stream5 UDP:\n"); buf[0] = '\0'; for (ignored_rule = ignored_udp_rules; ignored_rule != NULL; ) { UdpIgnoredRule *next_ignored_rule; if (any_any_flow == 0) { if (six_sids == 1) { SnortSnprintfAppend(buf, STD_BUF-1, "\n"); LogMessage(buf); six_sids = 0; } if (sids_ignored == 0) { SnortSnprintf(buf, STD_BUF-1, " %d:%d", ignored_rule->otn->sigInfo.generator, ignored_rule->otn->sigInfo.id); } else { SnortSnprintfAppend(buf, STD_BUF-1, ", %d:%d", ignored_rule->otn->sigInfo.generator, ignored_rule->otn->sigInfo.id); } sids_ignored++; if (sids_ignored %6 == 0) { /* Have it print next time through */ six_sids = 1; sids_ignored = 0; } } next_ignored_rule = ignored_rule->next; free(ignored_rule); ignored_rule = next_ignored_rule; } if (sids_ignored || six_sids) { SnortSnprintfAppend(buf, STD_BUF-1, "\n"); LogMessage(buf); } } return 0;}#ifdef DEBUG_STREAM5static void PrintUdpSession(UdpSession *us){ LogMessage("UdpSession:\n"); LogMessage(" ssn_time: %lu\n", us->ssn_time.tv_sec); LogMessage(" sender IP: 0x%08X\n", us->udp_sender_ip); LogMessage(" responder IP: 0x%08X\n", us->udp_responder_ip); LogMessage(" sender port: %d\n", us->udp_sender_port); LogMessage(" responder port: %d\n", us->udp_responder_port); LogMessage(" flags: 0x%X\n", us->lwSsn->session_flags);}#endifStream5LWSession *GetLWUdpSession(SessionKey *key){ return GetLWSessionFromKey(udp_lws_cache, key);}void UdpSessionCleanup(Stream5LWSession *lwssn){ UdpSession *udpssn = NULL; if (lwssn->proto_specific_data) udpssn = (UdpSession *)lwssn->proto_specific_data->data; if (!udpssn) { /* Huh? */ return; } /* Cleanup the proto specific data */ mempool_free(&udp_session_mempool, lwssn->proto_specific_data); lwssn->proto_specific_data = NULL; lwssn->session_state = STREAM5_STATE_NONE; lwssn->session_flags = SSNFLAG_NONE; lwssn->expire_time = 0; lwssn->ignore_direction = 0; s5stats.udp_sessions_released++; RemoveUDPSession(&sfPerf.sfBase);}void Stream5ResetUdp(void){ PurgeLWSessionCache(udp_lws_cache); mempool_clean(&udp_session_mempool);}void Stream5CleanUdp(void){ /* Clean up hash table -- delete all sessions */ DeleteLWSessionCache(udp_lws_cache); udp_lws_cache = NULL; mempool_destroy(&udp_session_mempool);}static int NewUdpSession(Packet *p, Stream5LWSession *lwssn, Stream5UdpPolicy *s5UdpPolicy){ UdpSession *tmp; MemBucket *tmpBucket; /****************************************************************** * create new sessions *****************************************************************/ tmpBucket = mempool_alloc(&udp_session_mempool); tmp = tmpBucket->data; DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Creating new session tracker!\n");); tmp->ssn_time.tv_sec = p->pkth->ts.tv_sec; tmp->ssn_time.tv_usec = p->pkth->ts.tv_usec; lwssn->session_flags |= SSNFLAG_SEEN_SENDER; DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "adding UdpSession to lightweight session\n");); lwssn->proto_specific_data = tmpBucket; lwssn->protocol = GET_IPH_PROTO(p); lwssn->direction = FROM_SENDER; tmp->lwSsn = lwssn;#ifdef DEBUG_STREAM5 PrintUdpSession(tmp);#endif Stream5SetExpire(p, lwssn, s5UdpPolicy->session_timeout); s5stats.udp_sessions_created++; AddUDPSession(&sfPerf.sfBase); return 1;}/* * Main entry point for UDP */int Stream5ProcessUdp(Packet *p){ Stream5UdpPolicy *s5UdpPolicy = NULL; SessionKey skey; Stream5LWSession *lwssn = NULL; int policyIndex; char action;#ifdef SUP_IP6// XXX-IPv6 Stream5ProcessUDP debugging#else DEBUG_WRAP( DebugMessage((DEBUG_STREAM|DEBUG_STREAM_STATE), "Got UDP Packet 0x%X:%d -> 0x%X:%d\n " "dsize: %lu\n" "active sessions: %lu\n", p->iph->ip_src.s_addr, p->sp, p->iph->ip_dst.s_addr, p->dp, p->dsize, sfxhash_count(udp_lws_cache->hashTable)); );#endif /* Find an Udp policy for this packet */ for (policyIndex = 0; policyIndex < numUdpPolicies; policyIndex++) { s5UdpPolicy = udpPolicyList[policyIndex]; /* * Does this policy handle packets to this IP address? */ if(IpAddrSetContains(s5UdpPolicy->bound_addrs, GET_DST_ADDR(p))) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "[Stream5] Found udp policy in IpAddrSet\n");); break; } else { s5UdpPolicy = NULL; } } if (!s5UdpPolicy) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "[Stream5] Could not find Udp Policy context " "for IP %s\n", inet_ntoa(GET_DST_ADDR(p)));); return 0; } action = (u_int8_t)(udp_ports[p->sp] | udp_ports[p->dp]); if (!(action & UDP_SESSION)) { if (!(action & UDP_INSPECT) && (s5UdpPolicy->flags & STREAM5_CONFIG_IGNORE_ANY)) { /* Ignore this UDP packet entirely */ DisableDetect(p); SetPreprocBit(p, PP_SFPORTSCAN); SetPreprocBit(p, PP_PERFMONITOR); //otn_tmp = NULL; } return 0; } /* UDP Sessions required */ if ((lwssn = GetLWSession(udp_lws_cache, p, &skey)) == NULL) { /* Create a new session, mark SENDER seen */ lwssn = NewLWSession(udp_lws_cache, p, &skey); s5stats.total_udp_sessions++; } else { DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Stream5: Retrieved existing session object.\n");); } if (!lwssn) { LogMessage("Stream5: Failed to retrieve session object. Out of memory?\n"); return -1; } p->ssnptr = lwssn; /* * Check if the session is expired. * Should be done before we do something with the packet... * ie, Insert a packet, or handle state change SYN, FIN, RST, etc. */ if ((lwssn->session_state & STREAM5_STATE_TIMEDOUT) || Stream5Expire(p, lwssn)) { lwssn->session_flags |= SSNFLAG_TIMEDOUT; /* Session is timed out */ DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Stream5 UDP session timedout!\n");); /* Clean it up */ UdpSessionCleanup(lwssn); ProcessUdp(lwssn, p, s5UdpPolicy); } else { ProcessUdp(lwssn, p, s5UdpPolicy); DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Finished Stream5 UDP cleanly!\n" "---------------------------------------------------\n");); } MarkupPacketFlags(p, lwssn); Stream5SetExpire(p, lwssn, s5UdpPolicy->session_timeout); return 0;}static int ProcessUdp(Stream5LWSession *lwssn, Packet *p, Stream5UdpPolicy *s5UdpPolicy){ char ignore = 0; UdpSession *udpssn = (UdpSession *)lwssn->proto_specific_data; DEBUG_WRAP( char *t = NULL; char *l = NULL; ); if (lwssn->protocol != IPPROTO_UDP) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Lightweight session not UDP on UDP packet\n");); return ACTION_NOTHING; } if (lwssn->session_flags & (SSNFLAG_DROP_CLIENT|SSNFLAG_DROP_SERVER)) { /* figure out direction of this packet */ GetLWPacketDirection(p, lwssn); /* Got a packet on a session that was dropped (by a rule). */ /* TODO: Send reset to other side if not already done for inline mode */ //if (!(lwssn->session_flags & SSNFLAG_SERVER_RESET) //{ // Send Server Reset // lwssn->session_state |= STREAM5_STATE_SERVER_RESET; //} //if (!(lwssn->session_flags & SSNFLAG_CLIENT_RESET) //{ // Send Client Reset // lwssn->session_state |= STREAM5_STATE_CLIENT_RESET; //} /* Drop this packet */ if (((p->packet_flags & PKT_FROM_SERVER) && (lwssn->session_flags & SSNFLAG_DROP_SERVER)) || ((p->packet_flags & PKT_FROM_CLIENT) && (lwssn->session_flags & SSNFLAG_DROP_CLIENT))) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Blocking %s packet as session was blocked\n", p->packet_flags & PKT_FROM_SERVER ? "server" : "client");); DisableDetect(p); /* Still want to add this number of bytes to totals */ SetPreprocBit(p, PP_PERFMONITOR); InlineDrop(p); return ACTION_NOTHING; } } if (udpssn == NULL) { lwssn->direction = FROM_SENDER; IP_COPY_VALUE(lwssn->client_ip, GET_SRC_IP(p)); lwssn->client_port = p->udph->uh_sport; IP_COPY_VALUE(lwssn->server_ip, GET_DST_IP(p)); lwssn->server_port = p->udph->uh_dport; lwssn->session_state |= STREAM5_STATE_SENDER_SEEN; NewUdpSession(p, lwssn, s5UdpPolicy); udpssn = (UdpSession *)lwssn->proto_specific_data; } /* figure out direction of this packet */ GetLWPacketDirection(p, lwssn); if (((p->packet_flags & PKT_FROM_SERVER) && (lwssn->ignore_direction & SSN_DIR_CLIENT)) || ((p->packet_flags & PKT_FROM_CLIENT) && (lwssn->ignore_direction & SSN_DIR_SERVER))) { Stream5DisableInspection(lwssn, p); DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Stream5 Ignoring packet from %d. " "Session marked as ignore\n", p->packet_flags & PKT_FROM_CLIENT? "sender" : "responder");); return ACTION_NOTHING; } /* Check if the session is to be ignored */ ignore = CheckIgnoreChannel(p); if (ignore) { /* Set the directions to ignore... */ lwssn->ignore_direction = ignore; DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Stream5: Ignoring packet from %d. " "Marking session marked as ignore.\n", p->packet_flags & PKT_FROM_CLIENT? "sender" : "responder");); Stream5DisableInspection(lwssn, p); return ACTION_NOTHING; } /* if both seen, mark established */ if(p->packet_flags & PKT_FROM_SERVER) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Stream5: Updating on packet from responder\n");); lwssn->session_flags |= SSNFLAG_SEEN_RESPONDER; DEBUG_WRAP( t = "Responder"; l = "Sender"); } else { DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Stream5: Updating on packet from client\n");); /* if we got here we had to see the SYN already... */ lwssn->session_flags |= SSNFLAG_SEEN_SENDER; DEBUG_WRAP( t = "Sender"; l = "Responder"); } if (!(lwssn->session_flags & SSNFLAG_ESTABLISHED)) { if ((lwssn->session_flags & SSNFLAG_SEEN_SENDER) && (lwssn->session_flags & SSNFLAG_SEEN_RESPONDER)) { lwssn->session_flags |= SSNFLAG_ESTABLISHED; } } return ACTION_NOTHING;}void UdpUpdateDirection(Stream5LWSession *ssn, char dir, snort_ip_p ip, u_int16_t port){ UdpSession *udpssn = (UdpSession *)ssn->proto_specific_data; snort_ip tmpIp; u_int16_t tmpPort;#ifdef SUP_IP6 if (IP_EQUALITY(&udpssn->udp_sender_ip, ip) && (udpssn->udp_sender_port == port)) { if ((dir == SSN_DIR_SENDER) && (ssn->direction == SSN_DIR_SENDER)) { /* Direction already set as SENDER */ return; } } else if (IP_EQUALITY(&udpssn->udp_responder_ip, ip) && (udpssn->udp_responder_port == port)) { if ((dir == SSN_DIR_RESPONDER) && (ssn->direction == SSN_DIR_RESPONDER)) { /* Direction already set as RESPONDER */ return; } }#else if (IP_EQUALITY(udpssn->udp_sender_ip, ip) && (udpssn->udp_sender_port == port)) { if ((dir == SSN_DIR_SENDER) && (ssn->direction == SSN_DIR_SENDER)) { /* Direction already set as SENDER */ return; } } else if (IP_EQUALITY(udpssn->udp_responder_ip, ip) && (udpssn->udp_responder_port == port)) { if ((dir == SSN_DIR_RESPONDER) && (ssn->direction == SSN_DIR_RESPONDER)) { /* Direction already set as RESPONDER */ return; } }#endif /* Swap them -- leave ssn->direction the same */ tmpIp = udpssn->udp_sender_ip; tmpPort = udpssn->udp_sender_port; udpssn->udp_sender_ip = udpssn->udp_responder_ip; udpssn->udp_sender_port = udpssn->udp_responder_port; udpssn->udp_responder_ip = tmpIp; udpssn->udp_responder_port = tmpPort;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -