Main Page   Data Structures   File List   Data Fields   Globals  

hashtable.c

Go to the documentation of this file.
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     /* use the sequence no. from the TCP packet
00117      * since it is unlikely to be the same for two
00118      * different tcp streams at the same time
00119      * however will make it very fast when looking for that packet,
00120      * clearing the same entry when the node forwards it
00121      */
00122    
00123     current = hash(seqno, ht->size);
00124 
00125     /* however it is possible that something else is
00126      * occupying this space
00127      */
00128     
00129     htb = &(const ht_bucket) ht->table[current];
00130 
00131     /* if entry is valid compare  */
00132     while( probes <= ht->size &&
00133             INVALID != htb->state){
00134         /*If bucket is valid, compare contents */
00135         if((VALID == htb->state)||(LATE == htb->state)){
00136             // printf("Comparing : \n");
00137             // hex_dump_packet(htb->packet);
00138             // hex_dump_packet(raw);
00139             // hop limit in ipv6 header changes by one !! need to ignore hop limit field
00140             // should differ by one !
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                 // identical packet was found
00146                 return current;
00147             }
00148         } else if(DELETED == htb->state){
00149                 // could have been marked for deletion by timeout
00150                 // free mem. if not already freed
00151                 if(NULL!=htb->packet){
00152                         free(htb->packet);
00153                         htb->packet = NULL;
00154                 }
00155                 // mark this position as the first empty slot
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         //printf("FIND: probing, position=%d, state is : %d\n", current, htb->state);
00167     }
00168      if(probes > ht->size)
00169          return emptyslot; /*if HT is full, emptyslot will be -1*/
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             /*such a packet already exists,
00182               so this must be a retransmission
00183               by the same host, update timestamp
00184               shouldnt we replace the old packet,
00185               something might have changed this time ?!?!
00186              */
00187             
00188             htb->timestamp = time;
00189         } else{ // either INVALID or DELETED
00190             htb->packet = raw;
00191             htb->timestamp = time;
00192             htb->state = VALID;
00193             (ht->count)++;
00194           //  printf("Entry made in hashtable, SIZE = %d\n", ht->count);
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 //      dump_packet(raw);
00211         htb = &(ht_bucket) ht->table[pos];
00212         if((VALID==htb->state)||(LATE==htb->state)){ 
00213                 // locate will return an empty slot position
00214                 // if no matching packet found, remove entry only if VALID
00215                 // such a packet already exists,
00216                 // so this must be the forwarded packet
00217              
00218             free(htb->packet);
00219             htb->packet = NULL;
00220             htb->timestamp = time;
00221             htb->state = DELETED;
00222             (ht->count)--;
00223           // entry removed from HT
00224         }
00225     }else{
00226         printf("No matching packet found in hashtable\n");
00227         return 0;
00228     }
00229 
00230     //print(ht);
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

Generated on Wed Mar 23 11:08:02 2005 for Snoop IDS by doxygen1.2.18