123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <netdissect-stdinc.h>
- #include "netdissect.h"
- #include "addrtoname.h"
- #include "extract.h"
- static const char *ftypes[] = {
- "Beacon",
- "Data",
- "ACK",
- "Command",
- "Reserved (0x4)",
- "Reserved (0x5)",
- "Reserved (0x6)",
- "Reserved (0x7)",
- };
- #define FC_FRAME_TYPE(fc) ((fc) & 0x7)
- #define FC_SECURITY_ENABLED 0x0008
- #define FC_FRAME_PENDING 0x0010
- #define FC_ACK_REQUEST 0x0020
- #define FC_PAN_ID_COMPRESSION 0x0040
- #define FC_DEST_ADDRESSING_MODE(fc) (((fc) >> 10) & 0x3)
- #define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3)
- #define FC_SRC_ADDRESSING_MODE(fc) (((fc) >> 14) & 0x3)
- #define FC_ADDRESSING_MODE_NONE 0x00
- #define FC_ADDRESSING_MODE_RESERVED 0x01
- #define FC_ADDRESSING_MODE_SHORT 0x02
- #define FC_ADDRESSING_MODE_LONG 0x03
- u_int
- ieee802_15_4_if_print(netdissect_options *ndo,
- const struct pcap_pkthdr *h, const u_char *p)
- {
- u_int caplen = h->caplen;
- u_int hdrlen;
- uint16_t fc;
- uint8_t seq;
- uint16_t panid = 0;
- if (caplen < 3) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return caplen;
- }
- hdrlen = 3;
- fc = EXTRACT_LE_16BITS(p);
- seq = EXTRACT_LE_8BITS(p + 2);
- p += 3;
- caplen -= 3;
- ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[FC_FRAME_TYPE(fc)]));
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"seq %02x ", seq));
-
- switch (FC_DEST_ADDRESSING_MODE(fc)) {
- case FC_ADDRESSING_MODE_NONE:
- if (fc & FC_PAN_ID_COMPRESSION) {
-
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"none "));
- break;
- case FC_ADDRESSING_MODE_RESERVED:
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"reserved destination addressing mode"));
- return hdrlen;
- case FC_ADDRESSING_MODE_SHORT:
- if (caplen < 2) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
- caplen -= 2;
- hdrlen += 2;
- if (caplen < 2) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
- p += 2;
- caplen -= 2;
- hdrlen += 2;
- break;
- case FC_ADDRESSING_MODE_LONG:
- if (caplen < 2) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
- caplen -= 2;
- hdrlen += 2;
- if (caplen < 8) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
- p += 8;
- caplen -= 8;
- hdrlen += 8;
- break;
- }
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"< "));
-
- switch (FC_SRC_ADDRESSING_MODE(fc)) {
- case FC_ADDRESSING_MODE_NONE:
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"none "));
- break;
- case FC_ADDRESSING_MODE_RESERVED:
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"reserved source addressing mode"));
- return 0;
- case FC_ADDRESSING_MODE_SHORT:
- if (!(fc & FC_PAN_ID_COMPRESSION)) {
-
- if (caplen < 2) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
- caplen -= 2;
- hdrlen += 2;
- }
- if (caplen < 2) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
- p += 2;
- caplen -= 2;
- hdrlen += 2;
- break;
- case FC_ADDRESSING_MODE_LONG:
- if (!(fc & FC_PAN_ID_COMPRESSION)) {
-
- if (caplen < 2) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
- caplen -= 2;
- hdrlen += 2;
- }
- if (caplen < 8) {
- ND_PRINT((ndo, "[|802.15.4]"));
- return hdrlen;
- }
- if (ndo->ndo_vflag)
- ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
- p += 8;
- caplen -= 8;
- hdrlen += 8;
- break;
- }
- if (!ndo->ndo_suppress_default_print)
- ND_DEFAULTPRINT(p, caplen);
- return hdrlen;
- }
|