@@ -38,144 +38,186 @@ static const char *ftypes[] = {
3838 "Data" , /* 1 */
3939 "ACK" , /* 2 */
4040 "Command" , /* 3 */
41- "Reserved" , /* 4 */
42- "Reserved" , /* 5 */
43- "Reserved" , /* 6 */
44- "Reserved" , /* 7 */
41+ "Reserved (0x4)" , /* 4 */
42+ "Reserved (0x5)" , /* 5 */
43+ "Reserved (0x6)" , /* 6 */
44+ "Reserved (0x7)" , /* 7 */
4545};
4646
47- static int
48- extract_header_length (uint16_t fc )
49- {
50- int len = 0 ;
51-
52- switch ((fc >> 10 ) & 0x3 ) {
53- case 0x00 :
54- if (fc & (1 << 6 )) /* intra-PAN with none dest addr */
55- return -1 ;
56- break ;
57- case 0x01 :
58- return -1 ;
59- case 0x02 :
60- len += 4 ;
61- break ;
62- case 0x03 :
63- len += 10 ;
64- break ;
65- }
66-
67- switch ((fc >> 14 ) & 0x3 ) {
68- case 0x00 :
69- break ;
70- case 0x01 :
71- return -1 ;
72- case 0x02 :
73- len += 4 ;
74- break ;
75- case 0x03 :
76- len += 10 ;
77- break ;
78- }
79-
80- if (fc & (1 << 6 )) {
81- if (len < 2 )
82- return -1 ;
83- len -= 2 ;
84- }
85-
86- return len ;
87- }
88-
47+ /*
48+ * Frame Control subfields.
49+ */
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)
58+
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
8963
9064u_int
9165ieee802_15_4_if_print (netdissect_options * ndo ,
9266 const struct pcap_pkthdr * h , const u_char * p )
9367{
9468 u_int caplen = h -> caplen ;
95- int hdrlen ;
69+ u_int hdrlen ;
9670 uint16_t fc ;
9771 uint8_t seq ;
72+ uint16_t panid = 0 ;
9873
9974 if (caplen < 3 ) {
100- ND_PRINT ((ndo , "[|802.15.4] %x" , caplen ));
75+ ND_PRINT ((ndo , "[|802.15.4]" ));
10176 return caplen ;
10277 }
78+ hdrlen = 3 ;
10379
10480 fc = EXTRACT_LE_16BITS (p );
105- hdrlen = extract_header_length (fc );
106-
10781 seq = EXTRACT_LE_8BITS (p + 2 );
10882
10983 p += 3 ;
11084 caplen -= 3 ;
11185
112- ND_PRINT ((ndo ,"IEEE 802.15.4 %s packet " , ftypes [fc & 0x7 ]));
86+ ND_PRINT ((ndo ,"IEEE 802.15.4 %s packet " , ftypes [FC_FRAME_TYPE ( fc ) ]));
11387 if (ndo -> ndo_vflag )
11488 ND_PRINT ((ndo ,"seq %02x " , seq ));
115- if (hdrlen == -1 ) {
116- ND_PRINT ((ndo ,"invalid! " ));
117- return caplen ;
118- }
119-
120-
121- if (!ndo -> ndo_vflag ) {
122- p += hdrlen ;
123- caplen -= hdrlen ;
124- } else {
125- uint16_t panid = 0 ;
12689
127- switch ((fc >> 10 ) & 0x3 ) {
128- case 0x00 :
90+ /*
91+ * Destination address and PAN ID, if present.
92+ */
93+ switch (FC_DEST_ADDRESSING_MODE (fc )) {
94+ case FC_ADDRESSING_MODE_NONE :
95+ if (fc & FC_PAN_ID_COMPRESSION ) {
96+ /*
97+ * PAN ID compression; this requires that both
98+ * the source and destination addresses be present,
99+ * but the destination address is missing.
100+ */
101+ ND_PRINT ((ndo , "[|802.15.4]" ));
102+ return hdrlen ;
103+ }
104+ if (ndo -> ndo_vflag )
129105 ND_PRINT ((ndo ,"none " ));
130- break ;
131- case 0x01 :
106+ break ;
107+ case FC_ADDRESSING_MODE_RESERVED :
108+ if (ndo -> ndo_vflag )
132109 ND_PRINT ((ndo ,"reserved destination addressing mode" ));
133- return 0 ;
134- case 0x02 :
135- panid = EXTRACT_LE_16BITS ( p );
136- p += 2 ;
137- ND_PRINT (( ndo , "%04x:%04x " , panid , EXTRACT_LE_16BITS ( p ))) ;
138- p += 2 ;
139- break ;
140- case 0x03 :
141- panid = EXTRACT_LE_16BITS ( p ) ;
142- p += 2 ;
143- ND_PRINT (( ndo , "%04x:%s " , panid , le64addr_string ( ndo , p )));
144- p += 8 ;
145- break ;
110+ return hdrlen ;
111+ case FC_ADDRESSING_MODE_SHORT :
112+ if ( caplen < 2 ) {
113+ ND_PRINT (( ndo , "[|802.15.4]" )) ;
114+ return hdrlen ;
115+ }
116+ panid = EXTRACT_LE_16BITS ( p ) ;
117+ p += 2 ;
118+ caplen -= 2 ;
119+ hdrlen += 2 ;
120+ if ( caplen < 2 ) {
121+ ND_PRINT (( ndo , "[|802.15.4]" )) ;
122+ return hdrlen ;
146123 }
124+ if (ndo -> ndo_vflag )
125+ ND_PRINT ((ndo ,"%04x:%04x " , panid , EXTRACT_LE_16BITS (p + 2 )));
126+ p += 2 ;
127+ caplen -= 2 ;
128+ hdrlen += 2 ;
129+ break ;
130+ case FC_ADDRESSING_MODE_LONG :
131+ if (caplen < 2 ) {
132+ ND_PRINT ((ndo , "[|802.15.4]" ));
133+ return hdrlen ;
134+ }
135+ panid = EXTRACT_LE_16BITS (p );
136+ p += 2 ;
137+ caplen -= 2 ;
138+ hdrlen += 2 ;
139+ if (caplen < 8 ) {
140+ ND_PRINT ((ndo , "[|802.15.4]" ));
141+ return hdrlen ;
142+ }
143+ if (ndo -> ndo_vflag )
144+ ND_PRINT ((ndo ,"%04x:%s " , panid , le64addr_string (ndo , p + 2 )));
145+ p += 8 ;
146+ caplen -= 8 ;
147+ hdrlen += 8 ;
148+ break ;
149+ }
150+ if (ndo -> ndo_vflag )
147151 ND_PRINT ((ndo ,"< " ));
148152
149- switch ((fc >> 14 ) & 0x3 ) {
150- case 0x00 :
153+ /*
154+ * Source address and PAN ID, if present.
155+ */
156+ switch (FC_SRC_ADDRESSING_MODE (fc )) {
157+ case FC_ADDRESSING_MODE_NONE :
158+ if (ndo -> ndo_vflag )
151159 ND_PRINT ((ndo ,"none " ));
152- break ;
153- case 0x01 :
160+ break ;
161+ case FC_ADDRESSING_MODE_RESERVED :
162+ if (ndo -> ndo_vflag )
154163 ND_PRINT ((ndo ,"reserved source addressing mode" ));
155- return 0 ;
156- case 0x02 :
157- if (!(fc & (1 << 6 ))) {
158- panid = EXTRACT_LE_16BITS (p );
159- p += 2 ;
164+ return 0 ;
165+ case FC_ADDRESSING_MODE_SHORT :
166+ if (!(fc & FC_PAN_ID_COMPRESSION )) {
167+ /*
168+ * The source PAN ID is not compressed out, so
169+ * fetch it. (Otherwise, we'll use the destination
170+ * PAN ID, fetched above.)
171+ */
172+ if (caplen < 2 ) {
173+ ND_PRINT ((ndo , "[|802.15.4]" ));
174+ return hdrlen ;
160175 }
161- ND_PRINT (( ndo , "%04x:%04x " , panid , EXTRACT_LE_16BITS (p )) );
176+ panid = EXTRACT_LE_16BITS (p );
162177 p += 2 ;
163- break ;
164- case 0x03 :
165- if (!(fc & (1 << 6 ))) {
166- panid = EXTRACT_LE_16BITS (p );
167- p += 2 ;
178+ caplen -= 2 ;
179+ hdrlen += 2 ;
180+ }
181+ if (caplen < 2 ) {
182+ ND_PRINT ((ndo , "[|802.15.4]" ));
183+ return hdrlen ;
184+ }
185+ if (ndo -> ndo_vflag )
186+ ND_PRINT ((ndo ,"%04x:%04x " , panid , EXTRACT_LE_16BITS (p )));
187+ p += 2 ;
188+ caplen -= 2 ;
189+ hdrlen += 2 ;
190+ break ;
191+ case FC_ADDRESSING_MODE_LONG :
192+ if (!(fc & FC_PAN_ID_COMPRESSION )) {
193+ /*
194+ * The source PAN ID is not compressed out, so
195+ * fetch it. (Otherwise, we'll use the destination
196+ * PAN ID, fetched above.)
197+ */
198+ if (caplen < 2 ) {
199+ ND_PRINT ((ndo , "[|802.15.4]" ));
200+ return hdrlen ;
168201 }
169- ND_PRINT ((ndo ,"%04x:%s " , panid , le64addr_string (ndo , p )));
170- p += 8 ;
171- break ;
202+ panid = EXTRACT_LE_16BITS (p );
203+ p += 2 ;
204+ caplen -= 2 ;
205+ hdrlen += 2 ;
172206 }
173-
174- caplen -= hdrlen ;
207+ if (caplen < 8 ) {
208+ ND_PRINT ((ndo , "[|802.15.4]" ));
209+ return hdrlen ;
210+ }
211+ if (ndo -> ndo_vflag )
212+ ND_PRINT ((ndo ,"%04x:%s " , panid , le64addr_string (ndo , p )));
213+ p += 8 ;
214+ caplen -= 8 ;
215+ hdrlen += 8 ;
216+ break ;
175217 }
176218
177219 if (!ndo -> ndo_suppress_default_print )
178220 ND_DEFAULTPRINT (p , caplen );
179221
180- return 0 ;
222+ return hdrlen ;
181223}
0 commit comments