void * hash_tbl_lookup (char *key, HASH_TABLE *htbl) { hash_bucket_t *pbkt = find_hash_entry (key, htbl); if (!pbkt) { return NULL; } return pbkt->data; }
static int hash_add_entry (uint8_t *string, HASH_TABLE *htbl, void *data) { hash_bucket_t *hentry = NULL; int bucket = -1; if (!htbl) return NULL; if (!(hentry = find_hash_entry (string, htbl))) { bucket = htbl->hash_index_gen (string); if (bucket > htbl->nbuckets) { return -1; } hentry = htbl->bucket_array[bucket]; while (hentry && hentry->next) hentry = hentry->next; if (hentry) { hentry->next = alloc_block (htbl->hmem_pool_id); if (!hentry->next) { return -1; } hentry = hentry->next; } else { htbl->bucket_array[bucket] = alloc_block (htbl->hmem_pool_id); hentry = htbl->bucket_array[bucket]; if (!hentry) return -1; } hentry->data = data; hentry->next = NULL; hentry->key = malloc (htbl->key_len); { int i = 0; for (; i < htbl->key_len; i++) hentry->key[i] = string[i]; } htbl->nentries++; } return 0; }
//External interface using a hash table to speedup the process funcPointerT findFunctionUsingDlopen(const char* function_name, const char* lib_name) { funcPointerT result =0; #if USE_UTHASH result = find_hash_entry(function_name); if (result) return result; else { result = findWithDlopen(function_name,lib_name); add_hash_entry(function_name,result); } #else result = findWithDlopen(function_name,lib_name); #endif return result; }
void count_flow (const struct ip * ip,uint16_t iplen,uint32_t tspkt) { flow tmp, tmp_peer; flow * flowrec=NULL; uint16_t hsize,psize,sslsize; uint32_t seq; struct tcphdr *t; int direction=0; t=(struct tcphdr *)(((uint8_t*)ip) + ip->ip_hl*4); hsize=ip->ip_hl*4+t->doff*4; psize=ntohs(ip->ip_len)-hsize; seq=ntohl(t->seq); if (psize>0) { // If this packet is a data packet, we look for its connection in the hashtable /* Set the key to the source/destination address pair. */ tmp.src.s_addr = ip->ip_src.s_addr; tmp.dst.s_addr = ip->ip_dst.s_addr; tmp.sport = ntohs (t->source); tmp.dport = ntohs (t->dest); // Peer tmp_peer.src.s_addr = tmp.dst.s_addr; tmp_peer.dst.s_addr = tmp.src.s_addr; tmp_peer.sport = tmp.dport; tmp_peer.dport = tmp.sport; direction=0; if (flowrec = (flow *) find_hash_entry (flow_hash, &tmp)) { direction=1; } else if (flowrec = (flow *) find_hash_entry (flow_hash, &tmp_peer)) { direction=2; } if (direction>0 && flowrec->label==LABEL_NONE) { // Connection exists, is classifiable (SYN seen) and in sequence //First we reorder the list of connection (connections with most recent packets at the end of the list) if (flowrec->next) { //Else connection is already the last in the last so no modification //Connection cannot be the first we have a special empty pointer for the head of the list (first_flow) flowrec->prev->next=flowrec->next; flowrec->next->prev=flowrec->prev; active_flows->next=flowrec; flowrec->prev=active_flows; flowrec->next=NULL; active_flows=flowrec; } flowrec->ts_latest=tspkt; if (direction==1) { if (flowrec->data1==0) { //First packet with data flowrec->data1=1; flowrec->nextseq=seq+psize; } else if (flowrec->nextseq!=seq) { //Out of sequence packet, we remove the entry for this connection flowrec->label=LABEL_OUTOFSEQ; if (memory>=OPT_NOSTORE) { print_flow(flowrec); clear_hash_entry(flow_hash,flowrec); return ; } } else { flowrec->nextseq+=psize; } } if (direction==2) { if (flowrec->data2==0) { //First packet in reverse direction, initialize sequence number flowrec->data2=1; flowrec->nextseqpeer=seq+psize; } else if (flowrec->nextseqpeer!=seq) { flowrec->label=LABEL_OUTOFSEQ; if (memory>=OPT_NOSTORE) { print_flow(flowrec); clear_hash_entry(flow_hash,flowrec); return ; } } else { flowrec->nextseqpeer+=psize; } } if (!flowrec->isSSL) { assert(flowrec->datapkts<pktlimit); flowrec->pkt_sizes[flowrec->datapkts]=(direction==1) ? psize : -psize; flowrec->datapkts+=1; analyze(flowrec); } //If packet is SSL we parse it if (flowrec->isSSL) { sslsize=0; if (!flowrec->SSLdata) { sslsize=sslpayload(((uint8_t*)t)+t->doff*4,psize,iplen-hsize); if (sslsize>0) flowrec->SSLdata=1; } else sslsize=psize-5; //5: length of SSL header if (flowrec->SSLdata) { assert(flowrec->datapkts<pktlimit); flowrec->pkt_sizes[flowrec->datapkts]=(direction==1) ? clearsize(sslsize) : -clearsize(sslsize); flowrec->datapkts+=1; analyze(flowrec); } } } // Else: Connection is not classifiable: ignored } else if (t->syn==1 && t->ack==0) { // We are only intersted in SYN packets when there is no data flowrec = (flow *) malloc (sizeof (flow)); if (flowrec == NULL) { fprintf (stderr, "Can't malloc new connection\n"); abort (); } flowrec->pkt_sizes=(int16_t *)malloc(pktlimit*sizeof(int16_t)); if (flowrec->pkt_sizes == NULL) { fprintf (stderr, "Can't malloc new connection\n"); abort (); } flowrec->label=LABEL_NONE; bzero(flowrec->pkt_sizes,pktlimit*sizeof(int16_t)); flowrec->src.s_addr=ip->ip_src.s_addr; flowrec->dst.s_addr=ip->ip_dst.s_addr; flowrec->sport=ntohs (t->source); flowrec->dport=ntohs (t->dest); flowrec->nextseq=0; flowrec->nextseqpeer=0; flowrec->data1=0; flowrec->data2=0; flowrec->isSSL=0; flowrec->SSLdata=0; flowrec->datapkts=0; flowrec->ts_latest=tspkt; flowrec->prev = active_flows; flowrec->next = NULL; active_flows->next = flowrec; active_flows = flowrec; nbflows++; add_hash_entry (flow_hash, flowrec); } else if (memory>=OPT_GARBAGE && (t->rst || t->fin)) { // We remove connections in which we see RST or FIN /* Set the key to the source/destination address pair. */ tmp.src.s_addr = ip->ip_src.s_addr; tmp.dst.s_addr = ip->ip_dst.s_addr; tmp.sport = ntohs (t->source); tmp.dport = ntohs (t->dest); // Peer tmp_peer.src.s_addr = tmp.dst.s_addr; tmp_peer.dst.s_addr = tmp.src.s_addr; tmp_peer.sport = tmp.dport; tmp_peer.dport = tmp.sport; flowrec = (flow *) find_hash_entry (flow_hash, &tmp); if (!flowrec) flowrec = (flow *) find_hash_entry (flow_hash, &tmp_peer); if (flowrec) { print_flow(flowrec); clear_hash_entry(flow_hash,flowrec); return ; } } flowrec; }