print-802_15_4.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * Copyright (c) 2009
  3. * Siemens AG, All rights reserved.
  4. * Dmitry Eremin-Solenikov (dbaryshkov@gmail.com)
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that: (1) source code distributions
  8. * retain the above copyright notice and this paragraph in its entirety, (2)
  9. * distributions including binary code include the above copyright notice and
  10. * this paragraph in its entirety in the documentation or other materials
  11. * provided with the distribution, and (3) all advertising materials mentioning
  12. * features or use of this software display the following acknowledgement:
  13. * ``This product includes software developed by the University of California,
  14. * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  15. * the University nor the names of its contributors may be used to endorse
  16. * or promote products derived from this software without specific prior
  17. * written permission.
  18. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  19. * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  20. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  21. */
  22. /* \summary: IEEE 802.15.4 printer */
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include <netdissect-stdinc.h>
  27. #include "netdissect.h"
  28. #include "addrtoname.h"
  29. #include "extract.h"
  30. static const char *ftypes[] = {
  31. "Beacon", /* 0 */
  32. "Data", /* 1 */
  33. "ACK", /* 2 */
  34. "Command", /* 3 */
  35. "Reserved (0x4)", /* 4 */
  36. "Reserved (0x5)", /* 5 */
  37. "Reserved (0x6)", /* 6 */
  38. "Reserved (0x7)", /* 7 */
  39. };
  40. /*
  41. * Frame Control subfields.
  42. */
  43. #define FC_FRAME_TYPE(fc) ((fc) & 0x7)
  44. #define FC_SECURITY_ENABLED 0x0008
  45. #define FC_FRAME_PENDING 0x0010
  46. #define FC_ACK_REQUEST 0x0020
  47. #define FC_PAN_ID_COMPRESSION 0x0040
  48. #define FC_DEST_ADDRESSING_MODE(fc) (((fc) >> 10) & 0x3)
  49. #define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3)
  50. #define FC_SRC_ADDRESSING_MODE(fc) (((fc) >> 14) & 0x3)
  51. #define FC_ADDRESSING_MODE_NONE 0x00
  52. #define FC_ADDRESSING_MODE_RESERVED 0x01
  53. #define FC_ADDRESSING_MODE_SHORT 0x02
  54. #define FC_ADDRESSING_MODE_LONG 0x03
  55. u_int
  56. ieee802_15_4_if_print(netdissect_options *ndo,
  57. const struct pcap_pkthdr *h, const u_char *p)
  58. {
  59. u_int caplen = h->caplen;
  60. u_int hdrlen;
  61. uint16_t fc;
  62. uint8_t seq;
  63. uint16_t panid = 0;
  64. if (caplen < 3) {
  65. ND_PRINT((ndo, "[|802.15.4]"));
  66. return caplen;
  67. }
  68. hdrlen = 3;
  69. fc = EXTRACT_LE_16BITS(p);
  70. seq = EXTRACT_LE_8BITS(p + 2);
  71. p += 3;
  72. caplen -= 3;
  73. ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[FC_FRAME_TYPE(fc)]));
  74. if (ndo->ndo_vflag)
  75. ND_PRINT((ndo,"seq %02x ", seq));
  76. /*
  77. * Destination address and PAN ID, if present.
  78. */
  79. switch (FC_DEST_ADDRESSING_MODE(fc)) {
  80. case FC_ADDRESSING_MODE_NONE:
  81. if (fc & FC_PAN_ID_COMPRESSION) {
  82. /*
  83. * PAN ID compression; this requires that both
  84. * the source and destination addresses be present,
  85. * but the destination address is missing.
  86. */
  87. ND_PRINT((ndo, "[|802.15.4]"));
  88. return hdrlen;
  89. }
  90. if (ndo->ndo_vflag)
  91. ND_PRINT((ndo,"none "));
  92. break;
  93. case FC_ADDRESSING_MODE_RESERVED:
  94. if (ndo->ndo_vflag)
  95. ND_PRINT((ndo,"reserved destination addressing mode"));
  96. return hdrlen;
  97. case FC_ADDRESSING_MODE_SHORT:
  98. if (caplen < 2) {
  99. ND_PRINT((ndo, "[|802.15.4]"));
  100. return hdrlen;
  101. }
  102. panid = EXTRACT_LE_16BITS(p);
  103. p += 2;
  104. caplen -= 2;
  105. hdrlen += 2;
  106. if (caplen < 2) {
  107. ND_PRINT((ndo, "[|802.15.4]"));
  108. return hdrlen;
  109. }
  110. if (ndo->ndo_vflag)
  111. ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
  112. p += 2;
  113. caplen -= 2;
  114. hdrlen += 2;
  115. break;
  116. case FC_ADDRESSING_MODE_LONG:
  117. if (caplen < 2) {
  118. ND_PRINT((ndo, "[|802.15.4]"));
  119. return hdrlen;
  120. }
  121. panid = EXTRACT_LE_16BITS(p);
  122. p += 2;
  123. caplen -= 2;
  124. hdrlen += 2;
  125. if (caplen < 8) {
  126. ND_PRINT((ndo, "[|802.15.4]"));
  127. return hdrlen;
  128. }
  129. if (ndo->ndo_vflag)
  130. ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
  131. p += 8;
  132. caplen -= 8;
  133. hdrlen += 8;
  134. break;
  135. }
  136. if (ndo->ndo_vflag)
  137. ND_PRINT((ndo,"< "));
  138. /*
  139. * Source address and PAN ID, if present.
  140. */
  141. switch (FC_SRC_ADDRESSING_MODE(fc)) {
  142. case FC_ADDRESSING_MODE_NONE:
  143. if (ndo->ndo_vflag)
  144. ND_PRINT((ndo,"none "));
  145. break;
  146. case FC_ADDRESSING_MODE_RESERVED:
  147. if (ndo->ndo_vflag)
  148. ND_PRINT((ndo,"reserved source addressing mode"));
  149. return 0;
  150. case FC_ADDRESSING_MODE_SHORT:
  151. if (!(fc & FC_PAN_ID_COMPRESSION)) {
  152. /*
  153. * The source PAN ID is not compressed out, so
  154. * fetch it. (Otherwise, we'll use the destination
  155. * PAN ID, fetched above.)
  156. */
  157. if (caplen < 2) {
  158. ND_PRINT((ndo, "[|802.15.4]"));
  159. return hdrlen;
  160. }
  161. panid = EXTRACT_LE_16BITS(p);
  162. p += 2;
  163. caplen -= 2;
  164. hdrlen += 2;
  165. }
  166. if (caplen < 2) {
  167. ND_PRINT((ndo, "[|802.15.4]"));
  168. return hdrlen;
  169. }
  170. if (ndo->ndo_vflag)
  171. ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
  172. p += 2;
  173. caplen -= 2;
  174. hdrlen += 2;
  175. break;
  176. case FC_ADDRESSING_MODE_LONG:
  177. if (!(fc & FC_PAN_ID_COMPRESSION)) {
  178. /*
  179. * The source PAN ID is not compressed out, so
  180. * fetch it. (Otherwise, we'll use the destination
  181. * PAN ID, fetched above.)
  182. */
  183. if (caplen < 2) {
  184. ND_PRINT((ndo, "[|802.15.4]"));
  185. return hdrlen;
  186. }
  187. panid = EXTRACT_LE_16BITS(p);
  188. p += 2;
  189. caplen -= 2;
  190. hdrlen += 2;
  191. }
  192. if (caplen < 8) {
  193. ND_PRINT((ndo, "[|802.15.4]"));
  194. return hdrlen;
  195. }
  196. if (ndo->ndo_vflag)
  197. ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
  198. p += 8;
  199. caplen -= 8;
  200. hdrlen += 8;
  201. break;
  202. }
  203. if (!ndo->ndo_suppress_default_print)
  204. ND_DEFAULTPRINT(p, caplen);
  205. return hdrlen;
  206. }