1 /* packet-6lowpan.c
2 *
3 * Add Selective Fragment Recovery per
4 * https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-02
5 * By James Ko <jck@exegin.com>
6 * Copyright 2019 Exegin Technologies Limited
7 *
8 * Routines for 6LoWPAN packet disassembly
9 * By Owen Kirby <osk@exegin.com>
10 * Copyright 2009 Owen Kirby
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 */
18 #include "config.h"
19 #include <stdio.h>
20 #include <epan/packet.h>
21 #include <epan/prefs.h>
22 #include <epan/expert.h>
23 #include <epan/reassemble.h>
24 #include <epan/ipproto.h>
25 #include <epan/addr_resolv.h>
26 #include <epan/proto_data.h>
27 #include <epan/etypes.h>
28 #include "packet-ip.h"
29 #include "packet-6lowpan.h"
30 #include "packet-btl2cap.h"
31 #include "packet-zbee.h"
32
33 void proto_register_6lowpan(void);
34 void proto_reg_handoff_6lowpan(void);
35
36 /* Definitions for 6lowpan packet disassembly structures and routines */
37
38 /* 6LoWPAN Patterns */
39 #define LOWPAN_PATTERN_NALP 0x00
40 #define LOWPAN_PATTERN_NALP_BITS 2
41 #define LOWPAN_PATTERN_IPV6 0x41
42 #define LOWPAN_PATTERN_IPV6_BITS 8
43 #define LOWPAN_PATTERN_HC1 0x42 /* Deprecated - replaced with IPHC. */
44 #define LOWPAN_PATTERN_HC1_BITS 8
45 #define LOWPAN_PATTERN_BC0 0x50
46 #define LOWPAN_PATTERN_BC0_BITS 8
47 #define LOWPAN_PATTERN_IPHC 0x03 /* See draft-ietf-6lowpan-hc-15.txt */
48 #define LOWPAN_PATTERN_IPHC_BITS 3
49 #define LOWPAN_PATTERN_ESC 0x7f
50 #define LOWPAN_PATTERN_ESC_BITS 8
51 #define LOWPAN_PATTERN_MESH 0x02
52 #define LOWPAN_PATTERN_MESH_BITS 2
53 #define LOWPAN_PATTERN_FRAG1 0x18
54 #define LOWPAN_PATTERN_FRAGN 0x1c
55 #define LOWPAN_PATTERN_FRAG_BITS 5
56 #define LOWPAN_PATTERN_RFRAG 0x74
57 #define LOWPAN_PATTERN_RFRAG_ACK 0x75
58 #define LOWPAN_PATTERN_RFRAG_BITS 7
59
60 #define LOWPAN_RFRAG_SEQUENCE_BITS 5
61 #define LOWPAN_RFRAG_FRAG_SZ_BITS 10
62
63 /* RFC8025 and RFC8138 */
64 #define LOWPAN_PATTERN_PAGING_DISPATCH 0xf
65 #define LOWPAN_PATTERN_PAGING_DISPATCH_BITS 4
66 #define LOWPAN_PATTERN_6LORHC 0x04
67 #define LOWPAN_PATTERN_6LORHE 0x05
68 #define LOWPAN_PATTERN_6LORHE_CLASS 0xe000
69 #define LOWPAN_PATTERN_6LORHE_CLASS_BITS 13
70 #define LOWPAN_PATTERN_6LORHE_LENGTH 0x1f00
71 #define LOWPAN_PATTERN_6LORHE_LENGTH_BITS 8
72 #define LOWPAN_PATTERN_6LORHE_TYPE 0x00ff
73 #define LOWPAN_PATTERN_6LORH_TYPE0 0x00
74 #define LOWPAN_PATTERN_6LORH_TYPE1 0x01
75 #define LOWPAN_PATTERN_6LORH_TYPE2 0x02
76 #define LOWPAN_PATTERN_6LORH_TYPE3 0x03
77 #define LOWPAN_PATTERN_6LORH_TYPE4 0x04
78 #define LOWPAN_PATTERN_6LORH_TYPE5 0x05
79 #define LOWPAN_PATTERN_6LORH_TYPE6 0x06
80 #define LOWPAN_PATTERN_6LORH_TYPE15 0x0F
81 #define LOWPAN_PATTERN_6LORH_TYPE16 0x10
82 #define LOWPAN_PATTERN_6LORH_TYPE17 0x11
83 #define LOWPAN_PATTERN_6LORH_TYPE18 0x12
84 #define LOWPAN_PATTERN_6LORH_TYPE19 0x13
85 #define LOWPAN_5_RPI_BIT_O 0x1000
86 #define LOWPAN_5_RPI_BIT_R 0x0800
87 #define LOWPAN_5_RPI_BIT_F 0x0400
88 #define LOWPAN_5_RPI_BIT_I 0x0200
89 #define LOWPAN_5_RPI_BIT_K 0x0100
90 #define LOWPAN_5_RPI_BITS_IK 0x0300
91 #define LOWPAN_6LORH_GENERAL_FORMAT 0x8000
92 #define LOWPAN_IP_IN_IP_6LORH 6
93 #define BITS_IK_0 0
94 #define BITS_IK_1 1
95 #define BITS_IK_2 2
96 #define BITS_IK_3 3
97 #define BITS_IK_4 4
98 #define IPV6_ADDR_COMPRESSED_1_BYTE 0
99 #define IPV6_ADDR_COMPRESSED_2_BYTE 1
100 #define IPV6_ADDR_COMPRESSED_4_BYTE 2
101 #define IPV6_ADDR_COMPRESSED_8_BYTE 3
102 #define IPV6_ADDR_COMPRESSED_16_BYTE 4
103
104 /* 6LoWPAN HC1 Header */
105 #define LOWPAN_HC1_SOURCE_PREFIX 0x80
106 #define LOWPAN_HC1_SOURCE_IFC 0x40
107 #define LOWPAN_HC1_DEST_PREFIX 0x20
108 #define LOWPAN_HC1_DEST_IFC 0x10
109 #define LOWPAN_HC1_TRAFFIC_CLASS 0x08
110 #define LOWPAN_HC1_NEXT 0x06
111 #define LOWPAN_HC1_MORE 0x01
112
113 /* IPv6 header field lengths (in bits) */
114 #define LOWPAN_IPV6_TRAFFIC_CLASS_BITS 8
115 #define LOWPAN_IPV6_FLOW_LABEL_BITS 20
116 #define LOWPAN_IPV6_NEXT_HEADER_BITS 8
117 #define LOWPAN_IPV6_HOP_LIMIT_BITS 8
118 #define LOWPAN_IPV6_PREFIX_BITS 64
119 #define LOWPAN_IPV6_INTERFACE_BITS 64
120
121 /* HC_UDP header field lengths (in bits). */
122 #define LOWPAN_UDP_PORT_BITS 16
123 #define LOWPAN_UDP_PORT_COMPRESSED_BITS 4
124 #define LOWPAN_UDP_LENGTH_BITS 16
125 #define LOWPAN_UDP_CHECKSUM_BITS 16
126
127 /* HC1 Next Header compression modes. */
128 #define LOWPAN_HC1_NEXT_NONE 0x00
129 #define LOWPAN_HC1_NEXT_UDP 0x01
130 #define LOWPAN_HC1_NEXT_ICMP 0x02
131 #define LOWPAN_HC1_NEXT_TCP 0x03
132
133 /* HC_UDP Header */
134 #define LOWPAN_HC2_UDP_SRCPORT 0x80
135 #define LOWPAN_HC2_UDP_DSTPORT 0x40
136 #define LOWPAN_HC2_UDP_LENGTH 0x20
137 #define LOWPAN_HC2_UDP_RESERVED 0x1f
138
139 /* IPHC Base flags */
140 #define LOWPAN_IPHC_FLAG_FLOW 0x1800
141 #define LOWPAN_IPHC_FLAG_NHDR 0x0400
142 #define LOWPAN_IPHC_FLAG_HLIM 0x0300
143 #define LOWPAN_IPHC_FLAG_CONTEXT_ID 0x0080
144 #define LOWPAN_IPHC_FLAG_SRC_COMP 0x0040
145 #define LOWPAN_IPHC_FLAG_SRC_MODE 0x0030
146 #define LOWPAN_IPHC_FLAG_MCAST_COMP 0x0008
147 #define LOWPAN_IPHC_FLAG_DST_COMP 0x0004
148 #define LOWPAN_IPHC_FLAG_DST_MODE 0x0003
149 #define LOWPAN_IPHC_FLAG_SCI 0xf0
150 #define LOWPAN_IPHC_FLAG_DCI 0x0f
151 /* Offsets for extracting integer fields. */
152 #define LOWPAN_IPHC_FLAG_OFFSET_FLOW 11
153 #define LOWPAN_IPHC_FLAG_OFFSET_HLIM 8
154 #define LOWPAN_IPHC_FLAG_OFFSET_SRC_MODE 4
155 #define LOWPAN_IPHC_FLAG_OFFSET_DST_MODE 0
156 #define LOWPAN_IPHC_FLAG_OFFSET_SCI 4
157 #define LOWPAN_IPHC_FLAG_OFFSET_DCI 0
158
159 /* IPHC Flow encoding values. */
160 #define LOWPAN_IPHC_FLOW_CLASS_LABEL 0x0
161 #define LOWPAN_IPHC_FLOW_ECN_LABEL 0x1
162 #define LOWPAN_IPHC_FLOW_CLASS 0x2
163 #define LOWPAN_IPHC_FLOW_COMPRESSED 0x3
164
165 /* IPHC Hop limit encoding. */
166 #define LOWPAN_IPHC_HLIM_INLINE 0x0
167 #define LOWPAN_IPHC_HLIM_1 0x1
168 #define LOWPAN_IPHC_HLIM_64 0x2
169 #define LOWPAN_IPHC_HLIM_255 0x3
170
171 /* IPHC address modes. */
172 #define LOWPAN_IPHC_ADDR_SRC_UNSPEC 0x0
173 #define LOWPAN_IPHC_ADDR_FULL_INLINE 0x0
174 #define LOWPAN_IPHC_ADDR_64BIT_INLINE 0x1
175 #define LOWPAN_IPHC_ADDR_16BIT_INLINE 0x2
176 #define LOWPAN_IPHC_ADDR_COMPRESSED 0x3
177
178 /* IPHC multicast address modes. */
179 #define LOWPAN_IPHC_MCAST_FULL 0x0
180 #define LOWPAN_IPHC_MCAST_48BIT 0x1
181 #define LOWPAN_IPHC_MCAST_32BIT 0x2
182 #define LOWPAN_IPHC_MCAST_8BIT 0x3
183
184 #define LOWPAN_IPHC_MCAST_STATEFUL_48BIT 0x0
185
186 /* IPHC Traffic class and flow label field sizes (in bits) */
187 #define LOWPAN_IPHC_ECN_BITS 2
188 #define LOWPAN_IPHC_DSCP_BITS 6
189 #define LOWPAN_IPHC_LABEL_BITS 20
190
191 /* NHC Patterns. */
192 #define LOWPAN_NHC_PATTERN_EXT 0x0e
193 #define LOWPAN_NHC_PATTERN_EXT_BITS 4
194 #define LOWPAN_NHC_PATTERN_UDP 0x1e
195 #define LOWPAN_NHC_PATTERN_UDP_BITS 5
196 /* IP-in-IP tunneling is handled as a separate NHC pattern. */
197 #define LOWPAN_NHC_PATTERN_EXT_IPV6 ((LOWPAN_NHC_PATTERN_EXT << LOWPAN_NHC_EXT_EID_BITS) | LOWPAN_NHC_EID_IPV6)
198 #define LOWPAN_NHC_PATTERN_EXT_IPV6_BITS (LOWPAN_NHC_PATTERN_EXT_BITS + LOWPAN_NHC_EXT_EID_BITS)
199
200 /* NHC Extension header fields. */
201 #define LOWPAN_NHC_EXT_EID 0x0e
202 #define LOWPAN_NHC_EXT_EID_OFFSET 1
203 #define LOWPAN_NHC_EXT_EID_BITS 3
204 #define LOWPAN_NHC_EXT_NHDR 0x01
205
206 /* Extension header ID codes. */
207 #define LOWPAN_NHC_EID_HOP_BY_HOP 0x00
208 #define LOWPAN_NHC_EID_ROUTING 0x01
209 #define LOWPAN_NHC_EID_FRAGMENT 0x02
210 #define LOWPAN_NHC_EID_DEST_OPTIONS 0x03
211 #define LOWPAN_NHC_EID_MOBILITY 0x04
212 #define LOWPAN_NHC_EID_IPV6 0x07
213
214 /* NHC UDP fields. */
215 #define LOWPAN_NHC_UDP_CHECKSUM 0x04
216 #define LOWPAN_NHC_UDP_PORTS 0x03
217
218 /* 6LoWPAN Mesh Header */
219 #define LOWPAN_MESH_HEADER_V 0x20
220 #define LOWPAN_MESH_HEADER_F 0x10
221 #define LOWPAN_MESH_HEADER_HOPS 0x0f
222
223 /* 6LoWPAN First Fragment Header */
224 #define LOWPAN_FRAG_DGRAM_SIZE_BITS 11
225
226 /* Uncompressed IPv6 Option types */
227 #define IP6OPT_PAD1 0x00
228 #define IP6OPT_PADN 0x01
229
230 /* UDP port compression encoding */
231 #define LOWPAN_NHC_UDP_PORT_INLINE 0x0
232 #define LOWPAN_NHC_UDP_PORT_8BIT_DST 0x1
233 #define LOWPAN_NHC_UDP_PORT_8BIT_SRC 0x2
234 #define LOWPAN_NHC_UDP_PORT_12BIT 0x3
235
236 /* Compressed port number offset. */
237 #define LOWPAN_PORT_8BIT_OFFSET 0xf000
238 #define LOWPAN_PORT_12BIT_OFFSET 0xf0b0
239
240 /* 6LoWPAN interface identifier length. */
241 #define LOWPAN_IFC_ID_LEN 8
242 /* Protocol fields handles. */
243 static int proto_6lowpan = -1;
244 static int hf_6lowpan_pattern = -1;
245 static int hf_6lowpan_nhc_pattern = -1;
246 static int hf_6lowpan_padding = -1;
247
248 /* Header compression fields. */
249 static int hf_6lowpan_hc1_encoding = -1;
250 static int hf_6lowpan_hc1_source_prefix = -1;
251 static int hf_6lowpan_hc1_source_ifc = -1;
252 static int hf_6lowpan_hc1_dest_prefix = -1;
253 static int hf_6lowpan_hc1_dest_ifc = -1;
254 static int hf_6lowpan_hc1_class = -1;
255 static int hf_6lowpan_hc1_next = -1;
256 static int hf_6lowpan_hc1_more = -1;
257 static int hf_6lowpan_hc2_udp_encoding = -1;
258 static int hf_6lowpan_hc2_udp_src = -1;
259 static int hf_6lowpan_hc2_udp_dst = -1;
260 static int hf_6lowpan_hc2_udp_len = -1;
261
262 /* 6loRH */
263 static int hf_6lowpan_pagenb = -1;
264 static int hf_6lowpan_routing_header = -1;
265 static int hf_6lowpan_6lorhe_length = -1;
266 static int hf_6lowpan_6lorhe_size = -1;
267 static int hf_6lowpan_6lorhc_size = -1;
268 static int hf_6lowpan_6lorhe_type = -1;
269 static int hf_6lowpan_6lorhe_hoplimit = -1;
270 static int hf_6lowpan_6lorhe_bitmap = -1;
271 static int hf_6lowpan_5_bit_o = -1;
272 static int hf_6lowpan_5_bit_r = -1;
273 static int hf_6lowpan_5_bit_f = -1;
274 static int hf_6lowpan_5_bit_i = -1;
275 static int hf_6lowpan_5_bit_k = -1;
276 static int hf_6lowpan_sender_rank1 = -1;
277 static int hf_6lowpan_sender_rank2 = -1;
278 static int hf_6lowpan_rpl_instance = -1;
279 static int hf_6lowpan_6lorhc_address_hop0 = -1;
280 static int hf_6lowpan_6lorhc_address_hop2 = -1;
281 static int hf_6lowpan_6lorhc_address_hop3 = -1;
282 static int hf_6lowpan_6lorhc_address_hop4 = -1;
283 static int hf_6lowpan_6lorhc_address_hop1 = -1;
284 static int hf_6lowpan_6lorhc_address_src = -1;
285
286 /* IPHC header field. */
287 static int hf_6lowpan_iphc_flag_tf = -1;
288 static int hf_6lowpan_iphc_flag_nhdr = -1;
289 static int hf_6lowpan_iphc_flag_hlim = -1;
290 static int hf_6lowpan_iphc_flag_cid = -1;
291 static int hf_6lowpan_iphc_flag_sac = -1;
292 static int hf_6lowpan_iphc_flag_sam = -1;
293 static int hf_6lowpan_iphc_flag_mcast = -1;
294 static int hf_6lowpan_iphc_flag_dac = -1;
295 static int hf_6lowpan_iphc_flag_dam = -1;
296 static int hf_6lowpan_iphc_sci = -1;
297 static int hf_6lowpan_iphc_dci = -1;
298
299 static int hf_6lowpan_iphc_sctx_prefix = -1;
300 static int hf_6lowpan_iphc_sctx_origin = -1;
301 static int hf_6lowpan_iphc_dctx_prefix = -1;
302 static int hf_6lowpan_iphc_dctx_origin = -1;
303
304 /* NHC IPv6 extension header fields. */
305 static int hf_6lowpan_nhc_ext_eid = -1;
306 static int hf_6lowpan_nhc_ext_nh = -1;
307 static int hf_6lowpan_nhc_ext_next = -1;
308 static int hf_6lowpan_nhc_ext_length = -1;
309 static int hf_6lowpan_nhc_ext_reserved = -1;
310
311 /* NHC UDP compression header fields. */
312 static int hf_6lowpan_nhc_udp_checksum = -1;
313 static int hf_6lowpan_nhc_udp_ports = -1;
314
315 /* Inline IPv6 header fields. */
316 static int hf_6lowpan_traffic_class = -1;
317 static int hf_6lowpan_flow_label = -1;
318 static int hf_6lowpan_ecn = -1;
319 static int hf_6lowpan_dscp = -1;
320 static int hf_6lowpan_next_header = -1;
321 static int hf_6lowpan_hop_limit = -1;
322 static int hf_6lowpan_source = -1;
323 static int hf_6lowpan_dest = -1;
324
325 /* Inline UDP header fields. */
326 static int hf_6lowpan_udp_src = -1;
327 static int hf_6lowpan_udp_dst = -1;
328 static int hf_6lowpan_udp_len = -1;
329 static int hf_6lowpan_udp_checksum = -1;
330
331 /* Broadcast header fields. */
332 static int hf_6lowpan_bcast_seqnum = -1;
333
334 /* Mesh header fields. */
335 static int hf_6lowpan_mesh_v = -1;
336 static int hf_6lowpan_mesh_f = -1;
337 static int hf_6lowpan_mesh_hops = -1;
338 static int hf_6lowpan_mesh_hops8 = -1;
339 static int hf_6lowpan_mesh_orig16 = -1;
340 static int hf_6lowpan_mesh_orig64 = -1;
341 static int hf_6lowpan_mesh_dest16 = -1;
342 static int hf_6lowpan_mesh_dest64 = -1;
343
344 /* Fragmentation header fields. */
345 static int hf_6lowpan_frag_dgram_size = -1;
346 static int hf_6lowpan_frag_dgram_tag = -1;
347 static int hf_6lowpan_frag_dgram_offset = -1;
348
349 /* Recoverable Fragmentation header fields. */
350 static int hf_6lowpan_rfrag_congestion = -1;
351 static int hf_6lowpan_rfrag_ack_requested = -1;
352 static int hf_6lowpan_rfrag_dgram_tag = -1;
353 static int hf_6lowpan_rfrag_sequence = -1;
354 static int hf_6lowpan_rfrag_size = -1;
355 static int hf_6lowpan_rfrag_dgram_size = -1;
356 static int hf_6lowpan_rfrag_offset = -1;
357 static int hf_6lowpan_rfrag_ack_bitmap = -1;
358
359 /* Protocol tree handles. */
360 static gint ett_6lowpan = -1;
361 static gint ett_6lowpan_hc1 = -1;
362 static gint ett_6lowpan_hc1_encoding = -1;
363 static gint ett_6lowpan_hc2_udp = -1;
364 static gint ett_6lowpan_iphc = -1;
365 static gint ett_lowpan_routing_header_dispatch = -1;
366 static gint ett_6lowpan_nhc_ext = -1;
367 static gint ett_6lowpan_nhc_udp = -1;
368 static gint ett_6lowpan_bcast = -1;
369 static gint ett_6lowpan_mesh = -1;
370 static gint ett_6lowpan_mesh_flags = -1;
371 static gint ett_6lowpan_frag = -1;
372
373 static expert_field ei_6lowpan_hc1_more_bits = EI_INIT;
374 static expert_field ei_6lowpan_illegal_dest_addr_mode = EI_INIT;
375 static expert_field ei_6lowpan_bad_ipv6_header_length = EI_INIT;
376 static expert_field ei_6lowpan_bad_ext_header_length = EI_INIT;
377
378 /* Subdissector handles. */
379 static dissector_handle_t handle_6lowpan;
380 static dissector_handle_t ipv6_handle;
381
382 /* Value Strings */
383 static const value_string lowpan_patterns [] = {
384 { LOWPAN_PATTERN_NALP, "Not a LoWPAN frame" },
385 { LOWPAN_PATTERN_IPV6, "Uncompressed IPv6" },
386 { LOWPAN_PATTERN_HC1, "Header compression" },
387 { LOWPAN_PATTERN_BC0, "Broadcast" },
388 { LOWPAN_PATTERN_IPHC, "IP header compression" },
389 { LOWPAN_PATTERN_ESC, "Escape" },
390 { LOWPAN_PATTERN_MESH, "Mesh" },
391 { LOWPAN_PATTERN_FRAG1, "First fragment" },
392 { LOWPAN_PATTERN_FRAGN, "Fragment" },
393 { LOWPAN_PATTERN_RFRAG, "Recoverable Fragment" },
394 { LOWPAN_PATTERN_RFRAG_ACK, "Recoverable Fragment ACK" },
395 { 0, NULL }
396 };
397 static const true_false_string lowpan_compression = {
398 "Compressed",
399 "Inline"
400 };
401 static const value_string lowpan_hc1_next [] = {
402 { LOWPAN_HC1_NEXT_NONE, "Inline" },
403 { LOWPAN_HC1_NEXT_UDP, "UDP" },
404 { LOWPAN_HC1_NEXT_ICMP, "ICMP" },
405 { LOWPAN_HC1_NEXT_TCP, "TCP" },
406 { 0, NULL }
407 };
408 static const value_string lowpan_iphc_traffic [] = {
409 { LOWPAN_IPHC_FLOW_CLASS_LABEL, "Traffic class and flow label inline" },
410 { LOWPAN_IPHC_FLOW_ECN_LABEL, "ECN and flow label inline" },
411 { LOWPAN_IPHC_FLOW_CLASS, "Traffic class inline" },
412 { LOWPAN_IPHC_FLOW_COMPRESSED, "Version, traffic class, and flow label compressed" },
413 { 0, NULL }
414 };
415 static const value_string lowpan_iphc_hop_limit [] = {
416 { LOWPAN_IPHC_HLIM_INLINE, "Inline" },
417 { LOWPAN_IPHC_HLIM_1, "1" },
418 { LOWPAN_IPHC_HLIM_64, "64" },
419 { LOWPAN_IPHC_HLIM_255, "255" },
420 { 0, NULL }
421 };
422 static const true_false_string lowpan_iphc_addr_compression = {
423 "Stateful",
424 "Stateless"
425 };
426 static const value_string lowpan_iphc_addr_modes [] = {
427 { LOWPAN_IPHC_ADDR_FULL_INLINE, "Inline" },
428 { LOWPAN_IPHC_ADDR_64BIT_INLINE,"64-bits inline" },
429 { LOWPAN_IPHC_ADDR_16BIT_INLINE,"16-bits inline" },
430 { LOWPAN_IPHC_ADDR_COMPRESSED, "Compressed" },
431 { 0, NULL }
432 };
433 static const value_string lowpan_iphc_saddr_stateful_modes [] = {
434 { LOWPAN_IPHC_ADDR_FULL_INLINE, "Unspecified address (::)" },
435 { LOWPAN_IPHC_ADDR_64BIT_INLINE,"64-bits inline" },
436 { LOWPAN_IPHC_ADDR_16BIT_INLINE,"16-bits inline" },
437 { LOWPAN_IPHC_ADDR_COMPRESSED, "Compressed" },
438 { 0, NULL }
439 };
440 static const value_string lowpan_iphc_daddr_stateful_modes [] = {
441 { LOWPAN_IPHC_ADDR_64BIT_INLINE,"64-bits inline" },
442 { LOWPAN_IPHC_ADDR_16BIT_INLINE,"16-bits inline" },
443 { LOWPAN_IPHC_ADDR_COMPRESSED, "Compressed" },
444 { 0, NULL }
445 };
446 static const value_string lowpan_iphc_mcast_modes [] = {
447 { LOWPAN_IPHC_MCAST_FULL, "Inline" },
448 { LOWPAN_IPHC_MCAST_48BIT, "48-bits inline" },
449 { LOWPAN_IPHC_MCAST_32BIT, "32-bits inline" },
450 { LOWPAN_IPHC_MCAST_8BIT, "8-bits inline" },
451 { 0, NULL }
452 };
453 static const value_string lowpan_iphc_mcast_stateful_modes [] = {
454 { LOWPAN_IPHC_MCAST_STATEFUL_48BIT, "48-bits inline" },
455 { 0, NULL }
456 };
457 static const value_string lowpan_nhc_patterns [] = {
458 { LOWPAN_NHC_PATTERN_EXT, "IPv6 extension header" },
459 { LOWPAN_NHC_PATTERN_UDP, "UDP compression header" },
460 { 0, NULL }
461 };
462 static const value_string lowpan_nhc_eid [] = {
463 { LOWPAN_NHC_EID_HOP_BY_HOP, "IPv6 hop-by-hop options" },
464 { LOWPAN_NHC_EID_ROUTING, "IPv6 routing" },
465 { LOWPAN_NHC_EID_FRAGMENT, "IPv6 fragment" },
466 { LOWPAN_NHC_EID_DEST_OPTIONS, "IPv6 destination options" },
467 { LOWPAN_NHC_EID_MOBILITY, "IPv6 mobility header" },
468 { LOWPAN_NHC_EID_IPV6, "IPv6 header" },
469 { 0, NULL }
470 };
471 static const value_string lowpan_udp_ports [] = {
472 { LOWPAN_NHC_UDP_PORT_INLINE, "Inline" },
473 { LOWPAN_NHC_UDP_PORT_8BIT_DST, "Source port inline, first 8 bits of destination port elided" },
474 { LOWPAN_NHC_UDP_PORT_8BIT_SRC, "Destination port inline, first 8 bits of source port elided" },
475 { LOWPAN_NHC_UDP_PORT_12BIT, "12 bits of both ports elided" },
476 { 0, NULL }
477 };
478 /* 6loRH */
479 static const value_string lowpan_patterns_rh_type [] = {
480 { LOWPAN_PATTERN_6LORH_TYPE0, "Routing Header 3, 1 byte compression" },
481 { LOWPAN_PATTERN_6LORH_TYPE1, "Routing Header 3, 2 byte compression" },
482 { LOWPAN_PATTERN_6LORH_TYPE2, "Routing Header 3, 4 byte compression" },
483 { LOWPAN_PATTERN_6LORH_TYPE3, "Routing Header 3, 8 byte compression" },
484 { LOWPAN_PATTERN_6LORH_TYPE4, "Routing Header 3, 16 byte compression" },
485 { LOWPAN_PATTERN_6LORH_TYPE5, "Routing Protocol Information" },
486 { LOWPAN_PATTERN_6LORH_TYPE6, "IP in IP" },
487 { LOWPAN_PATTERN_6LORH_TYPE15, "BIER Header, bit-by-bit encoding, no control fields, 32 bits word size" },
488 { LOWPAN_PATTERN_6LORH_TYPE16, "BIER Header, Bloom filter encoding, 2* 1-byte HashID control fields, 32 bits word size" },
489 { LOWPAN_PATTERN_6LORH_TYPE17, "BIER Header, bit-by-bit encoding, no control fields, 128 bits word size" },
490 { LOWPAN_PATTERN_6LORH_TYPE18, "BIER Header, Bloom filter encoding, 8* 1-byte HashID control fields, 128 bits word size" },
491 { LOWPAN_PATTERN_6LORH_TYPE19, "BIER Header, bit-by-bit encoding, 1-byte GroupID control fields, 128 bits word size" },
492 { 0, NULL }
493 };
494 static const value_string lowpan_patterns_rh [] = {
495 { LOWPAN_PATTERN_6LORHC, "Critical Routing Header" },
496 { LOWPAN_PATTERN_6LORHE, "Elective Routing Header" },
497 { 0, NULL }
498 };
499 static const true_false_string bit_I_RPL = {
500 "Elided (RPL Instance ID: 0)",
501 "Present"
502 };
503 static const true_false_string bit_K_RPL = {
504 "1 byte",
505 "2 bytes"
506 };
507
508 /* Reassembly Data */
509 static int hf_6lowpan_fragments = -1;
510 static int hf_6lowpan_fragment = -1;
511 static int hf_6lowpan_fragment_overlap = -1;
512 static int hf_6lowpan_fragment_overlap_conflicts = -1;
513 static int hf_6lowpan_fragment_multiple_tails = -1;
514 static int hf_6lowpan_fragment_too_long_fragment = -1;
515 static int hf_6lowpan_fragment_error = -1;
516 static int hf_6lowpan_fragment_count = -1;
517 static int hf_6lowpan_reassembled_in = -1;
518 static int hf_6lowpan_reassembled_length = -1;
519 static gint ett_6lowpan_fragment = -1;
520 static gint ett_6lowpan_fragments = -1;
521
522 static const fragment_items lowpan_frag_items = {
523 /* Fragment subtrees */
524 &ett_6lowpan_fragment,
525 &ett_6lowpan_fragments,
526 /* Fragment fields */
527 &hf_6lowpan_fragments,
528 &hf_6lowpan_fragment,
529 &hf_6lowpan_fragment_overlap,
530 &hf_6lowpan_fragment_overlap_conflicts,
531 &hf_6lowpan_fragment_multiple_tails,
532 &hf_6lowpan_fragment_too_long_fragment,
533 &hf_6lowpan_fragment_error,
534 &hf_6lowpan_fragment_count,
535 /* Reassembled in field */
536 &hf_6lowpan_reassembled_in,
537 /* Reassembled length field */
538 &hf_6lowpan_reassembled_length,
539 /* Reassembled data field */
540 NULL,
541 /* Tag */
542 "6LoWPAN fragments"
543 };
544
545 static reassembly_table lowpan_reassembly_table;
546 static GHashTable *lowpan_context_table = NULL;
547
548 /* Link-Local prefix used by 6LoWPAN (FF80::/10) */
549 static const guint8 lowpan_llprefix[8] = {
550 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
551 };
552
553 /* Context hash table map key. */
554 typedef struct {
555 guint16 pan; /* PAN Identifier */
556 guint8 cid; /* Context Identifier */
557 } lowpan_context_key;
558
559 /* Context hash table map data. */
560 typedef struct {
561 guint frame; /* Frame where the context was discovered. */
562 guint8 plen; /* Prefix length. */
563 ws_in6_addr prefix; /* Compression context. */
564 } lowpan_context_data;
565
566 /* 6LoWPAN contexts. */
567 #define LOWPAN_CONTEXT_MAX 16
568 #define LOWPAN_CONTEXT_DEFAULT 0
569 #define LOWPAN_CONTEXT_LINK_LOCAL LOWPAN_CONTEXT_MAX
570 #define LOWPAN_CONTEXT_LINK_LOCAL_BITS 10
571 static lowpan_context_data lowpan_context_local;
572 static lowpan_context_data lowpan_context_default;
573 static const gchar * lowpan_context_prefs[LOWPAN_CONTEXT_MAX];
574
575 /* Preferences */
576 static gboolean rfc4944_short_address_format = FALSE;
577 static gboolean iid_has_universal_local_bit = FALSE;
578 static gboolean ipv6_summary_in_tree = TRUE;
579
580 /* Helper macro to convert a bit offset/length into a byte count. */
581 #define BITS_TO_BYTE_LEN(bitoff, bitlen) ((bitlen)?(((bitlen) + ((bitoff)&0x07) + 7) >> 3):(0))
582
583 /* Structure for rebuilding UDP datagrams. */
584 struct udp_hdr {
585 guint16 src_port;
586 guint16 dst_port;
587 guint16 length;
588 guint16 checksum;
589 };
590
591 /* Structure used to store decompressed header chains until reassembly. */
592 struct lowpan_nhdr {
593 /* List Linking */
594 struct lowpan_nhdr *next;
595 /* Next Header */
596 guint8 proto;
597 guint length;
598 guint reported;
599 };
600 #define LOWPAN_NHDR_DATA(nhdr) ((guint8 *)(nhdr) + sizeof (struct lowpan_nhdr))
601
602 /* Dissector prototypes */
603 static void proto_init_6lowpan (void);
604 static void prefs_6lowpan_apply (void);
605 static int dissect_6lowpan (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
606 static tvbuff_t * dissect_6lowpan_ipv6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
607 static tvbuff_t * dissect_6lowpan_hc1 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size, const guint8 *siid, const guint8 *diid);
608 static tvbuff_t * dissect_6lowpan_bc0 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
609 static tvbuff_t * dissect_6lowpan_iphc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size, const guint8 *siid, const guint8 *diid);
610 static struct lowpan_nhdr *
611 dissect_6lowpan_iphc_nhc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint dgram_size, const guint8 *siid, const guint8 *diid);
612 static tvbuff_t * dissect_6lowpan_mesh (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 *siid, guint8 *diid);
613 static tvbuff_t * dissect_6lowpan_rfrag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const guint8 *siid, const guint8 *diid);
614 static tvbuff_t * dissect_6lowpan_rfrag_ack (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
615 static tvbuff_t * dissect_6lowpan_frag_first (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const guint8 *siid, const guint8 *diid);
616 static tvbuff_t * dissect_6lowpan_frag_middle (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
617 static void dissect_6lowpan_unknown (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
618 static tvbuff_t * dissect_6lowpan_6loRH (tvbuff_t *tvb, guint offset, proto_tree *tree);
619
620
621 /* Helper functions. */
622 static gboolean lowpan_dlsrc_to_ifcid (packet_info *pinfo, guint8 *ifcid);
623 static gboolean lowpan_dldst_to_ifcid (packet_info *pinfo, guint8 *ifcid);
624 static void lowpan_addr16_to_ifcid (guint16 addr, guint8 *ifcid);
625 static void lowpan_addr16_with_panid_to_ifcid(guint16 panid, guint16 addr, guint8 *ifcid);
626 static void lowpan_addr48_to_ifcid (const guint8 *addr, guint8 *ifcid);
627 static tvbuff_t * lowpan_reassemble_ipv6 (tvbuff_t *tvb, packet_info *pinfo, struct ws_ip6_hdr *ipv6, struct lowpan_nhdr *nhdr_list);
628 static guint8 lowpan_parse_nhc_proto (tvbuff_t *tvb, gint offset);
629
630 /* Context table helpers */
631 static guint lowpan_context_hash (gconstpointer key);
632 static gboolean lowpan_context_equal (gconstpointer a, gconstpointer b);
633 static lowpan_context_data *lowpan_context_find(guint8 cid, guint16 pan);
634
635 /*FUNCTION:------------------------------------------------------
636 * NAME
637 * lowpan_pfxcpy
638 * DESCRIPTION
639 * A version of memcpy that takes a length in bits. If the
640 * length is not byte-aligned, the final byte will be
641 * manipulated so that only the desired number of bits are
642 * copied.
643 * PARAMETERS
644 * dst ; Destination.
645 * src ; Source.
646 * bits ; Number of bits to copy.
647 * RETURNS
648 * void ;
649 *---------------------------------------------------------------
650 */
651 static void
lowpan_pfxcpy(void * dst,const void * src,size_t bits)652 lowpan_pfxcpy(void *dst, const void *src, size_t bits)
653 {
654 memcpy(dst, src, bits>>3);
655 if (bits & 0x7) {
656 guint8 mask = ((0xff00) >> (bits & 0x7));
657 guint8 last = ((const guint8 *)src)[bits>>3] & mask;
658 ((guint8 *)dst)[bits>>3] &= ~mask;
659 ((guint8 *)dst)[bits>>3] |= last;
660 }
661 } /* lowpan_pfxcpy */
662
663 /*FUNCTION:------------------------------------------------------
664 * NAME
665 * lowpan_context_hash
666 * DESCRIPTION
667 * Context table hash function.
668 * PARAMETERS
669 * key ; Pointer to a lowpan_context_key type.
670 * RETURNS
671 * guint ; The hashed key value.
672 *---------------------------------------------------------------
673 */
674 static guint
lowpan_context_hash(gconstpointer key)675 lowpan_context_hash(gconstpointer key)
676 {
677 return (((const lowpan_context_key *)key)->cid) | (((const lowpan_context_key *)key)->pan << 8);
678 } /* lowpan_context_hash */
679
680 /*FUNCTION:------------------------------------------------------
681 * NAME
682 * lowpan_context_equal
683 * DESCRIPTION
684 * Context table equals function.
685 * PARAMETERS
686 * key ; Pointer to a lowpan_context_key type.
687 * RETURNS
688 * gboolean ;
689 *---------------------------------------------------------------
690 */
691 static gboolean
lowpan_context_equal(gconstpointer a,gconstpointer b)692 lowpan_context_equal(gconstpointer a, gconstpointer b)
693 {
694 return (((const lowpan_context_key *)a)->pan == ((const lowpan_context_key *)b)->pan) &&
695 (((const lowpan_context_key *)a)->cid == ((const lowpan_context_key *)b)->cid);
696 } /* lowpan_context_equal */
697
698 /*FUNCTION:------------------------------------------------------
699 * NAME
700 * lowpan_context_find
701 * DESCRIPTION
702 * Context table lookup function.
703 * PARAMETERS
704 * cid ; Context identifier.
705 * pan ; PAN identifier.
706 * RETURNS
707 * lowpan_context_data *;
708 *---------------------------------------------------------------
709 */
710 static lowpan_context_data *
lowpan_context_find(guint8 cid,guint16 pan)711 lowpan_context_find(guint8 cid, guint16 pan)
712 {
713 lowpan_context_key key;
714 lowpan_context_data *data;
715
716 /* Check for the internal link-local context. */
717 if (cid == LOWPAN_CONTEXT_LINK_LOCAL) return &lowpan_context_local;
718
719 /* Lookup the context from the table. */
720 key.pan = pan;
721 key.cid = cid;
722 data = (lowpan_context_data *)g_hash_table_lookup(lowpan_context_table, &key);
723 if (data) return data;
724
725 /* If we didn't find a match, try again with the broadcast PAN. */
726 if (pan != IEEE802154_BCAST_PAN) {
727 key.pan = IEEE802154_BCAST_PAN;
728 data = (lowpan_context_data *)g_hash_table_lookup(lowpan_context_table, &key);
729 if (data) return data;
730 }
731
732 /* If the lookup failed, return the default context (::/0) */
733 return &lowpan_context_default;
734 } /* lowpan_context_find */
735
736 /*FUNCTION:------------------------------------------------------
737 * NAME
738 * lowpan_context_insert
739 * DESCRIPTION
740 * Context table insert function.
741 * PARAMETERS
742 * cid ; Context identifier.
743 * pan ; PAN identifier.
744 * plen ; Prefix length.
745 * prefix ; Compression prefix.
746 * frame ; Frame number.
747 * RETURNS
748 * void ;
749 *---------------------------------------------------------------
750 */
751 void
lowpan_context_insert(guint8 cid,guint16 pan,guint8 plen,ws_in6_addr * prefix,guint frame)752 lowpan_context_insert(guint8 cid, guint16 pan, guint8 plen, ws_in6_addr *prefix, guint frame)
753 {
754 lowpan_context_key key;
755 lowpan_context_data *data;
756 gpointer pkey;
757 gpointer pdata;
758
759 /* Sanity! */
760 if (plen > 128) return;
761 if (!prefix) return;
762 if (!lowpan_context_table) return;
763
764 /* Search the context table for an existing entry. */
765 key.pan = pan;
766 key.cid = cid;
767 if (g_hash_table_lookup_extended(lowpan_context_table, &key, NULL, &pdata)) {
768 /* Context already exists. */
769 data = (lowpan_context_data *)pdata;
770 if ( (data->plen == plen) && (memcmp(&data->prefix, prefix, (plen+7)/8) == 0) ) {
771 /* Context already exists with no change. */
772 return;
773 }
774 }
775 pkey = wmem_memdup(NULL, &key, sizeof(key));
776
777 /* Create a new context */
778 data = wmem_new(NULL, lowpan_context_data);
779 data->frame = frame;
780 data->plen = plen;
781 memset(&data->prefix, 0, sizeof(ws_in6_addr)); /* Ensure zero paddeding */
782 lowpan_pfxcpy(&data->prefix, prefix, plen);
783 g_hash_table_insert(lowpan_context_table, pkey, data);
784 } /* lowpan_context_insert */
785
786 /*FUNCTION:------------------------------------------------------
787 * NAME
788 * lowpan_context_free
789 * DESCRIPTION
790 * Frees the allocated memory for the context hash table
791 * PARAMETERS
792 * data ; Pointer to key or value
793 * RETURNS
794 * void ;
795 *---------------------------------------------------------------
796 */
797 static void
lowpan_context_free(gpointer data)798 lowpan_context_free(gpointer data)
799 {
800 wmem_free(NULL, data);
801 } /* lowpan_context_free */
802
803 /*FUNCTION:------------------------------------------------------
804 * NAME
805 * lowpan_addr16_to_ifcid
806 * DESCRIPTION
807 * Converts a short address to in interface identifier as
808 * per rfc 6282 section 3.2.2.
809 * PARAMETERS
810 * addr ; 16-bit short address.
811 * ifcid ; interface identifier (output).
812 * RETURNS
813 * void ;
814 *---------------------------------------------------------------
815 */
816 static void
lowpan_addr16_to_ifcid(guint16 addr,guint8 * ifcid)817 lowpan_addr16_to_ifcid(guint16 addr, guint8 *ifcid)
818 {
819 /* Note: The PANID is no longer used in building the IID. */
820 ifcid[0] = 0x00; /* the U/L bit must be cleared. */
821 ifcid[1] = 0x00;
822 ifcid[2] = 0x00;
823 ifcid[3] = 0xff;
824 ifcid[4] = 0xfe;
825 ifcid[5] = 0x00;
826 ifcid[6] = (addr >> 8) & 0xff;
827 ifcid[7] = (addr >> 0) & 0xff;
828 } /* lowpan_addr16_to_ifcid */
829
830 /*FUNCTION:------------------------------------------------------
831 * NAME
832 * lowpan_addr16_with_panid_to_ifcid
833 * DESCRIPTION
834 * Converts a short address to in interface identifier as
835 * per rfc 4944 section 6.
836 * PARAMETERS
837 * panid ; 16-bit PAN ID.
838 * addr ; 16-bit short address.
839 * ifcid ; interface identifier (output).
840 * RETURNS
841 * void ;
842 *---------------------------------------------------------------
843 */
844 static void
lowpan_addr16_with_panid_to_ifcid(guint16 panid,guint16 addr,guint8 * ifcid)845 lowpan_addr16_with_panid_to_ifcid(guint16 panid, guint16 addr, guint8 *ifcid)
846 {
847 /* Note: The PANID is used in building the IID following RFC 2464 section 4. */
848 ifcid[0] = (panid >> 8) & 0xfd; /* the U/L bit must be cleared. */
849 ifcid[1] = (panid >> 0) & 0xff;
850 ifcid[2] = 0x00;
851 ifcid[3] = 0xff;
852 ifcid[4] = 0xfe;
853 ifcid[5] = 0x00;
854 ifcid[6] = (addr >> 8) & 0xff;
855 ifcid[7] = (addr >> 0) & 0xff;
856 } /* lowpan_addr16_with_panid_to_ifcid */
857
858 /*FUNCTION:------------------------------------------------------
859 * NAME
860 * lowpan_addr48_to_ifcid
861 * DESCRIPTION
862 * Converts an IEEE 48-bit MAC identifier to an interface
863 * identifier as per RFC 4291 Appendix A.
864 * PARAMETERS
865 * addr ; 48-bit MAC identifier.
866 * ifcid ; interface identifier (output).
867 * RETURNS
868 * void ;
869 *---------------------------------------------------------------
870 */
871 static void
lowpan_addr48_to_ifcid(const guint8 * addr,guint8 * ifcid)872 lowpan_addr48_to_ifcid(const guint8 *addr, guint8 *ifcid)
873 {
874 static const guint8 unknown_addr[] = { 0, 0, 0, 0, 0, 0 };
875
876 /* Don't convert unknown addresses */
877 if (memcmp(addr, unknown_addr, sizeof(unknown_addr)) != 0) {
878 ifcid[0] = addr[0];
879 ifcid[1] = addr[1];
880 ifcid[2] = addr[2];
881 ifcid[3] = 0xff;
882 ifcid[4] = 0xfe;
883 ifcid[5] = addr[3];
884 ifcid[6] = addr[4];
885 ifcid[7] = addr[5];
886 if (iid_has_universal_local_bit) {
887 ifcid[0] ^= 0x02; /* Invert the U/L bit. */
888 }
889 } else {
890 memset(ifcid, 0, LOWPAN_IFC_ID_LEN);
891 }
892 } /* lowpan_ether_to_ifcid */
893
894 /*FUNCTION:------------------------------------------------------
895 * NAME
896 * lowpan_dlsrc_to_ifcid
897 * DESCRIPTION
898 * Finds an interface identifier from the data-link source
899 * addressing.
900 * PARAMETERS
901 * pinfo ; packet information.
902 * ifcid ; interface identifier (output).
903 * RETURNS
904 * gboolean ; TRUE if an interface identifier could
905 * be found.
906 *---------------------------------------------------------------
907 */
908 static gboolean
lowpan_dlsrc_to_ifcid(packet_info * pinfo,guint8 * ifcid)909 lowpan_dlsrc_to_ifcid(packet_info *pinfo, guint8 *ifcid)
910 {
911 ieee802154_hints_t *hints;
912
913 /* Check the link-layer address field. */
914 if (pinfo->dl_src.type == AT_EUI64) {
915 memcpy(ifcid, pinfo->dl_src.data, LOWPAN_IFC_ID_LEN);
916 /* RFC2464: Invert the U/L bit when using an EUI64 address. */
917 ifcid[0] ^= 0x02;
918 return TRUE;
919 } else if (pinfo->dl_src.type == AT_ETHER) {
920 lowpan_addr48_to_ifcid((const guint8 *)pinfo->dl_src.data, ifcid);
921 return TRUE;
922 }
923
924 /* Lookup the IEEE 802.15.4 addressing hints. */
925 hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
926 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
927 if (hints) {
928
929 /* Convert the 16-bit short address to an IID using the PAN ID (RFC 4944) or not depending on the preference */
930 if (rfc4944_short_address_format) {
931 lowpan_addr16_with_panid_to_ifcid(hints->src_pan, hints->src16, ifcid);
932 } else {
933 lowpan_addr16_to_ifcid(hints->src16, ifcid);
934 }
935
936 return TRUE;
937 } else {
938 /* Failed to find a link-layer source address. */
939 memset(ifcid, 0, LOWPAN_IFC_ID_LEN);
940 return FALSE;
941 }
942 } /* lowpan_dlsrc_to_ifcid */
943
944 /*FUNCTION:------------------------------------------------------
945 * NAME
946 * lowpan_dldst_to_ifcid
947 * DESCRIPTION
948 * Finds an interface identifier from the data-link destination
949 * addressing.
950 * PARAMETERS
951 * pinfo ; packet information.
952 * ifcid ; interface identifier (output).
953 * RETURNS
954 * gboolean ; TRUE if an interface identifier could
955 * be found.
956 *---------------------------------------------------------------
957 */
958 static gboolean
lowpan_dldst_to_ifcid(packet_info * pinfo,guint8 * ifcid)959 lowpan_dldst_to_ifcid(packet_info *pinfo, guint8 *ifcid)
960 {
961 ieee802154_hints_t *hints;
962
963 /* Check the link-layer address field. */
964 if (pinfo->dl_dst.type == AT_EUI64) {
965 memcpy(ifcid, pinfo->dl_dst.data, LOWPAN_IFC_ID_LEN);
966 /* RFC2464: Invert the U/L bit when using an EUI64 address. */
967 ifcid[0] ^= 0x02;
968 return TRUE;
969 } else if (pinfo->dl_dst.type == AT_ETHER) {
970 lowpan_addr48_to_ifcid((const guint8 *)pinfo->dl_dst.data, ifcid);
971 return TRUE;
972 }
973
974 /* Lookup the IEEE 802.15.4 addressing hints. */
975 hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
976 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
977 if (hints) {
978
979 /* Convert the 16-bit short address to an IID using the PAN ID (RFC 4944) or not depending on the preference */
980 if (rfc4944_short_address_format) {
981 lowpan_addr16_with_panid_to_ifcid(hints->src_pan, hints->dst16, ifcid);
982 } else {
983 lowpan_addr16_to_ifcid(hints->dst16, ifcid);
984 }
985
986 return TRUE;
987 } else {
988 /* Failed to find a link-layer destination address. */
989 memset(ifcid, 0, LOWPAN_IFC_ID_LEN);
990 return FALSE;
991 }
992 } /* lowpan_dldst_to_ifcid */
993
994 /*FUNCTION:------------------------------------------------------
995 * NAME
996 * lowpan_reassemble_ipv6
997 * DESCRIPTION
998 * Helper function to rebuild an IPv6 packet from the IPv6
999 * header structure, and a list of next header structures.
1000 * PARAMETERS
1001 * ipv6 ; IPv6 Header.
1002 * nhdr_list ; Next header list.
1003 * RETURNS
1004 * tvbuff_t * ; Reassembled IPv6 packet.
1005 *---------------------------------------------------------------
1006 */
1007 static tvbuff_t *
lowpan_reassemble_ipv6(tvbuff_t * tvb,packet_info * pinfo,struct ws_ip6_hdr * ipv6,struct lowpan_nhdr * nhdr_list)1008 lowpan_reassemble_ipv6(tvbuff_t *tvb, packet_info *pinfo, struct ws_ip6_hdr *ipv6, struct lowpan_nhdr *nhdr_list)
1009 {
1010 gint length = 0;
1011 gint reported = 0;
1012 guint8 * buffer;
1013 guint8 * cursor;
1014 struct lowpan_nhdr *nhdr;
1015
1016 /* Compute the real and reported lengths. */
1017 for (nhdr = nhdr_list; nhdr; nhdr = nhdr->next) {
1018 length += nhdr->length;
1019 reported += nhdr->reported;
1020 }
1021 ipv6->ip6h_plen = g_ntohs(reported);
1022
1023 /* Allocate a buffer for the packet and copy in the IPv6 header. */
1024 buffer = (guint8 *)wmem_alloc(pinfo->pool, length + IPv6_HDR_SIZE);
1025 memcpy(buffer, ipv6, IPv6_HDR_SIZE);
1026 cursor = buffer + IPv6_HDR_SIZE;
1027
1028 /* Add the next headers into the buffer. */
1029 for (nhdr = nhdr_list; nhdr; nhdr = nhdr->next) {
1030 memcpy(cursor, LOWPAN_NHDR_DATA(nhdr), nhdr->length);
1031 cursor += nhdr->length;
1032 };
1033
1034 /* Return the reassembled packet. */
1035 return tvb_new_child_real_data(tvb, buffer, length + IPv6_HDR_SIZE, reported + IPv6_HDR_SIZE);
1036 } /* lowpan_reassemble_ipv6 */
1037
1038 /*FUNCTION:------------------------------------------------------
1039 * NAME
1040 * lowpan_parse_nhc_proto
1041 * DESCRIPTION
1042 * Parses the start of an 6LoWPAN NHC header to determine the
1043 * next header protocol identifier. Will return IP_PROTO_NONE
1044 * if no valid protocol could be determined.
1045 * PARAMETERS
1046 * tvb ; packet buffer.
1047 * offset ; offset of the NHC.
1048 * RETURNS
1049 * guint8 ; IP_PROTO_* of the next header's protocol.
1050 *---------------------------------------------------------------
1051 */
1052 static guint8
lowpan_parse_nhc_proto(tvbuff_t * tvb,gint offset)1053 lowpan_parse_nhc_proto(tvbuff_t *tvb, gint offset)
1054 {
1055 /* Ensure that at least one byte exists. */
1056 if (!tvb_bytes_exist(tvb, offset, 1)) return IP_PROTO_NONE;
1057
1058 /* Check for IPv6 extension headers. */
1059 if (tvb_get_bits8(tvb, offset<<3, LOWPAN_NHC_PATTERN_EXT_BITS) == LOWPAN_NHC_PATTERN_EXT) {
1060 guint8 eid = (tvb_get_guint8(tvb, offset) & LOWPAN_NHC_EXT_EID) >> LOWPAN_NHC_EXT_EID_OFFSET;
1061 switch (eid) {
1062 case LOWPAN_NHC_EID_HOP_BY_HOP:
1063 return IP_PROTO_HOPOPTS;
1064 case LOWPAN_NHC_EID_ROUTING:
1065 return IP_PROTO_ROUTING;
1066 case LOWPAN_NHC_EID_FRAGMENT:
1067 return IP_PROTO_FRAGMENT;
1068 case LOWPAN_NHC_EID_DEST_OPTIONS:
1069 return IP_PROTO_DSTOPTS;
1070 case LOWPAN_NHC_EID_MOBILITY:
1071 return IP_PROTO_MIPV6;
1072 case LOWPAN_NHC_EID_IPV6:
1073 return IP_PROTO_IPV6;
1074 default:
1075 /* Unknown protocol type. */
1076 return IP_PROTO_NONE;
1077 };
1078 }
1079 /* Check for compressed UDP headers. */
1080 if (tvb_get_bits8(tvb, offset<<3, LOWPAN_NHC_PATTERN_UDP_BITS) == LOWPAN_NHC_PATTERN_UDP) {
1081 return IP_PROTO_UDP;
1082 }
1083 /* Unknown header type. */
1084 return IP_PROTO_NONE;
1085 } /* lowpan_parse_nhc_proto */
1086
1087 /*FUNCTION:------------------------------------------------------
1088 * NAME
1089 * lowpan_reassembly_id
1090 * DESCRIPTION
1091 * Creates an identifier that groups fragments based on the given datagram
1092 * tag and the link layer destination address (to differentiate packets
1093 * forwarded over different links in a mesh network).
1094 * PARAMETERS
1095 * pinfo : packet info.
1096 * dgram_tag ; datagram tag (from the Fragmentation Header).
1097 * RETURNS
1098 * guint32 ; identifier for this group of fragments.
1099 *---------------------------------------------------------------
1100 */
1101 static guint32
lowpan_reassembly_id(packet_info * pinfo,guint16 dgram_tag)1102 lowpan_reassembly_id(packet_info *pinfo, guint16 dgram_tag)
1103 {
1104 /* Start with the datagram tag for identification. If the packet is not
1105 * being forwarded, then this should be sufficient to prevent collisions
1106 * which could break reassembly. */
1107 guint32 frag_id = dgram_tag;
1108 ieee802154_hints_t *hints;
1109
1110 /* Forwarded packets in a mesh network have the same datagram tag, mix
1111 * the IEEE 802.15.4 destination link layer address. */
1112 if (pinfo->dl_dst.type == AT_EUI64) {
1113 /* IEEE 64-bit extended address */
1114 frag_id = add_address_to_hash(frag_id, &pinfo->dl_dst);
1115 } else {
1116 /* 16-bit short address */
1117 hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
1118 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
1119 if (hints) {
1120 frag_id |= hints->dst16 << 16;
1121 }
1122 }
1123 return frag_id;
1124 } /* lowpan_reassembly_id */
1125
1126 /*FUNCTION:------------------------------------------------------
1127 * NAME
1128 * dissect_6lowpan_heur
1129 * DESCRIPTION
1130 * Heuristic dissector for 6LoWPAN. Checks if the pattern is
1131 * a valid 6LoWPAN type, and not NALP.
1132 * PARAMETERS
1133 * tvb ; packet buffer.
1134 * pinfo ; packet info.
1135 * tree ; protocol display tree.
1136 * data : ieee802154_packet,
1137 * RETURNS
1138 * boolean ; TRUE if the tvbuff was dissected as a
1139 * 6LoWPAN packet. If this returns FALSE,
1140 * then no dissection will be attempted.
1141 *---------------------------------------------------------------
1142 */
1143 static gboolean
dissect_6lowpan_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)1144 dissect_6lowpan_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1145 {
1146 guint offset = 0;
1147
1148 /* Check for valid patterns. */
1149 for (;;) {
1150 /* Parse patterns until we find a match. */
1151 if (!tvb_reported_length_remaining(tvb, offset)) return FALSE;
1152 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) break;
1153 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) break;
1154 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_BC0_BITS) == LOWPAN_PATTERN_BC0) {
1155 /* Broadcast headers must be followed by another valid header. */
1156 offset += 2;
1157 continue;
1158 }
1159 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) break;
1160 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_MESH_BITS) == LOWPAN_PATTERN_MESH) {
1161 /* Mesh headers must be followed by another valid header. */
1162 guint8 mesh = tvb_get_guint8(tvb, offset++);
1163 offset += (mesh & LOWPAN_MESH_HEADER_V) ? 2 : 8;
1164 offset += (mesh & LOWPAN_MESH_HEADER_F) ? 2 : 8;
1165 if ((mesh & LOWPAN_MESH_HEADER_HOPS) == LOWPAN_MESH_HEADER_HOPS) offset++;
1166 continue;
1167 }
1168 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_RFRAG_BITS) == LOWPAN_PATTERN_RFRAG) break;
1169 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_RFRAG_BITS) == LOWPAN_PATTERN_RFRAG_ACK) break;
1170 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAG1) {
1171 /* First fragment headers must be followed by another valid header. */
1172 offset += 4;
1173 continue;
1174 }
1175 if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAGN) break;
1176
1177 /* If we get here, then we couldn't match to any pattern. */
1178 return FALSE;
1179 } /* for */
1180
1181 /* If we get here, then we found a matching pattern. */
1182 dissect_6lowpan(tvb, pinfo, tree, data);
1183 return TRUE;
1184 } /* dissect_6lowpan_heur */
1185
1186 /*FUNCTION:------------------------------------------------------
1187 * NAME
1188 * dissect_6lowpan
1189 * DESCRIPTION
1190 * Dissector routine for 6LoWPAN packets.
1191 * PARAMETERS
1192 * tvb ; packet buffer.
1193 * pinfo ; packet info.
1194 * tree ; protocol display tree.
1195 * data ; Packet data (ieee 802.15.4).
1196 * RETURNS
1197 * int ; Length of data processed, or 0 if not 6LoWPAN.
1198 *---------------------------------------------------------------
1199 */
1200 static int
dissect_6lowpan(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1201 dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1202 {
1203 proto_tree *lowpan_tree;
1204 proto_item *lowpan_root;
1205 tvbuff_t *next = tvb;
1206 guint offset = 0;
1207 /* Interface identifier of the encapsulating layer. */
1208 guint8 src_iid[LOWPAN_IFC_ID_LEN];
1209 guint8 dst_iid[LOWPAN_IFC_ID_LEN];
1210
1211 /* Get the interface identifiers from the encapsulating layer. */
1212 lowpan_dlsrc_to_ifcid(pinfo, src_iid);
1213 lowpan_dldst_to_ifcid(pinfo, dst_iid);
1214
1215 /* Create the protocol tree. */
1216 lowpan_root = proto_tree_add_protocol_format(tree, proto_6lowpan, tvb, 0, -1, "6LoWPAN");
1217 lowpan_tree = proto_item_add_subtree(lowpan_root, ett_6lowpan);
1218
1219 /* Add the protocol name. */
1220 col_set_str(pinfo->cinfo, COL_PROTOCOL, "6LoWPAN");
1221
1222 /* Mesh and Broadcast headers always come first in a 6LoWPAN frame. */
1223 if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_MESH_BITS) == LOWPAN_PATTERN_MESH) {
1224 next = dissect_6lowpan_mesh(next, pinfo, lowpan_tree, src_iid, dst_iid);
1225 if (!next) return tvb_captured_length(tvb);
1226 }
1227 if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_BC0_BITS) == LOWPAN_PATTERN_BC0) {
1228 next = dissect_6lowpan_bc0(next, pinfo, lowpan_tree);
1229 if (!next) return tvb_captured_length(tvb);
1230 }
1231
1232 /* After the mesh and broadcast headers, process dispatch codes recursively. */
1233 /* Recoverable Fragmentation headers.*/
1234 if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_RFRAG_BITS) == LOWPAN_PATTERN_RFRAG) {
1235 next = dissect_6lowpan_rfrag(next, pinfo, lowpan_tree, src_iid, dst_iid);
1236 if (!next) return tvb_captured_length(tvb);
1237 }
1238 else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_RFRAG_BITS) == LOWPAN_PATTERN_RFRAG_ACK) {
1239 next = dissect_6lowpan_rfrag_ack(next, pinfo, lowpan_tree);
1240 if (!next) return tvb_captured_length(tvb);
1241 }
1242 /* Fragmentation headers.*/
1243 if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAG1) {
1244 next = dissect_6lowpan_frag_first(next, pinfo, lowpan_tree, src_iid, dst_iid);
1245 }
1246 else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAGN) {
1247 next = dissect_6lowpan_frag_middle(next, pinfo, lowpan_tree);
1248 }
1249 /* Uncompressed IPv6 packets. */
1250 else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) {
1251 next = dissect_6lowpan_ipv6(next, pinfo, lowpan_tree);
1252 }
1253 else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_PAGING_DISPATCH_BITS) == LOWPAN_PATTERN_PAGING_DISPATCH) {
1254 proto_tree_add_bits_item(lowpan_tree, hf_6lowpan_pagenb, tvb, 4, 4, ENC_BIG_ENDIAN);
1255 offset += 1;
1256 next = dissect_6lowpan_6loRH(next, offset, lowpan_tree);
1257 if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
1258 next = dissect_6lowpan_iphc(next, pinfo, lowpan_tree, -1, src_iid, dst_iid);
1259 if (!next) return tvb_captured_length(tvb);
1260 }
1261 if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) {
1262 next = dissect_6lowpan_hc1(next, pinfo, lowpan_tree, -1, src_iid, dst_iid);
1263 }
1264 }
1265 /* Compressed IPv6 packets. */
1266 else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) {
1267 next = dissect_6lowpan_hc1(next, pinfo, lowpan_tree, -1, src_iid, dst_iid);
1268 }
1269 else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
1270 next = dissect_6lowpan_iphc(next, pinfo, lowpan_tree, -1, src_iid, dst_iid);
1271 }
1272 /* Unknown 6LoWPAN dispatch type */
1273 else {
1274 dissect_6lowpan_unknown(next, pinfo, lowpan_tree);
1275 return tvb_captured_length(tvb);
1276 }
1277
1278 /* The last step should have returned an uncompressed IPv6 datagram. */
1279 if (next) {
1280 call_dissector(ipv6_handle, next, pinfo, tree);
1281 }
1282 return tvb_captured_length(tvb);
1283 } /* dissect_6lowpan */
1284
1285 /*FUNCTION:------------------------------------------------------
1286 * NAME
1287 * dissect_6lowpan_6loRH
1288 * DESCRIPTION
1289 * Dissector routine for 6loRH fields in 6LoWPAN packets.
1290 * PARAMETERS
1291 * tvb ; packet buffer.
1292 * offset ; offset of the 6loRH fields
1293 * tree ; protocol display tree.
1294 * RETURNS
1295 * tvbuff_t * ; The remaining payload to be parsed.
1296 *---------------------------------------------------------------
1297 */
1298 static tvbuff_t *
dissect_6lowpan_6loRH(tvbuff_t * tvb,guint offset,proto_tree * tree)1299 dissect_6lowpan_6loRH(tvbuff_t *tvb, guint offset, proto_tree *tree)
1300 {
1301
1302 guint16 check;
1303 gint IK;
1304 guint16 loRH_flags;
1305 proto_tree * loRH_tree;
1306 guint16 loRHE_length;
1307 guint8 loRHE_type;
1308 guint16 loRHE_class;
1309 guint8 rpl_instance;
1310 gint condition = 1;
1311 gint16 loRHE_unitnums;
1312
1313 struct ws_ip6_hdr ipv6;
1314 static int * const bits_RHC[] = {
1315 &hf_6lowpan_5_bit_o,
1316 &hf_6lowpan_5_bit_r,
1317 &hf_6lowpan_5_bit_f,
1318 &hf_6lowpan_5_bit_i,
1319 &hf_6lowpan_5_bit_k,
1320 NULL
1321 };
1322
1323 loRH_flags = tvb_get_ntohs(tvb, offset);
1324 check = loRH_flags & 0xC000;
1325
1326 if (check == LOWPAN_6LORH_GENERAL_FORMAT) {
1327
1328 memset(&ipv6.ip6h_src, 0, sizeof(ipv6.ip6h_src));
1329
1330 while(condition > 0){
1331 condition -= 1 ;
1332 /*Create the tree*/
1333 loRH_tree = proto_tree_add_subtree(tree, tvb, offset, 2, ett_lowpan_routing_header_dispatch, NULL, "6LoRH:");
1334
1335 /* Get and display the pattern. */
1336 proto_tree_add_bits_item(loRH_tree, hf_6lowpan_routing_header, tvb, 8*offset, LOWPAN_PATTERN_IPHC_BITS, ENC_BIG_ENDIAN);
1337 /*=====================================================
1338 * Parse 6LoRH Header flags.
1339 *=====================================================
1340 */
1341
1342 loRHE_class = (loRH_flags & LOWPAN_PATTERN_6LORHE_CLASS) >> LOWPAN_PATTERN_6LORHE_CLASS_BITS;
1343 loRHE_length = (loRH_flags & LOWPAN_PATTERN_6LORHE_LENGTH) >> LOWPAN_PATTERN_6LORHE_LENGTH_BITS;
1344 loRHE_unitnums = loRHE_length + 1;
1345 loRHE_type = (loRH_flags & LOWPAN_PATTERN_6LORHE_TYPE);
1346 IK = (loRH_flags & LOWPAN_5_RPI_BITS_IK) >> 8;
1347
1348 proto_item_append_text(loRH_tree, " %s", val_to_str_const(loRHE_type, lowpan_patterns_rh_type, "Unknown"));
1349
1350 switch (loRHE_class){
1351 case (LOWPAN_PATTERN_6LORHE):/*Elective Routing Header*/
1352 condition = 1 ;
1353 if (loRHE_type >= 15) { /* BIER implementation */
1354 proto_tree_add_uint (loRH_tree, hf_6lowpan_6lorhe_size, tvb, offset, 2, loRH_flags & LOWPAN_PATTERN_6LORHE_LENGTH);
1355 proto_tree_add_uint (loRH_tree, hf_6lowpan_6lorhe_type, tvb, offset, 2, loRHE_type);
1356 offset += 2 ;
1357 if (loRHE_type == 15) {
1358 for (int i=0; i<loRHE_unitnums; i++) {
1359 proto_tree_add_item(loRH_tree, hf_6lowpan_6lorhe_bitmap, tvb, offset, 4, ENC_BIG_ENDIAN);
1360 offset += 4;
1361 }
1362 }
1363 }
1364 else if (loRHE_type == LOWPAN_IP_IN_IP_6LORH) {
1365 memset(&ipv6.ip6h_src, 0, sizeof(ipv6.ip6h_src));
1366 proto_tree_add_item(loRH_tree, hf_6lowpan_6lorhe_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1367 proto_tree_add_item(loRH_tree, hf_6lowpan_6lorhe_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1368 proto_tree_add_item(loRH_tree, hf_6lowpan_6lorhe_hoplimit, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
1369
1370 if (loRHE_length > 1) {
1371 for (int i = 0; i < 16; ++i) {
1372 ipv6.ip6h_src.bytes[i] = tvb_get_guint8(tvb, offset + 3 + i);
1373 }
1374 proto_tree_add_ipv6(loRH_tree, hf_6lowpan_6lorhc_address_src, tvb, offset + 3, 16,
1375 &ipv6.ip6h_src);
1376 }
1377 offset += 2 + loRHE_length;
1378 }
1379 else {
1380 condition -= 1;
1381 }
1382 break; /* case LOWPAN_PATTERN_6LORHE */
1383
1384 case (LOWPAN_PATTERN_6LORHC): /*Critical Routing Header*/
1385 condition = 1 ;
1386 if (loRHE_type == 5){
1387 proto_tree_add_bitmask_list (loRH_tree, tvb, offset, 2, bits_RHC, ENC_NA);
1388 proto_tree_add_item (loRH_tree, hf_6lowpan_6lorhe_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1389 offset += 2;
1390 switch (IK){
1391 case BITS_IK_0:
1392 proto_tree_add_item (loRH_tree, hf_6lowpan_rpl_instance, tvb, offset, 1, ENC_BIG_ENDIAN);
1393 proto_tree_add_item (loRH_tree, hf_6lowpan_sender_rank2, tvb, offset+1, 2, ENC_BIG_ENDIAN);
1394 offset += 3;
1395 break;
1396 case BITS_IK_1:
1397 proto_tree_add_item (loRH_tree, hf_6lowpan_rpl_instance, tvb, offset, 1, ENC_BIG_ENDIAN);
1398 proto_tree_add_item (loRH_tree, hf_6lowpan_sender_rank1, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1399 offset += 2;
1400 break;
1401 case BITS_IK_2:
1402 rpl_instance = 0x00;
1403 proto_tree_add_uint (loRH_tree, hf_6lowpan_rpl_instance, tvb, offset, 0, rpl_instance);
1404 proto_tree_add_item (loRH_tree, hf_6lowpan_sender_rank2, tvb, offset, 2, ENC_BIG_ENDIAN);
1405 offset += 2;
1406 break;
1407 case BITS_IK_3:
1408 rpl_instance = 0x00;
1409 proto_tree_add_uint (loRH_tree, hf_6lowpan_rpl_instance, tvb, offset, 0, rpl_instance);
1410 proto_tree_add_item (loRH_tree, hf_6lowpan_sender_rank1, tvb, offset, 1, ENC_BIG_ENDIAN);
1411 offset +=1;
1412 break;
1413 }
1414 }
1415 else if (loRHE_type <= 4){
1416 memset(&ipv6.ip6h_src, 0, sizeof(ipv6.ip6h_src));
1417 proto_tree_add_uint (loRH_tree, hf_6lowpan_6lorhc_size, tvb, offset, 2, loRH_flags & LOWPAN_PATTERN_6LORHE_LENGTH);
1418 proto_tree_add_uint (loRH_tree, hf_6lowpan_6lorhe_type, tvb, offset, 2, loRHE_type);
1419 offset += 2 ;
1420 switch (loRHE_type){
1421 case IPV6_ADDR_COMPRESSED_1_BYTE: /* IPv6 address compressed to 1 byte */
1422 for (int i=0; i<loRHE_unitnums; i++) {
1423 for (int j = 0; j < 1; j++){
1424 ipv6.ip6h_src.bytes[15-j] = tvb_get_guint8(tvb, offset);
1425 }
1426 proto_tree_add_ipv6(tree, hf_6lowpan_6lorhc_address_hop0, tvb, offset, 1, &ipv6.ip6h_src);
1427 offset +=1;
1428 }
1429 break;
1430
1431 case IPV6_ADDR_COMPRESSED_2_BYTE: /* IPv6 address compressed to 2 bytes */
1432 for (int i=0; i<loRHE_unitnums; i++) {
1433 for (int j = 0; j < 2; ++j){
1434 ipv6.ip6h_src.bytes[15-1+j] = tvb_get_guint8(tvb, offset);
1435 offset +=1;
1436 }
1437 proto_tree_add_ipv6(tree, hf_6lowpan_6lorhc_address_hop1, tvb, offset - 2, 2, &ipv6.ip6h_src);
1438 }
1439 break;
1440
1441 case IPV6_ADDR_COMPRESSED_4_BYTE: /* IPv6 address compressed to 4 bytes */
1442 for (int i=0; i<loRHE_unitnums; i++) {
1443 for (int j = 0; j < 4; j++){
1444 ipv6.ip6h_src.bytes[15-3+j] = tvb_get_guint8(tvb, offset);
1445 offset +=1;
1446 }
1447 proto_tree_add_ipv6(tree, hf_6lowpan_6lorhc_address_hop2, tvb, offset - 4, 4, &ipv6.ip6h_src);
1448 }
1449 break;
1450
1451 case IPV6_ADDR_COMPRESSED_8_BYTE: /* IPv6 address compressed to 8 bytes */
1452 for (int i=0; i<loRHE_unitnums; i++) {
1453 for (int j = 0; j < 8; j++){
1454 ipv6.ip6h_src.bytes[15-7+j] = tvb_get_guint8(tvb, offset);
1455 offset +=1;
1456 }
1457 proto_tree_add_ipv6(tree, hf_6lowpan_6lorhc_address_hop3, tvb, offset - 8, 8, &ipv6.ip6h_src);
1458 }
1459 break;
1460 case IPV6_ADDR_COMPRESSED_16_BYTE: /* IPv6 address compressed to 16 bytes */
1461 for (int i=0; i<loRHE_unitnums; i++) {
1462 for (int j = 0; j < 16; j++){
1463 ipv6.ip6h_src.bytes[j] = tvb_get_guint8(tvb, offset);
1464 offset +=1;
1465 }
1466 proto_tree_add_ipv6(tree, hf_6lowpan_6lorhc_address_hop4, tvb, offset - 16, 16, &ipv6.ip6h_src);
1467 }
1468 break; /**/
1469 } /* switch loRHE_type */
1470 } /* else if (loRHE_type <= 4) */
1471 else {
1472 condition -= 1;
1473 }
1474 break; /* case LOWPAN_PATTERN_6LORHC */
1475
1476 default:
1477 condition -= 1 ;
1478 break;
1479 } /* switch loRHE_class */
1480 loRH_flags = tvb_get_ntohs(tvb, offset);
1481 loRHE_class = (loRH_flags & LOWPAN_PATTERN_6LORHE_CLASS) >> 13;
1482
1483 if ((loRHE_class) != LOWPAN_PATTERN_6LORHE){
1484 if ((loRHE_class) != LOWPAN_PATTERN_6LORHC){
1485 condition -= 1;
1486 }
1487 }
1488 } /* while (condition > 0)*/
1489 }
1490 return tvb_new_subset_remaining(tvb, offset);
1491 } /* dissect_6lowpan_6loRH */
1492
1493 /*FUNCTION:------------------------------------------------------
1494 * NAME
1495 * dissect_6lowpan_ipv6
1496 * DESCRIPTION
1497 * Dissector routine for an uncompressed IPv6 header type.
1498 *
1499 * This is one of the final encapsulation types, and will
1500 * returned an uncompressed IPv6 datagram (or fragment
1501 * thereof).
1502 * PARAMETERS
1503 * tvb ; packet buffer.
1504 * pinfo ; packet info.
1505 * tree ; 6LoWPAN display tree.
1506 * offset ; offset to the start of the header.
1507 * RETURNS
1508 * tvbuff_t * ; The remaining payload to be parsed.
1509 *---------------------------------------------------------------
1510 */
1511 static tvbuff_t *
dissect_6lowpan_ipv6(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree)1512 dissect_6lowpan_ipv6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1513 {
1514 /* Get and display the pattern. */
1515 proto_tree_add_bits_item(tree, hf_6lowpan_pattern,
1516 tvb, 0, LOWPAN_PATTERN_IPV6_BITS, ENC_BIG_ENDIAN);
1517
1518 /* Create a tvbuff subset for the ipv6 datagram. */
1519 return tvb_new_subset_remaining(tvb, 1);
1520 } /* dissect_6lowpan_ipv6 */
1521
1522 /*FUNCTION:------------------------------------------------------
1523 * NAME
1524 * dissect_6lowpan_hc1
1525 * DESCRIPTION
1526 * Dissector routine for a 6LoWPAN HC1 header.
1527 * PARAMETERS
1528 * tvb ; packet buffer.
1529 * pinfo ; packet info.
1530 * tree ; 6LoWPAN display tree.
1531 * dgram_size ; Datagram size (or <0 if not fragmented).
1532 * siid ; Source Interface ID.
1533 * diid ; Destination Interface ID.
1534 * RETURNS
1535 * tvbuff_t * ; The remaining payload to be parsed.
1536 *---------------------------------------------------------------
1537 */
1538 static tvbuff_t *
dissect_6lowpan_hc1(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,gint dgram_size,const guint8 * siid,const guint8 * diid)1539 dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size, const guint8 *siid, const guint8 *diid)
1540 {
1541 gint offset = 0;
1542 gint bit_offset;
1543 int i;
1544 guint8 hc1_encoding;
1545 guint8 hc_udp_encoding = 0;
1546 guint8 next_header;
1547 proto_tree * hc_tree;
1548 proto_item * hc_item;
1549 tvbuff_t * ipv6_tvb;
1550 /* IPv6 header. */
1551 guint8 ipv6_class;
1552 guint32 ipv6_flow;
1553 struct ws_ip6_hdr ipv6;
1554 struct lowpan_nhdr *nhdr_list;
1555 static int * const hc1_encodings[] = {
1556 &hf_6lowpan_hc1_source_prefix,
1557 &hf_6lowpan_hc1_source_ifc,
1558 &hf_6lowpan_hc1_dest_prefix,
1559 &hf_6lowpan_hc1_dest_ifc,
1560 &hf_6lowpan_hc1_class,
1561 &hf_6lowpan_hc1_next,
1562 &hf_6lowpan_hc1_more,
1563 NULL
1564 };
1565 static int * const hc2_encodings[] = {
1566 &hf_6lowpan_hc2_udp_src,
1567 &hf_6lowpan_hc2_udp_dst,
1568 &hf_6lowpan_hc2_udp_len,
1569 NULL
1570 };
1571
1572 /*=====================================================
1573 * Parse HC Encoding Flags
1574 *=====================================================
1575 */
1576 /* Create a tree for the HC1 Header. */
1577 hc_tree = proto_tree_add_subtree(tree, tvb, 0, 2, ett_6lowpan_hc1, &hc_item, "HC1 Encoding");
1578
1579 /* Get and display the pattern. */
1580 proto_tree_add_bits_item(hc_tree, hf_6lowpan_pattern, tvb, 0, LOWPAN_PATTERN_HC1_BITS, ENC_BIG_ENDIAN);
1581 offset += 1;
1582
1583 /* Get and display the HC1 encoding bits. */
1584 hc1_encoding = tvb_get_guint8(tvb, offset);
1585 next_header = ((hc1_encoding & LOWPAN_HC1_NEXT) >> 1);
1586 proto_tree_add_bitmask(hc_tree, tvb, offset, hf_6lowpan_hc1_encoding,
1587 ett_6lowpan_hc1_encoding, hc1_encodings, ENC_NA);
1588 offset += 1;
1589
1590 /* Get and display the HC2 encoding bits, if present. */
1591 if (hc1_encoding & LOWPAN_HC1_MORE) {
1592 if (next_header == LOWPAN_HC1_NEXT_UDP) {
1593 hc_udp_encoding = tvb_get_guint8(tvb, offset);
1594 proto_tree_add_bitmask(tree, tvb, offset, hf_6lowpan_hc2_udp_encoding,
1595 ett_6lowpan_hc2_udp, hc2_encodings, ENC_NA);
1596 offset += 1;
1597 }
1598 else {
1599 /* HC1 states there are more bits, but an illegal next header was defined. */
1600 expert_add_info(pinfo, hc_item, &ei_6lowpan_hc1_more_bits);
1601 return NULL;
1602 }
1603 }
1604
1605 /*=====================================================
1606 * Parse Uncompressed IPv6 Header Fields
1607 *=====================================================
1608 */
1609 /*
1610 * And now all hell breaks loose. After the header encoding fields, we are
1611 * left with an assortment of optional fields from the IPv6 header,
1612 * depending on which fields are present or not, the headers may not be
1613 * aligned to an octet boundary.
1614 *
1615 * From now on we have to parse the uncompressed fields relative to a bit
1616 * offset.
1617 */
1618 bit_offset = offset << 3;
1619
1620 /* Parse hop limit */
1621 ipv6.ip6h_hlim = tvb_get_bits8(tvb, bit_offset, LOWPAN_IPV6_HOP_LIMIT_BITS);
1622 proto_tree_add_uint(tree, hf_6lowpan_hop_limit, tvb, bit_offset>>3,
1623 BITS_TO_BYTE_LEN(bit_offset, LOWPAN_IPV6_HOP_LIMIT_BITS), ipv6.ip6h_hlim);
1624 bit_offset += LOWPAN_IPV6_HOP_LIMIT_BITS;
1625
1626 /*=====================================================
1627 * Parse/Decompress IPv6 Source Address
1628 *=====================================================
1629 */
1630 offset = bit_offset;
1631 if (!(hc1_encoding & LOWPAN_HC1_SOURCE_PREFIX)) {
1632 for (i=0; i<8; i++, bit_offset += 8) {
1633 ipv6.ip6h_src.bytes[i] = tvb_get_bits8(tvb, bit_offset, 8);
1634 }
1635 }
1636 else {
1637 memcpy(ipv6.ip6h_src.bytes, lowpan_llprefix, sizeof(lowpan_llprefix));
1638 }
1639 if (!(hc1_encoding & LOWPAN_HC1_SOURCE_IFC)) {
1640 for (i=8; i<16; i++, bit_offset += 8) {
1641 ipv6.ip6h_src.bytes[i] = tvb_get_bits8(tvb, bit_offset, 8);
1642 }
1643 }
1644 else {
1645 memcpy(&ipv6.ip6h_src.bytes[sizeof(ipv6.ip6h_src) - LOWPAN_IFC_ID_LEN], siid, LOWPAN_IFC_ID_LEN);
1646 }
1647 /* Display the source address. */
1648 proto_tree_add_ipv6(tree, hf_6lowpan_source, tvb, offset>>3,
1649 BITS_TO_BYTE_LEN(offset, (bit_offset-offset)), &ipv6.ip6h_src);
1650
1651 /*
1652 * Do not set the address columns until after defragmentation, since we have
1653 * to do decompression before reassembly, and changing the address will cause
1654 * wireshark to think that the middle fragments came from another device.
1655 */
1656
1657 /*=====================================================
1658 * Parse/Decompress IPv6 Destination Address
1659 *=====================================================
1660 */
1661 offset = bit_offset;
1662 if (!(hc1_encoding & LOWPAN_HC1_DEST_PREFIX)) {
1663 for (i=0; i<8; i++, bit_offset += 8) {
1664 ipv6.ip6h_dst.bytes[i] = tvb_get_bits8(tvb, bit_offset, 8);
1665 }
1666 }
1667 else {
1668 memcpy(ipv6.ip6h_dst.bytes, lowpan_llprefix, sizeof(lowpan_llprefix));
1669 }
1670 if (!(hc1_encoding & LOWPAN_HC1_DEST_IFC)) {
1671 for (i=8; i<16; i++, bit_offset += 8) {
1672 ipv6.ip6h_dst.bytes[i] = tvb_get_bits8(tvb, bit_offset, 8);
1673 }
1674 }
1675 else {
1676 memcpy(&ipv6.ip6h_dst.bytes[sizeof(ipv6.ip6h_dst) - LOWPAN_IFC_ID_LEN], diid, LOWPAN_IFC_ID_LEN);
1677 }
1678 /* Display the destination address. */
1679 proto_tree_add_ipv6(tree, hf_6lowpan_dest, tvb, offset>>3,
1680 BITS_TO_BYTE_LEN(offset, (bit_offset-offset)), &ipv6.ip6h_dst);
1681
1682 /*
1683 * Do not set the address columns until after defragmentation, since we have
1684 * to do decompression before reassembly, and changing the address will cause
1685 * wireshark to think that the middle fragments came from another device.
1686 */
1687
1688 /* Parse the traffic class and flow label. */
1689 ipv6_class = 0;
1690 ipv6_flow = 0;
1691 if (!(hc1_encoding & LOWPAN_HC1_TRAFFIC_CLASS)) {
1692 /* Parse the traffic class. */
1693 ipv6_class = tvb_get_bits8(tvb, bit_offset, LOWPAN_IPV6_TRAFFIC_CLASS_BITS);
1694 proto_tree_add_uint(tree, hf_6lowpan_traffic_class, tvb, bit_offset>>3,
1695 BITS_TO_BYTE_LEN(bit_offset, LOWPAN_IPV6_TRAFFIC_CLASS_BITS), ipv6_class);
1696 bit_offset += LOWPAN_IPV6_TRAFFIC_CLASS_BITS;
1697
1698 /* Parse the flow label. */
1699 ipv6_flow = tvb_get_bits32(tvb, bit_offset, LOWPAN_IPV6_FLOW_LABEL_BITS, ENC_BIG_ENDIAN);
1700 proto_tree_add_uint(tree, hf_6lowpan_flow_label, tvb, bit_offset>>3,
1701 BITS_TO_BYTE_LEN(bit_offset, LOWPAN_IPV6_FLOW_LABEL_BITS), ipv6_flow);
1702 bit_offset += LOWPAN_IPV6_FLOW_LABEL_BITS;
1703 }
1704
1705 /* Rebuild the IPv6 flow label, traffic class and version fields. */
1706 ipv6.ip6h_vc_flow = ipv6_flow;
1707 ipv6.ip6h_vc_flow |= ((guint32)ipv6_class << LOWPAN_IPV6_FLOW_LABEL_BITS);
1708 ipv6.ip6h_vc_flow |= ((guint32)0x6 << (LOWPAN_IPV6_TRAFFIC_CLASS_BITS + LOWPAN_IPV6_FLOW_LABEL_BITS));
1709 ipv6.ip6h_vc_flow = g_ntohl(ipv6.ip6h_vc_flow);
1710
1711 /* Parse the IPv6 next header field. */
1712 if (next_header == LOWPAN_HC1_NEXT_UDP) {
1713 ipv6.ip6h_nxt = IP_PROTO_UDP;
1714 }
1715 else if (next_header == LOWPAN_HC1_NEXT_ICMP) {
1716 ipv6.ip6h_nxt = IP_PROTO_ICMPV6;
1717 }
1718 else if (next_header == LOWPAN_HC1_NEXT_TCP) {
1719 ipv6.ip6h_nxt = IP_PROTO_TCP;
1720 }
1721 else {
1722 /* Parse the next header field. */
1723 ipv6.ip6h_nxt = tvb_get_bits8(tvb, bit_offset, LOWPAN_IPV6_NEXT_HEADER_BITS);
1724 proto_tree_add_uint_format_value(tree, hf_6lowpan_next_header, tvb, bit_offset>>3,
1725 BITS_TO_BYTE_LEN(bit_offset, LOWPAN_IPV6_NEXT_HEADER_BITS), ipv6.ip6h_nxt,
1726 "%s (0x%02x)", ipprotostr(ipv6.ip6h_nxt), ipv6.ip6h_nxt);
1727 bit_offset += LOWPAN_IPV6_NEXT_HEADER_BITS;
1728 }
1729
1730 /*=====================================================
1731 * Parse and Reconstruct the UDP Header
1732 *=====================================================
1733 */
1734 if ((hc1_encoding & LOWPAN_HC1_MORE) && (next_header == LOWPAN_HC1_NEXT_UDP)) {
1735 struct udp_hdr udp;
1736 gint length;
1737
1738 /* Parse the source port. */
1739 offset = bit_offset;
1740 if (hc_udp_encoding & LOWPAN_HC2_UDP_SRCPORT) {
1741 udp.src_port = tvb_get_bits8(tvb, bit_offset, LOWPAN_UDP_PORT_COMPRESSED_BITS) + LOWPAN_PORT_12BIT_OFFSET;
1742 bit_offset += LOWPAN_UDP_PORT_COMPRESSED_BITS;
1743 }
1744 else {
1745 udp.src_port = tvb_get_bits16(tvb, bit_offset, LOWPAN_UDP_PORT_BITS, ENC_BIG_ENDIAN);
1746 bit_offset += LOWPAN_UDP_PORT_BITS;
1747 }
1748 proto_tree_add_uint(tree, hf_6lowpan_udp_src, tvb, offset>>3,
1749 BITS_TO_BYTE_LEN(offset, (bit_offset-offset)), udp.src_port);
1750 udp.src_port = g_ntohs(udp.src_port);
1751
1752 /* Parse the destination port. */
1753 offset = bit_offset;
1754 if (hc_udp_encoding & LOWPAN_HC2_UDP_DSTPORT) {
1755 udp.dst_port = tvb_get_bits8(tvb, bit_offset, LOWPAN_UDP_PORT_COMPRESSED_BITS) + LOWPAN_PORT_12BIT_OFFSET;
1756 bit_offset += LOWPAN_UDP_PORT_COMPRESSED_BITS;
1757 }
1758 else {
1759 udp.dst_port = tvb_get_bits16(tvb, bit_offset, LOWPAN_UDP_PORT_BITS, ENC_BIG_ENDIAN);
1760 bit_offset += LOWPAN_UDP_PORT_BITS;
1761 }
1762 proto_tree_add_uint(tree, hf_6lowpan_udp_dst, tvb, offset>>3,
1763 BITS_TO_BYTE_LEN(offset, (bit_offset-offset)), udp.dst_port);
1764 udp.dst_port = g_ntohs(udp.dst_port);
1765
1766 /* Parse the length, if present. */
1767 if (!(hc_udp_encoding & LOWPAN_HC2_UDP_LENGTH)) {
1768 udp.length = tvb_get_bits16(tvb, bit_offset, LOWPAN_UDP_LENGTH_BITS, ENC_BIG_ENDIAN);
1769 proto_tree_add_uint(tree, hf_6lowpan_udp_len, tvb, bit_offset>>3,
1770 BITS_TO_BYTE_LEN(bit_offset, LOWPAN_UDP_LENGTH_BITS), udp.length);
1771
1772 bit_offset += LOWPAN_UDP_LENGTH_BITS;
1773 }
1774 /* Compute the length from the fragmentation headers. */
1775 else if (dgram_size >= 0) {
1776 if (dgram_size < IPv6_HDR_SIZE) {
1777 /* Datagram size is too small */
1778 return NULL;
1779 }
1780 udp.length = dgram_size - IPv6_HDR_SIZE;
1781 }
1782 /* Compute the length from the tvbuff size. */
1783 else {
1784 udp.length = tvb_reported_length(tvb);
1785 udp.length -= BITS_TO_BYTE_LEN(0, bit_offset + LOWPAN_UDP_CHECKSUM_BITS);
1786 udp.length += (int)sizeof(struct udp_hdr);
1787 }
1788 udp.length = g_ntohs(udp.length);
1789
1790 /* Parse the checksum. */
1791 udp.checksum = tvb_get_bits16(tvb, bit_offset, LOWPAN_UDP_CHECKSUM_BITS, ENC_BIG_ENDIAN);
1792 proto_tree_add_uint(tree, hf_6lowpan_udp_checksum, tvb, bit_offset>>3,
1793 BITS_TO_BYTE_LEN(bit_offset, LOWPAN_UDP_CHECKSUM_BITS), udp.checksum);
1794 bit_offset += LOWPAN_UDP_CHECKSUM_BITS;
1795 udp.checksum = g_ntohs(udp.checksum);
1796
1797 /* Construct the next header for the UDP datagram. */
1798 offset = BITS_TO_BYTE_LEN(0, bit_offset);
1799 length = tvb_captured_length_remaining(tvb, offset);
1800 nhdr_list = (struct lowpan_nhdr *)wmem_alloc(pinfo->pool, sizeof(struct lowpan_nhdr) + sizeof(struct udp_hdr) + length);
1801 nhdr_list->next = NULL;
1802 nhdr_list->proto = IP_PROTO_UDP;
1803 nhdr_list->length = length + (int)sizeof(struct udp_hdr);
1804 nhdr_list->reported = g_ntohs(udp.length);
1805
1806 /* Copy the UDP header into the buffer. */
1807 memcpy(LOWPAN_NHDR_DATA(nhdr_list), &udp, sizeof(struct udp_hdr));
1808 tvb_memcpy(tvb, LOWPAN_NHDR_DATA(nhdr_list) + sizeof(struct udp_hdr), offset, length);
1809 }
1810 /*=====================================================
1811 * Reconstruct the IPv6 Packet
1812 *=====================================================
1813 */
1814 else {
1815 gint length;
1816 offset = BITS_TO_BYTE_LEN(0, bit_offset);
1817 length = tvb_captured_length_remaining(tvb, offset);
1818 nhdr_list = (struct lowpan_nhdr *)wmem_alloc(pinfo->pool, sizeof(struct lowpan_nhdr) + length);
1819 nhdr_list->next = NULL;
1820 nhdr_list->proto = ipv6.ip6h_nxt;
1821 nhdr_list->length = length;
1822 if (dgram_size < 0) {
1823 nhdr_list->reported = tvb_reported_length_remaining(tvb, offset);
1824 }
1825 else {
1826 nhdr_list->reported = dgram_size - IPv6_HDR_SIZE;
1827 }
1828 tvb_memcpy(tvb, LOWPAN_NHDR_DATA(nhdr_list), offset, nhdr_list->length);
1829 }
1830
1831 /* Link the reassembled tvbuff together. */
1832 ipv6_tvb = lowpan_reassemble_ipv6(tvb, pinfo, &ipv6, nhdr_list);
1833
1834 /* Add a new data source for it. */
1835 add_new_data_source(pinfo, ipv6_tvb, "Decompressed 6LoWPAN HC1");
1836
1837 return ipv6_tvb;
1838 } /* dissect_6lowpan_hc1 */
1839
1840 /*FUNCTION:------------------------------------------------------
1841 * NAME
1842 * dissect_6lowpan_iphc
1843 * DESCRIPTION
1844 * Dissector routine for a 6LoWPAN IPHC header.
1845 *
1846 * This header is still in the draft phase, but is expected
1847 * to replace HC1.
1848 *
1849 * See draft-ietf-6lowpan-hc-15.txt
1850 * PARAMETERS
1851 * tvb ; packet buffer.
1852 * pinfo ; packet info.
1853 * tree ; 6LoWPAN display tree.
1854 * dgram_size ; Datagram size (or <0 if not fragmented).
1855 * siid ; Source Interface ID.
1856 * diid ; Destination Interface ID.
1857 * RETURNS
1858 * tvbuff_t * ; The remaining payload to be parsed or NULL on error.
1859 *---------------------------------------------------------------
1860 */
1861 static tvbuff_t *
dissect_6lowpan_iphc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,gint dgram_size,const guint8 * siid,const guint8 * diid)1862 dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size, const guint8 *siid, const guint8 *diid)
1863 {
1864 ieee802154_hints_t *hints;
1865 guint16 hint_panid;
1866 gint offset = 0;
1867 gint length = 0;
1868 proto_tree * iphc_tree;
1869 proto_item * ti_dam = NULL;
1870 proto_item * ti;
1871 /* IPHC header fields. */
1872 guint16 iphc_flags;
1873 guint8 iphc_traffic;
1874 guint8 iphc_hop_limit;
1875 guint8 iphc_src_mode;
1876 guint8 iphc_dst_mode;
1877 guint8 iphc_ctx = 0;
1878 /* Contexts to use for address decompression. */
1879 gint iphc_sci = LOWPAN_CONTEXT_DEFAULT;
1880 gint iphc_dci = LOWPAN_CONTEXT_DEFAULT;
1881 lowpan_context_data *sctx;
1882 lowpan_context_data *dctx;
1883 /* IPv6 header */
1884 guint8 ipv6_dscp = 0;
1885 guint8 ipv6_ecn = 0;
1886 guint32 ipv6_flowlabel = 0;
1887 struct ws_ip6_hdr ipv6;
1888 tvbuff_t * ipv6_tvb;
1889 /* Next header chain */
1890 struct lowpan_nhdr *nhdr_list;
1891
1892 /* Lookup the IEEE 802.15.4 addressing hints. */
1893 hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
1894 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
1895 hint_panid = (hints) ? (hints->src_pan) : (IEEE802154_BCAST_PAN);
1896
1897 /* Create a tree for the IPHC header. */
1898 iphc_tree = proto_tree_add_subtree(tree, tvb, 0, 2, ett_6lowpan_iphc, NULL, "IPHC Header");
1899
1900 /* Display the pattern. */
1901 proto_tree_add_bits_item(iphc_tree, hf_6lowpan_pattern, tvb, 0, LOWPAN_PATTERN_IPHC_BITS, ENC_BIG_ENDIAN);
1902
1903 /*=====================================================
1904 * Parse IPHC Header flags.
1905 *=====================================================
1906 */
1907 iphc_flags = tvb_get_ntohs(tvb, offset);
1908 iphc_traffic = (iphc_flags & LOWPAN_IPHC_FLAG_FLOW) >> LOWPAN_IPHC_FLAG_OFFSET_FLOW;
1909 iphc_hop_limit = (iphc_flags & LOWPAN_IPHC_FLAG_HLIM) >> LOWPAN_IPHC_FLAG_OFFSET_HLIM;
1910 iphc_src_mode = (iphc_flags & LOWPAN_IPHC_FLAG_SRC_MODE) >> LOWPAN_IPHC_FLAG_OFFSET_SRC_MODE;
1911 iphc_dst_mode = (iphc_flags & LOWPAN_IPHC_FLAG_DST_MODE) >> LOWPAN_IPHC_FLAG_OFFSET_DST_MODE;
1912 if (tree) {
1913 const value_string *am_vs;
1914 proto_tree_add_uint (iphc_tree, hf_6lowpan_iphc_flag_tf, tvb, offset, 2, iphc_flags & LOWPAN_IPHC_FLAG_FLOW);
1915 proto_tree_add_boolean (iphc_tree, hf_6lowpan_iphc_flag_nhdr, tvb, offset, 2, iphc_flags & LOWPAN_IPHC_FLAG_NHDR);
1916 proto_tree_add_uint (iphc_tree, hf_6lowpan_iphc_flag_hlim, tvb, offset, 2, iphc_flags & LOWPAN_IPHC_FLAG_HLIM);
1917 proto_tree_add_boolean (iphc_tree, hf_6lowpan_iphc_flag_cid, tvb, offset, 2, iphc_flags & LOWPAN_IPHC_FLAG_CONTEXT_ID);
1918 proto_tree_add_boolean (iphc_tree, hf_6lowpan_iphc_flag_sac, tvb, offset, 2, iphc_flags & LOWPAN_IPHC_FLAG_SRC_COMP);
1919 am_vs = iphc_flags & LOWPAN_IPHC_FLAG_SRC_COMP ? lowpan_iphc_saddr_stateful_modes : lowpan_iphc_addr_modes;
1920 proto_tree_add_uint_format_value(iphc_tree, hf_6lowpan_iphc_flag_sam, tvb, offset, 2, iphc_flags & LOWPAN_IPHC_FLAG_SRC_MODE,
1921 "%s (0x%04x)", val_to_str_const(iphc_src_mode, am_vs, "Reserved"), iphc_src_mode);
1922 proto_tree_add_boolean (iphc_tree, hf_6lowpan_iphc_flag_mcast, tvb, offset, 2, iphc_flags & LOWPAN_IPHC_FLAG_MCAST_COMP);
1923 proto_tree_add_boolean (iphc_tree, hf_6lowpan_iphc_flag_dac, tvb, offset, 2, iphc_flags & LOWPAN_IPHC_FLAG_DST_COMP);
1924 /* Destination address mode changes meanings depending on multicast compression. */
1925 if (iphc_flags & LOWPAN_IPHC_FLAG_MCAST_COMP) {
1926 if (iphc_flags & LOWPAN_IPHC_FLAG_DST_COMP) {
1927 am_vs = lowpan_iphc_mcast_stateful_modes;
1928 } else {
1929 am_vs = lowpan_iphc_mcast_modes;
1930 }
1931 } else {
1932 if (iphc_flags & LOWPAN_IPHC_FLAG_DST_COMP) {
1933 am_vs = lowpan_iphc_daddr_stateful_modes;
1934 } else {
1935 am_vs = lowpan_iphc_addr_modes;
1936 }
1937 }
1938 ti_dam = proto_tree_add_uint_format_value(iphc_tree, hf_6lowpan_iphc_flag_dam, tvb, offset, 2,
1939 iphc_flags & LOWPAN_IPHC_FLAG_DST_MODE, "%s (0x%04x)", val_to_str_const(iphc_dst_mode, am_vs, "Reserved"), iphc_dst_mode);
1940 }
1941 offset += 2;
1942
1943 /* Display the context identifier extension, if present. */
1944 if (iphc_flags & LOWPAN_IPHC_FLAG_CONTEXT_ID) {
1945 iphc_ctx = tvb_get_guint8(tvb, offset);
1946 iphc_sci = (iphc_ctx & LOWPAN_IPHC_FLAG_SCI) >> LOWPAN_IPHC_FLAG_OFFSET_SCI;
1947 iphc_dci = (iphc_ctx & LOWPAN_IPHC_FLAG_DCI) >> LOWPAN_IPHC_FLAG_OFFSET_DCI;
1948 proto_tree_add_uint(iphc_tree, hf_6lowpan_iphc_sci, tvb, offset, 1, iphc_ctx & LOWPAN_IPHC_FLAG_SCI);
1949 proto_tree_add_uint(iphc_tree, hf_6lowpan_iphc_dci, tvb, offset, 1, iphc_ctx & LOWPAN_IPHC_FLAG_DCI);
1950 offset += 1;
1951 }
1952 /* Use link-local contexts if stateless. */
1953 if (!(iphc_flags & LOWPAN_IPHC_FLAG_SRC_COMP)) {
1954 iphc_sci = LOWPAN_CONTEXT_LINK_LOCAL;
1955 }
1956 if (!(iphc_flags & LOWPAN_IPHC_FLAG_DST_COMP)) {
1957 iphc_dci = LOWPAN_CONTEXT_LINK_LOCAL;
1958 }
1959 /* Lookup the contexts. */
1960 /*
1961 * Don't display their origin until after we decompress the address in case
1962 * the address modes indicate that we should use a different context.
1963 */
1964 sctx = lowpan_context_find(iphc_sci, hint_panid);
1965 dctx = lowpan_context_find(iphc_dci, hint_panid);
1966
1967 /*=====================================================
1968 * Parse Traffic Class and Flow Label
1969 *=====================================================
1970 */
1971 offset <<= 3;
1972 /* Parse the ECN field. */
1973 if (iphc_traffic != LOWPAN_IPHC_FLOW_COMPRESSED) {
1974 ipv6_ecn = tvb_get_bits8(tvb, offset, LOWPAN_IPHC_ECN_BITS);
1975 proto_tree_add_bits_item(tree, hf_6lowpan_ecn, tvb, offset, LOWPAN_IPHC_ECN_BITS, ENC_BIG_ENDIAN);
1976 offset += LOWPAN_IPHC_ECN_BITS;
1977 }
1978 /* Parse the DSCP field. */
1979 if ((iphc_traffic == LOWPAN_IPHC_FLOW_CLASS_LABEL) || (iphc_traffic == LOWPAN_IPHC_FLOW_CLASS)) {
1980 ipv6_dscp = tvb_get_bits8(tvb, offset, LOWPAN_IPHC_DSCP_BITS);
1981 proto_tree_add_bits_item(tree, hf_6lowpan_dscp, tvb, offset, LOWPAN_IPHC_DSCP_BITS, LOWPAN_IPHC_DSCP_BITS);
1982 offset += LOWPAN_IPHC_DSCP_BITS;
1983 }
1984 /* Add a generated entry to show the IPv6 traffic class byte. */
1985 if (ipv6_dscp || ipv6_ecn) {
1986 proto_item *tclass_item;
1987 tclass_item = proto_tree_add_uint(tree, hf_6lowpan_traffic_class, tvb, 0, 0,
1988 (ipv6_dscp << LOWPAN_IPHC_ECN_BITS) | ipv6_ecn);
1989 proto_item_set_generated(tclass_item);
1990 }
1991
1992 /* Parse the flow label. */
1993 if ((iphc_traffic == LOWPAN_IPHC_FLOW_CLASS_LABEL) || (iphc_traffic == LOWPAN_IPHC_FLOW_ECN_LABEL)) {
1994 /* Pad to 4-bits past the start of the byte. */
1995 guint pad_bits = ((4 - offset) & 0x7);
1996 if (pad_bits) {
1997 proto_tree_add_bits_item(tree, hf_6lowpan_padding, tvb, offset, pad_bits, ENC_BIG_ENDIAN);
1998 }
1999 offset += pad_bits;
2000 ipv6_flowlabel = tvb_get_bits32(tvb, offset, LOWPAN_IPHC_LABEL_BITS, ENC_BIG_ENDIAN);
2001 proto_tree_add_bits_item(tree, hf_6lowpan_flow_label, tvb, offset, LOWPAN_IPHC_LABEL_BITS, ENC_BIG_ENDIAN);
2002 offset += LOWPAN_IPHC_LABEL_BITS;
2003 }
2004
2005 /* Rebuild the IPv6 flow label, traffic class and version fields. */
2006 ipv6.ip6h_vc_flow = ipv6_flowlabel;
2007 ipv6.ip6h_vc_flow |= ((guint32)ipv6_ecn << LOWPAN_IPV6_FLOW_LABEL_BITS);
2008 ipv6.ip6h_vc_flow |= ((guint32)ipv6_dscp << (LOWPAN_IPHC_ECN_BITS + LOWPAN_IPV6_FLOW_LABEL_BITS));
2009 ipv6.ip6h_vc_flow |= ((guint32)0x6 << (LOWPAN_IPV6_TRAFFIC_CLASS_BITS + LOWPAN_IPV6_FLOW_LABEL_BITS));
2010 ipv6.ip6h_vc_flow = g_ntohl(ipv6.ip6h_vc_flow);
2011
2012 /* Convert back to byte offsets. */
2013 offset >>= 3;
2014
2015 /*=====================================================
2016 * Parse Next Header and Hop Limit
2017 *=====================================================
2018 */
2019 /* Get the next header field, if present. */
2020 if (!(iphc_flags & LOWPAN_IPHC_FLAG_NHDR)) {
2021 ipv6.ip6h_nxt = tvb_get_guint8(tvb, offset);
2022 proto_tree_add_uint_format_value(tree, hf_6lowpan_next_header, tvb, offset, 1, ipv6.ip6h_nxt,
2023 "%s (0x%02x)", ipprotostr(ipv6.ip6h_nxt), ipv6.ip6h_nxt);
2024 offset += 1;
2025 }
2026
2027 /* Get the hop limit field, if present. */
2028 if (iphc_hop_limit == LOWPAN_IPHC_HLIM_1) {
2029 ipv6.ip6h_hlim = 1;
2030 }
2031 else if (iphc_hop_limit == LOWPAN_IPHC_HLIM_64) {
2032 ipv6.ip6h_hlim = 64;
2033 }
2034 else if (iphc_hop_limit == LOWPAN_IPHC_HLIM_255) {
2035 ipv6.ip6h_hlim = 255;
2036 }
2037 else {
2038 ipv6.ip6h_hlim = tvb_get_guint8(tvb, offset);
2039 proto_tree_add_uint(tree, hf_6lowpan_hop_limit, tvb, offset, 1, ipv6.ip6h_hlim);
2040 offset += 1;
2041 }
2042
2043 /*=====================================================
2044 * Parse and decompress the source address.
2045 *=====================================================
2046 */
2047 length = 0;
2048 memset(&ipv6.ip6h_src, 0, sizeof(ipv6.ip6h_src));
2049 /* (SAC=1 && SAM=00) -> the unspecified address (::). */
2050 if ((iphc_flags & LOWPAN_IPHC_FLAG_SRC_COMP) && (iphc_src_mode == LOWPAN_IPHC_ADDR_SRC_UNSPEC)) {
2051 sctx = &lowpan_context_default;
2052 }
2053 /* The IID is derived from the encapsulating layer. */
2054 else if (iphc_src_mode == LOWPAN_IPHC_ADDR_COMPRESSED) {
2055 memcpy(&ipv6.ip6h_src.bytes[sizeof(ipv6.ip6h_src) - LOWPAN_IFC_ID_LEN], siid, LOWPAN_IFC_ID_LEN);
2056 }
2057 /* Full Address inline. */
2058 else if (iphc_src_mode == LOWPAN_IPHC_ADDR_FULL_INLINE) {
2059 if (!(iphc_flags & LOWPAN_IPHC_FLAG_SRC_COMP)) sctx = &lowpan_context_default;
2060 length = (int)sizeof(ipv6.ip6h_src);
2061 tvb_memcpy(tvb, &ipv6.ip6h_src, offset, length);
2062 }
2063 /* 64-bits inline. */
2064 else if (iphc_src_mode == LOWPAN_IPHC_ADDR_64BIT_INLINE) {
2065 length = 8;
2066 tvb_memcpy(tvb, &ipv6.ip6h_src.bytes[sizeof(ipv6.ip6h_src) - length], offset, length);
2067 }
2068 /* 16-bits inline. */
2069 else if (iphc_src_mode == LOWPAN_IPHC_ADDR_16BIT_INLINE) {
2070 length = 2;
2071 /* Format becomes ff:fe00:xxxx */
2072 ipv6.ip6h_src.bytes[11] = 0xff;
2073 ipv6.ip6h_src.bytes[12] = 0xfe;
2074 tvb_memcpy(tvb, &ipv6.ip6h_src.bytes[sizeof(ipv6.ip6h_src) - length], offset, length);
2075
2076 }
2077 /* Copy the context bits. */
2078 lowpan_pfxcpy(&ipv6.ip6h_src, &sctx->prefix, sctx->plen);
2079 /* Update the IID of the encapsulating layer. */
2080 siid = &ipv6.ip6h_src.bytes[sizeof(ipv6.ip6h_src) - LOWPAN_IFC_ID_LEN];
2081
2082 /* Display the source IPv6 address. */
2083 ti = proto_tree_add_ipv6(tree, hf_6lowpan_source, tvb, offset, length, &ipv6.ip6h_src);
2084 if (length == 0) {
2085 proto_item_set_generated(ti);
2086 }
2087 if (ipv6_summary_in_tree) {
2088 address src_addr = ADDRESS_INIT(AT_IPv6, sizeof(ipv6.ip6h_src), &ipv6.ip6h_src);
2089 proto_item_append_text(tree, ", Src: %s", address_with_resolution_to_str(pinfo->pool, &src_addr));
2090 }
2091
2092 /* Add information about where the context came from. */
2093 /* TODO: We should display the prefix length too. */
2094 if (sctx->plen) {
2095 ti = proto_tree_add_ipv6(iphc_tree, hf_6lowpan_iphc_sctx_prefix, tvb, 0, 0, &sctx->prefix);
2096 proto_item_set_generated(ti);
2097 if ( sctx->frame ) {
2098 ti = proto_tree_add_uint(iphc_tree, hf_6lowpan_iphc_sctx_origin, tvb, 0, 0, sctx->frame);
2099 proto_item_set_generated(ti);
2100 }
2101 }
2102 offset += length;
2103 /*
2104 * Do not set the address columns until after defragmentation, since we have
2105 * to do decompression before reassembly, and changing the address will cause
2106 * wireshark to think that the middle fragments came from another device.
2107 */
2108
2109 /*=====================================================
2110 * Parse and decompress a multicast address.
2111 *=====================================================
2112 */
2113 length = 0;
2114 memset(&ipv6.ip6h_dst, 0, sizeof(ipv6.ip6h_dst));
2115 /* Stateless multicast compression. */
2116 if ((iphc_flags & LOWPAN_IPHC_FLAG_MCAST_COMP) && !(iphc_flags & LOWPAN_IPHC_FLAG_DST_COMP)) {
2117 if (iphc_dst_mode == LOWPAN_IPHC_ADDR_FULL_INLINE) {
2118 length = (int)sizeof(ipv6.ip6h_dst);
2119 tvb_memcpy(tvb, &ipv6.ip6h_dst.bytes[sizeof(ipv6.ip6h_dst) - length], offset, length);
2120 }
2121 else if (iphc_dst_mode == LOWPAN_IPHC_MCAST_48BIT) {
2122 ipv6.ip6h_dst.bytes[0] = 0xff;
2123 ipv6.ip6h_dst.bytes[1] = tvb_get_guint8(tvb, offset + (length++));
2124 ipv6.ip6h_dst.bytes[11] = tvb_get_guint8(tvb, offset + (length++));
2125 ipv6.ip6h_dst.bytes[12] = tvb_get_guint8(tvb, offset + (length++));
2126 ipv6.ip6h_dst.bytes[13] = tvb_get_guint8(tvb, offset + (length++));
2127 ipv6.ip6h_dst.bytes[14] = tvb_get_guint8(tvb, offset + (length++));
2128 ipv6.ip6h_dst.bytes[15] = tvb_get_guint8(tvb, offset + (length++));
2129 }
2130 else if (iphc_dst_mode == LOWPAN_IPHC_MCAST_32BIT) {
2131 ipv6.ip6h_dst.bytes[0] = 0xff;
2132 ipv6.ip6h_dst.bytes[1] = tvb_get_guint8(tvb, offset + (length++));
2133 ipv6.ip6h_dst.bytes[13] = tvb_get_guint8(tvb, offset + (length++));
2134 ipv6.ip6h_dst.bytes[14] = tvb_get_guint8(tvb, offset + (length++));
2135 ipv6.ip6h_dst.bytes[15] = tvb_get_guint8(tvb, offset + (length++));
2136 }
2137 else if (iphc_dst_mode == LOWPAN_IPHC_MCAST_8BIT) {
2138 ipv6.ip6h_dst.bytes[0] = 0xff;
2139 ipv6.ip6h_dst.bytes[1] = 0x02;
2140 ipv6.ip6h_dst.bytes[15] = tvb_get_guint8(tvb, offset + (length++));
2141 }
2142 else {
2143 /* Illegal destination address compression mode. */
2144 expert_add_info(pinfo, ti_dam, &ei_6lowpan_illegal_dest_addr_mode);
2145 return NULL;
2146 }
2147 }
2148 /* Stateful multicast compression. */
2149 else if ((iphc_flags & LOWPAN_IPHC_FLAG_MCAST_COMP) && (iphc_flags & LOWPAN_IPHC_FLAG_DST_COMP)) {
2150 if (iphc_dst_mode == LOWPAN_IPHC_MCAST_STATEFUL_48BIT) {
2151 /* RFC 3306 unicast-prefix based multicast address of the form:
2152 * ffXX:XXLL:PPPP:PPPP:PPPP:PPPP:XXXX:XXXX
2153 * XX = inline byte.
2154 * LL = prefix/context length (up to 64-bits).
2155 * PP = prefix/context byte.
2156 */
2157 ipv6.ip6h_dst.bytes[0] = 0xff;
2158 ipv6.ip6h_dst.bytes[1] = tvb_get_guint8(tvb, offset + (length++));
2159 ipv6.ip6h_dst.bytes[2] = tvb_get_guint8(tvb, offset + (length++));
2160 ipv6.ip6h_dst.bytes[3] = (dctx->plen > 64) ? (64) : (dctx->plen);
2161 memcpy(&ipv6.ip6h_dst.bytes[4], &dctx->prefix, 8);
2162 ipv6.ip6h_dst.bytes[12] = tvb_get_guint8(tvb, offset + (length++));
2163 ipv6.ip6h_dst.bytes[13] = tvb_get_guint8(tvb, offset + (length++));
2164 ipv6.ip6h_dst.bytes[14] = tvb_get_guint8(tvb, offset + (length++));
2165 ipv6.ip6h_dst.bytes[15] = tvb_get_guint8(tvb, offset + (length++));
2166 }
2167 else {
2168 /* Illegal destination address compression mode. */
2169 expert_add_info(pinfo, ti_dam, &ei_6lowpan_illegal_dest_addr_mode);
2170 return NULL;
2171 }
2172 }
2173
2174 /*=====================================================
2175 * Parse and decompress a unicast destination address.
2176 *=====================================================
2177 */
2178 else {
2179 /* (DAC=1 && DAM=00) -> reserved value. */
2180 if ((iphc_flags & LOWPAN_IPHC_FLAG_DST_COMP) && (iphc_dst_mode == LOWPAN_IPHC_ADDR_FULL_INLINE)) {
2181 /* Illegal destination address compression mode. */
2182 expert_add_info(pinfo, ti_dam, &ei_6lowpan_illegal_dest_addr_mode);
2183 return NULL;
2184 }
2185 /* The IID is derived from the link-layer source. */
2186 else if (iphc_dst_mode == LOWPAN_IPHC_ADDR_COMPRESSED) {
2187 memcpy(&ipv6.ip6h_dst.bytes[sizeof(ipv6.ip6h_dst) - LOWPAN_IFC_ID_LEN], diid, LOWPAN_IFC_ID_LEN);
2188 }
2189 /* Full Address inline. */
2190 else if (iphc_dst_mode == LOWPAN_IPHC_ADDR_FULL_INLINE) {
2191 dctx = &lowpan_context_default;
2192 length = (int)sizeof(ipv6.ip6h_dst);
2193 tvb_memcpy(tvb, &ipv6.ip6h_dst, offset, length);
2194 }
2195 /* 64-bits inline. */
2196 else if (iphc_dst_mode == LOWPAN_IPHC_ADDR_64BIT_INLINE) {
2197 length = 8;
2198 tvb_memcpy(tvb, &ipv6.ip6h_dst.bytes[sizeof(ipv6.ip6h_dst) - length], offset, length);
2199 }
2200 /* 16-bits inline. */
2201 else if (iphc_dst_mode == LOWPAN_IPHC_ADDR_16BIT_INLINE) {
2202 length = 2;
2203 /* Format becomes ff:fe00:xxxx */
2204 ipv6.ip6h_dst.bytes[11] = 0xff;
2205 ipv6.ip6h_dst.bytes[12] = 0xfe;
2206 tvb_memcpy(tvb, &ipv6.ip6h_dst.bytes[sizeof(ipv6.ip6h_dst) - length], offset, length);
2207 }
2208 /* Copy the context bits. */
2209 lowpan_pfxcpy(&ipv6.ip6h_dst, &dctx->prefix, dctx->plen);
2210 /* Update the interface id of the encapsulating layer. */
2211 diid = &ipv6.ip6h_dst.bytes[sizeof(ipv6.ip6h_dst) - LOWPAN_IFC_ID_LEN];
2212 }
2213
2214 /* Display the destination IPv6 address. */
2215 ti = proto_tree_add_ipv6(tree, hf_6lowpan_dest, tvb, offset, length, &ipv6.ip6h_dst);
2216 if (length == 0) {
2217 proto_item_set_generated(ti);
2218 }
2219 if (ipv6_summary_in_tree) {
2220 address dst_addr = ADDRESS_INIT(AT_IPv6, sizeof(ipv6.ip6h_dst), &ipv6.ip6h_dst);
2221 proto_item_append_text(tree, ", Dest: %s", address_with_resolution_to_str(pinfo->pool, &dst_addr));
2222 }
2223
2224 /* Add information about where the context came from. */
2225 /* TODO: We should display the prefix length too. */
2226 if (dctx->plen) {
2227 ti = proto_tree_add_ipv6(iphc_tree, hf_6lowpan_iphc_dctx_prefix, tvb, 0, 0, &dctx->prefix);
2228 proto_item_set_generated(ti);
2229 if ( dctx->frame ) {
2230 ti = proto_tree_add_uint(iphc_tree, hf_6lowpan_iphc_dctx_origin, tvb, 0, 0, dctx->frame);
2231 proto_item_set_generated(ti);
2232 }
2233 }
2234 offset += length;
2235 /*
2236 * Do not set the address columns until after defragmentation, since we have
2237 * to do decompression before reassembly, and changing the address will cause
2238 * wireshark to think that the middle fragments came from another device.
2239 */
2240
2241 /*=====================================================
2242 * Decompress extension headers.
2243 *=====================================================
2244 */
2245 /* Parse the list of extension headers. */
2246 if (iphc_flags & LOWPAN_IPHC_FLAG_NHDR) {
2247 /* Parse the next header protocol identifier. */
2248 ipv6.ip6h_nxt = lowpan_parse_nhc_proto(tvb, offset);
2249
2250 /* Parse the 6LoWPAN NHC fields. */
2251 nhdr_list = dissect_6lowpan_iphc_nhc(tvb, pinfo, tree, offset, dgram_size - IPv6_HDR_SIZE, siid, diid);
2252 }
2253 /* Create an extension header for the remaining payload. */
2254 else {
2255 length = tvb_captured_length_remaining(tvb, offset);
2256 nhdr_list = (struct lowpan_nhdr *)wmem_alloc(pinfo->pool, sizeof(struct lowpan_nhdr) + length);
2257 nhdr_list->next = NULL;
2258 nhdr_list->proto = ipv6.ip6h_nxt;
2259 nhdr_list->length = length;
2260 if (dgram_size < 0) {
2261 nhdr_list->reported = tvb_reported_length_remaining(tvb, offset);
2262 }
2263 else {
2264 nhdr_list->reported = dgram_size - IPv6_HDR_SIZE;
2265 }
2266 tvb_memcpy(tvb, LOWPAN_NHDR_DATA(nhdr_list), offset, nhdr_list->length);
2267 }
2268
2269 /*=====================================================
2270 * Rebuild the IPv6 packet.
2271 *=====================================================
2272 */
2273 /* Reassemble the IPv6 packet. */
2274 ipv6_tvb = lowpan_reassemble_ipv6(tvb, pinfo, &ipv6, nhdr_list);
2275
2276 /* Add a new data source for it. */
2277 add_new_data_source(pinfo, ipv6_tvb, "Decompressed 6LoWPAN IPHC");
2278
2279 return ipv6_tvb;
2280 } /* dissect_6lowpan_iphc */
2281
2282 /*FUNCTION:------------------------------------------------------
2283 * NAME
2284 * dissect_6lowpan_iphc_nhc
2285 * DESCRIPTION
2286 * Dissector routine for a 6LoWPAN IPHC next header structure(s).
2287 * PARAMETERS
2288 * tvb ; packet buffer.
2289 * pinfo ; packet info.
2290 * tree ; 6LoWPAN display tree.
2291 * offset ; packet buffer offset.
2292 * dgram_size ; Remaining datagram size (or <0 if unknown).
2293 * siid ; Source Interface ID.
2294 * diid ; Destination Interface ID.
2295 * RETURNS
2296 * lowpan_nhdr * ; List of wmem_alloc'd next header structures.
2297 *---------------------------------------------------------------
2298 */
2299 static struct lowpan_nhdr *
dissect_6lowpan_iphc_nhc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,gint offset,gint dgram_size,const guint8 * siid,const guint8 * diid)2300 dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint dgram_size, const guint8 *siid, const guint8 *diid)
2301 {
2302 gint length;
2303 proto_item * ti = NULL;
2304 proto_tree * nhc_tree = NULL;
2305 struct lowpan_nhdr *nhdr;
2306
2307 /*=====================================================
2308 * IP-in-IP Tunneling
2309 *=====================================================
2310 */
2311 if (tvb_get_bits8(tvb, offset<<3, LOWPAN_NHC_PATTERN_EXT_IPV6_BITS) == LOWPAN_NHC_PATTERN_EXT_IPV6) {
2312 guint8 ext_flags;
2313 tvbuff_t *iphc_tvb;
2314
2315 /* Create a tree for the IPv6 extension header. */
2316 nhc_tree = proto_tree_add_subtree(tree, tvb, offset, 2, ett_6lowpan_nhc_ext, &ti, "IPv6 extension header");
2317 /* Display the IPv6 Extension Header NHC ID pattern. */
2318 proto_tree_add_bits_item(nhc_tree, hf_6lowpan_nhc_pattern, tvb, offset<<3, LOWPAN_NHC_PATTERN_EXT_BITS, ENC_BIG_ENDIAN);
2319
2320 /* Get and display the extension header compression flags. */
2321 ext_flags = tvb_get_guint8(tvb, offset);
2322 proto_tree_add_uint(nhc_tree, hf_6lowpan_nhc_ext_eid, tvb, offset, 1, ext_flags & LOWPAN_NHC_EXT_EID);
2323 proto_tree_add_boolean(nhc_tree, hf_6lowpan_nhc_ext_nh, tvb, offset, 1, ext_flags & LOWPAN_NHC_EXT_NHDR);
2324 if (ext_flags & LOWPAN_NHC_EXT_NHDR) {
2325 /* TODO: Flag a warning, the NH bit MUST be 0 when EID==0x7 (IP-in-IP). */
2326 }
2327 offset += 1;
2328
2329 /* Decode the remainder of the packet using IPHC encoding. */
2330 iphc_tvb = dissect_6lowpan_iphc(tvb_new_subset_remaining(tvb, offset), pinfo, tree, dgram_size, siid, diid);
2331 if (!iphc_tvb) return NULL;
2332
2333 /* Create the next header structure for the tunneled IPv6 header. */
2334 nhdr = (struct lowpan_nhdr *)wmem_alloc0(pinfo->pool, sizeof(struct lowpan_nhdr) + tvb_captured_length(iphc_tvb));
2335 nhdr->next = NULL;
2336 nhdr->proto = IP_PROTO_IPV6;
2337 nhdr->length = tvb_captured_length(iphc_tvb);
2338 nhdr->reported = tvb_reported_length(iphc_tvb);
2339 tvb_memcpy(iphc_tvb, LOWPAN_NHDR_DATA(nhdr), 0, nhdr->length);
2340 return nhdr;
2341 }
2342 /*=====================================================
2343 * IPv6 Extension Header
2344 *=====================================================
2345 */
2346 if (tvb_get_bits8(tvb, offset<<3, LOWPAN_NHC_PATTERN_EXT_BITS) == LOWPAN_NHC_PATTERN_EXT) {
2347 struct ip6_ext ipv6_ext = {0, 0};
2348 guint8 ext_flags;
2349 guint8 ext_hlen;
2350 guint8 ext_len;
2351 guint8 ext_proto;
2352 proto_item *ti_ext_len = NULL;
2353
2354 /* Parse the IPv6 extension header protocol. */
2355 ext_proto = lowpan_parse_nhc_proto(tvb, offset);
2356
2357 /* Create a tree for the IPv6 extension header. */
2358 nhc_tree = proto_tree_add_subtree(tree, tvb, offset, 2, ett_6lowpan_nhc_ext, NULL, "IPv6 extension header");
2359 /* Display the IPv6 Extension Header NHC ID pattern. */
2360 proto_tree_add_bits_item(nhc_tree, hf_6lowpan_nhc_pattern, tvb, offset<<3, LOWPAN_NHC_PATTERN_EXT_BITS, ENC_BIG_ENDIAN);
2361
2362 /* Get and display the extension header compression flags. */
2363 ext_flags = tvb_get_guint8(tvb, offset);
2364 proto_tree_add_uint(nhc_tree, hf_6lowpan_nhc_ext_eid, tvb, offset, 1, ext_flags & LOWPAN_NHC_EXT_EID);
2365 proto_tree_add_boolean(nhc_tree, hf_6lowpan_nhc_ext_nh, tvb, offset, 1, ext_flags & LOWPAN_NHC_EXT_NHDR);
2366 offset += 1;
2367
2368 /* Get and display the next header field, if present. */
2369 if (!(ext_flags & LOWPAN_NHC_EXT_NHDR)) {
2370 ipv6_ext.ip6e_nxt = tvb_get_guint8(tvb, offset);
2371 proto_tree_add_uint_format_value(nhc_tree, hf_6lowpan_nhc_ext_next, tvb, offset, 1, ipv6_ext.ip6e_nxt,
2372 "%s (0x%02x)", ipprotostr(ipv6_ext.ip6e_nxt), ipv6_ext.ip6e_nxt);
2373 proto_item_set_end(ti, tvb, offset+1);
2374 offset += 1;
2375 }
2376
2377 if (ext_proto == IP_PROTO_FRAGMENT) {
2378 /* Fragment header has a reserved byte in place of the Length field. */
2379 ext_hlen = 1;
2380 length = (guint8)sizeof(struct ip6_frag);
2381 ext_len = length - ext_hlen;
2382
2383 proto_tree_add_item(nhc_tree, hf_6lowpan_nhc_ext_reserved, tvb, offset, 1, ENC_NA);
2384
2385 } else {
2386 /* Get and display the extension header length. */
2387 ext_hlen = (guint8)sizeof(struct ip6_ext);
2388 ext_len = tvb_get_guint8(tvb, offset);
2389 ti_ext_len = proto_tree_add_uint(nhc_tree, hf_6lowpan_nhc_ext_length, tvb, offset, 1, ext_len);
2390 offset += 1;
2391
2392 /* Compute the length of the extension header padded to an 8-byte alignment. */
2393 length = ext_hlen + ext_len;
2394 length = (length + 7) & ~0x7;
2395 ipv6_ext.ip6e_len = length>>3; /* Convert to units of 8 bytes. */
2396 ipv6_ext.ip6e_len -= 1; /* Don't include the first 8 bytes. */
2397 }
2398
2399 /* Create the next header structure for the IPv6 extension header. */
2400 nhdr = (struct lowpan_nhdr *)wmem_alloc0(pinfo->pool, sizeof(struct lowpan_nhdr) + length);
2401 nhdr->next = NULL;
2402 nhdr->proto = ext_proto;
2403 nhdr->length = length;
2404 nhdr->reported = length;
2405
2406 /* Add the IPv6 extension header to the buffer. */
2407 if (ext_flags & LOWPAN_NHC_EXT_NHDR) {
2408 ipv6_ext.ip6e_nxt = lowpan_parse_nhc_proto(tvb, offset+ext_len);
2409 }
2410 memcpy(LOWPAN_NHDR_DATA(nhdr), &ipv6_ext, ext_hlen);
2411
2412 /*
2413 * If the extension header was truncated, display the remainder using
2414 * the data dissector, and end NHC dissection here.
2415 */
2416 if (!tvb_bytes_exist(tvb, offset, ext_len)) {
2417 /* Call the data dissector for the remainder. */
2418 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, nhc_tree);
2419
2420 /* Copy the remainder, and truncate the real buffer length. */
2421 nhdr->length = tvb_captured_length_remaining(tvb, offset) + ext_hlen;
2422 tvb_memcpy(tvb, LOWPAN_NHDR_DATA(nhdr) + ext_hlen, offset, tvb_captured_length_remaining(tvb, offset));
2423
2424 /* There is nothing more we can do. */
2425 return nhdr;
2426 }
2427
2428 if (ext_proto == IP_PROTO_FRAGMENT) {
2429 /* Display the extension header using the data dissector. */
2430 call_data_dissector(tvb_new_subset_length(tvb, offset+1, ext_len-1), pinfo, nhc_tree);
2431 } else {
2432 /* Display the extension header using the data dissector. */
2433 call_data_dissector(tvb_new_subset_length(tvb, offset, ext_len), pinfo, nhc_tree);
2434 }
2435
2436 /* Copy the extension header into the struct. */
2437 tvb_memcpy(tvb, LOWPAN_NHDR_DATA(nhdr) + ext_hlen, offset, ext_len);
2438 offset += ext_len;
2439
2440 /* Add padding option */
2441 if (length > ext_hlen + ext_len) {
2442 guint8 padding = length - (ext_hlen + ext_len);
2443 guint8 *pad_ptr = LOWPAN_NHDR_DATA(nhdr) + ext_hlen + ext_len;
2444 if (ext_proto != IP_PROTO_HOPOPTS && ext_proto != IP_PROTO_DSTOPTS) {
2445 expert_add_info(pinfo, ti_ext_len, &ei_6lowpan_bad_ext_header_length);
2446 }
2447 if (padding == 1) {
2448 pad_ptr[0] = IP6OPT_PAD1;
2449 } else {
2450 pad_ptr[0] = IP6OPT_PADN;
2451 pad_ptr[1] = padding - 2;
2452 /* No need to write pad data, as buffer is zero-initialised */
2453 }
2454 }
2455
2456 if (ext_flags & LOWPAN_NHC_EXT_NHDR) {
2457 /*
2458 * There are more LOWPAN_NHC structures to parse. Call ourself again
2459 * recursively to parse them and build the linked list.
2460 */
2461 nhdr->next = dissect_6lowpan_iphc_nhc(tvb, pinfo, tree, offset, dgram_size - nhdr->reported, siid, diid);
2462 }
2463 else if (ipv6_ext.ip6e_nxt != IP_PROTO_NONE) {
2464 /* Create another next header structure for the remaining payload. */
2465 length = tvb_captured_length_remaining(tvb, offset);
2466 nhdr->next = (struct lowpan_nhdr *)wmem_alloc(pinfo->pool, sizeof(struct lowpan_nhdr) + length);
2467 nhdr->next->next = NULL;
2468 nhdr->next->proto = ipv6_ext.ip6e_nxt;
2469 nhdr->next->length = length;
2470 if (dgram_size < 0) {
2471 nhdr->next->reported = tvb_reported_length_remaining(tvb, offset);
2472 }
2473 else {
2474 nhdr->next->reported = dgram_size - nhdr->reported;
2475 }
2476 tvb_memcpy(tvb, LOWPAN_NHDR_DATA(nhdr->next), offset, nhdr->next->length);
2477 }
2478
2479 /* Done. */
2480 return nhdr;
2481 }
2482 /*=====================================================
2483 * UDP Header
2484 *=====================================================
2485 */
2486 if (tvb_get_bits8(tvb, offset<<3, LOWPAN_NHC_PATTERN_UDP_BITS) == LOWPAN_NHC_PATTERN_UDP) {
2487 struct udp_hdr udp;
2488 gint src_bitlen;
2489 gint dst_bitlen;
2490 guint8 udp_flags;
2491 guint16 udp_src_port, udp_dst_port;
2492
2493 /* Create a tree for the UDP header. */
2494 nhc_tree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_6lowpan_nhc_udp, NULL, "UDP header compression");
2495 /* Display the UDP NHC ID pattern. */
2496 proto_tree_add_bits_item(nhc_tree, hf_6lowpan_nhc_pattern, tvb, offset<<3, LOWPAN_NHC_PATTERN_UDP_BITS, ENC_BIG_ENDIAN);
2497
2498 /* Get and display the UDP header compression options */
2499 proto_tree_add_item(nhc_tree, hf_6lowpan_nhc_udp_checksum, tvb, offset, 1, ENC_NA);
2500 proto_tree_add_item(nhc_tree, hf_6lowpan_nhc_udp_ports, tvb, offset, 1, ENC_NA);
2501 udp_flags = tvb_get_guint8(tvb, offset);
2502 offset += 1;
2503
2504 /* Get and display the ports. */
2505 switch (udp_flags & LOWPAN_NHC_UDP_PORTS) {
2506 case LOWPAN_NHC_UDP_PORT_INLINE:
2507 udp_src_port = tvb_get_ntohs(tvb, offset);
2508 udp_dst_port = tvb_get_ntohs(tvb, offset+2);
2509 src_bitlen = 16;
2510 dst_bitlen = 16;
2511 break;
2512
2513 case LOWPAN_NHC_UDP_PORT_8BIT_DST:
2514 udp_src_port = tvb_get_ntohs(tvb, offset);
2515 udp_dst_port = LOWPAN_PORT_8BIT_OFFSET + tvb_get_guint8(tvb, offset + 2);
2516 src_bitlen = 16;
2517 dst_bitlen = 8;
2518 break;
2519
2520 case LOWPAN_NHC_UDP_PORT_8BIT_SRC:
2521 udp_src_port = LOWPAN_PORT_8BIT_OFFSET + tvb_get_guint8(tvb, offset);
2522 udp_dst_port = tvb_get_ntohs(tvb, offset + 1);
2523 src_bitlen = 8;
2524 dst_bitlen = 16;
2525 break;
2526
2527 case LOWPAN_NHC_UDP_PORT_12BIT:
2528 udp_src_port = LOWPAN_PORT_12BIT_OFFSET + (tvb_get_guint8(tvb, offset) >> 4);
2529 udp_dst_port = LOWPAN_PORT_12BIT_OFFSET + (tvb_get_guint8(tvb, offset) & 0x0f);
2530 src_bitlen = 4;
2531 dst_bitlen = 4;
2532 break;
2533
2534 default:
2535 DISSECTOR_ASSERT_NOT_REACHED();
2536 break;
2537 } /* switch */
2538
2539 proto_tree_add_uint(tree, hf_6lowpan_udp_src, tvb, offset, BITS_TO_BYTE_LEN(offset<<3, src_bitlen), udp_src_port);
2540 proto_tree_add_uint(tree, hf_6lowpan_udp_dst, tvb, offset+(src_bitlen>>3), BITS_TO_BYTE_LEN((offset<<3)+src_bitlen, dst_bitlen), udp_dst_port);
2541 offset += ((src_bitlen + dst_bitlen)>>3);
2542 udp.src_port = g_htons(udp_src_port);
2543 udp.dst_port = g_htons(udp_dst_port);
2544
2545 /* Get and display the checksum. */
2546 if (!(udp_flags & LOWPAN_NHC_UDP_CHECKSUM)) {
2547 /* Parse the checksum. */
2548 tvb_memcpy(tvb, &udp.checksum, offset, sizeof(udp.checksum));
2549 proto_tree_add_checksum(tree, tvb, offset, hf_6lowpan_udp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
2550 offset += 2;
2551 }
2552 else {
2553 /* Checksum must be != 0 or the UDP dissector will flag the packet with a PI_ERROR */
2554 udp.checksum = 0xffff;
2555 }
2556
2557 /* Compute the datagram length. */
2558 if (dgram_size < 0) {
2559 length = tvb_reported_length_remaining(tvb, offset);
2560 udp.length = g_htons(length + (int)sizeof(struct udp_hdr));
2561 }
2562 else {
2563 udp.length = g_htons(dgram_size);
2564 }
2565
2566 /*
2567 * Although rfc768 (udp) allows a packet to be sent with a checksum of
2568 * 0 to mean that no checksum was computed, apparently IPv6 specifically
2569 * disallows sending UDP datagrams without checksums. Likewise, 6LoWPAN
2570 * requires that we recompute the checksum.
2571 *
2572 * If the datagram is incomplete, then leave the checksum at 0xffff.
2573 */
2574 #if 0
2575 /*
2576 * This has been disabled, since we might only be dissecting a fragment
2577 * of the packet, and thus we might not have the entire UDP payload at
2578 * this time.
2579 *
2580 * If we want to display the checksums, they will have to be recomputed
2581 * after packet reassembly. Lots of work for not much gain, since we can
2582 * just set the UDP checksum to 0xffff (anything != 0) and Wireshark
2583 * doesn't care.
2584 */
2585 if ((udp_flags & LOWPAN_NHC_UDP_CHECKSUM) && tvb_bytes_exist(tvb, offset, length)) {
2586 vec_t cksum_vec[3];
2587 struct {
2588 ws_in6_addr src;
2589 ws_in6_addr dst;
2590 guint32 length;
2591 guint8 zero[3];
2592 guint8 proto;
2593 } cksum_phdr;
2594
2595 /* Fill in the pseudo-header. */
2596 memcpy(&cksum_phdr.src, pinfo->src.data, sizeof(ws_in6_addr));
2597 memcpy(&cksum_phdr.dst, pinfo->dst.data, sizeof(ws_in6_addr));
2598 cksum_phdr.length = g_htonl(length + (int)sizeof(struct udp_hdr));
2599 memset(cksum_phdr.zero, 0, sizeof(cksum_phdr.zero));
2600 cksum_phdr.proto = IP_PROTO_UDP;
2601
2602 /* Compute the checksum. */
2603 SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)&cksum_phdr, sizeof(cksum_phdr));
2604 SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)&udp, sizeof(struct udp_hdr));
2605 SET_CKSUM_VEC_TVB(cksum_vec[2], tvb, offset, length);
2606 udp.checksum = in_cksum(cksum_vec, 3);
2607 if (udp.checksum == 0) udp.checksum = 0xffff;
2608 }
2609 #endif
2610
2611 /* Create the next header structure for the UDP datagram. */
2612 length = tvb_captured_length_remaining(tvb, offset);
2613 nhdr = (struct lowpan_nhdr *)wmem_alloc(pinfo->pool, sizeof(struct lowpan_nhdr) + sizeof(struct udp_hdr) + length);
2614 nhdr->next = NULL;
2615 nhdr->proto = IP_PROTO_UDP;
2616 nhdr->length = length + (int)sizeof(struct udp_hdr);
2617 nhdr->reported = g_ntohs(udp.length);
2618
2619 /* Copy the UDP header and payload into the buffer. */
2620 memcpy(LOWPAN_NHDR_DATA(nhdr), &udp, sizeof(struct udp_hdr));
2621 tvb_memcpy(tvb, LOWPAN_NHDR_DATA(nhdr) + sizeof(struct udp_hdr), offset, tvb_captured_length_remaining(tvb, offset));
2622 return nhdr;
2623 }
2624 /*=====================================================
2625 * Unknown Next Header Type
2626 *=====================================================
2627 */
2628 return NULL;
2629 } /* dissect_6lowpan_iphc_nhc */
2630
2631 /*FUNCTION:------------------------------------------------------
2632 * NAME
2633 * dissect_6lowpan_bc0
2634 * DESCRIPTION
2635 * Dissector routine for a 6LoWPAN broadcast header.
2636 * PARAMETERS
2637 * tvb ; packet buffer.
2638 * pinfo ; packet info.
2639 * tree ; 6LoWPAN display tree.
2640 * RETURNS
2641 * tvbuff_t * ; The remaining payload to be parsed.
2642 *---------------------------------------------------------------
2643 */
2644 static tvbuff_t *
dissect_6lowpan_bc0(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree)2645 dissect_6lowpan_bc0(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
2646 {
2647 guint8 seqnum;
2648 proto_tree * bcast_tree;
2649
2650 /* Create a tree for the broadcast header. */
2651 bcast_tree = proto_tree_add_subtree(tree, tvb, 0, 2, ett_6lowpan_bcast, NULL, "Broadcast Header");
2652
2653 /* Get and display the pattern. */
2654 proto_tree_add_bits_item(bcast_tree, hf_6lowpan_pattern, tvb, 0, LOWPAN_PATTERN_BC0_BITS, ENC_BIG_ENDIAN);
2655
2656 /* Get and display the sequence number. */
2657 seqnum = tvb_get_guint8(tvb, 1);
2658 proto_tree_add_uint(bcast_tree, hf_6lowpan_bcast_seqnum, tvb, 1, 1, seqnum);
2659
2660 /* Return the remaining buffer. */
2661 return tvb_new_subset_remaining(tvb, 2);
2662 } /* dissect_6lowpan_bc0 */
2663
2664 /*FUNCTION:------------------------------------------------------
2665 * NAME
2666 * dissect_6lowpan_mesh
2667 * DESCRIPTION
2668 * Dissector routine for a 6LoWPAN mesh header.
2669 * PARAMETERS
2670 * tvb ; packet buffer.
2671 * pinfo ; packet info.
2672 * tree ; 6LoWPAN display tree.
2673 * offset ; offset to the start of the header.
2674 * siid ; Source Interface ID.
2675 * diid ; Destination Interface ID.
2676 * RETURNS
2677 * tvbuff_t * ; The remaining payload to be parsed.
2678 *---------------------------------------------------------------
2679 */
2680 static tvbuff_t *
dissect_6lowpan_mesh(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint8 * siid,guint8 * diid)2681 dissect_6lowpan_mesh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 *siid, guint8 *diid)
2682 {
2683 gint offset = 0;
2684 guint8 mesh_header;
2685 proto_tree * mesh_tree;
2686 proto_tree * flag_tree;
2687 proto_item * ti;
2688
2689 ieee802154_hints_t *hints;
2690
2691 /* Create a tree for the mesh header. */
2692 mesh_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_6lowpan_mesh, &ti, "Mesh Header");
2693
2694 /* Get and display the mesh flags. */
2695 mesh_header = tvb_get_guint8(tvb, offset);
2696
2697 /* Create the mesh header subtree. */
2698 flag_tree = proto_tree_add_subtree(mesh_tree, tvb, offset, 1, ett_6lowpan_mesh, NULL, "Flags");
2699
2700 /* Add the mesh header fields. */
2701 proto_tree_add_bits_item(flag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_MESH_BITS, ENC_BIG_ENDIAN);
2702 proto_tree_add_boolean(flag_tree, hf_6lowpan_mesh_v, tvb, offset, 1, mesh_header & LOWPAN_MESH_HEADER_V);
2703 proto_tree_add_boolean(flag_tree, hf_6lowpan_mesh_f, tvb, offset, 1, mesh_header & LOWPAN_MESH_HEADER_F);
2704 proto_tree_add_uint(flag_tree, hf_6lowpan_mesh_hops, tvb, offset, 1, mesh_header & LOWPAN_MESH_HEADER_HOPS);
2705 offset += 1;
2706
2707 if ((mesh_header & LOWPAN_MESH_HEADER_HOPS) == LOWPAN_MESH_HEADER_HOPS) {
2708 proto_tree_add_item(mesh_tree, hf_6lowpan_mesh_hops8, tvb, offset, 1, ENC_BIG_ENDIAN);
2709 offset += 1;
2710 }
2711
2712 /* Get and display the originator address. */
2713 if (!(mesh_header & LOWPAN_MESH_HEADER_V)) {
2714 proto_tree_add_item(mesh_tree, hf_6lowpan_mesh_orig64,
2715 tvb, offset, 8, ENC_BIG_ENDIAN);
2716
2717 set_address_tvb(&pinfo->src, AT_EUI64, 8, tvb, offset);
2718 copy_address_shallow(&pinfo->net_src, &pinfo->src);
2719
2720 /* Update source IID */
2721 tvb_memcpy(tvb, siid, offset, LOWPAN_IFC_ID_LEN);
2722 /* RFC2464: Invert the U/L bit when using an EUI64 address. */
2723 siid[0] ^= 0x02;
2724 offset += 8;
2725 }
2726 else {
2727 guint16 addr16 = tvb_get_ntohs(tvb, offset);
2728 guint8 * ifcid;
2729
2730 proto_tree_add_uint(mesh_tree, hf_6lowpan_mesh_orig16, tvb, offset, 2, addr16);
2731 ifcid = (guint8 *)wmem_alloc(pinfo->pool, 8);
2732
2733 /* Lookup the IEEE 802.15.4 addressing hints wanting RFC 2464 compatibility. */
2734 hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
2735 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
2736
2737 /* Convert the 16-bit short address to an IID using the PAN ID (RFC 4944) or not depending on the preference and the presence of hints from lower layers */
2738 if (hints && rfc4944_short_address_format) {
2739 lowpan_addr16_with_panid_to_ifcid(hints->src_pan, addr16, ifcid);
2740 } else {
2741 lowpan_addr16_to_ifcid(addr16, ifcid);
2742 }
2743
2744 set_address(&pinfo->src, AT_EUI64, 8, ifcid);
2745 copy_address_shallow(&pinfo->net_src, &pinfo->src);
2746
2747 /* Update source IID */
2748 memcpy(siid, ifcid, LOWPAN_IFC_ID_LEN);
2749 offset += 2;
2750 }
2751
2752 /* Get and display the destination address. */
2753 if (!(mesh_header & LOWPAN_MESH_HEADER_F)) {
2754 proto_tree_add_item(mesh_tree, hf_6lowpan_mesh_dest64,
2755 tvb, offset, 8, ENC_BIG_ENDIAN);
2756
2757 set_address_tvb(&pinfo->dst, AT_EUI64, 8, tvb, offset);
2758 copy_address_shallow(&pinfo->net_dst, &pinfo->dst);
2759
2760 /* Update destination IID */
2761 tvb_memcpy(tvb, diid, offset, LOWPAN_IFC_ID_LEN);
2762 /* RFC2464: Invert the U/L bit when using an EUI64 address. */
2763 diid[0] ^= 0x02;
2764 offset += 8;
2765 }
2766 else {
2767 guint16 addr16 = tvb_get_ntohs(tvb, offset);
2768 guint8 * ifcid;
2769
2770 proto_tree_add_uint(mesh_tree, hf_6lowpan_mesh_dest16, tvb, offset, 2, addr16);
2771
2772 ifcid = (guint8 *)wmem_alloc(pinfo->pool, 8);
2773
2774 /* Lookup the IEEE 802.15.4 addressing hints wanting RFC 2464 compatibility. */
2775 hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
2776 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
2777
2778 /* Convert the 16-bit short address to an IID using the PAN ID (RFC 4944) or not depending on the preference and the presence of hints from lower layers */
2779 if (hints && rfc4944_short_address_format) {
2780 lowpan_addr16_with_panid_to_ifcid(hints->src_pan, addr16, ifcid);
2781 } else {
2782 lowpan_addr16_to_ifcid(addr16, ifcid);
2783 }
2784
2785 set_address(&pinfo->dst, AT_EUI64, 8, ifcid);
2786 copy_address_shallow(&pinfo->net_dst, &pinfo->dst);
2787
2788 /* Update destination IID */
2789 memcpy(diid, ifcid, LOWPAN_IFC_ID_LEN);
2790 offset += 2;
2791 }
2792
2793 /* Adjust the mesh header length. */
2794 proto_item_set_end(ti, tvb, offset);
2795
2796 /* Return the remaining buffer. */
2797 return tvb_new_subset_remaining(tvb, offset);
2798 } /* dissect_6lowpan_mesh */
2799
2800 /*FUNCTION:------------------------------------------------------
2801 * NAME
2802 * dissect_6lowpan_frag_headers
2803 * DESCRIPTION
2804 * Dissector routine for headers in the first fragment.
2805 * The first fragment can contain an uncompressed IPv6, HC1 or IPHC fragment.
2806 * PARAMETERS
2807 * tvb ; fragment buffer.
2808 * pinfo ; packet info.
2809 * tree ; 6LoWPAN display tree.
2810 * siid ; Source Interface ID.
2811 * diid ; Destination Interface ID.
2812 * RETURNS
2813 * tvbuff_t * ; buffer containing the uncompressed IPv6 headers
2814 *---------------------------------------------------------------
2815 */
2816 static tvbuff_t *
dissect_6lowpan_frag_headers(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_item * length_item,const guint8 * siid,const guint8 * diid)2817 dissect_6lowpan_frag_headers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *length_item, const guint8 *siid, const guint8 *diid)
2818 {
2819 tvbuff_t *frag_tvb = NULL;
2820
2821 /* The first fragment can contain an uncompressed IPv6, HC1 or IPHC fragment. */
2822 if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) {
2823 frag_tvb = dissect_6lowpan_ipv6(tvb, pinfo, tree);
2824 }
2825 else if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) {
2826 /* Check if the datagram size is sane. */
2827 if (tvb_reported_length(tvb) < IPv6_HDR_SIZE) {
2828 expert_add_info_format(pinfo, length_item, &ei_6lowpan_bad_ipv6_header_length,
2829 "Length is less than IPv6 header length %u", IPv6_HDR_SIZE);
2830 }
2831 frag_tvb = dissect_6lowpan_hc1(tvb, pinfo, tree, tvb_reported_length(tvb), siid, diid);
2832 }
2833 else if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
2834 /* Check if the datagram size is sane. */
2835 if (tvb_reported_length(tvb) < IPv6_HDR_SIZE) {
2836 expert_add_info_format(pinfo, length_item, &ei_6lowpan_bad_ipv6_header_length,
2837 "Length is less than IPv6 header length %u", IPv6_HDR_SIZE);
2838 }
2839 frag_tvb = dissect_6lowpan_iphc(tvb, pinfo, tree, tvb_reported_length(tvb), siid, diid);
2840 }
2841 /* Unknown 6LoWPAN dispatch type */
2842 else {
2843 dissect_6lowpan_unknown(tvb, pinfo, tree);
2844 }
2845 return frag_tvb;
2846 } /* dissect_6lowpan_frag_headers */
2847
2848 /*FUNCTION:------------------------------------------------------
2849 * NAME
2850 * dissect_6lowpan_rfrag
2851 * DESCRIPTION
2852 * Dissector routine for a 6LoWPAN Recoverable Fragment headers.
2853 *
2854 * If reassembly could be completed, this should return an
2855 * uncompressed IPv6 packet. If reassembly had to be delayed
2856 * for more packets, this will return NULL.
2857 * PARAMETERS
2858 * tvb ; packet buffer.
2859 * pinfo ; packet info.
2860 * tree ; 6LoWPAN display tree.
2861 * siid ; Source Interface ID.
2862 * diid ; Destination Interface ID.
2863 * RETURNS
2864 * tvbuff_t * ; reassembled IPv6 packet.
2865 *---------------------------------------------------------------
2866 */
2867 static tvbuff_t *
dissect_6lowpan_rfrag(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,const guint8 * siid,const guint8 * diid)2868 dissect_6lowpan_rfrag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const guint8 *siid, const guint8 *diid)
2869 {
2870 gint offset = 0;
2871 guint32 frag_size;
2872 guint32 dgram_tag;
2873 proto_tree * frag_tree;
2874 proto_item * ti;
2875 proto_item * length_item;
2876 /* Reassembly parameters. */
2877 tvbuff_t * new_tvb;
2878 tvbuff_t * frag_tvb;
2879 fragment_head * frag_data;
2880 gboolean save_fragmented;
2881 guint16 sequence;
2882 guint32 frag_offset;
2883
2884 /* Create a tree for the fragmentation header. */
2885 frag_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_6lowpan_frag, &ti, "RFRAG Header");
2886
2887 /* Get and display the pattern and explicit congestion bit. */
2888 proto_tree_add_bits_item(frag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_RFRAG_BITS, ENC_BIG_ENDIAN);
2889 proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_congestion, tvb, offset, 1, ENC_BIG_ENDIAN);
2890 offset += 1;
2891
2892 /* Get and display the datagram tag. */
2893 proto_tree_add_item_ret_uint(frag_tree, hf_6lowpan_rfrag_dgram_tag, tvb, offset, 1, ENC_BIG_ENDIAN, &dgram_tag);
2894 offset += 1;
2895
2896 proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_ack_requested, tvb, offset, 2, ENC_BIG_ENDIAN);
2897 sequence = tvb_get_bits16(tvb, (offset * 8) + 1, LOWPAN_RFRAG_SEQUENCE_BITS, ENC_BIG_ENDIAN);
2898 proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_sequence, tvb, offset, 2, ENC_BIG_ENDIAN);
2899
2900 frag_size = tvb_get_bits16(tvb, (offset * 8) + 1 + LOWPAN_RFRAG_SEQUENCE_BITS, LOWPAN_RFRAG_FRAG_SZ_BITS, ENC_BIG_ENDIAN);
2901 length_item = proto_tree_add_uint(frag_tree, hf_6lowpan_rfrag_size, tvb, offset * 8, 2, frag_size);
2902 offset += 2;
2903
2904 if (sequence) {
2905 proto_tree_add_item_ret_uint(frag_tree, hf_6lowpan_rfrag_offset, tvb, offset, 2, ENC_BIG_ENDIAN, &frag_offset);
2906 }
2907 else {
2908 proto_tree_add_item_ret_uint(frag_tree, hf_6lowpan_rfrag_dgram_size, tvb, offset, 2, ENC_BIG_ENDIAN, &frag_offset);
2909 }
2910 offset += 2;
2911
2912 /* Adjust the fragmentation header length. */
2913 proto_item_set_end(ti, tvb, offset);
2914
2915 frag_tvb = tvb_new_subset_length(tvb, offset, frag_size);
2916 if (sequence == 0) {
2917 dissect_6lowpan_frag_headers(frag_tvb, pinfo, tree, length_item, siid, diid);
2918 }
2919
2920 /* Add this datagram to the fragment table. */
2921 save_fragmented = pinfo->fragmented;
2922 pinfo->fragmented = TRUE;
2923 guint32 frag_id = lowpan_reassembly_id(pinfo, dgram_tag);
2924 if (sequence == 0) {
2925 frag_data = fragment_add_check(&lowpan_reassembly_table,
2926 frag_tvb, 0, pinfo, frag_id, NULL,
2927 0, frag_size, TRUE);
2928 fragment_set_tot_len(&lowpan_reassembly_table, pinfo, frag_id, NULL, frag_offset);
2929 }
2930 else {
2931 guint32 dgram_size = fragment_get_tot_len(&lowpan_reassembly_table, pinfo, frag_id, NULL);
2932 frag_data = fragment_add_check(&lowpan_reassembly_table,
2933 frag_tvb, 0, pinfo, frag_id, NULL,
2934 frag_offset, frag_size, (frag_offset+frag_size) < dgram_size);
2935 }
2936
2937 /* Attempt reassembly. */
2938 new_tvb = process_reassembled_data(frag_tvb, 0, pinfo,
2939 "Reassembled 6LoWPAN", frag_data, &lowpan_frag_items,
2940 NULL, tree);
2941
2942 pinfo->fragmented = save_fragmented;
2943
2944 if (new_tvb) {
2945 /* Reassembly was successful; return the completed datagram. */
2946 return new_tvb;
2947 } else {
2948 /* Reassembly was unsuccessful; show this fragment. This may
2949 just mean that we don't yet have all the fragments, so
2950 we should not just continue dissecting. */
2951 call_data_dissector(frag_tvb, pinfo, proto_tree_get_root(tree));
2952 return NULL;
2953 }
2954 } /* dissect_6lowpan_rfrag */
2955
2956 /*FUNCTION:------------------------------------------------------
2957 * NAME
2958 * dissect_6lowpan_rfrag_ack
2959 * DESCRIPTION
2960 * Dissector routine for a 6LoWPAN ACK Dispatch type and header
2961 * PARAMETERS
2962 * tvb ; packet buffer.
2963 * pinfo ; packet info.
2964 * tree ; 6LoWPAN display tree.
2965 * RETURNS
2966 * tvbuff_t * ; reassembled IPv6 packet.
2967 *---------------------------------------------------------------
2968 */
2969 static tvbuff_t *
dissect_6lowpan_rfrag_ack(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)2970 dissect_6lowpan_rfrag_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2971 {
2972 gint offset = 0;
2973 proto_tree * frag_tree;
2974 proto_item * ti;
2975 (void)pinfo;
2976
2977 /* Create a tree for the fragmentation header. */
2978 frag_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_6lowpan_frag, &ti, "RFRAG ACK Header");
2979
2980 /* Get and display the pattern and explicit congestion bit. */
2981 proto_tree_add_bits_item(frag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_RFRAG_BITS, ENC_BIG_ENDIAN);
2982 proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_congestion, tvb, offset, 1, ENC_BIG_ENDIAN);
2983 offset += 1;
2984
2985 /* Get and display the datagram tag. */
2986 proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_dgram_tag, tvb, offset, 1, ENC_BIG_ENDIAN);
2987 offset += 1;
2988
2989 proto_tree_add_bits_item(frag_tree, hf_6lowpan_rfrag_ack_bitmap, tvb, offset * 8, 32, ENC_BIG_ENDIAN);
2990 offset += 4;
2991
2992 /* TODO: Match ACK bits to original fragments? */
2993
2994 return tvb_new_subset_remaining(tvb, offset);
2995 } /* dissect_6lowpan_rfrag_ack */
2996
2997 /*FUNCTION:------------------------------------------------------
2998 * NAME
2999 * dissect_6lowpan_frag_first
3000 * DESCRIPTION
3001 * Dissector routine for a 6LoWPAN FRAG1 headers.
3002 *
3003 * If reassembly could be completed, this should return an
3004 * uncompressed IPv6 packet. If reassembly had to be delayed
3005 * for more packets, this will return NULL.
3006 * PARAMETERS
3007 * tvb ; packet buffer.
3008 * pinfo ; packet info.
3009 * tree ; 6LoWPAN display tree.
3010 * siid ; Source Interface ID.
3011 * diid ; Destination Interface ID.
3012 * RETURNS
3013 * tvbuff_t * ; reassembled IPv6 packet.
3014 *---------------------------------------------------------------
3015 */
3016 static tvbuff_t *
dissect_6lowpan_frag_first(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,const guint8 * siid,const guint8 * diid)3017 dissect_6lowpan_frag_first(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const guint8 *siid, const guint8 *diid)
3018 {
3019 gint offset = 0;
3020 gint frag_size;
3021 guint16 dgram_size;
3022 guint16 dgram_tag;
3023 proto_tree * frag_tree;
3024 proto_item * ti;
3025 proto_item * length_item;
3026 /* Reassembly parameters. */
3027 tvbuff_t * new_tvb;
3028 tvbuff_t * frag_tvb;
3029 fragment_head * frag_data;
3030 gboolean save_fragmented;
3031
3032 /* Create a tree for the fragmentation header. */
3033 frag_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_6lowpan_frag, &ti, "Fragmentation Header");
3034
3035 /* Get and display the pattern and datagram size. */
3036 dgram_size = tvb_get_bits16(tvb, (offset * 8) + LOWPAN_PATTERN_FRAG_BITS, LOWPAN_FRAG_DGRAM_SIZE_BITS, ENC_BIG_ENDIAN);
3037 proto_tree_add_bits_item(frag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_FRAG_BITS, ENC_BIG_ENDIAN);
3038 length_item = proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_size, tvb, offset, 2, dgram_size);
3039 offset += 2;
3040
3041 /* Get and display the datagram tag. */
3042 dgram_tag = tvb_get_ntohs(tvb, offset);
3043 proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_tag, tvb, offset, 2, dgram_tag);
3044 offset += 2;
3045
3046 /* Adjust the fragmentation header length. */
3047 proto_item_set_end(ti, tvb, offset);
3048
3049
3050 frag_tvb = tvb_new_subset_length(tvb, offset, dgram_size);
3051 frag_tvb = dissect_6lowpan_frag_headers(frag_tvb, pinfo, tree, length_item, siid, diid);
3052 /* Check call to dissect_6lowpan_xxx was successful */
3053 if (frag_tvb == NULL) {
3054 return NULL;
3055 }
3056
3057 /* Add this datagram to the fragment table. */
3058 frag_size = tvb_captured_length(frag_tvb);
3059 tvb_set_reported_length(frag_tvb, frag_size);
3060 save_fragmented = pinfo->fragmented;
3061 pinfo->fragmented = TRUE;
3062 guint32 frag_id = lowpan_reassembly_id(pinfo, dgram_tag);
3063 frag_data = fragment_add_check(&lowpan_reassembly_table,
3064 frag_tvb, 0, pinfo, frag_id, NULL,
3065 0, frag_size, (frag_size < dgram_size));
3066
3067 /* Attempt reassembly. */
3068 new_tvb = process_reassembled_data(frag_tvb, 0, pinfo,
3069 "Reassembled 6LoWPAN", frag_data, &lowpan_frag_items,
3070 NULL, tree);
3071
3072 pinfo->fragmented = save_fragmented;
3073
3074 if (new_tvb) {
3075 /* Reassembly was successful; return the completed datagram. */
3076 return new_tvb;
3077 } else {
3078 /* Reassembly was unsuccessful; show this fragment. This may
3079 just mean that we don't yet have all the fragments, so
3080 we should not just continue dissecting. */
3081 call_data_dissector(frag_tvb, pinfo, proto_tree_get_root(tree));
3082 return NULL;
3083 }
3084 } /* dissect_6lowpan_frag_first */
3085
3086 /*FUNCTION:------------------------------------------------------
3087 * NAME
3088 * dissect_6lowpan_frag_middle
3089 * DESCRIPTION
3090 * Dissector routine for a 6LoWPAN FRAGN headers.
3091 *
3092 * If reassembly could be completed, this should return an
3093 * uncompressed IPv6 packet. If reassembly had to be delayed
3094 * for more packets, this will return NULL.
3095 * PARAMETERS
3096 * tvb ; packet buffer.
3097 * pinfo ; packet info.
3098 * tree ; 6LoWPAN display tree.
3099 * RETURNS
3100 * tvbuff_t * ; reassembled IPv6 packet.
3101 *---------------------------------------------------------------
3102 */
3103 static tvbuff_t *
dissect_6lowpan_frag_middle(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)3104 dissect_6lowpan_frag_middle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3105 {
3106 gint offset = 0;
3107 gint frag_size;
3108 guint16 dgram_size;
3109 guint16 dgram_tag;
3110 guint16 dgram_offset = 0;
3111 proto_tree * frag_tree;
3112 proto_item * ti;
3113 /* Reassembly parameters. */
3114 tvbuff_t * new_tvb;
3115 fragment_head * frag_data;
3116 gboolean save_fragmented;
3117
3118 /* Create a tree for the fragmentation header. */
3119 frag_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_6lowpan_frag, &ti, "Fragmentation Header");
3120
3121 /* Get and display the pattern and datagram size. */
3122 dgram_size = tvb_get_bits16(tvb, (offset * 8) + LOWPAN_PATTERN_FRAG_BITS, LOWPAN_FRAG_DGRAM_SIZE_BITS, ENC_BIG_ENDIAN);
3123 proto_tree_add_bits_item(frag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_FRAG_BITS, ENC_BIG_ENDIAN);
3124 proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_size, tvb, offset, 2, dgram_size);
3125 offset += 2;
3126
3127 /* Get and display the datagram tag. */
3128 dgram_tag = tvb_get_ntohs(tvb, offset);
3129 proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_tag, tvb, offset, 2, dgram_tag);
3130 offset += 2;
3131
3132 /* Get and display the datagram offset. */
3133 dgram_offset = tvb_get_guint8(tvb, offset) * 8;
3134 proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_offset, tvb, offset, 1, dgram_offset);
3135 offset += 1;
3136
3137 /* Adjust the fragmentation header length. */
3138 frag_size = tvb_reported_length_remaining(tvb, offset);
3139 proto_item_set_end(ti, tvb, offset);
3140
3141 /* Add this datagram to the fragment table. */
3142 save_fragmented = pinfo->fragmented;
3143 pinfo->fragmented = TRUE;
3144 guint32 frag_id = lowpan_reassembly_id(pinfo, dgram_tag);
3145 frag_data = fragment_add_check(&lowpan_reassembly_table,
3146 tvb, offset, pinfo, frag_id, NULL,
3147 dgram_offset, frag_size, ((dgram_offset + frag_size) < dgram_size));
3148
3149 /* Attempt reassembly. */
3150 new_tvb = process_reassembled_data(tvb, offset, pinfo,
3151 "Reassembled 6LoWPAN", frag_data, &lowpan_frag_items,
3152 NULL, tree);
3153
3154 pinfo->fragmented = save_fragmented;
3155
3156 /* If reassembly was successful, then return the completed datagram. */
3157 if (new_tvb) {
3158 return new_tvb;
3159 }
3160 /* If reassembly failed, display the payload fragment using the data dissector. */
3161 else {
3162 new_tvb = tvb_new_subset_remaining(tvb, offset);
3163 call_data_dissector(new_tvb, pinfo, proto_tree_get_root(tree));
3164 return NULL;
3165 }
3166 } /* dissect_6lowpan_frag_middle */
3167
3168 /*FUNCTION:------------------------------------------------------
3169 * NAME
3170 * dissect_6lowpan_unknown
3171 * DESCRIPTION
3172 * Dissector routine for 6LoWPAN packets after encountering
3173 * an unknown header.
3174 * PARAMETERS
3175 * tvb ; packet buffer.
3176 * pinfo ; packet info.
3177 * tree ; 6LoWPAN display tree.
3178 * RETURNS
3179 * void ;
3180 *---------------------------------------------------------------
3181 */
3182 void
dissect_6lowpan_unknown(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)3183 dissect_6lowpan_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3184 {
3185 tvbuff_t * data_tvb;
3186
3187 /* Get and display the pattern. */
3188
3189 /* Give a special case for NALP. */
3190 if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
3191 proto_tree_add_bits_item(tree, hf_6lowpan_pattern, tvb, 0, LOWPAN_PATTERN_IPHC_BITS, ENC_BIG_ENDIAN);
3192 }
3193 else {
3194 guint8 pattern = tvb_get_guint8(tvb, 0);
3195 proto_tree_add_uint_bits_format_value(tree, hf_6lowpan_pattern, tvb, 0, 8, pattern, ENC_BIG_ENDIAN, "Unknown (0x%02x)", pattern);
3196 }
3197
3198 /* Create a tvbuff subset for the remaining data. */
3199 data_tvb = tvb_new_subset_remaining(tvb, 1);
3200 call_data_dissector(data_tvb, pinfo, proto_tree_get_root(tree));
3201 } /* dissect_6lowpan_unknown */
3202
3203 static void
proto_shutdown_6lowpan(void)3204 proto_shutdown_6lowpan(void)
3205 {
3206 g_hash_table_destroy(lowpan_context_table);
3207 }
3208
3209 /*FUNCTION:------------------------------------------------------
3210 * NAME
3211 * proto_register_6lowpan
3212 * DESCRIPTION
3213 * Protocol registration routine for 6LoWPAN. Called during
3214 * Wireshark initialization.
3215 * PARAMETERS
3216 * none ;
3217 * RETURNS
3218 * void ;
3219 *---------------------------------------------------------------
3220 */
3221 void
proto_register_6lowpan(void)3222 proto_register_6lowpan(void)
3223 {
3224 static hf_register_info hf[] = {
3225 /* Common 6LoWPAN fields. */
3226 { &hf_6lowpan_pattern,
3227 { "Pattern", "6lowpan.pattern",
3228 FT_UINT8, BASE_HEX, VALS(lowpan_patterns), 0x0, NULL, HFILL }},
3229 { &hf_6lowpan_nhc_pattern,
3230 { "Pattern", "6lowpan.nhc.pattern",
3231 FT_UINT8, BASE_HEX, VALS(lowpan_nhc_patterns), 0x0, NULL, HFILL }},
3232 { &hf_6lowpan_padding,
3233 { "Padding", "6lowpan.padding",
3234 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3235
3236 /* HC1 header fields. */
3237 { &hf_6lowpan_hc1_encoding,
3238 { "HC1 Encoding", "6lowpan.hc1.encoding",
3239 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3240 { &hf_6lowpan_hc1_source_prefix,
3241 { "Source prefix", "6lowpan.hc1.src_prefix",
3242 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_HC1_SOURCE_PREFIX, NULL, HFILL }},
3243 { &hf_6lowpan_hc1_source_ifc,
3244 { "Source interface", "6lowpan.hc1.src_ifc",
3245 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_HC1_SOURCE_IFC, NULL, HFILL }},
3246 { &hf_6lowpan_hc1_dest_prefix,
3247 { "Destination prefix", "6lowpan.hc1.dst_prefix",
3248 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_HC1_DEST_PREFIX, NULL, HFILL }},
3249 { &hf_6lowpan_hc1_dest_ifc,
3250 { "Destination interface", "6lowpan.hc1.dst_ifc",
3251 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_HC1_DEST_IFC, NULL, HFILL }},
3252 { &hf_6lowpan_hc1_class,
3253 { "Traffic class and flow label", "6lowpan.hc1.class",
3254 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_HC1_TRAFFIC_CLASS, NULL, HFILL }},
3255 { &hf_6lowpan_hc1_next,
3256 { "Next header", "6lowpan.hc1.next",
3257 FT_UINT8, BASE_HEX, VALS(lowpan_hc1_next), LOWPAN_HC1_NEXT, NULL, HFILL }},
3258 { &hf_6lowpan_hc1_more,
3259 { "More HC bits", "6lowpan.hc1.more",
3260 FT_BOOLEAN, 8, NULL, LOWPAN_HC1_MORE, NULL, HFILL }},
3261
3262 /* HC_UDP header fields. */
3263 { &hf_6lowpan_hc2_udp_encoding,
3264 { "HC_UDP Encoding", "6lowpan.hc2.udp.encoding",
3265 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3266 { &hf_6lowpan_hc2_udp_src,
3267 { "Source port", "6lowpan.hc2.udp.src",
3268 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_HC2_UDP_SRCPORT, NULL, HFILL }},
3269 { &hf_6lowpan_hc2_udp_dst,
3270 { "Destination port", "6lowpan.hc2.udp.dst",
3271 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_HC2_UDP_DSTPORT, NULL, HFILL }},
3272 { &hf_6lowpan_hc2_udp_len,
3273 { "Length", "6lowpan.hc2.udp.length",
3274 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_HC2_UDP_LENGTH, NULL, HFILL }},
3275
3276 /* IPHC header fields. */
3277 { &hf_6lowpan_iphc_flag_tf,
3278 { "Traffic class and flow label", "6lowpan.iphc.tf",
3279 FT_UINT16, BASE_HEX, VALS(lowpan_iphc_traffic), LOWPAN_IPHC_FLAG_FLOW, "traffic class and flow control encoding", HFILL }},
3280 { &hf_6lowpan_iphc_flag_nhdr,
3281 { "Next header", "6lowpan.iphc.nh",
3282 FT_BOOLEAN, 16, TFS(&lowpan_compression), LOWPAN_IPHC_FLAG_NHDR, NULL, HFILL }},
3283 { &hf_6lowpan_iphc_flag_hlim,
3284 { "Hop limit", "6lowpan.iphc.hlim",
3285 FT_UINT16, BASE_HEX, VALS(lowpan_iphc_hop_limit), LOWPAN_IPHC_FLAG_HLIM, NULL, HFILL }},
3286 { &hf_6lowpan_iphc_flag_cid,
3287 { "Context identifier extension", "6lowpan.iphc.cid",
3288 FT_BOOLEAN, 16, NULL, LOWPAN_IPHC_FLAG_CONTEXT_ID, NULL, HFILL }},
3289 { &hf_6lowpan_iphc_flag_sac,
3290 { "Source address compression", "6lowpan.iphc.sac",
3291 FT_BOOLEAN, 16, TFS(&lowpan_iphc_addr_compression), LOWPAN_IPHC_FLAG_SRC_COMP, NULL, HFILL }},
3292 { &hf_6lowpan_iphc_flag_sam,
3293 { "Source address mode", "6lowpan.iphc.sam",
3294 FT_UINT16, BASE_HEX, VALS(lowpan_iphc_addr_modes), LOWPAN_IPHC_FLAG_SRC_MODE, NULL, HFILL }},
3295 { &hf_6lowpan_iphc_flag_mcast,
3296 { "Multicast address compression", "6lowpan.iphc.m",
3297 FT_BOOLEAN, 16, NULL, LOWPAN_IPHC_FLAG_MCAST_COMP, NULL, HFILL }},
3298 { &hf_6lowpan_iphc_flag_dac,
3299 { "Destination address compression","6lowpan.iphc.dac",
3300 FT_BOOLEAN, 16, TFS(&lowpan_iphc_addr_compression), LOWPAN_IPHC_FLAG_DST_COMP, NULL, HFILL }},
3301 { &hf_6lowpan_iphc_flag_dam,
3302 { "Destination address mode", "6lowpan.iphc.dam",
3303 FT_UINT16, BASE_HEX, VALS(lowpan_iphc_addr_modes), LOWPAN_IPHC_FLAG_DST_MODE, NULL, HFILL }},
3304 { &hf_6lowpan_iphc_sci,
3305 { "Source context identifier", "6lowpan.iphc.sci",
3306 FT_UINT8, BASE_HEX, NULL, LOWPAN_IPHC_FLAG_SCI, NULL, HFILL }},
3307 { &hf_6lowpan_iphc_dci,
3308 { "Destination context identifier", "6lowpan.iphc.dci",
3309 FT_UINT8, BASE_HEX, NULL, LOWPAN_IPHC_FLAG_DCI, NULL, HFILL }},
3310
3311 /* Context information fields. */
3312 { &hf_6lowpan_iphc_sctx_prefix,
3313 { "Source context", "6lowpan.iphc.sctx.prefix", FT_IPv6, BASE_NONE, NULL, 0x0,
3314 NULL, HFILL }},
3315 { &hf_6lowpan_iphc_sctx_origin,
3316 { "Origin", "6lowpan.iphc.sctx.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3317 NULL, HFILL }},
3318 { &hf_6lowpan_iphc_dctx_prefix,
3319 { "Destination context", "6lowpan.iphc.dctx.prefix", FT_IPv6, BASE_NONE, NULL, 0x0,
3320 NULL, HFILL }},
3321 { &hf_6lowpan_iphc_dctx_origin,
3322 { "Origin", "6lowpan.iphc.dctx.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3323 NULL, HFILL }},
3324
3325 /* NHC IPv6 extension header fields. */
3326 { &hf_6lowpan_nhc_ext_eid,
3327 { "Header ID", "6lowpan.nhc.ext.eid",
3328 FT_UINT8, BASE_HEX, VALS(lowpan_nhc_eid), LOWPAN_NHC_EXT_EID, NULL, HFILL }},
3329 { &hf_6lowpan_nhc_ext_nh,
3330 { "Next header", "6lowpan.nhc.ext.nh",
3331 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_NHC_EXT_NHDR, NULL, HFILL }},
3332 { &hf_6lowpan_nhc_ext_next,
3333 { "Next header", "6lowpan.nhc.ext.next",
3334 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3335 { &hf_6lowpan_nhc_ext_length,
3336 { "Header length", "6lowpan.nhc.ext.length",
3337 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3338 { &hf_6lowpan_nhc_ext_reserved,
3339 { "Reserved octet", "6lowpan.nhc.ext.reserved",
3340 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3341
3342 /* NHC UDP header fields. */
3343 { &hf_6lowpan_nhc_udp_checksum,
3344 { "Checksum", "6lowpan.nhc.udp.checksum",
3345 FT_BOOLEAN, 8, TFS(&lowpan_compression), LOWPAN_NHC_UDP_CHECKSUM, NULL, HFILL }},
3346 { &hf_6lowpan_nhc_udp_ports,
3347 { "Ports", "6lowpan.nhc.udp.ports",
3348 FT_UINT8, BASE_DEC, VALS(lowpan_udp_ports), LOWPAN_NHC_UDP_PORTS, NULL, HFILL }},
3349
3350 /* Uncompressed IPv6 fields. */
3351 { &hf_6lowpan_traffic_class,
3352 { "Traffic class", "6lowpan.class",
3353 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3354 { &hf_6lowpan_flow_label,
3355 { "Flow label", "6lowpan.flow",
3356 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3357 { &hf_6lowpan_ecn,
3358 { "ECN", "6lowpan.ecn",
3359 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3360 { &hf_6lowpan_dscp,
3361 { "DSCP", "6lowpan.dscp",
3362 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3363 { &hf_6lowpan_next_header,
3364 { "Next header", "6lowpan.next",
3365 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3366 { &hf_6lowpan_hop_limit,
3367 { "Hop limit", "6lowpan.hops",
3368 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3369 { &hf_6lowpan_source,
3370 { "Source", "6lowpan.src",
3371 FT_IPv6, BASE_NONE, NULL, 0x0, "Source IPv6 address", HFILL }},
3372 { &hf_6lowpan_dest,
3373 { "Destination", "6lowpan.dst",
3374 FT_IPv6, BASE_NONE, NULL, 0x0, "Destination IPv6 address", HFILL }},
3375
3376 /* Uncompressed UDP fields. */
3377 { &hf_6lowpan_udp_src,
3378 { "Source port", "6lowpan.udp.src",
3379 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3380 { &hf_6lowpan_udp_dst,
3381 { "Destination port", "6lowpan.udp.dst",
3382 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3383 { &hf_6lowpan_udp_len,
3384 { "UDP length", "6lowpan.udp.length",
3385 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3386 { &hf_6lowpan_udp_checksum,
3387 { "UDP checksum", "6lowpan.udp.checksum",
3388 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3389
3390 /* Broadcast header fields. */
3391 { &hf_6lowpan_bcast_seqnum,
3392 { "Sequence number", "6lowpan.bcast.seqnum",
3393 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3394
3395 /* Mesh header fields. */
3396 { &hf_6lowpan_mesh_v,
3397 { "V", "6lowpan.mesh.v",
3398 FT_BOOLEAN, 8, NULL, LOWPAN_MESH_HEADER_V, "short originator address present", HFILL }},
3399 { &hf_6lowpan_mesh_f,
3400 { "D", "6lowpan.mesh.f",
3401 FT_BOOLEAN, 8, NULL, LOWPAN_MESH_HEADER_F, "short destination address present", HFILL }},
3402 { &hf_6lowpan_mesh_hops,
3403 { "Hops left", "6lowpan.mesh.hops",
3404 FT_UINT8, BASE_DEC, NULL, LOWPAN_MESH_HEADER_HOPS, NULL, HFILL }},
3405 { &hf_6lowpan_mesh_hops8,
3406 { "Deep Hops left (Flags.Hops left == 15)", "6lowpan.mesh.hops8",
3407 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3408 { &hf_6lowpan_mesh_orig16,
3409 { "Originator", "6lowpan.mesh.orig16",
3410 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3411 { &hf_6lowpan_mesh_orig64,
3412 { "Originator", "6lowpan.mesh.orig64",
3413 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3414 { &hf_6lowpan_mesh_dest16,
3415 { "Destination", "6lowpan.mesh.dest16",
3416 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3417 { &hf_6lowpan_mesh_dest64,
3418 { "Destination", "6lowpan.mesh.dest64",
3419 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3420
3421 /* Fragmentation header fields. */
3422 { &hf_6lowpan_frag_dgram_size,
3423 { "Datagram size", "6lowpan.frag.size",
3424 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3425 { &hf_6lowpan_frag_dgram_tag,
3426 { "Datagram tag", "6lowpan.frag.tag",
3427 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3428 { &hf_6lowpan_frag_dgram_offset,
3429 { "Datagram offset", "6lowpan.frag.offset",
3430 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3431
3432 /* Recoverable Fragmentation header fields. */
3433 { &hf_6lowpan_rfrag_congestion,
3434 { "Congestion", "6lowpan.rfrag.congestion",
3435 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, NULL, HFILL }},
3436 { &hf_6lowpan_rfrag_ack_requested,
3437 { "Ack requested", "6lowpan.rfrag.ack_requested",
3438 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x8000, NULL, HFILL }},
3439 { &hf_6lowpan_rfrag_dgram_tag,
3440 { "Datagram tag", "6lowpan.rfrag.tag",
3441 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3442 { &hf_6lowpan_rfrag_sequence,
3443 { "Fragment sequence", "6lowpan.rfrag.sequence",
3444 FT_UINT16, BASE_DEC, NULL, 0x7C00, NULL, HFILL }},
3445 { &hf_6lowpan_rfrag_size,
3446 { "Fragment size", "6lowpan.rfrag.size",
3447 FT_UINT16, BASE_DEC, NULL, 0x03FF, NULL, HFILL }},
3448 { &hf_6lowpan_rfrag_dgram_size,
3449 { "Datagram size", "6lowpan.rfrag.datagram_size",
3450 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3451 { &hf_6lowpan_rfrag_offset,
3452 { "Fragment offset", "6lowpan.rfrag.offset",
3453 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3454 { &hf_6lowpan_rfrag_ack_bitmap,
3455 { "Fragment ACK bitmask", "6lowpan.rfrag.ack_bitmask",
3456 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3457
3458 /* Reassembly fields. */
3459 { &hf_6lowpan_fragments,
3460 { "Message fragments", "6lowpan.fragments",
3461 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3462 { &hf_6lowpan_fragment,
3463 { "Message fragment", "6lowpan.fragment",
3464 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3465 { &hf_6lowpan_fragment_overlap,
3466 { "Message fragment overlap", "6lowpan.fragment.overlap",
3467 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3468 { &hf_6lowpan_fragment_overlap_conflicts,
3469 { "Message fragment overlapping with conflicting data", "6lowpan.fragment.overlap.conflicts",
3470 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3471 { &hf_6lowpan_fragment_multiple_tails,
3472 { "Message has multiple tail fragments", "6lowpan.fragment.multiple_tails",
3473 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3474 { &hf_6lowpan_fragment_too_long_fragment,
3475 { "Message fragment too long", "6lowpan.fragment.too_long_fragment",
3476 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3477 { &hf_6lowpan_fragment_error,
3478 { "Message defragmentation error", "6lowpan.fragment.error",
3479 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3480 { &hf_6lowpan_fragment_count,
3481 { "Message fragment count", "6lowpan.fragment.count",
3482 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }},
3483 { &hf_6lowpan_reassembled_in,
3484 { "Reassembled in", "6lowpan.reassembled.in",
3485 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3486 { &hf_6lowpan_reassembled_length,
3487 { "Reassembled 6LoWPAN length", "6lowpan.reassembled.length",
3488 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }},
3489
3490 /* 6loRH fields */
3491 { &hf_6lowpan_6lorhc_address_src,
3492 { "Encapsulator Address", "6lowpan.src",
3493 FT_IPv6, BASE_NONE, NULL, 0x0, "Source IPv6 address", HFILL }},
3494 { &hf_6lowpan_6lorhc_address_hop0,
3495 { "Source/15, Delta", "6lowpan.src",
3496 FT_IPv6, BASE_NONE, NULL, 0x0, "Source IPv6 address", HFILL }},
3497 { &hf_6lowpan_6lorhc_address_hop1,
3498 { "Source/14, Delta", "6lowpan.src",
3499 FT_IPv6, BASE_NONE, NULL, 0x0, "Source IPv6 address", HFILL }},
3500 { &hf_6lowpan_6lorhc_address_hop2,
3501 { "Source/12, Delta", "6lowpan.src",
3502 FT_IPv6, BASE_NONE, NULL, 0x0, "Source IPv6 address", HFILL }},
3503 { &hf_6lowpan_6lorhc_address_hop3,
3504 { "Source/8, Delta", "6lowpan.src",
3505 FT_IPv6, BASE_NONE, NULL, 0x0, "Source IPv6 address", HFILL }},
3506 { &hf_6lowpan_6lorhc_address_hop4,
3507 { "Source/0 Delta", "6lowpan.src",
3508 FT_IPv6, BASE_NONE, NULL, 0x0, "Source IPv6 address", HFILL }},
3509 { &hf_6lowpan_sender_rank1,
3510 { "Sender Rank", "6lowpan.sender.rank",
3511 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3512 { &hf_6lowpan_sender_rank2,
3513 { "Sender Rank", "6lowpan.sender.rank",
3514 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3515 { &hf_6lowpan_rpl_instance,
3516 { "RPL Instance", "6lowpan.rpl.instance",
3517 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3518 { &hf_6lowpan_5_bit_o,
3519 { "Packet direction (bit O)", "6lowpan.6loRH.bitO",
3520 FT_BOOLEAN, 16, TFS(&tfs_down_up), LOWPAN_5_RPI_BIT_O, NULL, HFILL }},
3521 { &hf_6lowpan_5_bit_r,
3522 { "Rank-Error (bit R)", "6lowpan.6loRH.bitR",
3523 FT_BOOLEAN, 16, TFS(&tfs_yes_no), LOWPAN_5_RPI_BIT_R, NULL, HFILL }},
3524 { &hf_6lowpan_5_bit_f,
3525 { "Forwarding-Error (bit F)", "6lowpan.6loRH.bitF",
3526 FT_BOOLEAN, 16, TFS(&tfs_yes_no), LOWPAN_5_RPI_BIT_F, NULL, HFILL }},
3527 { &hf_6lowpan_5_bit_i,
3528 { "RPL Instance (bit I)", "6lowpan.6loRH.bitI",
3529 FT_BOOLEAN, 16, TFS(&bit_I_RPL), LOWPAN_5_RPI_BIT_I, NULL, HFILL }},
3530 { &hf_6lowpan_5_bit_k,
3531 { "Sender Rank Compression size (bit K)", "6lowpan.6loRH.bitK",
3532 FT_BOOLEAN, 16, TFS(&bit_K_RPL), LOWPAN_5_RPI_BIT_K, NULL, HFILL }},
3533 { &hf_6lowpan_6lorhe_hoplimit,
3534 { "6loRH Hop Limit", "6lowpan.rhhop.limit",
3535 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3536 { &hf_6lowpan_6lorhe_bitmap,
3537 { "6loRH BIER Bitmap", "6lowpan.bitmap",
3538 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3539 { &hf_6lowpan_6lorhe_type,
3540 { "6loRH Type", "6lowpan.rhtype",
3541 FT_UINT16, BASE_HEX, VALS(lowpan_patterns_rh_type), LOWPAN_PATTERN_6LORHE_TYPE, NULL, HFILL }},
3542 { &hf_6lowpan_6lorhc_size,
3543 { "6loRH Hop Number-1", "6lowpan.HopNuevo",
3544 FT_UINT16, BASE_HEX, NULL, LOWPAN_PATTERN_6LORHE_LENGTH, NULL, HFILL }},
3545 { &hf_6lowpan_6lorhe_size,
3546 { "6loRH Bitmap Word Number-1", "6lowpan.WordNuevo",
3547 FT_UINT16, BASE_HEX, NULL, LOWPAN_PATTERN_6LORHE_LENGTH, NULL, HFILL }},
3548 { &hf_6lowpan_6lorhe_length,
3549 { "6loRH Elective Length", "6lowpan.rhElength",
3550 FT_UINT16, BASE_DEC, NULL, LOWPAN_PATTERN_6LORHE_LENGTH, NULL, HFILL }},
3551 { &hf_6lowpan_routing_header,
3552 { "Routing Header 6lo", "6lowpan.routingheader",
3553 FT_UINT8, BASE_HEX, VALS(lowpan_patterns_rh), 0x0, NULL, HFILL }},
3554 { &hf_6lowpan_pagenb,
3555 { "Page Number", "6lowpan.pagenb",
3556 FT_UINT16, 16, NULL, 0x0, NULL, HFILL }}
3557 };
3558
3559 static gint *ett[] = {
3560 &ett_6lowpan,
3561 &ett_6lowpan_hc1,
3562 &ett_6lowpan_hc1_encoding,
3563 &ett_6lowpan_hc2_udp,
3564 &ett_6lowpan_iphc,
3565 &ett_lowpan_routing_header_dispatch,
3566 &ett_6lowpan_nhc_ext,
3567 &ett_6lowpan_nhc_udp,
3568 &ett_6lowpan_bcast,
3569 &ett_6lowpan_mesh,
3570 &ett_6lowpan_mesh_flags,
3571 &ett_6lowpan_frag,
3572 /* Reassembly subtrees. */
3573 &ett_6lowpan_fragment,
3574 &ett_6lowpan_fragments
3575 };
3576
3577 static ei_register_info ei[] = {
3578 { &ei_6lowpan_hc1_more_bits, { "6lowpan.hc1_more_bits", PI_MALFORMED, PI_ERROR, "HC1 more bits expected for illegal next header type.", EXPFILL }},
3579 { &ei_6lowpan_illegal_dest_addr_mode, { "6lowpan.illegal_dest_addr_mode", PI_MALFORMED, PI_ERROR, "Illegal destination address mode", EXPFILL }},
3580 { &ei_6lowpan_bad_ipv6_header_length, { "6lowpan.bad_ipv6_header_length", PI_MALFORMED, PI_ERROR, "Length is less than IPv6 header length", EXPFILL }},
3581 { &ei_6lowpan_bad_ext_header_length, { "6lowpan.bad_ext_header_length", PI_MALFORMED, PI_ERROR, "Extension header not 8-octet aligned", EXPFILL }},
3582 };
3583
3584 int i;
3585 module_t *prefs_module;
3586 expert_module_t* expert_6lowpan;
3587
3588 lowpan_context_table = g_hash_table_new_full(lowpan_context_hash, lowpan_context_equal, lowpan_context_free, lowpan_context_free);
3589
3590 proto_6lowpan = proto_register_protocol("IPv6 over Low power Wireless Personal Area Networks", "6LoWPAN", "6lowpan");
3591 proto_register_field_array(proto_6lowpan, hf, array_length(hf));
3592 proto_register_subtree_array(ett, array_length(ett));
3593 expert_6lowpan = expert_register_protocol(proto_6lowpan);
3594 expert_register_field_array(expert_6lowpan, ei, array_length(ei));
3595
3596 /* Register the dissector with wireshark. */
3597 handle_6lowpan = register_dissector("6lowpan", dissect_6lowpan, proto_6lowpan);
3598
3599 /* Initialize the fragment reassembly table. */
3600 reassembly_table_register(&lowpan_reassembly_table, &addresses_reassembly_table_functions);
3601
3602 /* Register the dissector init function */
3603 register_init_routine(proto_init_6lowpan);
3604 register_shutdown_routine(proto_shutdown_6lowpan);
3605
3606 /* Initialize the context preferences. */
3607 memset((gchar*)lowpan_context_prefs, 0, sizeof(lowpan_context_prefs));
3608
3609 /* Register preferences. */
3610 prefs_module = prefs_register_protocol(proto_6lowpan, prefs_6lowpan_apply);
3611
3612 prefs_register_bool_preference(prefs_module, "rfc4944_short_address_format",
3613 "Derive IID according to RFC 4944",
3614 "Derive IID from a short 16-bit address according to RFC 4944 (using the PAN ID).",
3615 &rfc4944_short_address_format);
3616 prefs_register_bool_preference(prefs_module, "iid_has_universal_local_bit",
3617 "IID has Universal/Local bit",
3618 "Linux kernels before version 4.12 does toggle the Universal/Local bit.",
3619 &iid_has_universal_local_bit);
3620 prefs_register_bool_preference(prefs_module, "summary_in_tree",
3621 "Show IPv6 summary in protocol tree",
3622 "Whether the IPv6 summary line should be shown in the protocol tree",
3623 &ipv6_summary_in_tree);
3624
3625 for (i = 0; i < LOWPAN_CONTEXT_MAX; i++) {
3626 char *pref_name, *pref_title;
3627
3628 /*
3629 * Inspired by the IEEE 802.11 dissector - the preferences are expecting
3630 * that each pref has a unique string passed in, and will crash if we
3631 * try to reuse any for multiple preferences.
3632 */
3633 pref_name = wmem_strdup_printf(wmem_epan_scope(), "context%d", i);
3634 pref_title = wmem_strdup_printf(wmem_epan_scope(), "Context %d", i);
3635 prefs_register_string_preference(prefs_module, pref_name, pref_title,
3636 "IPv6 prefix to use for stateful address decompression.",
3637 &lowpan_context_prefs[i]);
3638 }
3639 } /* proto_register_6lowpan */
3640
3641 /*FUNCTION:------------------------------------------------------
3642 * NAME
3643 * proto_init_6lowpan
3644 * DESCRIPTION
3645 * 6LoWPAN initialization function.
3646 * PARAMETERS
3647 * none ;
3648 * RETURNS
3649 * void ;
3650 *---------------------------------------------------------------
3651 */
3652 static void
proto_init_6lowpan(void)3653 proto_init_6lowpan(void)
3654 {
3655 /* Initialize the link-local context. */
3656 lowpan_context_local.frame = 0;
3657 lowpan_context_local.plen = LOWPAN_CONTEXT_LINK_LOCAL_BITS;
3658 memcpy(&lowpan_context_local.prefix, lowpan_llprefix, sizeof(lowpan_llprefix));
3659
3660 /* Reload static contexts from our preferences. */
3661 prefs_6lowpan_apply();
3662 } /* proto_init_6lowpan */
3663
3664 /*FUNCTION:------------------------------------------------------
3665 * NAME
3666 * prefs_6lowpan_apply
3667 * DESCRIPTION
3668 * Prefs "apply" callback. Parses the context table for
3669 * IPv6 addresses/prefixes.
3670 * PARAMETERS
3671 * none ;
3672 * RETURNS
3673 * void ;
3674 *---------------------------------------------------------------
3675 */
3676 void
prefs_6lowpan_apply(void)3677 prefs_6lowpan_apply(void)
3678 {
3679 int i;
3680 ws_in6_addr prefix;
3681 gchar *prefix_str;
3682 gchar *prefix_len_str;
3683 guint32 prefix_len;
3684 gchar prefix_buf[48]; /* max length of IPv6 str. plus a bit */
3685
3686 for (i = 0; i < LOWPAN_CONTEXT_MAX; i++) {
3687 if (!lowpan_context_prefs[i]) continue;
3688 (void) g_strlcpy(prefix_buf, lowpan_context_prefs[i], 48);
3689 if ((prefix_str = strtok(prefix_buf, "/")) == NULL) continue;
3690 if ((prefix_len_str = strtok(NULL, "/")) == NULL) continue;
3691 if (sscanf(prefix_len_str, "%u", &prefix_len) != 1) continue;
3692 if (!str_to_ip6(prefix_str, &prefix)) continue;
3693 /* Set the prefix */
3694 lowpan_context_insert(i, IEEE802154_BCAST_PAN, prefix_len, &prefix, 0);
3695 } /* for */
3696 } /* prefs_6lowpan_apply */
3697
3698 /*FUNCTION:------------------------------------------------------
3699 * NAME
3700 * proto_reg_handoff_6lowpan
3701 * DESCRIPTION
3702 * Protocol handoff routine for 6LoWPAN. Called after all
3703 * protocols have been loaded.
3704 * PARAMETERS
3705 * none ;
3706 * RETURNS
3707 * void ;
3708 *---------------------------------------------------------------
3709 */
3710 void
proto_reg_handoff_6lowpan(void)3711 proto_reg_handoff_6lowpan(void)
3712 {
3713 ipv6_handle = find_dissector_add_dependency("ipv6", proto_6lowpan);
3714
3715 /* Register the 6LoWPAN dissector with IEEE 802.15.4 */
3716 dissector_add_for_decode_as(IEEE802154_PROTOABBREV_WPAN_PANID, handle_6lowpan);
3717 heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_6lowpan_heur, "6LoWPAN over IEEE 802.15.4", "6lowpan_wlan", proto_6lowpan, HEURISTIC_ENABLE);
3718
3719 /* Register Ethertype (RFC 7973) */
3720 dissector_add_uint("ethertype", ETHERTYPE_6LOWPAN, handle_6lowpan);
3721
3722 dissector_add_uint("btl2cap.psm", BTL2CAP_PSM_LE_IPSP, handle_6lowpan);
3723 dissector_add_for_decode_as("btl2cap.cid", handle_6lowpan);
3724 } /* proto_reg_handoff_6lowpan */
3725
3726
3727 /*
3728 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3729 *
3730 * Local variables:
3731 * c-basic-offset: 4
3732 * tab-width: 8
3733 * indent-tabs-mode: nil
3734 * End:
3735 *
3736 * vi: set shiftwidth=4 tabstop=8 expandtab:
3737 * :indentSize=4:tabSize=8:noTabs=true:
3738 */
3739