00001
00057 #ifndef _HASHTABLE_C
00058 #define _HASHTABLE_C
00059
00060 #include "common.h"
00061 #include "hashtable.h"
00062
00063 hashtable* createHashtable(unsigned int size){
00064 unsigned int i;
00065 hashtable * ht;
00066
00067 if(size<MINSIZE){
00068 printf("HT size should be at least %d",MINSIZE);
00069 exit(0);
00070 }
00071
00072 ht = (hashtable *) malloc(sizeof(hashtable));
00073
00074 if(NULL==ht){
00075 printf("Couldn't allocate memory for HT. Quitting ...\n");
00076 exit(0);
00077 }
00078
00079 ht->table = (ht_bucket *) malloc(sizeof(ht_bucket)*size);
00080
00081 if(NULL==ht->table){
00082 printf("Couldn't allocate memory for HT. Quitting ...\n");
00083 exit(0);
00084 }
00085
00086 ht->size = size;
00087 ht->count = 0;
00088
00089 for(i=0;i<size;i++){
00090 ht_bucket *b = &(const ht_bucket) ht->table[i];
00091 b->packet = (u_char *)0;
00092 b->state = INVALID;
00093 b->timestamp = 0;
00094 }
00095
00096 return ht;
00097 }
00098
00099 unsigned int hash(u_int32_t key, u_int32_t size){
00100 return key%size;
00101 }
00102
00103 unsigned int locate(hashtable *ht, u_char * raw){
00104 int current, collisions, probes, emptyslot=-1;
00105 u_int32_t seqno;
00106 struct tcphdr* tcp_hdr;
00107 ht_bucket* htb;
00108 int etherlen = sizeof(struct ether_header);
00109 collisions = 0;
00110 probes = 0;
00111
00112
00113 tcp_hdr = (const struct tcphdr*) (raw + sizeof(struct ether_header) + sizeof(struct ip6_hdr));
00114 seqno = ntohl(tcp_hdr->seq);
00115
00116
00117
00118
00119
00120
00121
00122
00123 current = hash(seqno, ht->size);
00124
00125
00126
00127
00128
00129 htb = &(const ht_bucket) ht->table[current];
00130
00131
00132 while( probes <= ht->size &&
00133 INVALID != htb->state){
00134
00135 if((VALID == htb->state)||(LATE == htb->state)){
00136
00137
00138
00139
00140
00141 if( (0 == memcmp(htb->packet+etherlen, raw+etherlen, 7))
00142 &&
00143 (0 == memcmp(htb->packet+etherlen+8, raw+etherlen+8, sizeof(struct ip6_hdr) + sizeof(struct tcphdr)-8))
00144 ){
00145
00146 return current;
00147 }
00148 } else if(DELETED == htb->state){
00149
00150
00151 if(NULL!=htb->packet){
00152 free(htb->packet);
00153 htb->packet = NULL;
00154 }
00155
00156 if(-1!=emptyslot)
00157 emptyslot=current;
00158 }
00159
00160 ++probes;
00161 current += 2 * ++collisions - 1;
00162 if( current >= ht->size )
00163 current -= ht->size;
00164
00165 htb = &(const ht_bucket) ht->table[current];
00166
00167 }
00168 if(probes > ht->size)
00169 return emptyslot;
00170 return current;
00171 }
00172
00173
00174 int makeEntry(hashtable * ht, u_char * raw, clock_t time){
00175 unsigned int pos = locate(ht, raw);
00176 ht_bucket * htb;
00177
00178 if(pos!=-1){
00179 htb = &(ht_bucket) ht->table[pos];
00180 if((VALID==htb->state)||(LATE==htb->state)){
00181
00182
00183
00184
00185
00186
00187
00188 htb->timestamp = time;
00189 } else{
00190 htb->packet = raw;
00191 htb->timestamp = time;
00192 htb->state = VALID;
00193 (ht->count)++;
00194
00195 }
00196 }else{
00197 printf("Hash table full, cannot snoop ...\n");
00198 return 0;
00199 }
00200
00201 return 1;
00202
00203 }
00204
00205 int performID(hashtable * ht, u_char * raw, clock_t time){
00206 unsigned int pos = locate(ht, raw);
00207 ht_bucket * htb;
00208
00209 if(pos!=-1){
00210
00211 htb = &(ht_bucket) ht->table[pos];
00212 if((VALID==htb->state)||(LATE==htb->state)){
00213
00214
00215
00216
00217
00218 free(htb->packet);
00219 htb->packet = NULL;
00220 htb->timestamp = time;
00221 htb->state = DELETED;
00222 (ht->count)--;
00223
00224 }
00225 }else{
00226 printf("No matching packet found in hashtable\n");
00227 return 0;
00228 }
00229
00230
00231
00232 return 1;
00233
00234 }
00235
00236
00237 void print(hashtable *ht){
00238 int i;
00239 ht_bucket* htb;
00240 printf("***** Hash Table contents *********\n");
00241 for(i=0;i<ht->size;i++){
00242 htb = &(const ht_bucket) ht->table[i];
00243 if(VALID == htb->state){
00244 printf("(V) [%u]:", htb->timestamp);
00245 dump_packet(htb->packet);
00246 }
00247 if(LATE == htb->state){
00248 printf("(L) [%u]:", htb->timestamp);
00249 dump_packet(htb->packet);
00250 }
00251
00252 }
00253 printf("*****************************************\n");
00254
00255 }
00256
00257 void dump_packet(u_char * packet){
00258
00259 struct ip6_hdr * ip6;
00260 struct tcphdr * tcp;
00261 u_int32_t seqno;
00262 char *src;
00263 char ntop_buf[INET6_ADDRSTRLEN];
00264 u_int16_t sport, dport;
00265
00266 ip6 = (const struct ip6_hdr*) (packet+ sizeof(struct ether_header));
00267 tcp = (const struct tcphdr*) (packet + sizeof(struct ether_header) + sizeof(struct ip6_hdr) );
00268
00269 seqno = ntohl(tcp->seq);
00270 sport = ntohs(tcp->source);
00271 dport = ntohs(tcp->dest);
00272
00273 src = inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf));
00274 printf("%s.%d >> ", src, sport);
00275 src = inet_ntop(AF_INET6, &ip6->ip6_dst, ntop_buf, sizeof(ntop_buf));
00276 printf("%s.%d %u\n", src, dport, seqno);
00277
00278 }
00279
00280 void hex_dump_packet(u_char * packet){
00281 int i,len;
00282 u_int8_t * raw = (const u_int8_t *) packet;
00283 for(i=0;i< (sizeof(struct ether_header) + sizeof(struct ip6_hdr) + sizeof(struct tcphdr));i++)
00284 printf("%x",raw[i]);
00285 printf("\n");
00286
00287 }
00288
00289
00290
00291 #endif