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} |