3 * Siemens AG, All rights reserved.
4 * Dmitry Eremin-Solenikov (dbaryshkov@gmail.com)
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
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.
23 /* \summary: IEEE 802.15.4 printer */
29 #include "netdissect-stdinc.h"
31 #include "netdissect.h"
32 #include "addrtoname.h"
36 static const char *ftypes
[] = {
41 "Reserved (0x4)", /* 4 */
42 "Reserved (0x5)", /* 5 */
43 "Reserved (0x6)", /* 6 */
44 "Reserved (0x7)", /* 7 */
48 * Frame Control subfields.
50 #define FC_FRAME_TYPE(fc) ((fc) & 0x7)
51 #define FC_SECURITY_ENABLED 0x0008
52 #define FC_FRAME_PENDING 0x0010
53 #define FC_ACK_REQUEST 0x0020
54 #define FC_PAN_ID_COMPRESSION 0x0040
55 #define FC_DEST_ADDRESSING_MODE(fc) (((fc) >> 10) & 0x3)
56 #define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3)
57 #define FC_SRC_ADDRESSING_MODE(fc) (((fc) >> 14) & 0x3)
59 #define FC_ADDRESSING_MODE_NONE 0x00
60 #define FC_ADDRESSING_MODE_RESERVED 0x01
61 #define FC_ADDRESSING_MODE_SHORT 0x02
62 #define FC_ADDRESSING_MODE_LONG 0x03
65 ieee802_15_4_print(netdissect_options
*ndo
,
66 const u_char
*p
, u_int caplen
)
73 ndo
->ndo_protocol
= "802.15.4";
80 fc
= EXTRACT_LE_U_2(p
);
81 seq
= EXTRACT_U_1(p
+ 2);
86 ND_PRINT("IEEE 802.15.4 %s packet ", ftypes
[FC_FRAME_TYPE(fc
)]);
88 ND_PRINT("seq %02x ", seq
);
91 * Destination address and PAN ID, if present.
93 switch (FC_DEST_ADDRESSING_MODE(fc
)) {
94 case FC_ADDRESSING_MODE_NONE
:
95 if (fc
& FC_PAN_ID_COMPRESSION
) {
97 * PAN ID compression; this requires that both
98 * the source and destination addresses be present,
99 * but the destination address is missing.
107 case FC_ADDRESSING_MODE_RESERVED
:
109 ND_PRINT("reserved destination addressing mode");
111 case FC_ADDRESSING_MODE_SHORT
:
116 panid
= EXTRACT_LE_U_2(p
);
125 ND_PRINT("%04x:%04x ", panid
, EXTRACT_LE_U_2(p
));
130 case FC_ADDRESSING_MODE_LONG
:
135 panid
= EXTRACT_LE_U_2(p
);
144 ND_PRINT("%04x:%s ", panid
, le64addr_string(ndo
, p
));
154 * Source address and PAN ID, if present.
156 switch (FC_SRC_ADDRESSING_MODE(fc
)) {
157 case FC_ADDRESSING_MODE_NONE
:
161 case FC_ADDRESSING_MODE_RESERVED
:
163 ND_PRINT("reserved source addressing mode");
165 case FC_ADDRESSING_MODE_SHORT
:
166 if (!(fc
& FC_PAN_ID_COMPRESSION
)) {
168 * The source PAN ID is not compressed out, so
169 * fetch it. (Otherwise, we'll use the destination
170 * PAN ID, fetched above.)
176 panid
= EXTRACT_LE_U_2(p
);
186 ND_PRINT("%04x:%04x ", panid
, EXTRACT_LE_U_2(p
));
191 case FC_ADDRESSING_MODE_LONG
:
192 if (!(fc
& FC_PAN_ID_COMPRESSION
)) {
194 * The source PAN ID is not compressed out, so
195 * fetch it. (Otherwise, we'll use the destination
196 * PAN ID, fetched above.)
202 panid
= EXTRACT_LE_U_2(p
);
212 ND_PRINT("%04x:%s ", panid
, le64addr_string(ndo
, p
));
219 if (!ndo
->ndo_suppress_default_print
)
220 ND_DEFAULTPRINT(p
, caplen
);
225 /* For DLT_IEEE802_15_4 and DLT_IEEE802_15_4_NOFCS */
227 ieee802_15_4_if_print(netdissect_options
*ndo
,
228 const struct pcap_pkthdr
*h
, const u_char
*p
)
230 ndo
->ndo_protocol
= "802.15.4_if";
231 return ieee802_15_4_print(ndo
, p
, h
->caplen
);
234 /* For DLT_IEEE802_15_4_TAP */
235 /* https://github.com/jkcko/ieee802.15.4-tap */
237 ieee802_15_4_tap_if_print(netdissect_options
*ndo
,
238 const struct pcap_pkthdr
*h
, const u_char
*p
)
243 ndo
->ndo_protocol
= "802.15.4_tap";
249 version
= EXTRACT_U_1(p
);
250 length
= EXTRACT_LE_U_2(p
+2);
251 if (version
!= 0 || length
< 4) {
252 nd_print_invalid(ndo
);
256 if (h
->caplen
< length
) {
261 return ieee802_15_4_print(ndo
, p
+length
, h
->caplen
-length
) + length
;