Deleted Added
full compact
print-802_15_4.c (313537) print-802_15_4.c (327234)
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)

--- 24 unchanged lines hidden (view full) ---

33
34#include "extract.h"
35
36static const char *ftypes[] = {
37 "Beacon", /* 0 */
38 "Data", /* 1 */
39 "ACK", /* 2 */
40 "Command", /* 3 */
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)

--- 24 unchanged lines hidden (view full) ---

33
34#include "extract.h"
35
36static const char *ftypes[] = {
37 "Beacon", /* 0 */
38 "Data", /* 1 */
39 "ACK", /* 2 */
40 "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 */
45};
46
45};
46
47static int
48extract_header_length(uint16_t fc)
49{
50 int len = 0;
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)
51
58
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 }
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
66
63
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
89
90u_int
91ieee802_15_4_if_print(netdissect_options *ndo,
92 const struct pcap_pkthdr *h, const u_char *p)
93{
94 u_int caplen = h->caplen;
64u_int
65ieee802_15_4_if_print(netdissect_options *ndo,
66 const struct pcap_pkthdr *h, const u_char *p)
67{
68 u_int caplen = h->caplen;
95 int hdrlen;
69 u_int hdrlen;
96 uint16_t fc;
97 uint8_t seq;
70 uint16_t fc;
71 uint8_t seq;
72 uint16_t panid = 0;
98
99 if (caplen < 3) {
73
74 if (caplen < 3) {
100 ND_PRINT((ndo, "[|802.15.4] %x", caplen));
75 ND_PRINT((ndo, "[|802.15.4]"));
101 return caplen;
102 }
76 return caplen;
77 }
78 hdrlen = 3;
103
104 fc = EXTRACT_LE_16BITS(p);
79
80 fc = EXTRACT_LE_16BITS(p);
105 hdrlen = extract_header_length(fc);
106
107 seq = EXTRACT_LE_8BITS(p + 2);
108
109 p += 3;
110 caplen -= 3;
111
81 seq = EXTRACT_LE_8BITS(p + 2);
82
83 p += 3;
84 caplen -= 3;
85
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)]));
113 if (ndo->ndo_vflag)
114 ND_PRINT((ndo,"seq %02x ", seq));
87 if (ndo->ndo_vflag)
88 ND_PRINT((ndo,"seq %02x ", seq));
115 if (hdrlen == -1) {
116 ND_PRINT((ndo,"invalid! "));
117 return caplen;
118 }
119
89
120
121 if (!ndo->ndo_vflag) {
122 p+= hdrlen;
123 caplen -= hdrlen;
124 } else {
125 uint16_t panid = 0;
126
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)
129 ND_PRINT((ndo,"none "));
105 ND_PRINT((ndo,"none "));
130 break;
131 case 0x01:
106 break;
107 case FC_ADDRESSING_MODE_RESERVED:
108 if (ndo->ndo_vflag)
132 ND_PRINT((ndo,"reserved destination addressing mode"));
109 ND_PRINT((ndo,"reserved destination addressing mode"));
133 return 0;
134 case 0x02:
135 panid = EXTRACT_LE_16BITS(p);
136 p += 2;
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;
123 }
124 if (ndo->ndo_vflag)
137 ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
125 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;
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;
146 }
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)));
145 p += 8;
146 caplen -= 8;
147 hdrlen += 8;
148 break;
149 }
150 if (ndo->ndo_vflag)
147 ND_PRINT((ndo,"< "));
148
151 ND_PRINT((ndo,"< "));
152
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)
151 ND_PRINT((ndo,"none "));
159 ND_PRINT((ndo,"none "));
152 break;
153 case 0x01:
160 break;
161 case FC_ADDRESSING_MODE_RESERVED:
162 if (ndo->ndo_vflag)
154 ND_PRINT((ndo,"reserved source addressing mode"));
163 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;
160 }
175 }
161 ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
176 panid = EXTRACT_LE_16BITS(p);
162 p += 2;
177 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;
168 }
201 }
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;
172 }
206 }
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;
175 }
176
177 if (!ndo->ndo_suppress_default_print)
178 ND_DEFAULTPRINT(p, caplen);
179
217 }
218
219 if (!ndo->ndo_suppress_default_print)
220 ND_DEFAULTPRINT(p, caplen);
221
180 return 0;
222 return hdrlen;
181}
223}