00001
00052 #ifndef _SNOOP_C
00053 #define _SNOOP_C
00054
00055 #include "common.h"
00056 #include "hashtable.h"
00057 #include "snoop.h"
00058
00059 hashtable * ht;
00060 neighbor neighbors[2*MAXNEIGHBORS];
00061 int received, forwarded;
00062 FILE *logfile;
00063
00064 void SIGALRM_handler(int sig){
00065 printf("<<<<<<<< SIGARLM >>>>>>>>>>\n");
00066 signal(sig, SIGALRM_handler);
00067 printf("Hashtable size was : %d\n", ht->count);
00068
00069 timer_update_state();
00070 printf("Hashtable size now, is : %d\n", ht->count);
00071 printf("<<<<<<<<<<<<<>>>>>>>>>>>>>>\n");
00072 print_neighbors();
00073 log_intrusions();
00074
00075 alarm(ALARM_TIMEOUT);
00076 }
00077
00078
00079 void timer_update_state(void){
00080 int i;
00081 ht_bucket* htb;
00082 struct ether_header* ether_hdr;
00083 struct ether_addr* ether_dst;
00084 for(i=0;i<ht->size;i++){
00085 htb = &(const ht_bucket) ht->table[i];
00086 switch(htb->state){
00087 case VALID:
00088 htb->state = LATE;
00089 break;
00090 case LATE:
00091
00092
00093 ether_hdr = (struct ether_header*) htb->packet;
00094 ether_dst = (struct ether_addr*)(ether_hdr->ether_dhost);
00095 incr_dropcount(ether_dst);
00096 htb->state = DELETED;
00097 (ht->count)--;
00098 break;
00099 case INVALID:
00100 case DELETED:
00101 default:
00102
00103 }
00104 }
00105
00106 }
00107
00108
00109
00110
00111 void pkt_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet){
00112 u_int16_t type = handle_ethernet(args,pkthdr,packet);
00113 if(type == ETHERTYPE_IPV6){
00114
00115 handle_IPv6(args, pkthdr, packet);
00116 }
00117 }
00118
00119 u_int16_t
00120 handle_ethernet(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet){
00121 u_int caplen = pkthdr->caplen;
00122 u_int length = pkthdr->len;
00123 struct ether_header *eptr;
00124 u_short ether_type;
00125
00126 if (caplen < ETHER_HDRLEN)
00127 {
00128 fprintf(stdout,"Incomplete ethernet header info\n");
00129 return -1;
00130 }
00131
00132 eptr = (struct ether_header *) packet;
00133 ether_type = ntohs(eptr->ether_type);
00134
00135 return ether_type;
00136 }
00137
00138 int
00139 handle_IPv6(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet){
00140 struct ip6_hdr *ip6;
00141 struct ether_header *ether;
00142 u_int length = pkthdr->len;
00143 u_int caplen = pkthdr->caplen;
00144 u_int hlen, off, version;
00145 int len,i;
00146 char *src;
00147 char ntop_buf[INET6_ADDRSTRLEN];
00148 u_int8_t nexthdr;
00149 const struct udphdr* udp_hdr;
00150 const struct tcphdr* tcp_hdr;
00151 u_int16_t sport, dport, udplen, udpchecksum;
00152 u_int8_t rawpacket[1500];
00153 u_char* packet_hdrs;
00154 u_int8_t aodv_type;
00155 u_int32_t seqno;
00156 neighbor n_pair;
00157
00158
00159
00160 ether = (const struct ether_header*) packet;
00161
00162 ip6 = (const struct ip6_hdr *) (packet + sizeof(struct ether_header));
00163
00164 length-=sizeof(struct ether_header);
00165
00166
00167
00168 if(length < sizeof(struct ip6_hdr)){
00169 printf("Truncated ip6 packet %d\n",length);
00170 return -1;
00171 }
00172
00173 len = ntohs(ip6->ip6_plen);
00174
00175 src = inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf));
00176 src = inet_ntop(AF_INET6, &ip6->ip6_dst, ntop_buf, sizeof(ntop_buf));
00177
00178 memcpy(rawpacket, ip6, len);
00179 packet_hdrs = (u_char *) malloc(sizeof(struct ether_header) + sizeof(struct ip6_hdr) + sizeof(struct tcphdr));
00180 if(NULL==packet_hdrs){
00181 printf("Couldn't allocate mem. for packet, ignoring this one !\n");
00182 }
00183 else{
00184 memcpy(packet_hdrs, packet, sizeof(struct ether_header) + sizeof(struct ip6_hdr) + sizeof(struct tcphdr));
00185 }
00186
00187 nexthdr = ip6->ip6_nxt;
00188
00189 switch(nexthdr){
00190 case IP_PROTO_TCP:
00191 tcp_hdr = (const struct tcphdr *) (rawpacket + sizeof(struct ip6_hdr));
00192 sport = ntohs(tcp_hdr->source);
00193 dport = ntohs(tcp_hdr->dest);
00194 seqno = ntohl(tcp_hdr->seq);
00195
00196
00197
00198
00199 memcpy(&n_pair.src_ether,ðer->ether_shost,6);
00200 memcpy(&n_pair.src_ip6,&ip6->ip6_src,16);
00201
00202 if(-1==find_neighbor(&n_pair)){
00203
00204 printf("#############################\n");
00205 printf("source(ether)!=source(ip6), FORWARDED = %d\n",++forwarded );
00206 printf("#############################\n");
00207
00208 if(NULL!=packet_hdrs)
00209 performID(ht, packet_hdrs,time(NULL));
00210 }
00211
00212 memcpy(&n_pair.src_ether,ðer->ether_dhost,6);
00213 memcpy(&n_pair.src_ip6,&ip6->ip6_dst,16);
00214
00215 if(-1==find_neighbor(&n_pair)){
00216
00217 printf("#############################\n");
00218 printf("dest(ether)!= dest(ip6), RECEIVED = %d\n", ++received);
00219 printf("#############################\n");
00220
00221 if(NULL!=packet_hdrs)
00222 makeEntry(ht, packet_hdrs,time(NULL));
00223 }
00224 break;
00225
00226 case IP_PROTO_UDP:
00227 udp_hdr = (const struct udphdr *) (rawpacket + sizeof(struct ip6_hdr));
00228 sport = ntohs(udp_hdr->source);
00229 dport = ntohs(udp_hdr->dest);
00230 udplen = ntohs(udp_hdr->len);
00231 udpchecksum = ntohs(udp_hdr->check);
00232
00233 if((654==sport)&&(654==dport))
00234 handle_AODV(packet);
00235
00236 break;
00237
00238 case IP_PROTO_ICMPV6:
00239 break;
00240
00241 default:
00242
00243 }
00244
00245 return 0;
00246 }
00247
00248
00249 int handle_AODV(const u_char* packet){
00250 u_int8_t type, flags, hops, prefixsize;
00251 u_int32_t reqid, dsn, osn, lifetime;
00252 struct ether_header * ether;
00253 struct ip6_hdr * ip6;
00254 struct aodv_rreq6_draft_01* rreq;
00255 struct aodv_rrep6_draft_01* rrep;
00256 neighbor aodv_pair, interface_pair;
00257 char * addr;
00258 char ntop_buf[INET6_ADDRSTRLEN];
00259 int i;
00260 union aodv* aodvpacket;
00261
00262
00263
00264 aodvpacket = (const union aodv *)
00265 ( packet
00266 + sizeof(struct ether_header)
00267 + sizeof(struct ip6_hdr)
00268 + sizeof(struct udphdr) ) ;
00269
00270 type = aodvpacket->rrep6.rrep_type;
00271
00272 switch(type){
00273 case AODV6_RREQ:
00274 rreq = (const struct aodv_rreq6_draft_01*) aodvpacket;
00275 addr = inet_ntop(AF_INET6, &rreq->rreq_oa, ntop_buf, sizeof(ntop_buf));
00276 addr = inet_ntop(AF_INET6, &rreq->rreq_da, ntop_buf, sizeof(ntop_buf));
00277 break;
00278 case AODV6_RREP:
00279
00280
00281 rrep = (const struct aodv_rrep6_draft_01*) aodvpacket;
00282 addr = inet_ntop(AF_INET6, &rrep->rrep_oa, ntop_buf, sizeof(ntop_buf));
00283 addr = inet_ntop(AF_INET6, &rrep->rrep_da, ntop_buf, sizeof(ntop_buf));
00284
00285
00286
00287 if((0==rrep->rrep_hops) && (0== memcmp(&rrep->rrep_oa,&rrep->rrep_da, sizeof(struct in6_addr)))){
00288
00289
00290 ether = (const struct ether_header*) packet;
00291 ip6 = (const struct ip6_hdr*) (packet+sizeof(struct ether_header));
00292
00293
00294 memcpy(&aodv_pair.src_ether,ðer->ether_shost,6);
00295 memcpy(&aodv_pair.src_ip6,&ip6->ip6_src, 16);
00296 memcpy(&interface_pair.src_ether,ðer->ether_shost,6);
00297 memcpy(&interface_pair.src_ip6,&rrep->rrep_oa, 16);
00298
00299 if(-1==find_neighbor(&aodv_pair))
00300 add_neighbor(&aodv_pair);
00301 if(-1==find_neighbor(&interface_pair))
00302 add_neighbor(&interface_pair);
00303
00304
00305
00306 }
00307
00308 break;
00309 default:
00310
00311
00312 }
00313
00314 return 0;
00315
00316 }
00317
00318 int find_neighbor(neighbor* pair){
00319 int i;
00320 for(i=0;i<2*MAXNEIGHBORS;i++){
00321 if((LIVE==neighbors[i].route_state)&&
00322 (0==memcmp(&neighbors[i],pair,22))){
00323
00324 return i;
00325 }
00326 }
00327 return -1;
00328 }
00329
00330 int add_neighbor(neighbor* pair){
00331 int i;
00332 for(i=0;i<2*MAXNEIGHBORS;i++){
00333 if(LIVE!=neighbors[i].route_state){
00334 memcpy(&neighbors[i],pair,22);
00335 neighbors[i].route_state = LIVE;
00336 printf("Added a neighbor\n");
00337
00338 return 1;
00339 }
00340 }
00341 return 0;
00342 }
00343
00344 int incr_dropcount(struct ether_addr* ether_src){
00345 int i;
00346 for(i=0;i<2*MAXNEIGHBORS;i++){
00347 if(0==memcmp(&neighbors[i],ether_src,6)){
00348 neighbors[i].dropcount++;
00349 }
00350 }
00351 return 0;
00352 }
00353
00354 void print_neighbors(void){
00355 int i,j;
00356
00357 printf("\n====== Neighbor Table ======\n");
00358 printf("(dropcount, mac address, ip6 address)\n");
00359 for(i=0;i<2*MAXNEIGHBORS;i++)
00360 if(LIVE==neighbors[i].route_state){
00361 printf("[%d] ", neighbors[i].dropcount);
00362 for(j=0;j<6;j++)
00363 printf("%x",neighbors[i].src_ether[j]);
00364 printf(" = ");
00365 for(j=0;j<16;j++)
00366 printf("%x",neighbors[i].src_ip6[j]);
00367 printf("\n");
00368 }
00369 printf("============================\n");
00370 }
00371
00372 void log_intrusions(void){
00373
00374
00375 int i;
00376 intruder badguy;
00377 const int n = sizeof(intruder);
00378
00379 for(i=0;i<2*MAXNEIGHBORS;i++){
00380 if(LIVE==neighbors[i].route_state && neighbors[i].dropcount>0){
00381 memcpy(&badguy,&neighbors[i],22);
00382 badguy.when_detected = time(0);
00383 badguy.dropcount = neighbors[i].dropcount;
00384
00385 neighbors[i].dropcount = 0;
00386
00387
00388
00389
00390
00391 fwrite(&badguy, sizeof(intruder), 1, logfile);
00392 fflush(logfile);
00393
00394
00395 }
00396 }
00397
00398
00399 }
00400
00401 int main(int argc,char **argv){
00402
00403 char *dev;
00404 char errbuf[PCAP_ERRBUF_SIZE];
00405 pcap_t* descr;
00406 struct bpf_program fp;
00407 bpf_u_int32 maskp;
00408 bpf_u_int32 netp;
00409 u_char* args = NULL;
00410 int i;
00411 received = 0;
00412 forwarded = 0;
00413
00414
00415 if(argc < 2){
00416 fprintf(stdout,"Usage: %s numpackets \"options\"\n",argv[0]);
00417 return 0;
00418 }
00419
00420
00421 if((logfile = fopen("/tmp/suspects","w")) == NULL){
00422 printf("Couldn't open log file ...\n");
00423 exit(0);
00424 }
00425
00426 dev = pcap_lookupdev(errbuf);
00427 if(dev == NULL)
00428 { printf("%s\n",errbuf); exit(1); }
00429
00430
00431 ht = createHashtable(HTSIZE);
00432
00433 for(i=0;i<2*MAXNEIGHBORS;i++){
00434 neighbors[i].route_state = EXPIRED;
00435 }
00436
00437
00438
00439 if(SIG_ERR==signal(SIGALRM, SIGALRM_handler)){
00440 printf("SIGALRM handler couldnt be installed ...\n");
00441 exit(1);
00442 }
00443
00444 alarm(ALARM_TIMEOUT);
00445
00446
00447 pcap_lookupnet(dev,&netp,&maskp,errbuf);
00448
00449
00450
00451 descr = pcap_open_live(dev,1500,1,-1,errbuf);
00452 if(descr == NULL)
00453 { printf("pcap_open_live(): %s\n",errbuf); exit(1); }
00454
00455
00456 if(argc > 2)
00457 {
00458 if(pcap_compile(descr,&fp,argv[2],0,netp) == -1)
00459 { fprintf(stderr,"Error calling pcap_compile\n"); exit(1); }
00460
00461 if(pcap_setfilter(descr,&fp) == -1)
00462 { fprintf(stderr,"Error setting filter\n"); exit(1); }
00463 }
00464
00465
00466 pcap_loop(descr,atoi(argv[1]),pkt_callback,args);
00467
00468 fprintf(stdout,"\nDone...\n");
00469 print_neighbors();
00470 fclose(logfile);
00471
00472 return 0;
00473 }
00474
00475 #endif
00476
00477
00478