/* System includes */ #include #include #include #include #include #include #include /* Our includes */ #include "constants.h" #include "packet.h" #include "hash.h" /* Table of packets */ struct hash_table* PacketTable; /* Hash related functions we need to define */ int pack_clean(struct pdata* data) { /* Never clean unless explicitly demanded */ return 0; } int pack_compare(struct pkey* k1, struct pkey* k2) { if (k1 == NULL || k2 == NULL) return 0; if (k1->seqnum == k2->seqnum && k1->dport == k2->dport) return 1; else return 0; } unsigned long pack_hash1(struct pkey* k, unsigned long size) { /* Here we just hash sum of fields */ return (k->seqnum % size + k->dport % size) % size; } void create_packtable() { /* Create hash with same min and max size to avoid rehashing since we did not use locks for any operation */ create_hash(&PacketTable, PACK_TABLE_SIZE, PACK_TABLE_SIZE, PACK_TABLE_SIZE, 1, 0, sizeof(struct pkey), sizeof(struct pdata), (int (*)(void*))pack_clean, (int (*)(void*,void*))pack_compare, (unsigned long (*)(void*,unsigned long))pack_hash1); } /* Utility functions that mask hash structure */ /* Insert new packet */ long insert_packet(unsigned int seqnum, unsigned short dport, double timestamp) { struct pkey key; struct pdata* data; int index, outcome; key.seqnum = seqnum; key.dport = dport; index = find(&key, PacketTable); if (index != NOT_FOUND) outcome = EXISTING; else index = insert(&key, PacketTable,&outcome); if (index != NOT_FOUND && outcome == NEW) { data = (struct pdata*)PacketTable->entries[index].data; data->ts = 0; data->timestamp[data->ts++] = timestamp; return index; } else if (index != NOT_FOUND && outcome == EXISTING) { data = (struct pdata*)PacketTable->entries[index].data; if (data->ts < MAX_TS) data->timestamp[data->ts++] = timestamp; return index; } return NOT_FOUND; } /* Find packet and return its index in hash*/ unsigned long find_packet(unsigned int seqnum, unsigned short dport) { struct pkey key; key.seqnum = seqnum; key.dport = dport; return find(&key, PacketTable); } /* Remove packet from hash */ void delete_packet(unsigned int seqnum, unsigned short dport) { struct pkey key; unsigned int index; key.seqnum = seqnum; key.dport = dport; index = find(&key, PacketTable); if (index != NOT_FOUND) { struct pdata* data = (struct pdata*)PacketTable->entries[index].data; if (data->ts == 1) { delete(&key,PacketTable); } else { int i; for (i=0;its-1;i++) data->timestamp[i] = data->timestamp[i+1]; data->ts--; } } } void reset_packtable() { reset_table(PacketTable); } /* Delete hash table on exit */ void delete_packtable() { int i; if (PacketTable == NULL || PacketTable->entries == NULL) return; for(i=0;isize;i++) { if(PacketTable->entries[i].state == VALID) { free(PacketTable->entries[i].key); PacketTable->entries[i].key = NULL; free(PacketTable->entries[i].data); PacketTable->entries[i].data = NULL; } } free(PacketTable->entries); PacketTable->entries = NULL; free(PacketTable); PacketTable = NULL; } struct pdata* get_pdata(unsigned long index) { struct pdata* d = (struct pdata*)PacketTable->entries[index].data; return d; } int isFullPacketTable() { int isfull = (PacketTable->filled >= PacketTable->size*FULL_ALERT_LF); if (isfull) printf("Is full \n"); return isfull; }