void capture_packet_time_sorter(vector_t *vector, void *item) { struct timeval curts, prevts; int count = vector_count(vector); int i; // TODO Implement multiframe packets curts = packet_time(item); prevts = packet_time(vector_last(vector)); // Check if the item is already sorted if (timeval_is_older(curts, prevts)) { return; } for (i = count - 2 ; i >= 0; i--) { // Get previous packet prevts = packet_time(vector_item(vector, i)); // Check if the item is already in a sorted position if (timeval_is_older(curts, prevts)) { vector_insert(vector, item, i + 1); return; } } // Put this item at the begining of the vector vector_insert(vector, item, 0); }
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; }
static int ps_tracker_update_icmp(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) { switch(p->icmph->type) { case ICMP_ECHO: case ICMP_TIMESTAMP: case ICMP_ADDRESS: case ICMP_INFO_REQUEST: if(scanner) { ps_proto_update(&scanner->proto,1,0, GET_DST_IP(p), 0, packet_time()); } break; case ICMP_DEST_UNREACH: if(scanner) { ps_proto_update(&scanner->proto,0,1,CLEARED,0,0); scanner->priority_node = 1; } break; default: break; } } return 0; }
/** ** This function is passed into the hash algorithm, so that ** we only reuse nodes that aren't priority nodes. We have to make ** sure that we only track so many priority nodes, otherwise we could ** have all priority nodes and not be able to allocate more. */ static int ps_tracker_free(void *key, void *data) { PS_TRACKER *tracker; if(!key || !data) return 0; tracker = (PS_TRACKER *)data; if(!tracker->priority_node) return 0; /* ** Cycle through the protos to see if it's past the time. ** We only get here if we ARE a priority node. */ if(tracker->proto.window >= packet_time()) return 1; 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; }