3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
11 * SHIM6 support added by Matthijs Mekking <matthijs@NLnetLabs.nl>
16 #include <epan/packet.h>
17 #include <epan/expert.h>
19 #include <wsutil/array.h>
20 #include <epan/in_cksum.h>
21 #include <epan/ipproto.h>
23 #include "packet-ip.h"
25 void proto_register_shim6(void);
26 void proto_reg_handoff_shim6(void);
28 static dissector_handle_t shim6_handle
;
32 uint8_t ip6s_nxt
; /* next header */
33 uint8_t ip6s_len
; /* header extension length */
34 uint8_t ip6s_p
; /* P field and first 7 bits of remainder */
35 /* followed by shim6 specific data*/
38 /* SHIM6 control message types */
39 #define SHIM6_TYPE_I1 0x01 /* 0 000 0001 */
40 #define SHIM6_TYPE_R1 0x02 /* 0 000 0010 */
41 #define SHIM6_TYPE_I2 0x03 /* 0 000 0011 */
42 #define SHIM6_TYPE_R2 0x04 /* 0 000 0100 */
43 #define SHIM6_TYPE_R1BIS 0x05 /* 0 000 0101 */
44 #define SHIM6_TYPE_I2BIS 0x06 /* 0 000 0110 */
45 #define SHIM6_TYPE_UPD_REQ 0x40 /* 0 100 0000 = 64 */
46 #define SHIM6_TYPE_UPD_ACK 0x41 /* 0 100 0001 = 65 */
47 #define SHIM6_TYPE_KEEPALIVE 0x42 /* 0 100 0010 = 66 */
48 #define SHIM6_TYPE_PROBE 0x43 /* 0 100 0011 = 67 */
51 #define SHIM6_OPT_RESPVAL 0x01 /* 0 000 0001 */
52 #define SHIM6_OPT_LOCLIST 0x02 /* 0 000 0010 */
53 #define SHIM6_OPT_LOCPREF 0x03 /* 0 000 0011 */
54 #define SHIM6_OPT_CGAPDM 0x04 /* 0 000 0100 */
55 #define SHIM6_OPT_CGASIG 0x05 /* 0 000 0101 */
56 #define SHIM6_OPT_ULIDPAIR 0x06 /* 0 000 0110 */
57 #define SHIM6_OPT_FII 0x07 /* 0 000 0111 */
60 #define SHIM6_BITMASK_P 0x80 /* 1 000 0000 */
61 #define SHIM6_BITMASK_TYPE 0x7F /* 0 111 1111 */
62 #define SHIM6_BITMASK_PROTOCOL 0x01 /* 0 000 0001 */
63 #define SHIM6_BITMASK_SPECIFIC 0xFE /* 1 111 1110 */
64 #define SHIM6_BITMASK_R 0x80 /* 1 000 0000 */
65 #define SHIM6_BITMASK_CT 0x7F /* 0 111 1111 */
66 #define SHIM6_BITMASK_OPT_TYPE 0xFFFE /* 1 111 1111 1 111 1110 */
67 #define SHIM6_BITMASK_CRITICAL 0x01 /* 0 000 0001 */
68 #define SHIM6_BITMASK_PRECVD 0xF0 /* 1 111 0000 */
69 #define SHIM6_BITMASK_PSENT 0x0F /* 0 000 1111 */
70 #define SHIM6_BITMASK_STA 0xC0 /* 1 100 0000 */
72 /* SHIM6 Verification Methods */
73 #define SHIM6_VERIF_HBA 0x01 /* 0 000 0001 */
74 #define SHIM6_VERIF_CGA 0x02 /* 0 000 0010 */
77 #define SHIM6_FLAG_BROKEN 0x01 /* 0 000 0001 */
78 #define SHIM6_FLAG_TEMPORARY 0x02 /* 0 000 0010 */
80 /* SHIM6 REAP States */
81 #define SHIM6_REAP_OPERATIONAL 0x00 /* 0 000 0000 */
82 #define SHIM6_REAP_EXPLORING 0x01 /* 0 000 0001 */
83 #define SHIM6_REAP_INBOUNDOK 0x02 /* 0 000 0010 */
85 static int proto_shim6
;
87 static int hf_shim6_nxt
;
88 static int hf_shim6_len
;
89 static int hf_shim6_len_oct
;
90 static int hf_shim6_p
;
91 /* context tag is 49 bits, cannot be used for filter yet */
92 static int hf_shim6_ct
;
93 static int hf_shim6_type
;
94 static int hf_shim6_proto
;
95 static int hf_shim6_checksum
;
96 static int hf_shim6_checksum_status
;
97 static int hf_shim6_inonce
; /* also for request nonce */
98 static int hf_shim6_rnonce
;
99 static int hf_shim6_reserved
;
100 static int hf_shim6_reserved2
;
101 static int hf_shim6_precvd
;
102 static int hf_shim6_psent
;
103 static int hf_shim6_psrc
;
104 static int hf_shim6_pdst
;
105 static int hf_shim6_pnonce
;
106 static int hf_shim6_pdata
;
107 static int hf_shim6_sulid
;
108 static int hf_shim6_rulid
;
109 static int hf_shim6_reap
;
110 static int hf_shim6_opt_type
;
111 static int hf_shim6_opt_len
;
112 static int hf_shim6_opt_total_len
;
113 static int hf_shim6_opt_loc_verif_methods
;
114 static int hf_shim6_opt_critical
;
115 static int hf_shim6_opt_loclist
;
116 static int hf_shim6_locator
;
117 static int hf_shim6_loc_flag
;
118 static int hf_shim6_loc_prio
;
119 static int hf_shim6_loc_weight
;
120 static int hf_shim6_opt_locnum
;
121 static int hf_shim6_opt_elemlen
;
122 static int hf_shim6_opt_fii
;
123 static int hf_shim6_validator
;
124 static int hf_shim6_cga_parameter_data_structure
;
125 static int hf_shim6_cga_signature
;
126 static int hf_shim6_padding
;
128 static int ett_shim6_proto
;
129 static int ett_shim6_option
;
130 static int ett_shim6_locators
;
131 static int ett_shim6_verif_methods
;
132 static int ett_shim6_loc_pref
;
133 static int ett_shim6_probes_sent
;
134 static int ett_shim6_probe_sent
;
135 static int ett_shim6_probes_rcvd
;
136 static int ett_shim6_probe_rcvd
;
137 static int ett_shim6_cksum
;
139 static expert_field ei_shim6_opt_elemlen_invalid
;
140 static expert_field ei_shim6_checksum_bad
;
142 static const value_string shimoptvals
[] = {
143 { SHIM6_OPT_RESPVAL
, "Responder Validator Option" },
144 { SHIM6_OPT_LOCLIST
, "Locator List Option" },
145 { SHIM6_OPT_LOCPREF
, "Locator Preferences Option" },
146 { SHIM6_OPT_CGAPDM
, "CGA Parameter Data Structure Option" },
147 { SHIM6_OPT_CGASIG
, "CGA Signature Option" },
148 { SHIM6_OPT_ULIDPAIR
, "ULID Pair Option" },
149 { SHIM6_OPT_FII
, "Forked Instance Identifier Option" },
153 static const value_string shimverifmethods
[] = {
154 { SHIM6_VERIF_HBA
, "HBA" },
155 { SHIM6_VERIF_CGA
, "CGA" },
159 static const value_string shimflags
[] _U_
= {
160 { SHIM6_FLAG_BROKEN
, "BROKEN" },
161 { SHIM6_FLAG_TEMPORARY
, "TEMPORARY" },
165 static const value_string shimreapstates
[] = {
166 { SHIM6_REAP_OPERATIONAL
, "Operational" },
167 { SHIM6_REAP_EXPLORING
, "Exploring" },
168 { SHIM6_REAP_INBOUNDOK
, "InboundOK" },
172 static const value_string shim6_protocol
[] = {
180 dissect_shim6_opt_loclist(proto_tree
* opt_tree
, tvbuff_t
* tvb
, int *offset
)
186 proto_tree_add_item(opt_tree
, hf_shim6_opt_loclist
, tvb
, *offset
, 4, ENC_BIG_ENDIAN
);
189 optlen
= tvb_get_uint8(tvb
, *offset
);
190 proto_tree_add_item(opt_tree
, hf_shim6_opt_locnum
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
193 /* Verification Methods */
194 subtree
= proto_tree_add_subtree(opt_tree
, tvb
, *offset
, optlen
,
195 ett_shim6_verif_methods
, NULL
, "Locator Verification Methods");
197 for (count
=0; count
< optlen
; count
++)
198 proto_tree_add_item(subtree
, hf_shim6_opt_loc_verif_methods
, tvb
,
199 *offset
+count
, 1, ENC_BIG_ENDIAN
);
202 /* Padding, included in length field */
203 if ((7 - optlen
% 8) > 0) {
204 proto_tree_add_item(opt_tree
, hf_shim6_padding
, tvb
, *offset
, (7 - optlen
% 8), ENC_NA
);
205 *offset
+= (7 - optlen
% 8);
209 subtree
= proto_tree_add_subtree(opt_tree
, tvb
, *offset
, 16 * optlen
, ett_shim6_locators
, NULL
, "Locators");
211 for (count
=0; count
< optlen
; count
++) {
212 proto_tree_add_item(subtree
, hf_shim6_locator
, tvb
, *offset
, 16, ENC_NA
);
218 dissect_shim6_opt_loc_pref(proto_tree
* opt_tree
, tvbuff_t
* tvb
, int *offset
, int len
, packet_info
*pinfo
)
226 proto_tree_add_item(opt_tree
, hf_shim6_opt_loclist
, tvb
, *offset
, 4, ENC_BIG_ENDIAN
);
229 optlen
= tvb_get_uint8(tvb
, *offset
);
230 proto_tree_add_item(opt_tree
, hf_shim6_opt_elemlen
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
232 if (optlen
< 1 || optlen
> 3) {
233 proto_tree_add_expert_format(opt_tree
, pinfo
, &ei_shim6_opt_elemlen_invalid
, tvb
, *offset
, 1,
234 "Invalid element length: %u", optlen
);
240 /* Locator Preferences */
242 while (*offset
< len
) {
243 subtree
= proto_tree_add_subtree_format(opt_tree
, tvb
, *offset
, optlen
, ett_shim6_loc_pref
, NULL
,
244 "Locator Preferences %u", count
);
248 proto_tree_add_item(subtree
, hf_shim6_loc_flag
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
251 proto_tree_add_item(subtree
, hf_shim6_loc_prio
, tvb
, *offset
+1, 1, ENC_BIG_ENDIAN
);
254 proto_tree_add_item(subtree
, hf_shim6_loc_weight
, tvb
, *offset
+2, 1, ENC_BIG_ENDIAN
);
256 * Shim6 Draft 08 doesn't specify the format when the Element length is
257 * more than three, except that any such formats MUST be defined so that
258 * the first three octets are the same as in the above case, that is, a
259 * of a 1 octet flags field followed by a 1 octet priority field, and a
260 * 1 octet weight field.
269 dissect_shimopts(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, packet_info
*pinfo
)
273 proto_tree
*opt_tree
;
278 len
= tvb_get_ntohs(tvb
, offset
+2);
279 padding
= 7 - ((len
+ 3) % 8);
280 total_len
= 4 + len
+ padding
;
285 opt_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, total_len
, ett_shim6_option
, NULL
,
286 val_to_str_const( (tvb_get_ntohs(tvb
, offset
) & SHIM6_BITMASK_OPT_TYPE
) >> 1, shimoptvals
, "Unknown Option Type"));
288 proto_tree_add_item(opt_tree
, hf_shim6_opt_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
291 proto_tree_add_item(opt_tree
, hf_shim6_opt_critical
, tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
294 proto_tree_add_item(opt_tree
, hf_shim6_opt_len
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
295 ti
= proto_tree_add_uint(opt_tree
, hf_shim6_opt_total_len
, tvb
, offset
+2, 2, total_len
);
296 proto_item_set_generated(ti
);
298 /* Option Type Specific */
299 switch (tvb_get_ntohs(tvb
, offset
) >> 1)
301 case SHIM6_OPT_RESPVAL
:
302 proto_tree_add_item(opt_tree
, hf_shim6_validator
, tvb
, offset
, len
, ENC_NA
);
304 if (total_len
-(len
+4) > 0)
305 proto_tree_add_item(opt_tree
, hf_shim6_padding
, tvb
, offset
, total_len
-(len
+4), ENC_NA
);
307 case SHIM6_OPT_LOCLIST
:
308 dissect_shim6_opt_loclist(opt_tree
, tvb
, &offset
);
310 case SHIM6_OPT_LOCPREF
:
311 dissect_shim6_opt_loc_pref(opt_tree
, tvb
, &offset
, offset
+len
+4, pinfo
);
312 if (total_len
-(len
+4) > 0)
313 proto_tree_add_item(opt_tree
, hf_shim6_padding
, tvb
, offset
, total_len
-(len
+4), ENC_NA
);
315 case SHIM6_OPT_CGAPDM
:
316 proto_tree_add_item(opt_tree
, hf_shim6_cga_parameter_data_structure
, tvb
, offset
, len
, ENC_NA
);
318 if (total_len
-(len
+4) > 0)
319 proto_tree_add_item(opt_tree
, hf_shim6_padding
, tvb
, offset
, total_len
-(len
+4), ENC_NA
);
321 case SHIM6_OPT_CGASIG
:
322 proto_tree_add_item(opt_tree
, hf_shim6_cga_signature
, tvb
, offset
, len
, ENC_NA
);
324 if (total_len
-(len
+4) > 0)
325 proto_tree_add_item(opt_tree
, hf_shim6_padding
, tvb
, offset
, total_len
-(len
+4), ENC_NA
);
327 case SHIM6_OPT_ULIDPAIR
:
328 proto_tree_add_item(opt_tree
, hf_shim6_reserved
, tvb
, offset
, 4, ENC_NA
);
330 proto_tree_add_item(opt_tree
, hf_shim6_sulid
, tvb
, offset
, 16, ENC_NA
);
332 proto_tree_add_item(opt_tree
, hf_shim6_rulid
, tvb
, offset
, 16, ENC_NA
);
336 proto_tree_add_item(opt_tree
, hf_shim6_opt_fii
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
347 dissect_shim6_ct(packet_info
*pinfo
, proto_tree
* shim_tree
, int hf_item
, tvbuff_t
* tvb
, int offset
, const unsigned char * label
)
350 unsigned char *ct_str
;
352 tmp
[0] = tvb_get_uint8(tvb
, offset
++);
353 tmp
[1] = tvb_get_uint8(tvb
, offset
++);
354 tmp
[2] = tvb_get_uint8(tvb
, offset
++);
355 tmp
[3] = tvb_get_uint8(tvb
, offset
++);
356 tmp
[4] = tvb_get_uint8(tvb
, offset
++);
357 tmp
[5] = tvb_get_uint8(tvb
, offset
++);
359 ct_str
= wmem_strdup_printf(pinfo
->pool
,
360 "%s: %02X %02X %02X %02X %02X %02X", label
,
361 tmp
[0] & SHIM6_BITMASK_CT
, tmp
[1], tmp
[2],
362 tmp
[3], tmp
[4], tmp
[5]
364 proto_tree_add_none_format(shim_tree
, hf_item
, tvb
, offset
- 6, 6, "%s", ct_str
);
368 dissect_shim6_probes(proto_tree
* shim_tree
, tvbuff_t
* tvb
, int offset
,
369 const unsigned char * label
, unsigned nbr_probe
,
372 proto_tree
*probes_tree
;
373 proto_tree
*probe_tree
;
379 ett_probes
= ett_shim6_probes_rcvd
;
380 ett_probe
= ett_shim6_probe_rcvd
;
382 ett_probes
= ett_shim6_probes_sent
;
383 ett_probe
= ett_shim6_probe_sent
;
385 probes_tree
= proto_tree_add_subtree(shim_tree
, tvb
, offset
, 40 * nbr_probe
, ett_probes
, NULL
, label
);
387 for (count
=0; count
< nbr_probe
; count
++) {
388 probe_tree
= proto_tree_add_subtree_format(probes_tree
, tvb
, offset
, 40,
389 ett_probe
, NULL
, "Probe %u", count
+1);
391 proto_tree_add_item(probe_tree
, hf_shim6_psrc
, tvb
, offset
, 16, ENC_NA
);
393 proto_tree_add_item(probe_tree
, hf_shim6_pdst
, tvb
, offset
, 16, ENC_NA
);
396 proto_tree_add_item(probe_tree
, hf_shim6_pnonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
399 proto_tree_add_item(probe_tree
, hf_shim6_pdata
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
404 /* Dissect SHIM6 data: control messages */
406 dissect_shimctrl(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, unsigned type
, proto_tree
*shim_tree
)
410 unsigned probes_sent
;
411 unsigned probes_rcvd
;
416 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Initiator Context Tag");
418 proto_tree_add_item(shim_tree
, hf_shim6_inonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
422 proto_tree_add_item(shim_tree
, hf_shim6_reserved2
, tvb
, offset
, 2, ENC_NA
);
424 proto_tree_add_item(shim_tree
, hf_shim6_inonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
426 proto_tree_add_item(shim_tree
, hf_shim6_rnonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
430 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Initiator Context Tag");
432 proto_tree_add_item(shim_tree
, hf_shim6_inonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
434 proto_tree_add_item(shim_tree
, hf_shim6_rnonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
436 proto_tree_add_item(shim_tree
, hf_shim6_reserved2
, tvb
, offset
, 4, ENC_NA
);
440 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Responder Context Tag");
442 proto_tree_add_item(shim_tree
, hf_shim6_inonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
445 case SHIM6_TYPE_R1BIS
:
446 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Packet Context Tag");
448 proto_tree_add_item(shim_tree
, hf_shim6_rnonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
451 case SHIM6_TYPE_I2BIS
:
452 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Initiator Context Tag");
454 proto_tree_add_item(shim_tree
, hf_shim6_inonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
456 proto_tree_add_item(shim_tree
, hf_shim6_rnonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
458 proto_tree_add_item(shim_tree
, hf_shim6_reserved2
, tvb
, offset
, 6, ENC_NA
);
460 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Initiator Context Tag");
463 case SHIM6_TYPE_UPD_REQ
:
464 case SHIM6_TYPE_UPD_ACK
:
465 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Receiver Context Tag");
467 proto_tree_add_item(shim_tree
, hf_shim6_rnonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
470 case SHIM6_TYPE_KEEPALIVE
:
471 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Receiver Context Tag");
473 proto_tree_add_item(shim_tree
, hf_shim6_reserved2
, tvb
, offset
, 4, ENC_NA
);
476 case SHIM6_TYPE_PROBE
:
477 dissect_shim6_ct(pinfo
, shim_tree
, hf_shim6_ct
, tvb
, offset
, "Receiver Context Tag");
480 tmp
= tvb_get_uint8(tvb
, offset
);
481 probes_sent
= tmp
& SHIM6_BITMASK_PSENT
;
482 probes_rcvd
= (tmp
& SHIM6_BITMASK_PRECVD
) >> 4;
483 proto_tree_add_item(shim_tree
, hf_shim6_psent
, tvb
,
484 offset
, 1, ENC_BIG_ENDIAN
);
485 proto_tree_add_item(shim_tree
, hf_shim6_precvd
, tvb
,
486 offset
, 1, ENC_BIG_ENDIAN
);
489 sta
= val_to_str_const((tvb_get_uint8(tvb
, offset
) & SHIM6_BITMASK_STA
) >> 6,
490 shimreapstates
, "Unknown REAP State");
491 proto_tree_add_uint_format_value(shim_tree
, hf_shim6_reap
, tvb
,
492 offset
, 1, (tvb_get_uint8(tvb
, offset
) & SHIM6_BITMASK_STA
) >> 6,
495 proto_tree_add_item(shim_tree
, hf_shim6_reserved2
, tvb
, offset
, 3, ENC_NA
);
500 dissect_shim6_probes(shim_tree
, tvb
, offset
, "Probes Sent",
502 offset
+= 40 * probes_sent
;
505 /* Probes Received */
507 dissect_shim6_probes(shim_tree
, tvb
, offset
, "Probes Received",
509 offset
+= 40 * probes_rcvd
;
518 /* Dissect SHIM6 data: payload, common part, options */
519 static const value_string shimctrlvals
[] = {
520 { SHIM6_TYPE_I1
, "I1" },
521 { SHIM6_TYPE_R1
, "R1" },
522 { SHIM6_TYPE_I2
, "I2" },
523 { SHIM6_TYPE_R2
, "R2" },
524 { SHIM6_TYPE_R1BIS
, "R1bis" },
525 { SHIM6_TYPE_I2BIS
, "I2bis" },
526 { SHIM6_TYPE_UPD_REQ
, "Update Request" },
527 { SHIM6_TYPE_UPD_ACK
, "Update Acknowledgment" },
528 { SHIM6_TYPE_KEEPALIVE
, "Keepalive" },
529 { SHIM6_TYPE_PROBE
, "Probe" },
534 dissect_shim6(tvbuff_t
*tvb
, packet_info
* pinfo
, proto_tree
*tree
, void* data
)
536 struct ip6_shim shim
;
538 proto_tree
*shim_tree
, *root_tree
;
539 proto_item
*ti
, *ti_len
;
543 tvb_memcpy(tvb
, (uint8_t *)&shim
, offset
, sizeof(shim
));
544 len
= (shim
.ip6s_len
+ 1) << 3;
547 if (shim
.ip6s_p
& SHIM6_BITMASK_P
) {
548 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " , ", "Shim6 (Payload)");
551 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " , ", "Shim6 (%s)",
552 val_to_str_const(shim
.ip6s_p
& SHIM6_BITMASK_TYPE
, shimctrlvals
, "Unknown"));
555 root_tree
= p_ipv6_pinfo_select_root(pinfo
, tree
);
556 p_ipv6_pinfo_add_len(pinfo
, len
);
558 ti
= proto_tree_add_item(root_tree
, proto_shim6
, tvb
, offset
, len
, ENC_NA
);
559 shim_tree
= proto_item_add_subtree(ti
, ett_shim6_proto
);
562 proto_tree_add_uint_format_value(shim_tree
, hf_shim6_nxt
, tvb
,
563 offset
, 1, shim
.ip6s_nxt
,
564 "%s (%u)", ipprotostr(shim
.ip6s_nxt
), shim
.ip6s_nxt
);
567 /* Header Extension Length */
568 ti_len
= proto_tree_add_item(shim_tree
, hf_shim6_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
569 ti
= proto_tree_add_uint(shim_tree
, hf_shim6_len_oct
, tvb
, offset
, 1, len
);
570 proto_item_append_text(ti
, " bytes");
571 proto_item_set_generated(ti
);
572 proto_item_set_hidden(ti
);
573 proto_item_append_text(ti_len
, " (%d bytes)", len
);
577 proto_tree_add_item(shim_tree
, hf_shim6_p
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
579 if (shim
.ip6s_p
& SHIM6_BITMASK_P
) {
580 tmp
[0] = tvb_get_uint8(tvb
, offset
+1);
581 tmp
[1] = tvb_get_uint8(tvb
, offset
+2);
582 tmp
[2] = tvb_get_uint8(tvb
, offset
+3);
583 tmp
[3] = tvb_get_uint8(tvb
, offset
+4);
584 tmp
[4] = tvb_get_uint8(tvb
, offset
+5);
586 /* Payload Extension Header */
587 proto_tree_add_none_format(shim_tree
, hf_shim6_ct
, tvb
,
589 "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
590 shim
.ip6s_p
& SHIM6_BITMASK_CT
, tmp
[0], tmp
[1], tmp
[2], tmp
[3], tmp
[4]);
592 /* Control Message */
597 proto_tree_add_item(shim_tree
, hf_shim6_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
599 /* Protocol bit (Must be zero for SHIM6) */
600 proto_tree_add_item(shim_tree
, hf_shim6_proto
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
604 csum
= ip_checksum_tvb(tvb
, 0, len
);
605 proto_tree_add_checksum(shim_tree
, tvb
, offset
, hf_shim6_checksum
, hf_shim6_checksum_status
, &ei_shim6_checksum_bad
, pinfo
, csum
,
606 ENC_BIG_ENDIAN
, PROTO_CHECKSUM_VERIFY
|PROTO_CHECKSUM_IN_CKSUM
);
608 col_append_str(pinfo
->cinfo
, COL_INFO
, " [Shim6 CHECKSUM INCORRECT]");
611 /* Type specific data */
612 advance
= dissect_shimctrl(pinfo
, tvb
, offset
, shim
.ip6s_p
& SHIM6_BITMASK_TYPE
, shim_tree
);
616 while (offset
< len
) {
617 offset
+= dissect_shimopts(tvb
, offset
, shim_tree
, pinfo
);
621 next_tvb
= tvb_new_subset_remaining(tvb
, len
);
622 ipv6_dissect_next(shim
.ip6s_nxt
, next_tvb
, pinfo
, tree
, (ws_ip6
*)data
);
623 return tvb_captured_length(tvb
);
627 proto_register_shim6(void)
629 static hf_register_info hf_shim6
[] = {
631 { "Next Header", "shim6.nxt",
632 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
636 { "Length", "shim6.len",
637 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
638 "Extension header length in 8-octet words (minus 1)", HFILL
}
641 { "Length", "shim6.len_oct",
642 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
643 "Extension header length in octets", HFILL
}
646 { "P Bit", "shim6.p",
647 FT_BOOLEAN
, 8, NULL
, SHIM6_BITMASK_P
,
651 { "Context Tag", "shim6.ct",
652 FT_NONE
, BASE_NONE
, NULL
, 0x0,
656 { "Message Type", "shim6.type",
657 FT_UINT8
, BASE_DEC
, VALS(shimctrlvals
), SHIM6_BITMASK_TYPE
,
661 { "Protocol", "shim6.proto",
662 FT_UINT8
, BASE_DEC
, VALS(shim6_protocol
), SHIM6_BITMASK_PROTOCOL
,
665 { &hf_shim6_checksum
,
666 { "Checksum", "shim6.checksum",
667 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
668 "Shim6 Checksum", HFILL
}
670 { &hf_shim6_checksum_status
,
671 { "Checksum Status", "shim6.checksum.status",
672 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
676 { "Initiator Nonce", "shim6.inonce",
677 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
681 { "Responder Nonce", "shim6.rnonce",
682 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
685 { &hf_shim6_reserved
,
686 { "Reserved", "shim6.reserved",
687 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
690 { &hf_shim6_reserved2
,
691 { "Reserved2", "shim6.reserved2",
692 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
696 { "Probes Received", "shim6.precvd",
697 FT_UINT8
, BASE_DEC
, NULL
, SHIM6_BITMASK_PRECVD
,
701 { "Probes Sent", "shim6.psent",
702 FT_UINT8
, BASE_DEC
, NULL
, SHIM6_BITMASK_PSENT
,
706 { "Source Address", "shim6.psrc",
707 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
708 "Shim6 Probe Source Address", HFILL
}
711 { "Destination Address", "shim6.pdst",
712 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
713 "Shim6 Probe Destination Address", HFILL
}
716 { "Nonce", "shim6.pnonce",
717 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
718 "Shim6 Probe Nonce", HFILL
}
721 { "Data", "shim6.pdata",
722 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
723 "Shim6 Probe Data", HFILL
}
726 { "Sender ULID", "shim6.sulid",
727 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
728 "Shim6 Sender ULID", HFILL
}
731 { "Receiver ULID", "shim6.rulid",
732 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
733 "Shim6 Receiver ULID", HFILL
}
736 { "REAP State", "shim6.reap",
737 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
740 { &hf_shim6_opt_type
,
741 { "Option Type", "shim6.opt.type",
742 FT_UINT16
, BASE_DEC
, VALS(shimoptvals
), SHIM6_BITMASK_OPT_TYPE
,
743 "Shim6 Option Type", HFILL
}
745 { &hf_shim6_opt_critical
,
746 { "Option Critical Bit", "shim6.opt.critical",
747 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), SHIM6_BITMASK_CRITICAL
,
748 "true: option is critical, false: option is not critical", HFILL
}
751 { "Content Length", "shim6.opt.len",
752 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
753 "Content Length Option", HFILL
}
755 { &hf_shim6_opt_total_len
,
756 { "Total Length", "shim6.opt.total_len",
757 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
758 "Total Option Length", HFILL
}
760 { &hf_shim6_opt_loc_verif_methods
,
761 { "Verification Method", "shim6.opt.verif_method",
762 FT_UINT8
, BASE_DEC
, VALS(shimverifmethods
), 0x0,
763 "Locator Verification Method", HFILL
}
765 { &hf_shim6_opt_loclist
,
766 { "Locator List Generation", "shim6.opt.loclist",
767 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
771 { "Locator", "shim6.locator",
772 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
773 "Shim6 Locator", HFILL
}
775 { &hf_shim6_opt_locnum
,
776 { "Num Locators", "shim6.opt.locnum",
777 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
778 "Number of locators in Locator List", HFILL
}
780 { &hf_shim6_opt_elemlen
,
781 { "Element Length", "shim6.opt.elemlen",
782 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
783 "Length of Elements in Locator Preferences Option", HFILL
}
785 { &hf_shim6_loc_flag
,
786 { "Flags", "shim6.loc.flags",
787 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
788 "Locator Preferences Flags", HFILL
}
790 { &hf_shim6_loc_prio
,
791 { "Priority", "shim6.loc.prio",
792 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
793 "Locator Preferences Priority", HFILL
}
795 { &hf_shim6_loc_weight
,
796 { "Weight", "shim6.loc.weight",
797 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
798 "Locator Preferences Weight", HFILL
}
801 { "Forked Instance Identifier", "shim6.opt.fii",
802 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
805 { &hf_shim6_validator
,
806 { "Validator", "shim6.validator",
807 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
810 { &hf_shim6_cga_parameter_data_structure
,
811 { "CGA Parameter Data Structure", "shim6.cga_parameter_data_structure",
812 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
815 { &hf_shim6_cga_signature
,
816 { "CGA Signature", "shim6.cga_signature",
817 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
821 { "Padding", "shim6.padding",
822 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
827 static int *ett_shim6
[] = {
831 &ett_shim6_verif_methods
,
833 &ett_shim6_probes_sent
,
834 &ett_shim6_probes_rcvd
,
835 &ett_shim6_probe_sent
,
836 &ett_shim6_probe_rcvd
,
840 static ei_register_info ei_shim6
[] = {
841 { &ei_shim6_opt_elemlen_invalid
,
842 { "shim6.opt.elemlen.invalid", PI_MALFORMED
, PI_ERROR
,
843 "Invalid element length", EXPFILL
}
845 { &ei_shim6_checksum_bad
,
846 { "shim6.checksum_bad.expert", PI_CHECKSUM
, PI_ERROR
,
847 "Bad checksum", EXPFILL
}
851 expert_module_t
* expert_shim6
;
853 proto_shim6
= proto_register_protocol("Shim6 Protocol", "Shim6", "shim6");
854 proto_register_field_array(proto_shim6
, hf_shim6
, array_length(hf_shim6
));
855 proto_register_subtree_array(ett_shim6
, array_length(ett_shim6
));
856 expert_shim6
= expert_register_protocol(proto_shim6
);
857 expert_register_field_array(expert_shim6
, ei_shim6
, array_length(ei_shim6
));
858 shim6_handle
= register_dissector("shim6", dissect_shim6
, proto_shim6
);
862 proto_reg_handoff_shim6(void)
864 dissector_add_uint("ip.proto", IP_PROTO_SHIM6
, shim6_handle
);
873 * indent-tabs-mode: nil
876 * ex: set shiftwidth=4 tabstop=8 expandtab:
877 * :indentSize=4:tabSize=8:noTabs=true: