static int ps_tracker_lookup(PS_PKT *ps_pkt, PS_TRACKER **scanner, PS_TRACKER **scanned) { PS_HASH_KEY key; Packet *p; if (ps_pkt->pkt == NULL) return -1; p = (Packet *)ps_pkt->pkt; if (ps_get_proto(ps_pkt, &key.protocol) == -1) return -1; ps_pkt->proto = key.protocol; key.policyId = getRuntimePolicy(); /* ** Let's lookup the host that is being scanned, taking into account ** the pkt may be reversed. */ if (portscan_eval_config->detect_scan_type & (PS_TYPE_PORTSCAN | PS_TYPE_DECOYSCAN | PS_TYPE_DISTPORTSCAN)) { IP_CLEAR(key.scanner); if(ps_pkt->reverse_pkt) IP_COPY_VALUE(key.scanned, GET_SRC_IP(p)); else IP_COPY_VALUE(key.scanned, GET_DST_IP(p)); /* ** Get the scanned tracker. */ ps_tracker_get(scanned, &key); } /* ** Let's lookup the host that is scanning. */ if(portscan_eval_config->detect_scan_type & PS_TYPE_PORTSWEEP) { IP_CLEAR(key.scanned); if(ps_pkt->reverse_pkt) IP_COPY_VALUE(key.scanner, GET_DST_IP(p)); else IP_COPY_VALUE(key.scanner, GET_SRC_IP(p)); /* ** Get the scanner tracker */ ps_tracker_get(scanner, &key); } if ((*scanner == NULL) && (*scanned == NULL)) return -1; return 0; }
void setUdpDirectionAndPorts( Packet *p, SessionControlBlock *scb ) { scb->ha_state.direction = FROM_SENDER; IP_COPY_VALUE(scb->client_ip, GET_SRC_IP(p)); scb->client_port = p->udph->uh_sport; IP_COPY_VALUE(scb->server_ip, GET_DST_IP(p)); scb->server_port = p->udph->uh_dport; }
static int ps_tracker_update_udp(PS_PKT *ps_pkt, PS_TRACKER *scanner, PS_TRACKER *scanned) { Packet *p; snort_ip cleared; IP_CLEAR(cleared); p = (Packet *)ps_pkt->pkt; if(p->icmph) { if(scanned) { ps_proto_update(&scanned->proto,0,1,CLEARED,0,0); scanned->priority_node = 1; } if(scanner) { ps_proto_update(&scanner->proto,0,1,CLEARED,0,0); scanner->priority_node = 1; } } else if(p->udph) { if (stream_api && (stream_api->version >= STREAM_API_VERSION5) && p->ssnptr) { uint32_t direction = stream_api->get_packet_direction(p); if (direction == PKT_FROM_CLIENT) { if(scanned) { ps_proto_update(&scanned->proto,1,0, GET_SRC_IP(p),p->dp, packet_time()); } if(scanner) { ps_proto_update(&scanner->proto,1,0, GET_DST_IP(p),p->dp, packet_time()); } } else if (direction == PKT_FROM_SERVER) { if(scanned) ps_proto_update(&scanned->proto,-1,0,CLEARED,0,0); if(scanner) ps_proto_update(&scanner->proto,-1,0,CLEARED,0,0); } } } return 0; }
/** * * @param sip - source IP address * @param dip - destination IP address * @param sport - server sport number * @param file_sig - file signature * @param expiry - session expiry in seconds. */ int file_resume_block_add_file(void *pkt, uint32_t file_sig, uint32_t timeout, File_Verdict verdict, uint32_t file_type_id, uint8_t *signature) { FileHashKey hashKey; SFXHASH_NODE *hash_node = NULL; FileNode *node; FileNode new_node; snort_ip_p srcIP; snort_ip_p dstIP; Packet *p = (Packet *)pkt; time_t now = p->pkth->ts.tv_sec; srcIP = GET_SRC_IP(p); dstIP = GET_DST_IP(p); IP_COPY_VALUE(hashKey.dip, dstIP); IP_COPY_VALUE(hashKey.sip, srcIP); hashKey.file_sig = file_sig; hash_node = sfxhash_find_node(fileHash, &hashKey); if (hash_node) { if (!(node = hash_node->data)) sfxhash_free_node(fileHash, hash_node); } else node = NULL; if (node) { node->expires = now + timeout; updateFileNode(node, verdict, file_type_id, signature); } else { DEBUG_WRAP(DebugMessage(DEBUG_FILE, "Adding file node\n");); updateFileNode(&new_node, verdict, file_type_id, signature); /* * use the time that we keep files around * since this info would effectively be invalid * after that anyway because the file that * caused this will be gone. */ new_node.expires = now + timeout; /* Add it to the table */ if (sfxhash_add(fileHash, &hashKey, &new_node) != SFXHASH_OK) { /* Uh, shouldn't get here... * There is already a node or couldn't alloc space * for key. This means bigger problems, but fail * gracefully. */ DEBUG_WRAP(DebugMessage(DEBUG_FILE, "Failed to add file node to hash table\n"););
static inline void rekeyMasterAFActKey (SFSnortPacket *p, int dir, tAppId forecast) { int i; sfaddr_t *src; src = dir ? GET_DST_IP(p) : GET_SRC_IP(p); for (i = 0; i < 4; i++) master_key.ip[i] = src->ia32[i]; master_key.forecast = forecast; }
static int LogPortscanAlert(Packet *p, char *msg, uint32_t event_id, uint32_t event_ref, uint32_t gen_id, uint32_t sig_id) { char timebuf[TIMEBUF_SIZE]; snort_ip_p src_addr; snort_ip_p dst_addr; if(!p->iph_api) return -1; /* Do not log if being suppressed */ src_addr = GET_SRC_IP(p); dst_addr = GET_DST_IP(p); if( sfthreshold_test(gen_id, sig_id, src_addr, dst_addr, p->pkth->ts.tv_sec) ) { return 0; } ts_print((struct timeval *)&p->pkth->ts, timebuf); fprintf(g_logfile, "Time: %s\n", timebuf); if(event_id) fprintf(g_logfile, "event_id: %u\n", event_id); else fprintf(g_logfile, "event_ref: %u\n", event_ref); fprintf(g_logfile, "%s ", inet_ntoa(GET_SRC_ADDR(p))); fprintf(g_logfile, "-> %s %s\n", inet_ntoa(GET_DST_ADDR(p)), msg); fprintf(g_logfile, "%.*s\n", p->dsize, p->data); fflush(g_logfile); return 0; }
/** ** Determine how to update the portscan counter depending on the type ** of TCP packet we have. ** ** We are concerned with three types of TCP packets: ** ** - initiating TCP packets (we don't care about flags) ** - TCP 3-way handshake packets (we decrement the counter) ** - TCP reset packets on unestablished streams. */ static int ps_tracker_update_tcp(PS_PKT *ps_pkt, PS_TRACKER *scanner, PS_TRACKER *scanned) { Packet *p; uint32_t session_flags; snort_ip cleared; IP_CLEAR(cleared); p = (Packet *)ps_pkt->pkt; /* ** Handle the initiating packet. ** ** If this what stream4 considers to be a valid initiator, then ** we will use the available stream4 information. Otherwise, we ** can just revert to flow and look for initiators and responders. ** ** For Stream5, depending on the configuration, there might not ** be a session created only based on the SYN packet. Stream5 ** by default has code that helps deal with SYN flood attacks, ** and may simply ignore the SYN. In this case, we fall through ** to the checks for specific TCP header files (SYN, SYN-ACK, RST). ** ** The "midstream" logic below says that, if we include sessions ** picked up midstream, then we don't care about the MIDSTREAM flag. ** Otherwise, only consider streams not picked up midstream. */ if(p->ssnptr && stream_api) { session_flags = stream_api->get_session_flags(p->ssnptr); if((session_flags & SSNFLAG_SEEN_CLIENT) && !(session_flags & SSNFLAG_SEEN_SERVER) && (portscan_eval_config->include_midstream || !(session_flags & SSNFLAG_MIDSTREAM))) { if(scanned) { ps_proto_update(&scanned->proto,1,0, GET_SRC_IP(p),p->dp, packet_time()); } if(scanner) { ps_proto_update(&scanner->proto,1,0, GET_DST_IP(p),p->dp, packet_time()); } } /* ** Handle the final packet of the three-way handshake. */ else if(p->packet_flags & PKT_STREAM_TWH) { if(scanned) { ps_proto_update(&scanned->proto,-1,0,CLEARED,0,0); } if(scanner) { ps_proto_update(&scanner->proto,-1,0,CLEARED,0,0); } } /* ** RST packet on unestablished streams */ else if((p->packet_flags & PKT_FROM_SERVER) && (p->tcph && (p->tcph->th_flags & TH_RST)) && (!(p->packet_flags & PKT_STREAM_EST) || (session_flags & SSNFLAG_MIDSTREAM))) { if(scanned) { ps_proto_update(&scanned->proto,0,1,CLEARED,0,0); scanned->priority_node = 1; } if(scanner) { ps_proto_update(&scanner->proto,0,1,CLEARED,0,0); scanner->priority_node = 1; } } /* ** We only get here on the server's response to the intial ** client connection. ** ** That's why we use the sp, because that's the port that is ** open. */ else if((p->packet_flags & PKT_FROM_SERVER) && !(p->packet_flags & PKT_STREAM_EST)) { if(scanned) { ps_update_open_ports(&scanned->proto, p->sp); } if(scanner) { if(scanner->proto.alerts == PS_ALERT_GENERATED) scanner->proto.alerts = PS_ALERT_OPEN_PORT; } } } /* ** Stream didn't create a session on the SYN packet, ** so check specifically for SYN here. */ else if (p->tcph && (p->tcph->th_flags == TH_SYN)) { /* No session established, packet only has SYN. SYN only ** packet always from client, so use dp. */ if(scanned) { ps_proto_update(&scanned->proto,1,0, GET_SRC_IP(p),p->dp, packet_time()); } if(scanner) { ps_proto_update(&scanner->proto,1,0, GET_DST_IP(p),p->dp, packet_time()); } } /* ** Stream didn't create a session on the SYN packet, ** so check specifically for SYN & ACK here. Clear based ** on the 'completion' of three-way handshake. */ else if(p->tcph && (p->tcph->th_flags == (TH_SYN|TH_ACK))) { if(scanned) { ps_proto_update(&scanned->proto,-1,0,CLEARED,0,0); } if(scanner) { ps_proto_update(&scanner->proto,-1,0,CLEARED,0,0); } } /* ** No session created, clear based on the RST on non ** established session. */ else if (p->tcph && (p->tcph->th_flags & TH_RST)) { if(scanned) { ps_proto_update(&scanned->proto,0,1,CLEARED,0,0); scanned->priority_node = 1; } if(scanner) { ps_proto_update(&scanner->proto,0,1,CLEARED,0,0); scanner->priority_node = 1; } } /* ** If we are an icmp unreachable, deal with it here. */ else if(p->icmph) { if(scanned) { ps_proto_update(&scanned->proto,0,1,CLEARED,0,0); scanned->priority_node = 1; } if(scanner) { ps_proto_update(&scanner->proto,0,1,CLEARED,0,0); scanner->priority_node = 1; } } return 0; }
/** ** Check the incoming packet to decide whether portscan detection cares ** about this packet. We try to ignore as many packets as possible. */ static int ps_filter_ignore(PS_PKT *ps_pkt) { Packet *p; int reverse_pkt = 0; snort_ip_p scanner, scanned; p = (Packet *)ps_pkt->pkt; if(!IPH_IS_VALID(p)) return 1; if(p->tcph) { if(!(portscan_eval_config->detect_scans & PS_PROTO_TCP)) return 1; /* ** This is where we check all of snort's flags for different ** TCP session scenarios. The checks cover: ** ** - dropping packets in established sessions, but not the ** TWH packet. ** - dropping the SYN/ACK packet from the server on a valid ** connection (we'll catch the TWH later if it happens). */ /* ** Ignore packets that are already part of an established TCP ** stream. */ if(((p->packet_flags & (PKT_STREAM_EST | PKT_STREAM_TWH)) == PKT_STREAM_EST) && !(p->tcph->th_flags & TH_RST)) { return 1; } /* ** Ignore the server's initial response, unless it's to RST ** the connection. */ /* if(!(p->tcph->th_flags & TH_RST) && !(p->packet_flags & (PKT_STREAM_EST)) && (p->packet_flags & PKT_FROM_SERVER)) { return 1; } */ } else if(p->udph) { if(!(portscan_eval_config->detect_scans & PS_PROTO_UDP)) return 1; } else if(p->icmph) { if(p->icmph->type != ICMP_DEST_UNREACH && !(portscan_eval_config->detect_scans & PS_PROTO_ICMP)) { return 1; } } else { if(!(portscan_eval_config->detect_scans & PS_PROTO_IP)) return 1; } /* ** Check if the packet is reversed */ if((p->packet_flags & PKT_FROM_SERVER)) { reverse_pkt = 1; } else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH) { reverse_pkt = 1; } else if (p->udph && p->ssnptr && stream_api && stream_api->version >= STREAM_API_VERSION5) { if (stream_api->get_packet_direction(p) & PKT_FROM_SERVER) reverse_pkt = 1; } scanner = GET_SRC_IP(p); scanned = GET_DST_IP(p); if(reverse_pkt) { if(ps_ignore_ip(scanned, p->dp, scanner, p->sp)) return 1; } else { if(ps_ignore_ip(scanner, p->sp, scanned, p->dp)) return 1; } ps_pkt->reverse_pkt = reverse_pkt; if(portscan_eval_config->watch_ip) { if(ipset_contains(portscan_eval_config->watch_ip, scanner, &(p->sp))) return 0; if(ipset_contains(portscan_eval_config->watch_ip, scanned, &(p->dp))) return 0; return 1; } return 0; }
int GetSessionKey(Packet *p, SessionHashKey *key) { ip_p srcIp, dstIp; u_int16_t srcPort, dstPort; if (!key) return 0; memset(key, 0, sizeof(SessionHashKey)); srcIp = GET_SRC_IP(p); dstIp = GET_DST_IP(p); if (p->tcph) { srcPort = p->tcph->th_sport; dstPort = p->tcph->th_dport; } #ifdef STREAM4_UDP else if (p->udph) { srcPort = p->udph->uh_sport; dstPort = p->udph->uh_dport; } #endif else { srcPort = 0; dstPort = 0; } if (IP_LESSER(srcIp, dstIp)) { IP_COPY_VALUE(key->lowIP, srcIp); key->port = srcPort; IP_COPY_VALUE(key->highIP, dstIp); key->port2 = dstPort; } else if (IP_EQUALITY(srcIp, dstIp)) { IP_COPY_VALUE(key->lowIP, srcIp); IP_COPY_VALUE(key->highIP, dstIp); if (srcPort < dstPort) { key->port = srcPort; key->port2 = dstPort; } else { key->port2 = srcPort; key->port = dstPort; } } else { IP_COPY_VALUE(key->lowIP, dstIp); key->port = dstPort; IP_COPY_VALUE(key->highIP, srcIp); key->port2 = srcPort; } key->proto = GET_IPH_PROTO(p); #ifdef _LP64 key->pad1 = key->pad2 = 0; #endif return 1; }
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; }
/******************************************************************** * Function: DCE2_ClProcess() * * Main entry point for connectionless DCE/RPC processing. Gets * the activity tracker associated with this session and passes * along to client or server handling. * * Arguments: * DCE2_SsnData * * Pointer to the session data structure. * DCE2_ClTracker * * Pointer to the connectionless tracker structure. * * Returns: None * ********************************************************************/ void DCE2_ClProcess(DCE2_SsnData *sd, DCE2_ClTracker *clt) { DceRpcClHdr *cl_hdr; DCE2_ClActTracker *at; const uint8_t *data_ptr = sd->wire_pkt->payload; uint16_t data_len = sd->wire_pkt->payload_size; PROFILE_VARS; DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Cl processing ...\n")); dce2_stats.cl_pkts++; if (data_len < sizeof(DceRpcClHdr)) { if (!DCE2_SsnAutodetected(sd)) DCE2_Alert(sd, DCE2_EVENT__CL_DATA_LT_HDR, data_len, sizeof(DceRpcClHdr)); return; } cl_hdr = (DceRpcClHdr *)data_ptr; DCE2_MOVE(data_ptr, data_len, sizeof(DceRpcClHdr)); if (DCE2_ClHdrChecks(sd, cl_hdr) != DCE2_RET__SUCCESS) return; PREPROC_PROFILE_START(dce2_pstat_cl_acts); at = DCE2_ClGetActTracker(clt, cl_hdr); PREPROC_PROFILE_END(dce2_pstat_cl_acts); if (at == NULL) return; if (DCE2_SsnFromClient(sd->wire_pkt)) { switch (DceRpcClPduType(cl_hdr)) { case DCERPC_PDU_TYPE__REQUEST: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Request\n")); dce2_stats.cl_request++; DCE2_ClRequest(sd, at, cl_hdr, data_ptr, data_len); break; case DCERPC_PDU_TYPE__ACK: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Ack\n")); dce2_stats.cl_ack++; break; case DCERPC_PDU_TYPE__CL_CANCEL: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Cancel\n")); dce2_stats.cl_cancel++; break; case DCERPC_PDU_TYPE__FACK: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Fack\n")); dce2_stats.cl_cli_fack++; break; case DCERPC_PDU_TYPE__PING: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Ping\n")); dce2_stats.cl_ping++; break; case DCERPC_PDU_TYPE__RESPONSE: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Response from client. Changing stream direction.")); _dpd.streamAPI->update_direction(sd->wire_pkt->stream_session, SSN_DIR_FROM_RESPONDER, GET_SRC_IP(((SFSnortPacket *)sd->wire_pkt)), sd->wire_pkt->src_port); break; default: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Other pdu type\n")); dce2_stats.cl_other_req++; break; } } else { switch (DceRpcClPduType(cl_hdr)) { case DCERPC_PDU_TYPE__RESPONSE: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Response\n")); dce2_stats.cl_response++; break; case DCERPC_PDU_TYPE__REJECT: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Reject\n")); dce2_stats.cl_reject++; if (DceRpcClSeqNum(cl_hdr) == at->seq_num) { DCE2_ClResetFragTracker(&at->frag_tracker); at->seq_num_invalid = 1; } break; case DCERPC_PDU_TYPE__CANCEL_ACK: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Cancel Ack\n")); dce2_stats.cl_cancel_ack++; break; case DCERPC_PDU_TYPE__FACK: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Fack\n")); dce2_stats.cl_srv_fack++; break; case DCERPC_PDU_TYPE__FAULT: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Fault\n")); dce2_stats.cl_fault++; break; case DCERPC_PDU_TYPE__NOCALL: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "No call\n")); dce2_stats.cl_nocall++; break; case DCERPC_PDU_TYPE__WORKING: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Working\n")); dce2_stats.cl_working++; break; default: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__CL, "Other pdu type\n")); dce2_stats.cl_other_resp++; break; } } }
void ppm_pkt_log(ppm_cfg_t *ppm_cfg, Packet* p) { int filterEvent = 0; if (!ppm_cfg->max_pkt_ticks) return; ppm_cfg->pkt_event_cnt++; if (ppm_cfg->pkt_log & PPM_LOG_ALERT) { OptTreeNode* potn; Event ev; /* make sure we have an otn already in our table for this event */ potn = OtnLookup(snort_conf->otn_map, GENERATOR_PPM, PPM_EVENT_PACKET_ABORTED); if (potn == NULL) { /* have to make one */ potn = GenerateSnortEventOtn(GENERATOR_PPM, /* GID */ PPM_EVENT_PACKET_ABORTED, /* SID */ 1, /* Rev */ 0, /* classification */ 3, /* priority (low) */ PPM_EVENT_PACKET_ABORTED_STR /* msg string */); if (potn == NULL) return; OtnLookupAdd(snort_conf->otn_map, potn); } SetEvent(&ev, potn->sigInfo.generator, /* GID */ potn->sigInfo.id, /* SID */ potn->sigInfo.rev, /* Rev */ potn->sigInfo.class_id, /* classification */ potn->sigInfo.priority, /* priority (low) */ #if !defined(FEAT_OPEN_APPID) 0); #else /* defined(FEAT_OPEN_APPID) */ 0, NULL); #endif /* defined(FEAT_OPEN_APPID) */ if ( IPH_IS_VALID(p) ) { filterEvent = sfthreshold_test( potn->event_data.sig_generator, potn->event_data.sig_id, GET_SRC_IP(p), GET_DST_IP(p), p->pkth->ts.tv_sec); } else { snort_ip cleared; IP_CLEAR(cleared); filterEvent = sfthreshold_test( potn->event_data.sig_generator, potn->event_data.sig_id, IP_ARG(cleared), IP_ARG(cleared), p->pkth->ts.tv_sec); } if(filterEvent < 0) filterEvent = 0; else AlertAction(p, potn, &ev); }
/** * * @param sip - source IP address * @param dip - destination IP address * @param sport - server sport number * @param file_sig - file signature * @param expiry - session expiry in seconds. */ int file_resume_block_add_file(void *pkt, uint32_t file_sig, uint32_t timeout, File_Verdict verdict, uint32_t file_type_id, uint8_t *signature) { FileHashKey hashKey; SFXHASH_NODE *hash_node = NULL; FileNode *node; FileNode new_node; sfaddr_t* srcIP; sfaddr_t* dstIP; Packet *p = (Packet*)pkt; time_t now = p->pkth->ts.tv_sec; srcIP = GET_SRC_IP(p); dstIP = GET_DST_IP(p); sfaddr_copy_to_raw(&hashKey.dip, dstIP); sfaddr_copy_to_raw(&hashKey.sip, srcIP); hashKey.file_sig = file_sig; #ifdef HAVE_DAQ_DP_ADD_DC { DAQ_DC_Params params; memset(¶ms, 0, sizeof(params)); params.flags = DAQ_DC_ALLOW_MULTIPLE | DAQ_DC_PERSIST; params.timeout_ms = 5 * 60 * 1000; /* 5 minutes */ if (p->packet_flags & PKT_FROM_CLIENT) DAQ_Add_Dynamic_Protocol_Channel(p, srcIP, 0, dstIP, p->dp, GET_IPH_PROTO(p), ¶ms); else if (p->packet_flags & PKT_FROM_SERVER) DAQ_Add_Dynamic_Protocol_Channel(p, dstIP, 0, srcIP, p->sp, GET_IPH_PROTO(p), ¶ms); } #endif hash_node = sfxhash_find_node(fileHash, &hashKey); if (hash_node) { if (!(node = hash_node->data)) sfxhash_free_node(fileHash, hash_node); } else node = NULL; if (node) { node->expires = now + timeout; updateFileNode(node, verdict, file_type_id, signature); } else { DEBUG_WRAP(DebugMessage(DEBUG_FILE, "Adding file node\n");); updateFileNode(&new_node, verdict, file_type_id, signature); /* * use the time that we keep files around * since this info would effectively be invalid * after that anyway because the file that * caused this will be gone. */ new_node.expires = now + timeout; /* Add it to the table */ if (sfxhash_add(fileHash, &hashKey, &new_node) != SFXHASH_OK) { /* Uh, shouldn't get here... * There is already a node or couldn't alloc space * for key. This means bigger problems, but fail * gracefully. */ DEBUG_WRAP(DebugMessage(DEBUG_FILE, "Failed to add file node to hash table\n"););
FileEntry *file_cache_get(FileCache *fileCache, void* p, uint64_t file_id, bool can_create) { SFXHASH_NODE *hnode; FileKey fileKey; Packet *pkt = (Packet *)p; sfaddr_t* srcIP; sfaddr_t* dstIP; if ((fileCache == NULL) || (fileCache->hashTable == NULL)) return NULL; if ((pkt->packet_flags & PKT_FROM_CLIENT)) { srcIP = GET_SRC_IP(pkt); dstIP = GET_DST_IP(pkt); } else { srcIP = GET_DST_IP(pkt); dstIP = GET_SRC_IP(pkt); } sfaddr_copy_to_raw(&fileKey.dip, dstIP); sfaddr_copy_to_raw(&fileKey.sip, srcIP); fileKey.file_id = file_id; if (!can_create) { hnode = sfxhash_find_node(fileCache->hashTable, &fileKey); } else { hnode = sfxhash_get_node(fileCache->hashTable, &fileKey); if (!hnode) { /*No more file entries, free up some old ones*/ pruneFileCache(fileCache, NULL); /* Should have some freed nodes now */ hnode = sfxhash_get_node(fileCache->hashTable, &fileKey); #ifdef DEBUG_MSGS if (!hnode) LogMessage("%s(%d) Problem, no freed nodes\n", __FILE__, __LINE__); #endif } } if (hnode && hnode->data) { FileEntry *file_entry = (FileEntry *)hnode->data; return file_entry; } else { return NULL; } }