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: src/tools/tools/net80211/w00t/ap/ap.c,v 1.2 2009/07/24 15:31:22 sam Exp $
27 */
28 #include <sys/types.h>
29 #include <sys/select.h>
30 #include <sys/time.h>
31 #include <sys/endian.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <err.h>
37 #include <assert.h>
38 #include "w00t.h"
39
40 struct client {
41 char mac[6];
42 int seq;
43
44 struct client *next;
45 };
46
47 struct params {
48 /* fds */
49 int tx;
50 int rx;
51 int tap;
52
53 /* ap params */
54 char mac[6];
55 char ssid[256];
56 int chan;
57
58 /* beacon */
59 int bint;
60 struct timeval blast;
61
62 int seq;
63
64 /* wep */
65 int wep_len;
66 char wep_key[13];
67 int wep_iv;
68
69 struct client *clients;
70
71 /* lame window */
72 char packet[4096];
73 int packet_len;
74 int packet_try;
75 struct timeval plast;
76 };
77
usage(char * name)78 void usage(char *name)
79 {
80 printf("Usage: %s <opts>\n"
81 "-h\thelp\n"
82 "-i\t<iface>\n"
83 "-s\t<ssid>\n"
84 "-m\t<mac>\n"
85 "-w\t<wep key>\n"
86 "-c\t<chan>\n"
87 "-t\t<tap>\n"
88 , name);
89 exit(0);
90 }
91
fill_basic(struct ieee80211_frame * wh,struct params * p)92 void fill_basic(struct ieee80211_frame *wh, struct params *p)
93 {
94 short *seq;
95
96 wh->i_dur[0] = 0x69;
97 wh->i_dur[1] = 0x00;
98
99 memcpy(wh->i_addr2, p->mac, 6);
100
101 seq = (short*)wh->i_seq;
102 *seq = seqfn(p->seq, 0);
103 }
104
send_frame(struct params * p,void * buf,int len)105 void send_frame(struct params *p, void *buf, int len)
106 {
107 int rc;
108
109 rc = inject(p->tx, buf, len);
110 if (rc == -1)
111 err(1, "inject()");
112 if (rc != len) {
113 printf("injected %d/%d\n", rc, len);
114 exit(1);
115 }
116 p->seq++;
117 }
118
fill_beacon(struct params * p,struct ieee80211_frame * wh)119 int fill_beacon(struct params *p, struct ieee80211_frame *wh)
120 {
121 int len;
122 char *ptr;
123
124 ptr = (char*) (wh+1);
125 ptr += 8; /* timestamp */
126 ptr += 2; /* bint */
127 *ptr |= IEEE80211_CAPINFO_ESS;
128 ptr += 2; /* capa */
129
130 /* ssid */
131 len = strlen(p->ssid);
132 *ptr++ = 0;
133 *ptr++ = len;
134 memcpy(ptr, p->ssid, len);
135 ptr += len;
136
137 /* rates */
138 *ptr++ = 1;
139 *ptr++ = 4;
140 *ptr++ = 2 | 0x80;
141 *ptr++ = 4 | 0x80;
142 *ptr++ = 11;
143 *ptr++ = 22;
144
145 /* ds param */
146 *ptr++ = 3;
147 *ptr++ = 1;
148 *ptr++ = p->chan;
149
150 return ptr - ((char*) wh);
151 }
152
send_beacon(struct params * p)153 void send_beacon(struct params *p)
154 {
155 char buf[4096];
156 struct ieee80211_frame *wh;
157 int len;
158 char *ptr;
159
160 wh = (struct ieee80211_frame*) buf;
161
162 memset(buf, 0, sizeof(buf));
163 fill_basic(wh, p);
164 memset(wh->i_addr1, 0xff, 6);
165 memcpy(wh->i_addr3, p->mac, 6);
166
167 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT;
168 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_BEACON;
169
170 len = fill_beacon(p, wh);
171
172 /* TIM */
173 ptr = (char*)wh + len;
174 *ptr++ = 5;
175 *ptr++ = 4;
176 len += 2+4;
177 #if 0
178 printf("sending beacon\n");
179 #endif
180 send_frame(p, wh, len);
181
182 if (gettimeofday(&p->blast, NULL) == -1)
183 err(1, "gettimeofday()");
184 }
185
186
send_pres(struct params * p,char * mac)187 void send_pres(struct params *p, char *mac)
188 {
189 char buf[4096];
190 struct ieee80211_frame *wh;
191 int len;
192
193 wh = (struct ieee80211_frame*) buf;
194
195 memset(buf, 0, sizeof(buf));
196 fill_basic(wh, p);
197 memcpy(wh->i_addr1, mac, 6);
198 memcpy(wh->i_addr3, p->mac, 6);
199
200 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT;
201 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PROBE_RESP;
202
203 len = fill_beacon(p, wh);
204
205 printf("sending probe response\n");
206 send_frame(p, wh, len);
207 }
208
read_preq(struct params * p,struct ieee80211_frame * wh,int len)209 void read_preq(struct params *p, struct ieee80211_frame *wh, int len)
210 {
211 unsigned char *ptr;
212 unsigned char *end;
213 unsigned char macs[6*3];
214
215 ptr = (unsigned char*) (wh+1);
216
217 /* ssid */
218 if (*ptr != 0) {
219 printf("weird pr %x\n", *ptr);
220 return;
221 }
222 ptr++;
223
224 end = ptr + (*ptr) + 1;
225 *end = 0;
226 ptr++;
227
228 mac2str(macs, wh->i_addr2);
229 printf("Probe request for [%s] from %s\n", ptr, macs);
230
231 if ((strcmp(ptr, "") == 0) || (strcmp(ptr, p->ssid) == 0))
232 send_pres(p, wh->i_addr2);
233 }
234
send_auth(struct params * p,char * mac)235 void send_auth(struct params* p, char *mac)
236 {
237 char buf[4096];
238 struct ieee80211_frame *wh;
239 unsigned short *ptr;
240 int len;
241
242 wh = (struct ieee80211_frame*) buf;
243
244 memset(buf, 0, sizeof(buf));
245 fill_basic(wh, p);
246 memcpy(wh->i_addr1, mac, 6);
247 memcpy(wh->i_addr3, p->mac, 6);
248
249 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT;
250 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_AUTH;
251
252 ptr = (unsigned short*) (wh+1);
253 *ptr++ = htole16(0);
254 *ptr++ = htole16(2);
255 *ptr++ = htole16(0);
256
257 len = ((char*)ptr) - ((char*) wh);
258 printf("sending auth\n");
259 send_frame(p, wh, len);
260 }
261
read_auth(struct params * p,struct ieee80211_frame * wh,int len)262 void read_auth(struct params *p, struct ieee80211_frame *wh, int len)
263 {
264 unsigned short *ptr;
265 char mac[6*3];
266
267 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
268 return;
269
270 ptr = (unsigned short*) (wh+1);
271 if (le16toh(*ptr) != 0) {
272 printf("Unknown auth algo %d\n", le16toh(*ptr));
273 return;
274 }
275 ptr++;
276 if (le16toh(*ptr) == 1) {
277 mac2str(mac, wh->i_addr2);
278 printf("Got auth from %s\n", mac);
279 send_auth(p, wh->i_addr2);
280 } else {
281 printf("Weird seq in auth %d\n", le16toh(*ptr));
282 }
283 }
284
send_assoc(struct params * p,char * mac)285 void send_assoc(struct params *p, char *mac)
286 {
287 char buf[4096];
288 struct ieee80211_frame *wh;
289 char *ptr;
290 int len;
291
292 wh = (struct ieee80211_frame*) buf;
293
294 memset(buf, 0, sizeof(buf));
295 fill_basic(wh, p);
296 memcpy(wh->i_addr1, mac, 6);
297 memcpy(wh->i_addr3, p->mac, 6);
298
299 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT;
300 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
301
302 ptr = (char*) (wh+1);
303 *ptr |= IEEE80211_CAPINFO_ESS;
304 ptr += 2; /* cap */
305 ptr += 2; /* status */
306 ptr += 2; /* aid */
307
308 /* rates */
309 *ptr++ = 1;
310 *ptr++ = 4;
311 *ptr++ = 2 | 0x80;
312 *ptr++ = 4 | 0x80;
313 *ptr++ = 11;
314 *ptr++ = 22;
315
316 len = ptr - ((char*) wh);
317 printf("sending assoc response\n");
318 send_frame(p, wh, len);
319 }
320
read_assoc(struct params * p,struct ieee80211_frame * wh,int len)321 void read_assoc(struct params *p, struct ieee80211_frame *wh, int len)
322 {
323 unsigned char *ptr;
324 unsigned char *end;
325 unsigned char macs[6*3];
326
327 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
328 return;
329
330 ptr = (unsigned char*) (wh+1);
331 ptr += 2; /* capa */
332 ptr += 2; /* list interval */
333
334 /* ssid */
335 if (*ptr != 0) {
336 printf("weird pr %x\n", *ptr);
337 return;
338 }
339 ptr++;
340
341 end = ptr + (*ptr) + 1;
342 *end = 0;
343 ptr++;
344
345 mac2str(macs, wh->i_addr2);
346 printf("Assoc request for [%s] from %s\n", ptr, macs);
347
348 if (strcmp(ptr, p->ssid) == 0)
349 send_assoc(p, wh->i_addr2);
350 }
351
read_mgt(struct params * p,struct ieee80211_frame * wh,int len)352 void read_mgt(struct params *p, struct ieee80211_frame *wh, int len)
353 {
354 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
355 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
356 read_preq(p, wh, len);
357 break;
358
359 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
360 break;
361
362 case IEEE80211_FC0_SUBTYPE_AUTH:
363 read_auth(p, wh, len);
364 break;
365
366 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
367 read_assoc(p, wh, len);
368 break;
369
370 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
371 case IEEE80211_FC0_SUBTYPE_BEACON:
372 break;
373
374 default:
375 printf("wtf %d\n", (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
376 IEEE80211_FC0_SUBTYPE_SHIFT);
377 abort();
378 break;
379 }
380 }
381
send_cts(struct params * p,char * mac)382 void send_cts(struct params *p, char *mac)
383 {
384 char buf[64];
385 struct ieee80211_frame *wh;
386
387 memset(buf, 0, sizeof(buf));
388 wh = (struct ieee80211_frame*) buf;
389 wh->i_fc[0] |= IEEE80211_FC0_TYPE_CTL;
390 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_CTS;
391 wh->i_dur[0] = 0x69;
392 wh->i_dur[1] = 0x00;
393 memcpy(wh->i_addr1, mac, 6);
394
395 send_frame(p, wh, 10);
396 }
397
read_rts(struct params * p,struct ieee80211_frame * wh,int len)398 void read_rts(struct params *p, struct ieee80211_frame *wh, int len)
399 {
400 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
401 return;
402
403 send_cts(p, wh->i_addr2);
404 }
405
read_ack(struct params * p,struct ieee80211_frame * wh,int len)406 void read_ack(struct params *p, struct ieee80211_frame *wh, int len)
407 {
408 if (memcmp(wh->i_addr1, p->mac, 6) == 0)
409 p->packet_try = 0;
410 }
411
read_ctl(struct params * p,struct ieee80211_frame * wh,int len)412 void read_ctl(struct params *p, struct ieee80211_frame *wh, int len)
413 {
414 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
415 case IEEE80211_FC0_SUBTYPE_RTS:
416 read_rts(p, wh, len);
417 break;
418
419 case IEEE80211_FC0_SUBTYPE_ACK:
420 read_ack(p, wh, len);
421 break;
422
423 case IEEE80211_FC0_SUBTYPE_CTS:
424 break;
425
426 default:
427 printf("wtf %d\n", (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
428 IEEE80211_FC0_SUBTYPE_SHIFT);
429 abort();
430 break;
431 }
432 #if 0
433 printf("ctl\n");
434 #endif
435 }
436
broadcast(struct ieee80211_frame * wh)437 int broadcast(struct ieee80211_frame *wh)
438 {
439 /* XXX multicast */
440
441 if (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0)
442 return 1;
443
444 return 0;
445 }
446
enque(struct params * p,struct ieee80211_frame * wh,int len)447 void enque(struct params *p, struct ieee80211_frame *wh, int len)
448 {
449 if (broadcast(wh))
450 return;
451
452 assert(sizeof(p->packet) >= len);
453
454 memcpy(p->packet, wh, len);
455 p->packet_len = len;
456 p->packet_try = 1;
457
458 wh = (struct ieee80211_frame*) p->packet;
459 wh->i_fc[1] |= IEEE80211_FC1_RETRY;
460
461 if (gettimeofday(&p->plast, NULL) == -1)
462 err(1, "gettimeofday()");
463 }
464
relay_data(struct params * p,struct ieee80211_frame * wh,int len)465 void relay_data(struct params *p, struct ieee80211_frame *wh, int len)
466 {
467 char seq[2];
468 char fc[2];
469 unsigned short *ps;
470
471 /* copy crap */
472 memcpy(fc, wh->i_fc, 2);
473 memcpy(seq, wh->i_seq, 2);
474
475 /* relay frame */
476 wh->i_fc[1] &= ~(IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_RETRY);
477 wh->i_fc[1] |= IEEE80211_FC1_DIR_FROMDS;
478 memcpy(wh->i_addr1, wh->i_addr3, sizeof(wh->i_addr1));
479 memcpy(wh->i_addr3, wh->i_addr2, sizeof(wh->i_addr3));
480 memcpy(wh->i_addr2, p->mac, sizeof(wh->i_addr2));
481 ps = (unsigned short*)wh->i_seq;
482 *ps = seqfn(p->seq, 0);
483
484 send_frame(p, wh, len);
485 enque(p, wh, len);
486
487 /* restore */
488 memcpy(wh->i_fc, fc, sizeof(fc));
489 memcpy(wh->i_addr2, wh->i_addr3, sizeof(wh->i_addr2));
490 memcpy(wh->i_addr3, wh->i_addr1, sizeof(wh->i_addr2));
491 memcpy(wh->i_addr1, p->mac, sizeof(wh->i_addr1));
492 memcpy(wh->i_seq, seq, sizeof(seq));
493 }
494
read_real_data(struct params * p,struct ieee80211_frame * wh,int len)495 void read_real_data(struct params *p, struct ieee80211_frame *wh, int len)
496 {
497 char dst[6];
498 int rc;
499 char *ptr = (char*) (wh+1);
500
501 /* stuff not for this net */
502 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
503 return;
504
505 /* relay data */
506 if (memcmp(wh->i_addr3, p->mac, 6) != 0)
507 relay_data(p, wh, len);
508
509 memcpy(dst, wh->i_addr3, 6);
510
511
512 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
513 if (!p->wep_len) {
514 printf("Got wep but i aint wep\n");
515 return;
516 }
517
518 if (wep_decrypt(wh, len, p->wep_key, p->wep_len) == -1){
519 printf("Can't decrypt\n");
520 return;
521 }
522
523 ptr += 4;
524 len -= 8;
525 }
526
527 /* ether header */
528 ptr += 8 - 2;
529 ptr -= 6;
530 memcpy(ptr, wh->i_addr2, 6);
531 ptr -= 6;
532 memcpy(ptr, dst, 6);
533
534 len -= sizeof(*wh);
535 len -= 8;
536 len += 14;
537
538 /* send to tap */
539 rc = write(p->tap, ptr, len);
540 if (rc == -1)
541 err(1, "write()");
542 if (rc != len) {
543 printf("Wrote %d/%d\n", rc, len);
544 exit(1);
545 }
546 }
547
read_data(struct params * p,struct ieee80211_frame * wh,int len)548 void read_data(struct params *p, struct ieee80211_frame *wh, int len)
549 {
550 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
551 case IEEE80211_FC0_SUBTYPE_DATA:
552 read_real_data(p, wh, len);
553 break;
554
555 case IEEE80211_FC0_SUBTYPE_NODATA:
556 break;
557
558 default:
559 printf("wtf %d\n", (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
560 IEEE80211_FC0_SUBTYPE_SHIFT);
561 abort();
562 break;
563 }
564 }
565
client_find(struct params * p,char * mac)566 struct client* client_find(struct params *p, char *mac)
567 {
568 struct client* c = p->clients;
569
570 while (c) {
571 if (memcmp(c->mac, mac, 6) == 0)
572 return c;
573
574 c = c->next;
575 }
576
577 return NULL;
578 }
579
client_insert(struct params * p,struct client * c)580 void client_insert(struct params *p, struct client *c)
581 {
582 #if 1
583 do {
584 char mac[6*3];
585
586 mac2str(mac, c->mac);
587 printf("Adding client %s\n", mac);
588 } while(0);
589 #endif
590
591 c->next = p->clients;
592 p->clients = c;
593 }
594
duplicate(struct params * p,struct ieee80211_frame * wh,int rc)595 int duplicate(struct params *p, struct ieee80211_frame *wh, int rc)
596 {
597 struct client *c;
598 int s;
599
600 if (!frame_type(wh, IEEE80211_FC0_TYPE_DATA,
601 IEEE80211_FC0_SUBTYPE_DATA))
602 return 0;
603
604 s = seqno(wh);
605
606 c = client_find(p, wh->i_addr2);
607 if (!c) {
608 c = malloc(sizeof(*c));
609 if (!c)
610 err(1, "malloc()");
611
612 memset(c, 0, sizeof(*c));
613 memcpy(c->mac, wh->i_addr2, 6);
614
615 c->seq = s-1;
616 client_insert(p, c);
617 }
618
619 if (wh->i_fc[1] & IEEE80211_FC1_RETRY) {
620 if ( (s <= c->seq) && ((c->seq - s ) < 5)) {
621 #if 0
622 printf("Dup seq %d prev %d\n",
623 s, c->seq);
624 #endif
625 return 1;
626 }
627 }
628
629 #if 0
630 do {
631 char mac[3*6];
632
633 mac2str(mac, c->mac);
634 printf("%s seq %d prev %d\n", mac, s, c->seq);
635 } while (0);
636 #endif
637
638 c->seq = s;
639 return 0;
640 }
641
ack(struct params * p,struct ieee80211_frame * wh)642 void ack(struct params *p, struct ieee80211_frame *wh)
643 {
644 if (memcmp(wh->i_addr1, p->mac, 6) != 0)
645 return;
646
647 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
648 return;
649
650 send_ack(p->tx, wh->i_addr2);
651 }
652
read_wifi(struct params * p)653 void read_wifi(struct params *p)
654 {
655 char buf[4096];
656 int rc;
657 struct ieee80211_frame *wh;
658
659 rc = sniff(p->rx, buf, sizeof(buf));
660 if (rc == -1)
661 err(1, "sniff()");
662
663 wh = get_wifi(buf, &rc);
664 if (!wh)
665 return;
666
667 /* filter my own shit */
668 if (memcmp(wh->i_addr2, p->mac, 6) == 0) {
669 /* XXX CTL frames */
670 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
671 IEEE80211_FC0_TYPE_CTL)
672 return;
673 }
674
675 #if 1
676 ack(p, wh);
677 #endif
678
679 if (duplicate(p, wh, rc)) {
680 #if 0
681 printf("Dup\n");
682 #endif
683 return;
684 }
685
686 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
687 case IEEE80211_FC0_TYPE_MGT:
688 read_mgt(p, wh, rc);
689 break;
690
691 case IEEE80211_FC0_TYPE_CTL:
692 read_ctl(p, wh, rc);
693 break;
694
695 case IEEE80211_FC0_TYPE_DATA:
696 read_data(p, wh, rc);
697 break;
698
699 default:
700 printf("wtf\n");
701 abort();
702 break;
703 }
704 }
705
read_tap(struct params * p)706 void read_tap(struct params *p)
707 {
708 char buf[4096];
709 char *ptr;
710 int len = sizeof(buf);
711 int offset;
712 char src[6], dst[6];
713 struct ieee80211_frame *wh;
714 int rd;
715
716 ptr = buf;
717 offset = sizeof(struct ieee80211_frame) + 8 - 14;
718 if (p->wep_len)
719 offset += 4;
720
721 ptr += offset;
722 len -= offset;
723
724 /* read packet */
725 memset(buf, 0, sizeof(buf));
726 rd = read(p->tap, ptr, len);
727 if (rd == -1)
728 err(1, "read()");
729
730 /* 802.11 header */
731 wh = (struct ieee80211_frame*) buf;
732 memcpy(dst, ptr, sizeof(dst));
733 memcpy(src, ptr+6, sizeof(src));
734 fill_basic(wh, p);
735 memcpy(wh->i_addr3, src, sizeof(wh->i_addr3));
736 memcpy(wh->i_addr1, dst, sizeof(wh->i_addr1));
737 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
738 wh->i_fc[1] |= IEEE80211_FC1_DIR_FROMDS;
739 if (p->wep_len)
740 wh->i_fc[1] |= IEEE80211_FC1_WEP;
741
742 /* LLC & SNAP */
743 ptr = (char*) (wh+1);
744 if (p->wep_len)
745 ptr += 4;
746 *ptr++ = 0xAA;
747 *ptr++ = 0xAA;
748 *ptr++ = 0x03;
749 *ptr++ = 0x00;
750 *ptr++ = 0x00;
751 *ptr++ = 0x00;
752 /* ether type overlaps w00t */
753
754 rd += offset;
755
756 /* WEP */
757 if (p->wep_len) {
758 ptr = (char*) (wh+1);
759 memcpy(ptr, &p->wep_iv, 3);
760 ptr[3] = 0;
761 p->wep_iv++;
762
763 wep_encrypt(wh, rd, p->wep_key, p->wep_len);
764 rd += 4; /* ICV */
765 }
766
767 send_frame(p, wh, rd);
768 }
769
retransmit(struct params * p)770 int retransmit(struct params *p)
771 {
772 #if 0
773 printf("RETRANS %d\n", p->packet_try);
774 #endif
775
776 send_frame(p, p->packet, p->packet_len);
777 p->packet_try++;
778
779 if (p->packet_try > 3)
780 p->packet_try = 0;
781 else {
782 if (gettimeofday(&p->plast, NULL) == -1)
783 err(1, "gettimeofday()");
784 }
785
786 return p->packet_try;
787 }
788
next_event(struct params * p)789 void next_event(struct params *p)
790 {
791 struct timeval to, now;
792 int el;
793 int max;
794 fd_set fds;
795 int rtr = 3*1000;
796
797 /* figure out select timeout */
798 if (gettimeofday(&now, NULL) == -1)
799 err(1, "gettimeofday()");
800
801 /* check beacon timeout */
802 el = elapsed(&p->blast, &now);
803 if (el >= p->bint) {
804 send_beacon(p);
805 el = 0;
806 }
807 el = p->bint - el;
808 to.tv_sec = el/1000/1000;
809 to.tv_usec = el - to.tv_sec*1000*1000;
810
811 /* check tx timeout */
812 if (p->packet_try) {
813 el = elapsed(&p->plast, &now);
814 if (el >= rtr) {
815 /* check if we gotta retransmit more */
816 if (retransmit(p)) {
817 el = 0;
818 }
819 else
820 el = -1;
821 }
822
823 /* gotta retransmit in future */
824 if (el != -1) {
825 el = rtr - el;
826 if ((to.tv_sec*1000*1000 + to.tv_usec) > el) {
827 to.tv_sec = el/1000/1000;
828 to.tv_usec = el - to.tv_sec*1000*1000;
829 }
830 }
831 }
832
833 /* select */
834 FD_ZERO(&fds);
835 FD_SET(p->rx, &fds);
836 FD_SET(p->tap, &fds);
837 max = p->rx > p->tap ? p->rx : p->tap;
838 if (select(max+1, &fds, NULL, NULL, &to) == -1)
839 err(1, "select()");
840
841 if (FD_ISSET(p->tap, &fds))
842 read_tap(p);
843 if (FD_ISSET(p->rx, &fds))
844 read_wifi(p);
845 }
846
main(int argc,char * argv[])847 int main(int argc, char *argv[])
848 {
849 char *iface = "wlan0";
850 char *tap = "tap0";
851 struct params p;
852 int ch;
853
854 /* default params */
855 memset(&p, 0, sizeof(p));
856 memcpy(p.mac, "\x00\x00\xde\xfa\xce\x0d", 6);
857 strcpy(p.ssid, "sorbo");
858 p.bint = 500*1000;
859 p.seq = getpid();
860 if (gettimeofday(&p.blast, NULL) == -1)
861 err(1, "gettimeofday()");
862 p.chan = 3;
863
864 while ((ch = getopt(argc, argv, "hi:s:m:w:c:t:")) != -1) {
865 switch (ch) {
866 case 'i':
867 iface = optarg;
868 break;
869 case 't':
870 tap = optarg;
871 break;
872
873 case 'c':
874 p.chan = atoi(optarg);
875 break;
876
877 case 's':
878 strncpy(p.ssid, optarg, sizeof(p.ssid)-1);
879 p.ssid[sizeof(p.ssid)-1] = 0;
880 break;
881
882 case 'm':
883 str2mac(p.mac, optarg);
884 break;
885
886 case 'w':
887 if (str2wep(p.wep_key, &p.wep_len, optarg)) {
888 printf("Error parsing WEP key\n");
889 exit(1);
890 }
891 break;
892
893 case 'h':
894 default:
895 usage(argv[0]);
896 break;
897 }
898 }
899
900 /* init */
901 if ((p.tx = open_tx(iface)) == -1)
902 err(1, "open_tx()");
903 if ((p.rx = open_rx(iface)) == -1)
904 err(1, "open_rx()");
905
906 if ((p.tap = open_tap(tap)) == -1)
907 err(1, "open_tap()");
908 if (set_iface_mac(tap, p.mac) == -1)
909 err(1, "set_iface_mac()");
910
911 while (1) {
912 next_event(&p);
913 }
914
915 exit(0);
916 }
917