diff options
Diffstat (limited to 'src/transport/gnunet-transport-wlan-helper.c')
-rw-r--r-- | src/transport/gnunet-transport-wlan-helper.c | 1033 |
1 files changed, 505 insertions, 528 deletions
diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c index 53e0efedd..ca4542f1a 100644 --- a/src/transport/gnunet-transport-wlan-helper.c +++ b/src/transport/gnunet-transport-wlan-helper.c | |||
@@ -239,35 +239,35 @@ enum ieee80211_radiotap_type | |||
239 | }; | 239 | }; |
240 | 240 | ||
241 | /* For IEEE80211_RADIOTAP_FLAGS */ | 241 | /* For IEEE80211_RADIOTAP_FLAGS */ |
242 | #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received | 242 | #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received |
243 | * during CFP | 243 | * during CFP |
244 | */ | 244 | */ |
245 | #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received | 245 | #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received |
246 | * with short | 246 | * with short |
247 | * preamble | 247 | * preamble |
248 | */ | 248 | */ |
249 | #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received | 249 | #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received |
250 | * with WEP encryption | 250 | * with WEP encryption |
251 | */ | 251 | */ |
252 | #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received | 252 | #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received |
253 | * with fragmentation | 253 | * with fragmentation |
254 | */ | 254 | */ |
255 | #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ | 255 | #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ |
256 | #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between | 256 | #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between |
257 | * 802.11 header and payload | 257 | * 802.11 header and payload |
258 | * (to 32-bit boundary) | 258 | * (to 32-bit boundary) |
259 | */ | 259 | */ |
260 | /* For IEEE80211_RADIOTAP_RX_FLAGS */ | 260 | /* For IEEE80211_RADIOTAP_RX_FLAGS */ |
261 | #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ | 261 | #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ |
262 | 262 | ||
263 | /* For IEEE80211_RADIOTAP_TX_FLAGS */ | 263 | /* For IEEE80211_RADIOTAP_TX_FLAGS */ |
264 | #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive | 264 | #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive |
265 | * retries */ | 265 | * retries */ |
266 | #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ | 266 | #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ |
267 | #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ | 267 | #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ |
268 | #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* frame should not be ACKed */ | 268 | #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* frame should not be ACKed */ |
269 | #define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010 /* sequence number handled | 269 | #define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010 /* sequence number handled |
270 | * by userspace */ | 270 | * by userspace */ |
271 | 271 | ||
272 | 272 | ||
273 | /** | 273 | /** |
@@ -478,10 +478,9 @@ struct ieee80211_radiotap_iterator | |||
478 | * index corresponds to the IEEE80211_RADIOTAP_... defines. | 478 | * index corresponds to the IEEE80211_RADIOTAP_... defines. |
479 | */ | 479 | */ |
480 | static int | 480 | static int |
481 | ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator | 481 | ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator, |
482 | *iterator, | 482 | struct ieee80211_radiotap_header |
483 | struct ieee80211_radiotap_header | 483 | *radiotap_header, int max_length) |
484 | *radiotap_header, int max_length) | ||
485 | { | 484 | { |
486 | if (iterator == NULL) | 485 | if (iterator == NULL) |
487 | return (-EINVAL); | 486 | return (-EINVAL); |
@@ -503,47 +502,47 @@ ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator | |||
503 | iterator->arg_index = 0; | 502 | iterator->arg_index = 0; |
504 | iterator->bitmap_shifter = le32toh (radiotap_header->it_present); | 503 | iterator->bitmap_shifter = le32toh (radiotap_header->it_present); |
505 | iterator->arg = | 504 | iterator->arg = |
506 | ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header); | 505 | ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header); |
507 | iterator->this_arg = 0; | 506 | iterator->this_arg = 0; |
508 | 507 | ||
509 | /* find payload start allowing for extended bitmap(s) */ | 508 | /* find payload start allowing for extended bitmap(s) */ |
510 | 509 | ||
511 | if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)) | 510 | if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)) |
511 | { | ||
512 | while (le32toh (*((uint32_t *) iterator->arg)) & | ||
513 | IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK) | ||
512 | { | 514 | { |
513 | while (le32toh (*((uint32_t *) iterator->arg)) & | ||
514 | IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK) | ||
515 | { | ||
516 | iterator->arg += sizeof (uint32_t); | ||
517 | |||
518 | /* | ||
519 | * check for insanity where the present bitmaps | ||
520 | * keep claiming to extend up to or even beyond the | ||
521 | * stated radiotap header length | ||
522 | */ | ||
523 | |||
524 | if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > | ||
525 | iterator->max_length) | ||
526 | return (-EINVAL); | ||
527 | |||
528 | } | ||
529 | |||
530 | iterator->arg += sizeof (uint32_t); | 515 | iterator->arg += sizeof (uint32_t); |
531 | 516 | ||
532 | /* | 517 | /* |
533 | * no need to check again for blowing past stated radiotap | 518 | * check for insanity where the present bitmaps |
534 | * header length, becuase ieee80211_radiotap_iterator_next | 519 | * keep claiming to extend up to or even beyond the |
535 | * checks it before it is dereferenced | 520 | * stated radiotap header length |
536 | */ | 521 | */ |
537 | 522 | ||
523 | if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > | ||
524 | iterator->max_length) | ||
525 | return (-EINVAL); | ||
526 | |||
538 | } | 527 | } |
539 | 528 | ||
529 | iterator->arg += sizeof (uint32_t); | ||
530 | |||
531 | /* | ||
532 | * no need to check again for blowing past stated radiotap | ||
533 | * header length, becuase ieee80211_radiotap_iterator_next | ||
534 | * checks it before it is dereferenced | ||
535 | */ | ||
536 | |||
537 | } | ||
538 | |||
540 | /* we are all initialized happily */ | 539 | /* we are all initialized happily */ |
541 | return 0; | 540 | return 0; |
542 | } | 541 | } |
543 | 542 | ||
544 | 543 | ||
545 | /** | 544 | /** |
546 | * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg | 545 | * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg |
547 | * | 546 | * |
548 | * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...) | 547 | * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...) |
549 | * and sets iterator->this_arg to point to the payload for the arg. It takes | 548 | * and sets iterator->this_arg to point to the payload for the arg. It takes |
@@ -556,8 +555,7 @@ ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator | |||
556 | * @return next present arg index on success or negative if no more or error | 555 | * @return next present arg index on success or negative if no more or error |
557 | */ | 556 | */ |
558 | static int | 557 | static int |
559 | ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator | 558 | ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator) |
560 | *iterator) | ||
561 | { | 559 | { |
562 | 560 | ||
563 | /* | 561 | /* |
@@ -594,10 +592,10 @@ ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator | |||
594 | [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22, | 592 | [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22, |
595 | [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11, | 593 | [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11, |
596 | [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11 | 594 | [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11 |
597 | /* | 595 | /* |
598 | * add more here as they are defined in | 596 | * add more here as they are defined in |
599 | * include/net/ieee80211_radiotap.h | 597 | * include/net/ieee80211_radiotap.h |
600 | */ | 598 | */ |
601 | }; | 599 | }; |
602 | 600 | ||
603 | /* | 601 | /* |
@@ -606,92 +604,92 @@ ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator | |||
606 | */ | 604 | */ |
607 | 605 | ||
608 | while (iterator->arg_index < (int) sizeof (rt_sizes)) | 606 | while (iterator->arg_index < (int) sizeof (rt_sizes)) |
607 | { | ||
608 | int hit = 0; | ||
609 | |||
610 | if (!(iterator->bitmap_shifter & 1)) | ||
611 | goto next_entry; /* arg not present */ | ||
612 | |||
613 | /* | ||
614 | * arg is present, account for alignment padding | ||
615 | * 8-bit args can be at any alignment | ||
616 | * 16-bit args must start on 16-bit boundary | ||
617 | * 32-bit args must start on 32-bit boundary | ||
618 | * 64-bit args must start on 64-bit boundary | ||
619 | * | ||
620 | * note that total arg size can differ from alignment of | ||
621 | * elements inside arg, so we use upper nybble of length | ||
622 | * table to base alignment on | ||
623 | * | ||
624 | * also note: these alignments are ** relative to the | ||
625 | * start of the radiotap header **. There is no guarantee | ||
626 | * that the radiotap header itself is aligned on any | ||
627 | * kind of boundary. | ||
628 | */ | ||
629 | |||
630 | if ((((void *) iterator->arg) - | ||
631 | ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4) | ||
632 | - 1)) | ||
633 | iterator->arg_index += | ||
634 | (rt_sizes[iterator->arg_index] >> 4) - | ||
635 | ((((void *) iterator->arg) - | ||
636 | ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> | ||
637 | 4) - 1)); | ||
638 | |||
639 | /* | ||
640 | * this is what we will return to user, but we need to | ||
641 | * move on first so next call has something fresh to test | ||
642 | */ | ||
643 | |||
644 | iterator->this_arg_index = iterator->arg_index; | ||
645 | iterator->this_arg = iterator->arg; | ||
646 | hit = 1; | ||
647 | |||
648 | /* internally move on the size of this arg */ | ||
649 | |||
650 | iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; | ||
651 | |||
652 | /* | ||
653 | * check for insanity where we are given a bitmap that | ||
654 | * claims to have more arg content than the length of the | ||
655 | * radiotap section. We will normally end up equalling this | ||
656 | * max_length on the last arg, never exceeding it. | ||
657 | */ | ||
658 | |||
659 | if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > | ||
660 | iterator->max_length) | ||
661 | return (-EINVAL); | ||
662 | |||
663 | next_entry: | ||
664 | |||
665 | iterator->arg_index++; | ||
666 | if (((iterator->arg_index & 31) == 0)) | ||
609 | { | 667 | { |
610 | int hit = 0; | 668 | /* completed current uint32_t bitmap */ |
611 | 669 | if (iterator->bitmap_shifter & 1) | |
612 | if (!(iterator->bitmap_shifter & 1)) | 670 | { |
613 | goto next_entry; /* arg not present */ | 671 | /* b31 was set, there is more */ |
614 | 672 | /* move to next uint32_t bitmap */ | |
615 | /* | 673 | iterator->bitmap_shifter = le32toh (*iterator->next_bitmap); |
616 | * arg is present, account for alignment padding | 674 | iterator->next_bitmap++; |
617 | * 8-bit args can be at any alignment | 675 | } |
618 | * 16-bit args must start on 16-bit boundary | ||
619 | * 32-bit args must start on 32-bit boundary | ||
620 | * 64-bit args must start on 64-bit boundary | ||
621 | * | ||
622 | * note that total arg size can differ from alignment of | ||
623 | * elements inside arg, so we use upper nybble of length | ||
624 | * table to base alignment on | ||
625 | * | ||
626 | * also note: these alignments are ** relative to the | ||
627 | * start of the radiotap header **. There is no guarantee | ||
628 | * that the radiotap header itself is aligned on any | ||
629 | * kind of boundary. | ||
630 | */ | ||
631 | |||
632 | if ((((void *) iterator->arg) - | ||
633 | ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> | ||
634 | 4) - 1)) | ||
635 | iterator->arg_index += | ||
636 | (rt_sizes[iterator->arg_index] >> 4) - | ||
637 | ((((void *) iterator->arg) - | ||
638 | ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] | ||
639 | >> 4) - 1)); | ||
640 | |||
641 | /* | ||
642 | * this is what we will return to user, but we need to | ||
643 | * move on first so next call has something fresh to test | ||
644 | */ | ||
645 | |||
646 | iterator->this_arg_index = iterator->arg_index; | ||
647 | iterator->this_arg = iterator->arg; | ||
648 | hit = 1; | ||
649 | |||
650 | /* internally move on the size of this arg */ | ||
651 | |||
652 | iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; | ||
653 | |||
654 | /* | ||
655 | * check for insanity where we are given a bitmap that | ||
656 | * claims to have more arg content than the length of the | ||
657 | * radiotap section. We will normally end up equalling this | ||
658 | * max_length on the last arg, never exceeding it. | ||
659 | */ | ||
660 | |||
661 | if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > | ||
662 | iterator->max_length) | ||
663 | return (-EINVAL); | ||
664 | |||
665 | next_entry: | ||
666 | |||
667 | iterator->arg_index++; | ||
668 | if (((iterator->arg_index & 31) == 0)) | ||
669 | { | ||
670 | /* completed current uint32_t bitmap */ | ||
671 | if (iterator->bitmap_shifter & 1) | ||
672 | { | ||
673 | /* b31 was set, there is more */ | ||
674 | /* move to next uint32_t bitmap */ | ||
675 | iterator->bitmap_shifter = le32toh (*iterator->next_bitmap); | ||
676 | iterator->next_bitmap++; | ||
677 | } | ||
678 | else | ||
679 | { | ||
680 | /* no more bitmaps: end */ | ||
681 | iterator->arg_index = sizeof (rt_sizes); | ||
682 | } | ||
683 | } | ||
684 | else | 676 | else |
685 | { /* just try the next bit */ | 677 | { |
686 | iterator->bitmap_shifter >>= 1; | 678 | /* no more bitmaps: end */ |
687 | } | 679 | iterator->arg_index = sizeof (rt_sizes); |
680 | } | ||
681 | } | ||
682 | else | ||
683 | { /* just try the next bit */ | ||
684 | iterator->bitmap_shifter >>= 1; | ||
685 | } | ||
688 | 686 | ||
689 | /* if we found a valid arg earlier, return it now */ | 687 | /* if we found a valid arg earlier, return it now */ |
690 | 688 | ||
691 | if (hit) | 689 | if (hit) |
692 | return (iterator->this_arg_index); | 690 | return (iterator->this_arg_index); |
693 | 691 | ||
694 | } | 692 | } |
695 | 693 | ||
696 | /* we don't know how to handle any more args, we're done */ | 694 | /* we don't know how to handle any more args, we're done */ |
697 | 695 | ||
@@ -841,7 +839,7 @@ check_crc_buf_osdep (const unsigned char *buf, size_t len) | |||
841 | crc = calc_crc_osdep (buf, len); | 839 | crc = calc_crc_osdep (buf, len); |
842 | buf += len; | 840 | buf += len; |
843 | return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && | 841 | return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && |
844 | ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); | 842 | ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); |
845 | } | 843 | } |
846 | 844 | ||
847 | 845 | ||
@@ -890,8 +888,8 @@ linux_get_channel (const struct Hardware_Infos *dev) | |||
890 | * @return size read from the buffer | 888 | * @return size read from the buffer |
891 | */ | 889 | */ |
892 | static ssize_t | 890 | static ssize_t |
893 | linux_read (struct Hardware_Infos *dev, unsigned char *buf, | 891 | linux_read (struct Hardware_Infos *dev, unsigned char *buf, size_t buf_size, |
894 | size_t buf_size, struct Radiotap_rx *ri) | 892 | struct Radiotap_rx *ri) |
895 | { | 893 | { |
896 | unsigned char tmpbuf[buf_size]; | 894 | unsigned char tmpbuf[buf_size]; |
897 | ssize_t caplen; | 895 | ssize_t caplen; |
@@ -901,172 +899,170 @@ linux_read (struct Hardware_Infos *dev, unsigned char *buf, | |||
901 | 899 | ||
902 | caplen = read (dev->fd_raw, tmpbuf, buf_size); | 900 | caplen = read (dev->fd_raw, tmpbuf, buf_size); |
903 | if (0 > caplen) | 901 | if (0 > caplen) |
904 | { | 902 | { |
905 | if (EAGAIN == errno) | 903 | if (EAGAIN == errno) |
906 | return 0; | 904 | return 0; |
907 | fprintf (stderr, "Failed to read from RAW socket: %s\n", | 905 | fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno)); |
908 | strerror (errno)); | 906 | return -1; |
909 | return -1; | 907 | } |
910 | } | ||
911 | 908 | ||
912 | memset (buf, 0, buf_size); | 909 | memset (buf, 0, buf_size); |
913 | memset (ri, 0, sizeof (*ri)); | 910 | memset (ri, 0, sizeof (*ri)); |
914 | 911 | ||
915 | switch (dev->arptype_in) | 912 | switch (dev->arptype_in) |
913 | { | ||
914 | case ARPHRD_IEEE80211_PRISM: | ||
915 | { | ||
916 | /* skip the prism header */ | ||
917 | if (tmpbuf[7] == 0x40) | ||
916 | { | 918 | { |
917 | case ARPHRD_IEEE80211_PRISM: | 919 | /* prism54 uses a different format */ |
918 | { | 920 | ri->ri_power = tmpbuf[0x33]; |
919 | /* skip the prism header */ | 921 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); |
920 | if (tmpbuf[7] == 0x40) | 922 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; |
921 | { | 923 | got_signal = 1; |
922 | /* prism54 uses a different format */ | 924 | got_noise = 1; |
923 | ri->ri_power = tmpbuf[0x33]; | 925 | n = 0x40; |
924 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); | 926 | } |
925 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; | 927 | else |
926 | got_signal = 1; | 928 | { |
927 | got_noise = 1; | 929 | ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48); |
928 | n = 0x40; | 930 | ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); |
929 | } | 931 | ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); |
930 | else | 932 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); |
931 | { | 933 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; |
932 | ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48); | 934 | got_channel = 1; |
933 | ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); | 935 | got_signal = 1; |
934 | ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); | 936 | got_noise = 1; |
935 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); | 937 | n = *(int *) (tmpbuf + 4); |
936 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; | 938 | } |
937 | got_channel = 1; | 939 | |
938 | got_signal = 1; | 940 | if (n < 8 || n >= caplen) |
939 | got_noise = 1; | 941 | return (0); |
940 | n = *(int *) (tmpbuf + 4); | 942 | } |
941 | } | 943 | break; |
942 | |||
943 | if (n < 8 || n >= caplen) | ||
944 | return (0); | ||
945 | } | ||
946 | break; | ||
947 | 944 | ||
948 | case ARPHRD_IEEE80211_FULL: | 945 | case ARPHRD_IEEE80211_FULL: |
946 | { | ||
947 | struct ieee80211_radiotap_iterator iterator; | ||
948 | struct ieee80211_radiotap_header *rthdr; | ||
949 | |||
950 | rthdr = (struct ieee80211_radiotap_header *) tmpbuf; | ||
951 | |||
952 | if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0) | ||
953 | return (0); | ||
954 | |||
955 | /* go through the radiotap arguments we have been given | ||
956 | * by the driver | ||
957 | */ | ||
958 | |||
959 | while (ieee80211_radiotap_iterator_next (&iterator) >= 0) | ||
960 | { | ||
961 | |||
962 | switch (iterator.this_arg_index) | ||
949 | { | 963 | { |
950 | struct ieee80211_radiotap_iterator iterator; | 964 | |
951 | struct ieee80211_radiotap_header *rthdr; | 965 | case IEEE80211_RADIOTAP_TSFT: |
952 | 966 | ri->ri_mactime = le64toh (*((uint64_t *) iterator.this_arg)); | |
953 | rthdr = (struct ieee80211_radiotap_header *) tmpbuf; | 967 | break; |
954 | 968 | ||
955 | if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0) | 969 | case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: |
956 | return (0); | 970 | if (!got_signal) |
957 | 971 | { | |
958 | /* go through the radiotap arguments we have been given | 972 | if (*iterator.this_arg < 127) |
959 | * by the driver | 973 | ri->ri_power = *iterator.this_arg; |
960 | */ | 974 | else |
961 | 975 | ri->ri_power = *iterator.this_arg - 255; | |
962 | while (ieee80211_radiotap_iterator_next (&iterator) >= 0) | 976 | |
963 | { | 977 | got_signal = 1; |
964 | 978 | } | |
965 | switch (iterator.this_arg_index) | 979 | break; |
966 | { | 980 | |
967 | 981 | case IEEE80211_RADIOTAP_DB_ANTSIGNAL: | |
968 | case IEEE80211_RADIOTAP_TSFT: | 982 | if (!got_signal) |
969 | ri->ri_mactime = le64toh (*((uint64_t *) iterator.this_arg)); | 983 | { |
970 | break; | 984 | if (*iterator.this_arg < 127) |
971 | 985 | ri->ri_power = *iterator.this_arg; | |
972 | case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: | 986 | else |
973 | if (!got_signal) | 987 | ri->ri_power = *iterator.this_arg - 255; |
974 | { | 988 | |
975 | if (*iterator.this_arg < 127) | 989 | got_signal = 1; |
976 | ri->ri_power = *iterator.this_arg; | 990 | } |
977 | else | 991 | break; |
978 | ri->ri_power = *iterator.this_arg - 255; | 992 | |
979 | 993 | case IEEE80211_RADIOTAP_DBM_ANTNOISE: | |
980 | got_signal = 1; | 994 | if (!got_noise) |
981 | } | 995 | { |
982 | break; | 996 | if (*iterator.this_arg < 127) |
983 | 997 | ri->ri_noise = *iterator.this_arg; | |
984 | case IEEE80211_RADIOTAP_DB_ANTSIGNAL: | 998 | else |
985 | if (!got_signal) | 999 | ri->ri_noise = *iterator.this_arg - 255; |
986 | { | 1000 | |
987 | if (*iterator.this_arg < 127) | 1001 | got_noise = 1; |
988 | ri->ri_power = *iterator.this_arg; | 1002 | } |
989 | else | 1003 | break; |
990 | ri->ri_power = *iterator.this_arg - 255; | 1004 | |
991 | 1005 | case IEEE80211_RADIOTAP_DB_ANTNOISE: | |
992 | got_signal = 1; | 1006 | if (!got_noise) |
993 | } | 1007 | { |
994 | break; | 1008 | if (*iterator.this_arg < 127) |
995 | 1009 | ri->ri_noise = *iterator.this_arg; | |
996 | case IEEE80211_RADIOTAP_DBM_ANTNOISE: | 1010 | else |
997 | if (!got_noise) | 1011 | ri->ri_noise = *iterator.this_arg - 255; |
998 | { | 1012 | |
999 | if (*iterator.this_arg < 127) | 1013 | got_noise = 1; |
1000 | ri->ri_noise = *iterator.this_arg; | 1014 | } |
1001 | else | 1015 | break; |
1002 | ri->ri_noise = *iterator.this_arg - 255; | 1016 | |
1003 | 1017 | case IEEE80211_RADIOTAP_ANTENNA: | |
1004 | got_noise = 1; | 1018 | ri->ri_antenna = *iterator.this_arg; |
1005 | } | 1019 | break; |
1006 | break; | 1020 | |
1007 | 1021 | case IEEE80211_RADIOTAP_CHANNEL: | |
1008 | case IEEE80211_RADIOTAP_DB_ANTNOISE: | 1022 | ri->ri_channel = *iterator.this_arg; |
1009 | if (!got_noise) | 1023 | got_channel = 1; |
1010 | { | 1024 | break; |
1011 | if (*iterator.this_arg < 127) | 1025 | |
1012 | ri->ri_noise = *iterator.this_arg; | 1026 | case IEEE80211_RADIOTAP_RATE: |
1013 | else | 1027 | ri->ri_rate = (*iterator.this_arg) * 500000; |
1014 | ri->ri_noise = *iterator.this_arg - 255; | 1028 | break; |
1015 | 1029 | ||
1016 | got_noise = 1; | 1030 | case IEEE80211_RADIOTAP_FLAGS: |
1017 | } | 1031 | /* is the CRC visible at the end? |
1018 | break; | 1032 | * remove |
1019 | 1033 | */ | |
1020 | case IEEE80211_RADIOTAP_ANTENNA: | 1034 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) |
1021 | ri->ri_antenna = *iterator.this_arg; | 1035 | { |
1022 | break; | 1036 | fcs_removed = 1; |
1023 | 1037 | caplen -= 4; | |
1024 | case IEEE80211_RADIOTAP_CHANNEL: | 1038 | } |
1025 | ri->ri_channel = *iterator.this_arg; | 1039 | |
1026 | got_channel = 1; | 1040 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) |
1027 | break; | 1041 | return (0); |
1028 | 1042 | ||
1029 | case IEEE80211_RADIOTAP_RATE: | 1043 | break; |
1030 | ri->ri_rate = (*iterator.this_arg) * 500000; | ||
1031 | break; | ||
1032 | |||
1033 | case IEEE80211_RADIOTAP_FLAGS: | ||
1034 | /* is the CRC visible at the end? | ||
1035 | * remove | ||
1036 | */ | ||
1037 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) | ||
1038 | { | ||
1039 | fcs_removed = 1; | ||
1040 | caplen -= 4; | ||
1041 | } | ||
1042 | |||
1043 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) | ||
1044 | return (0); | ||
1045 | |||
1046 | break; | ||
1047 | } | ||
1048 | } | ||
1049 | n = le16toh (rthdr->it_len); | ||
1050 | if (n <= 0 || n >= caplen) | ||
1051 | return 0; | ||
1052 | } | 1044 | } |
1053 | break; | ||
1054 | case ARPHRD_IEEE80211: | ||
1055 | /* do nothing? */ | ||
1056 | break; | ||
1057 | default: | ||
1058 | errno = ENOTSUP; | ||
1059 | return -1; | ||
1060 | } | 1045 | } |
1046 | n = le16toh (rthdr->it_len); | ||
1047 | if (n <= 0 || n >= caplen) | ||
1048 | return 0; | ||
1049 | } | ||
1050 | break; | ||
1051 | case ARPHRD_IEEE80211: | ||
1052 | /* do nothing? */ | ||
1053 | break; | ||
1054 | default: | ||
1055 | errno = ENOTSUP; | ||
1056 | return -1; | ||
1057 | } | ||
1061 | 1058 | ||
1062 | caplen -= n; | 1059 | caplen -= n; |
1063 | 1060 | ||
1064 | //detect fcs at the end, even if the flag wasn't set and remove it | 1061 | //detect fcs at the end, even if the flag wasn't set and remove it |
1065 | if ((0 == fcs_removed) | 1062 | if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4))) |
1066 | && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4))) | 1063 | { |
1067 | { | 1064 | caplen -= 4; |
1068 | caplen -= 4; | 1065 | } |
1069 | } | ||
1070 | memcpy (buf, tmpbuf + n, caplen); | 1066 | memcpy (buf, tmpbuf + n, caplen); |
1071 | if (!got_channel) | 1067 | if (!got_channel) |
1072 | ri->ri_channel = linux_get_channel (dev); | 1068 | ri->ri_channel = linux_get_channel (dev); |
@@ -1092,12 +1088,11 @@ openraw (struct Hardware_Infos *dev) | |||
1092 | memset (&ifr, 0, sizeof (ifr)); | 1088 | memset (&ifr, 0, sizeof (ifr)); |
1093 | strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ); | 1089 | strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ); |
1094 | if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr)) | 1090 | if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr)) |
1095 | { | 1091 | { |
1096 | fprintf (stderr, | 1092 | fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n", |
1097 | "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n", | 1093 | IFNAMSIZ, dev->iface, strerror (errno)); |
1098 | IFNAMSIZ, dev->iface, strerror (errno)); | 1094 | return 1; |
1099 | return 1; | 1095 | } |
1100 | } | ||
1101 | 1096 | ||
1102 | /* lookup the hardware type */ | 1097 | /* lookup the hardware type */ |
1103 | memset (&sll, 0, sizeof (sll)); | 1098 | memset (&sll, 0, sizeof (sll)); |
@@ -1105,78 +1100,72 @@ openraw (struct Hardware_Infos *dev) | |||
1105 | sll.sll_ifindex = ifr.ifr_ifindex; | 1100 | sll.sll_ifindex = ifr.ifr_ifindex; |
1106 | sll.sll_protocol = htons (ETH_P_ALL); | 1101 | sll.sll_protocol = htons (ETH_P_ALL); |
1107 | if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) | 1102 | if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) |
1108 | { | 1103 | { |
1109 | fprintf (stderr, | 1104 | fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", |
1110 | "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", | 1105 | IFNAMSIZ, dev->iface, strerror (errno)); |
1111 | IFNAMSIZ, dev->iface, strerror (errno)); | 1106 | return 1; |
1112 | return 1; | 1107 | } |
1113 | } | ||
1114 | 1108 | ||
1115 | /* lookup iw mode */ | 1109 | /* lookup iw mode */ |
1116 | memset (&wrq, 0, sizeof (struct iwreq)); | 1110 | memset (&wrq, 0, sizeof (struct iwreq)); |
1117 | strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); | 1111 | strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); |
1118 | if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq)) | 1112 | if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq)) |
1119 | { | 1113 | { |
1120 | /* most probably not supported (ie for rtap ipw interface) * | 1114 | /* most probably not supported (ie for rtap ipw interface) * |
1121 | * so just assume its correctly set... */ | 1115 | * so just assume its correctly set... */ |
1122 | wrq.u.mode = IW_MODE_MONITOR; | 1116 | wrq.u.mode = IW_MODE_MONITOR; |
1123 | } | 1117 | } |
1124 | 1118 | ||
1125 | if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && | 1119 | if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && |
1126 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && | 1120 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && |
1127 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) || | 1121 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) || |
1128 | (wrq.u.mode != IW_MODE_MONITOR)) | 1122 | (wrq.u.mode != IW_MODE_MONITOR)) |
1129 | { | 1123 | { |
1130 | fprintf (stderr, | 1124 | fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n", |
1131 | "Error: interface `%.*s' is not in monitor mode\n", | 1125 | IFNAMSIZ, dev->iface); |
1132 | IFNAMSIZ, dev->iface); | 1126 | return 1; |
1133 | return 1; | 1127 | } |
1134 | } | ||
1135 | 1128 | ||
1136 | /* Is interface st to up, broadcast & running ? */ | 1129 | /* Is interface st to up, broadcast & running ? */ |
1137 | if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags) | 1130 | if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags) |
1131 | { | ||
1132 | /* Bring interface up */ | ||
1133 | ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; | ||
1134 | |||
1135 | if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr)) | ||
1138 | { | 1136 | { |
1139 | /* Bring interface up */ | 1137 | fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n", |
1140 | ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; | 1138 | IFNAMSIZ, dev->iface, strerror (errno)); |
1141 | 1139 | return 1; | |
1142 | if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr)) | ||
1143 | { | ||
1144 | fprintf (stderr, | ||
1145 | "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n", | ||
1146 | IFNAMSIZ, dev->iface, strerror (errno)); | ||
1147 | return 1; | ||
1148 | } | ||
1149 | } | 1140 | } |
1141 | } | ||
1150 | 1142 | ||
1151 | /* bind the raw socket to the interface */ | 1143 | /* bind the raw socket to the interface */ |
1152 | if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll))) | 1144 | if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll))) |
1153 | { | 1145 | { |
1154 | fprintf (stderr, | 1146 | fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ, |
1155 | "Failed to bind interface `%.*s': %s\n", IFNAMSIZ, | 1147 | dev->iface, strerror (errno)); |
1156 | dev->iface, strerror (errno)); | 1148 | return 1; |
1157 | return 1; | 1149 | } |
1158 | } | ||
1159 | 1150 | ||
1160 | /* lookup the hardware type */ | 1151 | /* lookup the hardware type */ |
1161 | if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) | 1152 | if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) |
1162 | { | 1153 | { |
1163 | fprintf (stderr, | 1154 | fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", |
1164 | "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", | 1155 | IFNAMSIZ, dev->iface, strerror (errno)); |
1165 | IFNAMSIZ, dev->iface, strerror (errno)); | 1156 | return 1; |
1166 | return 1; | 1157 | } |
1167 | } | ||
1168 | 1158 | ||
1169 | memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE); | 1159 | memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE); |
1170 | dev->arptype_in = ifr.ifr_hwaddr.sa_family; | 1160 | dev->arptype_in = ifr.ifr_hwaddr.sa_family; |
1171 | if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && | 1161 | if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && |
1172 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && | 1162 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && |
1173 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) | 1163 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) |
1174 | { | 1164 | { |
1175 | fprintf (stderr, | 1165 | fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n", |
1176 | "Unsupported hardware link type %d on interface `%.*s'\n", | 1166 | ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface); |
1177 | ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface); | 1167 | return 1; |
1178 | return 1; | 1168 | } |
1179 | } | ||
1180 | 1169 | ||
1181 | /* enable promiscuous mode */ | 1170 | /* enable promiscuous mode */ |
1182 | memset (&mr, 0, sizeof (mr)); | 1171 | memset (&mr, 0, sizeof (mr)); |
@@ -1184,13 +1173,12 @@ openraw (struct Hardware_Infos *dev) | |||
1184 | mr.mr_type = PACKET_MR_PROMISC; | 1173 | mr.mr_type = PACKET_MR_PROMISC; |
1185 | if (0 != | 1174 | if (0 != |
1186 | setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, | 1175 | setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, |
1187 | sizeof (mr))) | 1176 | sizeof (mr))) |
1188 | { | 1177 | { |
1189 | fprintf (stderr, | 1178 | fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n", |
1190 | "Failed to enable promiscuous mode on interface `%.*s'\n", | 1179 | IFNAMSIZ, dev->iface); |
1191 | IFNAMSIZ, dev->iface); | 1180 | return 1; |
1192 | return 1; | 1181 | } |
1193 | } | ||
1194 | 1182 | ||
1195 | return 0; | 1183 | return 0; |
1196 | } | 1184 | } |
@@ -1211,36 +1199,34 @@ wlaninit (struct Hardware_Infos *dev, const char *iface) | |||
1211 | 1199 | ||
1212 | dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); | 1200 | dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); |
1213 | if (0 > dev->fd_raw) | 1201 | if (0 > dev->fd_raw) |
1214 | { | 1202 | { |
1215 | fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno)); | 1203 | fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno)); |
1216 | return 1; | 1204 | return 1; |
1217 | } | 1205 | } |
1218 | if (dev->fd_raw >= FD_SETSIZE) | 1206 | if (dev->fd_raw >= FD_SETSIZE) |
1219 | { | 1207 | { |
1220 | fprintf (stderr, | 1208 | fprintf (stderr, "File descriptor too large for select (%d > %d)\n", |
1221 | "File descriptor too large for select (%d > %d)\n", | 1209 | dev->fd_raw, FD_SETSIZE); |
1222 | dev->fd_raw, FD_SETSIZE); | 1210 | close (dev->fd_raw); |
1223 | close (dev->fd_raw); | 1211 | return 1; |
1224 | return 1; | 1212 | } |
1225 | } | ||
1226 | 1213 | ||
1227 | /* mac80211 stack detection */ | 1214 | /* mac80211 stack detection */ |
1228 | ret = | 1215 | ret = |
1229 | snprintf (strbuf, | 1216 | snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem", |
1230 | sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem", iface); | 1217 | iface); |
1231 | if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf))) | 1218 | if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf))) |
1232 | { | 1219 | { |
1233 | fprintf (stderr, | 1220 | fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface); |
1234 | "Did not find 802.11 interface `%s'. Exiting.\n", iface); | 1221 | close (dev->fd_raw); |
1235 | close (dev->fd_raw); | 1222 | return 1; |
1236 | return 1; | 1223 | } |
1237 | } | ||
1238 | strncpy (dev->iface, iface, IFNAMSIZ); | 1224 | strncpy (dev->iface, iface, IFNAMSIZ); |
1239 | if (0 != openraw (dev)) | 1225 | if (0 != openraw (dev)) |
1240 | { | 1226 | { |
1241 | close (dev->fd_raw); | 1227 | close (dev->fd_raw); |
1242 | return 1; | 1228 | return 1; |
1243 | } | 1229 | } |
1244 | return 0; | 1230 | return 0; |
1245 | } | 1231 | } |
1246 | 1232 | ||
@@ -1254,7 +1240,7 @@ wlaninit (struct Hardware_Infos *dev, const char *iface) | |||
1254 | */ | 1240 | */ |
1255 | static int | 1241 | static int |
1256 | mac_test (const struct ieee80211_frame *uint8_taIeeeHeader, | 1242 | mac_test (const struct ieee80211_frame *uint8_taIeeeHeader, |
1257 | const struct Hardware_Infos *dev) | 1243 | const struct Hardware_Infos *dev) |
1258 | { | 1244 | { |
1259 | if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE)) | 1245 | if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE)) |
1260 | return 1; | 1246 | return 1; |
@@ -1273,7 +1259,7 @@ mac_test (const struct ieee80211_frame *uint8_taIeeeHeader, | |||
1273 | */ | 1259 | */ |
1274 | static void | 1260 | static void |
1275 | mac_set (struct ieee80211_frame *uint8_taIeeeHeader, | 1261 | mac_set (struct ieee80211_frame *uint8_taIeeeHeader, |
1276 | const struct Hardware_Infos *dev) | 1262 | const struct Hardware_Infos *dev) |
1277 | { | 1263 | { |
1278 | uint8_taIeeeHeader->i_fc[0] = 0x08; | 1264 | uint8_taIeeeHeader->i_fc[0] = 0x08; |
1279 | uint8_taIeeeHeader->i_fc[1] = 0x00; | 1265 | uint8_taIeeeHeader->i_fc[1] = 0x00; |
@@ -1289,8 +1275,7 @@ mac_set (struct ieee80211_frame *uint8_taIeeeHeader, | |||
1289 | * @param hdr pointer to the start of the packet | 1275 | * @param hdr pointer to the start of the packet |
1290 | */ | 1276 | */ |
1291 | static void | 1277 | static void |
1292 | stdin_send_hw (void *cls, void *client, | 1278 | stdin_send_hw (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) |
1293 | const struct GNUNET_MessageHeader *hdr) | ||
1294 | { | 1279 | { |
1295 | struct Hardware_Infos *dev = cls; | 1280 | struct Hardware_Infos *dev = cls; |
1296 | struct sendbuf *write_pout = &dev->write_pout; | 1281 | struct sendbuf *write_pout = &dev->write_pout; |
@@ -1305,7 +1290,7 @@ stdin_send_hw (void *cls, void *client, | |||
1305 | rtheader.rate = 0x00; | 1290 | rtheader.rate = 0x00; |
1306 | rtheader.pad1 = 0x00; | 1291 | rtheader.pad1 = 0x00; |
1307 | rtheader.txflags = | 1292 | rtheader.txflags = |
1308 | htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ); | 1293 | htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ); |
1309 | 1294 | ||
1310 | /* { 0x00, 0x00, <-- radiotap version | 1295 | /* { 0x00, 0x00, <-- radiotap version |
1311 | * 0x0c, 0x00, <- radiotap header length | 1296 | * 0x0c, 0x00, <- radiotap header length |
@@ -1318,24 +1303,23 @@ stdin_send_hw (void *cls, void *client, | |||
1318 | sendsize = ntohs (hdr->size); | 1303 | sendsize = ntohs (hdr->size); |
1319 | if (sendsize < | 1304 | if (sendsize < |
1320 | sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader)) | 1305 | sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader)) |
1321 | { | 1306 | { |
1322 | fprintf (stderr, | 1307 | fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n"); |
1323 | "Function stdin_send_hw: malformed packet (too small)\n"); | 1308 | exit (1); |
1324 | exit (1); | 1309 | } |
1325 | } | ||
1326 | sendsize -= | 1310 | sendsize -= |
1327 | sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader); | 1311 | sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader); |
1328 | 1312 | ||
1329 | if (MAXLINE < sendsize) | 1313 | if (MAXLINE < sendsize) |
1330 | { | 1314 | { |
1331 | fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n"); | 1315 | fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n"); |
1332 | exit (1); | 1316 | exit (1); |
1333 | } | 1317 | } |
1334 | if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) | 1318 | if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) |
1335 | { | 1319 | { |
1336 | fprintf (stderr, "Function stdin_send: wrong packet type\n"); | 1320 | fprintf (stderr, "Function stdin_send: wrong packet type\n"); |
1337 | exit (1); | 1321 | exit (1); |
1338 | } | 1322 | } |
1339 | 1323 | ||
1340 | rtheader.header.it_len = htole16 (sizeof (rtheader)); | 1324 | rtheader.header.it_len = htole16 (sizeof (rtheader)); |
1341 | rtheader.rate = header->rate; | 1325 | rtheader.rate = header->rate; |
@@ -1343,8 +1327,7 @@ stdin_send_hw (void *cls, void *client, | |||
1343 | memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize); | 1327 | memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize); |
1344 | /* payload contains MAC address, but we don't trust it, so we'll | 1328 | /* payload contains MAC address, but we don't trust it, so we'll |
1345 | * overwrite it with OUR MAC address again to prevent mischief */ | 1329 | * overwrite it with OUR MAC address again to prevent mischief */ |
1346 | wlanheader = | 1330 | wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader)); |
1347 | (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader)); | ||
1348 | mac_set (wlanheader, dev); | 1331 | mac_set (wlanheader, dev); |
1349 | write_pout->size = sendsize + sizeof (rtheader); | 1332 | write_pout->size = sendsize + sizeof (rtheader); |
1350 | } | 1333 | } |
@@ -1372,19 +1355,19 @@ main (int argc, char *argv[]) | |||
1372 | struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst; | 1355 | struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst; |
1373 | 1356 | ||
1374 | if (2 != argc) | 1357 | if (2 != argc) |
1375 | { | 1358 | { |
1376 | fprintf (stderr, | 1359 | fprintf (stderr, |
1377 | "You must specify the name of the interface as the first and only argument to this program.\n"); | 1360 | "You must specify the name of the interface as the first and only argument to this program.\n"); |
1378 | return 1; | 1361 | return 1; |
1379 | } | 1362 | } |
1380 | if (0 != wlaninit (&dev, argv[1])) | 1363 | if (0 != wlaninit (&dev, argv[1])) |
1381 | return 1; | 1364 | return 1; |
1382 | uid = getuid (); | 1365 | uid = getuid (); |
1383 | if (0 != setresuid (uid, uid, uid)) | 1366 | if (0 != setresuid (uid, uid, uid)) |
1384 | { | 1367 | { |
1385 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); | 1368 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); |
1386 | /* not critical, continue anyway */ | 1369 | /* not critical, continue anyway */ |
1387 | } | 1370 | } |
1388 | 1371 | ||
1389 | dev.write_pout.size = 0; | 1372 | dev.write_pout.size = 0; |
1390 | dev.write_pout.pos = 0; | 1373 | dev.write_pout.pos = 0; |
@@ -1396,135 +1379,129 @@ main (int argc, char *argv[]) | |||
1396 | stdin_open = 1; | 1379 | stdin_open = 1; |
1397 | 1380 | ||
1398 | while (1) | 1381 | while (1) |
1382 | { | ||
1383 | maxfd = -1; | ||
1384 | FD_ZERO (&rfds); | ||
1385 | if ((0 == dev.write_pout.size) && (1 == stdin_open)) | ||
1386 | { | ||
1387 | FD_SET (STDIN_FILENO, &rfds); | ||
1388 | maxfd = MAX (maxfd, STDIN_FILENO); | ||
1389 | } | ||
1390 | if (0 == write_std.size) | ||
1391 | { | ||
1392 | FD_SET (dev.fd_raw, &rfds); | ||
1393 | maxfd = MAX (maxfd, dev.fd_raw); | ||
1394 | } | ||
1395 | FD_ZERO (&wfds); | ||
1396 | if (0 < write_std.size) | ||
1397 | { | ||
1398 | FD_SET (STDOUT_FILENO, &wfds); | ||
1399 | maxfd = MAX (maxfd, STDOUT_FILENO); | ||
1400 | } | ||
1401 | if (0 < dev.write_pout.size) | ||
1402 | { | ||
1403 | FD_SET (dev.fd_raw, &wfds); | ||
1404 | maxfd = MAX (maxfd, dev.fd_raw); | ||
1405 | } | ||
1406 | retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); | ||
1407 | if ((-1 == retval) && (EINTR == errno)) | ||
1408 | continue; | ||
1409 | if (0 > retval) | ||
1410 | { | ||
1411 | fprintf (stderr, "select failed: %s\n", strerror (errno)); | ||
1412 | break; | ||
1413 | } | ||
1414 | if (FD_ISSET (STDOUT_FILENO, &wfds)) | ||
1415 | { | ||
1416 | ret = | ||
1417 | write (STDOUT_FILENO, write_std.buf + write_std.pos, | ||
1418 | write_std.size - write_std.pos); | ||
1419 | if (0 > ret) | ||
1420 | { | ||
1421 | fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno)); | ||
1422 | break; | ||
1423 | } | ||
1424 | write_std.pos += ret; | ||
1425 | if (write_std.pos == write_std.size) | ||
1426 | { | ||
1427 | write_std.pos = 0; | ||
1428 | write_std.size = 0; | ||
1429 | } | ||
1430 | } | ||
1431 | if (FD_ISSET (dev.fd_raw, &wfds)) | ||
1432 | { | ||
1433 | ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size); | ||
1434 | if (0 > ret) | ||
1435 | { | ||
1436 | fprintf (stderr, "Failed to write to WLAN device: %s\n", | ||
1437 | strerror (errno)); | ||
1438 | break; | ||
1439 | } | ||
1440 | dev.write_pout.pos += ret; | ||
1441 | if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0)) | ||
1442 | { | ||
1443 | /* we should not get partial sends with packet-oriented devices... */ | ||
1444 | fprintf (stderr, "Write error, partial send: %u/%u\n", | ||
1445 | dev.write_pout.pos, dev.write_pout.size); | ||
1446 | break; | ||
1447 | } | ||
1448 | if (dev.write_pout.pos == dev.write_pout.size) | ||
1449 | { | ||
1450 | dev.write_pout.pos = 0; | ||
1451 | dev.write_pout.size = 0; | ||
1452 | } | ||
1453 | } | ||
1454 | |||
1455 | if (FD_ISSET (STDIN_FILENO, &rfds)) | ||
1399 | { | 1456 | { |
1400 | maxfd = -1; | 1457 | ret = read (STDIN_FILENO, readbuf, sizeof (readbuf)); |
1401 | FD_ZERO (&rfds); | 1458 | if (0 > ret) |
1402 | if ((0 == dev.write_pout.size) && (1 == stdin_open)) | 1459 | { |
1403 | { | 1460 | fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno)); |
1404 | FD_SET (STDIN_FILENO, &rfds); | 1461 | break; |
1405 | maxfd = MAX (maxfd, STDIN_FILENO); | 1462 | } |
1406 | } | 1463 | if (0 == ret) |
1407 | if (0 == write_std.size) | 1464 | { |
1408 | { | 1465 | /* stop reading... */ |
1409 | FD_SET (dev.fd_raw, &rfds); | 1466 | stdin_open = 0; |
1410 | maxfd = MAX (maxfd, dev.fd_raw); | 1467 | } |
1411 | } | 1468 | GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO, |
1412 | FD_ZERO (&wfds); | 1469 | GNUNET_NO); |
1413 | if (0 < write_std.size) | 1470 | } |
1414 | { | ||
1415 | FD_SET (STDOUT_FILENO, &wfds); | ||
1416 | maxfd = MAX (maxfd, STDOUT_FILENO); | ||
1417 | } | ||
1418 | if (0 < dev.write_pout.size) | ||
1419 | { | ||
1420 | FD_SET (dev.fd_raw, &wfds); | ||
1421 | maxfd = MAX (maxfd, dev.fd_raw); | ||
1422 | } | ||
1423 | retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); | ||
1424 | if ((-1 == retval) && (EINTR == errno)) | ||
1425 | continue; | ||
1426 | if (0 > retval) | ||
1427 | { | ||
1428 | fprintf (stderr, "select failed: %s\n", strerror (errno)); | ||
1429 | break; | ||
1430 | } | ||
1431 | if (FD_ISSET (STDOUT_FILENO, &wfds)) | ||
1432 | { | ||
1433 | ret = | ||
1434 | write (STDOUT_FILENO, | ||
1435 | write_std.buf + write_std.pos, | ||
1436 | write_std.size - write_std.pos); | ||
1437 | if (0 > ret) | ||
1438 | { | ||
1439 | fprintf (stderr, | ||
1440 | "Failed to write to STDOUT: %s\n", strerror (errno)); | ||
1441 | break; | ||
1442 | } | ||
1443 | write_std.pos += ret; | ||
1444 | if (write_std.pos == write_std.size) | ||
1445 | { | ||
1446 | write_std.pos = 0; | ||
1447 | write_std.size = 0; | ||
1448 | } | ||
1449 | } | ||
1450 | if (FD_ISSET (dev.fd_raw, &wfds)) | ||
1451 | { | ||
1452 | ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size); | ||
1453 | if (0 > ret) | ||
1454 | { | ||
1455 | fprintf (stderr, | ||
1456 | "Failed to write to WLAN device: %s\n", | ||
1457 | strerror (errno)); | ||
1458 | break; | ||
1459 | } | ||
1460 | dev.write_pout.pos += ret; | ||
1461 | if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0)) | ||
1462 | { | ||
1463 | /* we should not get partial sends with packet-oriented devices... */ | ||
1464 | fprintf (stderr, | ||
1465 | "Write error, partial send: %u/%u\n", | ||
1466 | dev.write_pout.pos, dev.write_pout.size); | ||
1467 | break; | ||
1468 | } | ||
1469 | if (dev.write_pout.pos == dev.write_pout.size) | ||
1470 | { | ||
1471 | dev.write_pout.pos = 0; | ||
1472 | dev.write_pout.size = 0; | ||
1473 | } | ||
1474 | } | ||
1475 | |||
1476 | if (FD_ISSET (STDIN_FILENO, &rfds)) | ||
1477 | { | ||
1478 | ret = read (STDIN_FILENO, readbuf, sizeof (readbuf)); | ||
1479 | if (0 > ret) | ||
1480 | { | ||
1481 | fprintf (stderr, | ||
1482 | "Read error from STDIN: %s\n", strerror (errno)); | ||
1483 | break; | ||
1484 | } | ||
1485 | if (0 == ret) | ||
1486 | { | ||
1487 | /* stop reading... */ | ||
1488 | stdin_open = 0; | ||
1489 | } | ||
1490 | GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO, | ||
1491 | GNUNET_NO); | ||
1492 | } | ||
1493 | |||
1494 | if (FD_ISSET (dev.fd_raw, &rfds)) | ||
1495 | { | ||
1496 | struct GNUNET_MessageHeader *header; | ||
1497 | struct Radiotap_rx *rxinfo; | ||
1498 | struct ieee80211_frame *datastart; | ||
1499 | |||
1500 | header = (struct GNUNET_MessageHeader *) write_std.buf; | ||
1501 | rxinfo = (struct Radiotap_rx *) &header[1]; | ||
1502 | datastart = (struct ieee80211_frame *) &rxinfo[1]; | ||
1503 | ret = | ||
1504 | linux_read (&dev, (unsigned char *) datastart, | ||
1505 | sizeof (write_std.buf) - sizeof (struct Radiotap_rx) - | ||
1506 | sizeof (struct GNUNET_MessageHeader), rxinfo); | ||
1507 | if (0 > ret) | ||
1508 | { | ||
1509 | fprintf (stderr, | ||
1510 | "Read error from raw socket: %s\n", strerror (errno)); | ||
1511 | break; | ||
1512 | } | ||
1513 | if ((0 < ret) && (0 == mac_test (datastart, &dev))) | ||
1514 | { | ||
1515 | write_std.size = | ||
1516 | ret + sizeof (struct GNUNET_MessageHeader) + | ||
1517 | sizeof (struct Radiotap_rx); | ||
1518 | header->size = htons (write_std.size); | ||
1519 | header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1520 | } | ||
1521 | } | ||
1522 | 1471 | ||
1472 | if (FD_ISSET (dev.fd_raw, &rfds)) | ||
1473 | { | ||
1474 | struct GNUNET_MessageHeader *header; | ||
1475 | struct Radiotap_rx *rxinfo; | ||
1476 | struct ieee80211_frame *datastart; | ||
1477 | |||
1478 | header = (struct GNUNET_MessageHeader *) write_std.buf; | ||
1479 | rxinfo = (struct Radiotap_rx *) &header[1]; | ||
1480 | datastart = (struct ieee80211_frame *) &rxinfo[1]; | ||
1481 | ret = | ||
1482 | linux_read (&dev, (unsigned char *) datastart, | ||
1483 | sizeof (write_std.buf) - sizeof (struct Radiotap_rx) - | ||
1484 | sizeof (struct GNUNET_MessageHeader), rxinfo); | ||
1485 | if (0 > ret) | ||
1486 | { | ||
1487 | fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno)); | ||
1488 | break; | ||
1489 | } | ||
1490 | if ((0 < ret) && (0 == mac_test (datastart, &dev))) | ||
1491 | { | ||
1492 | write_std.size = | ||
1493 | ret + sizeof (struct GNUNET_MessageHeader) + | ||
1494 | sizeof (struct Radiotap_rx); | ||
1495 | header->size = htons (write_std.size); | ||
1496 | header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1497 | } | ||
1523 | } | 1498 | } |
1499 | |||
1500 | } | ||
1524 | /* Error handling, try to clean up a bit at least */ | 1501 | /* Error handling, try to clean up a bit at least */ |
1525 | GNUNET_SERVER_mst_destroy (stdin_mst); | 1502 | GNUNET_SERVER_mst_destroy (stdin_mst); |
1526 | close (dev.fd_raw); | 1503 | close (dev.fd_raw); |
1527 | return 1; /* we never exit 'normally' */ | 1504 | return 1; /* we never exit 'normally' */ |
1528 | } | 1505 | } |
1529 | 1506 | ||
1530 | /* end of gnunet-transport-wlan-helper.c */ | 1507 | /* end of gnunet-transport-wlan-helper.c */ |