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