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