ieee80211_hdr.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* $Id: ieee80211_hdr.c 1866 2007-05-12 19:48:48Z aturner $ */
  2. /*
  3. * Copyright (c) 2006-2007 Aaron Turner.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the names of the copyright owners nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  25. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  27. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "dlt_plugins-int.h"
  34. #include "ieee80211.h"
  35. /*
  36. * Does the given 802.11 header have data?
  37. * returns 1 for true & 0 for false
  38. */
  39. int
  40. ieee80211_is_data(tcpeditdlt_t *ctx, const void *packet, const int pktlen)
  41. {
  42. u_int16_t *frame_control, fc;
  43. struct tcpr_802_2snap_hdr *snap;
  44. int hdrlen;
  45. assert(ctx);
  46. assert(packet);
  47. /* Ack, Auth, NULL packets often are very small (10-30 bytes) */
  48. if (pktlen >= (int)sizeof(ieee80211_hdr_t))
  49. return 0;
  50. /*
  51. * Fields: Version|Type|Subtype|Flags
  52. * Bytes: 2|2|4|8
  53. * Types: 00 = Management, 01 = Control, 10 = Data
  54. * Data Subtypes (in binary):
  55. * 0000 - Data
  56. * 0001 - Data + Ack
  57. * 0010 - Data + Poll
  58. * 0011 - Data + Ack + Poll
  59. * 01?? - Data + Null (no data)
  60. * 1??? - Reserved
  61. * FIXME:
  62. * So right now, we only look for pure data frames, since I'm not sure what to do with ACK/Poll
  63. */
  64. frame_control = (u_int16_t *)packet;
  65. fc = ntohs(*frame_control);
  66. if ((fc & 0x2000) != 0x2000) {
  67. return 0;
  68. }
  69. /* frame must also have a 802.2 SNAP header */
  70. if (ieee80211_USE_4(fc)) {
  71. hdrlen = sizeof(ieee80211_addr4_hdr_t);
  72. } else {
  73. hdrlen = sizeof(ieee80211_hdr_t);
  74. }
  75. /*
  76. * FIXME: 802.11e? has a QoS feature which apparently extends the header by another
  77. * 2 bytes, but I don't know how to test for that yet.
  78. */
  79. if (pktlen < hdrlen + (int)sizeof(struct tcpr_802_2snap_hdr)) {
  80. return 0; /* not long enough for SNAP */
  81. }
  82. snap = (struct tcpr_802_2snap_hdr *)&((u_char *)packet)[hdrlen];
  83. /* verify the header is 802.2SNAP (8 bytes) not 802.2 (3 bytes) */
  84. if (snap->snap_dsap == 0xAA && snap->snap_ssap == 0xAA) {
  85. return 1;
  86. }
  87. return 0;
  88. }
  89. /*
  90. * returns 1 if WEP is enabled, 0 if not
  91. */
  92. int
  93. ieee80211_is_encrypted(tcpeditdlt_t *ctx, const void *packet, const int pktlen)
  94. {
  95. u_int16_t *frame_control, fc;
  96. assert(ctx);
  97. assert(packet);
  98. assert(pktlen >= (int)sizeof(ieee80211_hdr_t));
  99. frame_control = (u_int16_t *)packet;
  100. fc = ntohs(*frame_control);
  101. if ((fc & 0x0002) == 0x0002) {
  102. return 1;
  103. }
  104. return 0;
  105. }
  106. /*
  107. * 802.11 headers are variable length and the clients (non-AP's) have their
  108. * src & dst MAC addresses in different places in the header based on the
  109. * flags set in the first two bytes of the header (frame control)
  110. */
  111. u_char *
  112. ieee80211_get_src(const void *header)
  113. {
  114. ieee80211_hdr_t *addr3;
  115. ieee80211_addr4_hdr_t *addr4;
  116. u_int16_t *frame_control, fc;
  117. assert(header);
  118. frame_control = (u_int16_t *)header;
  119. fc = ntohs(*frame_control);
  120. if (ieee80211_USE_4(fc)) {
  121. addr4 = (ieee80211_addr4_hdr_t *)header;
  122. return addr4->addr4;
  123. } else {
  124. addr3 = (ieee80211_hdr_t *)header;
  125. switch (fc & (ieee80211_FC_TO_DS_MASK + ieee80211_FC_FROM_DS_MASK)) {
  126. case ieee80211_FC_TO_DS_MASK:
  127. return addr3->addr2;
  128. case ieee80211_FC_FROM_DS_MASK:
  129. return addr3->addr3;
  130. case 0:
  131. return addr3->addr2;
  132. default:
  133. err(1, "Whoops... we shouldn't of gotten here.");
  134. }
  135. }
  136. return NULL;
  137. }
  138. u_char *
  139. ieee80211_get_dst(const void *header)
  140. {
  141. ieee80211_hdr_t *addr3;
  142. ieee80211_addr4_hdr_t *addr4;
  143. u_int16_t *frame_control, fc;
  144. assert(header);
  145. frame_control = (u_int16_t *)header;
  146. fc = ntohs(*frame_control);
  147. if (ieee80211_USE_4(fc)) {
  148. addr4 = (ieee80211_addr4_hdr_t *)header;
  149. return addr4->addr3;
  150. } else {
  151. addr3 = (ieee80211_hdr_t *)header;
  152. switch (fc & (ieee80211_FC_TO_DS_MASK + ieee80211_FC_FROM_DS_MASK)) {
  153. case ieee80211_FC_TO_DS_MASK:
  154. return addr3->addr3;
  155. case ieee80211_FC_FROM_DS_MASK:
  156. return addr3->addr2;
  157. case 0:
  158. return addr3->addr3;
  159. default:
  160. err(1, "Whoops... we shouldn't of gotten here.");
  161. }
  162. }
  163. return NULL;
  164. }