Coverage Report

Created: 2026-08-14 06:45

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