Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-shim6.c
blob9f26d67a95a9b2e045c6db6e891afcbdcf168d6f
1 /* packet-shim6.c
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
9 * RFC 5533
11 * SHIM6 support added by Matthijs Mekking <matthijs@NLnetLabs.nl>
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/expert.h>
18 #include <epan/tfs.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;
30 /* SHIM6 header */
31 struct ip6_shim {
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 */
50 /* SHIM6 Options */
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 */
59 /* SHIM6 Bitmasks */
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 */
76 /* SHIM6 Flags */
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" },
150 { 0, NULL }
153 static const value_string shimverifmethods[] = {
154 { SHIM6_VERIF_HBA, "HBA" },
155 { SHIM6_VERIF_CGA, "CGA" },
156 { 0, NULL }
159 static const value_string shimflags[] _U_ = {
160 { SHIM6_FLAG_BROKEN, "BROKEN" },
161 { SHIM6_FLAG_TEMPORARY, "TEMPORARY" },
162 { 0, NULL }
165 static const value_string shimreapstates[] = {
166 { SHIM6_REAP_OPERATIONAL, "Operational" },
167 { SHIM6_REAP_EXPLORING, "Exploring" },
168 { SHIM6_REAP_INBOUNDOK, "InboundOK" },
169 { 0, NULL }
172 static const value_string shim6_protocol[] = {
173 { 0, "SHIM6" },
174 { 1, "HIP" },
175 { 0, NULL }
179 static void
180 dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, int *offset)
182 proto_tree *subtree;
183 unsigned count;
184 unsigned optlen;
186 proto_tree_add_item(opt_tree, hf_shim6_opt_loclist, tvb, *offset, 4, ENC_BIG_ENDIAN);
187 *offset += 4;
189 optlen = tvb_get_uint8(tvb, *offset);
190 proto_tree_add_item(opt_tree, hf_shim6_opt_locnum, tvb, *offset, 1, ENC_BIG_ENDIAN);
191 *offset += 1;
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);
200 *offset += optlen;
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);
208 /* Locators */
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);
213 *offset += 16;
217 static void
218 dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, int *offset, int len, packet_info *pinfo)
220 proto_tree *subtree;
222 int optlen;
223 int count;
226 proto_tree_add_item(opt_tree, hf_shim6_opt_loclist, tvb, *offset, 4, ENC_BIG_ENDIAN);
227 *offset += 4;
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);
235 return;
238 *offset += 1;
240 /* Locator Preferences */
241 count = 1;
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);
246 /* Flags */
247 if (optlen >= 1)
248 proto_tree_add_item(subtree, hf_shim6_loc_flag, tvb, *offset, 1, ENC_BIG_ENDIAN);
249 /* Priority */
250 if (optlen >= 2)
251 proto_tree_add_item(subtree, hf_shim6_loc_prio, tvb, *offset+1, 1, ENC_BIG_ENDIAN);
252 /* Weight */
253 if (optlen >= 3)
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.
262 *offset += optlen;
263 count++;
268 static int
269 dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo)
271 int len, total_len;
272 int padding;
273 proto_tree *opt_tree;
274 proto_item *ti;
276 offset += 4;
278 len = tvb_get_ntohs(tvb, offset+2);
279 padding = 7 - ((len + 3) % 8);
280 total_len = 4 + len + padding;
282 if (tree)
284 /* Option Type */
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);
290 /* Critical */
291 proto_tree_add_item(opt_tree, hf_shim6_opt_critical, tvb, offset+1, 1, ENC_BIG_ENDIAN);
293 /* Content Length */
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);
303 offset += len;
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);
306 break;
307 case SHIM6_OPT_LOCLIST:
308 dissect_shim6_opt_loclist(opt_tree, tvb, &offset);
309 break;
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);
314 break;
315 case SHIM6_OPT_CGAPDM:
316 proto_tree_add_item(opt_tree, hf_shim6_cga_parameter_data_structure, tvb, offset, len, ENC_NA);
317 offset += len;
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);
320 break;
321 case SHIM6_OPT_CGASIG:
322 proto_tree_add_item(opt_tree, hf_shim6_cga_signature, tvb, offset, len, ENC_NA);
323 offset += len;
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);
326 break;
327 case SHIM6_OPT_ULIDPAIR:
328 proto_tree_add_item(opt_tree, hf_shim6_reserved, tvb, offset, 4, ENC_NA);
329 offset += 4;
330 proto_tree_add_item(opt_tree, hf_shim6_sulid, tvb, offset, 16, ENC_NA);
331 offset += 16;
332 proto_tree_add_item(opt_tree, hf_shim6_rulid, tvb, offset, 16, ENC_NA);
333 offset += 16;
334 break;
335 case SHIM6_OPT_FII:
336 proto_tree_add_item(opt_tree, hf_shim6_opt_fii, tvb, offset, 4, ENC_BIG_ENDIAN);
337 offset += 4;
338 break;
339 default:
340 break;
343 return total_len;
346 static void
347 dissect_shim6_ct(packet_info *pinfo, proto_tree * shim_tree, int hf_item, tvbuff_t * tvb, int offset, const unsigned char * label)
349 uint8_t tmp[6];
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);
367 static void
368 dissect_shim6_probes(proto_tree * shim_tree, tvbuff_t * tvb, int offset,
369 const unsigned char * label, unsigned nbr_probe,
370 bool probes_rcvd)
372 proto_tree *probes_tree;
373 proto_tree *probe_tree;
374 int ett_probes;
375 int ett_probe;
376 unsigned count;
378 if (probes_rcvd) {
379 ett_probes = ett_shim6_probes_rcvd;
380 ett_probe = ett_shim6_probe_rcvd;
381 } else {
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);
392 offset += 16;
393 proto_tree_add_item(probe_tree, hf_shim6_pdst, tvb, offset, 16, ENC_NA);
394 offset += 16;
396 proto_tree_add_item(probe_tree, hf_shim6_pnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
397 offset += 4;
399 proto_tree_add_item(probe_tree, hf_shim6_pdata, tvb, offset, 4, ENC_BIG_ENDIAN);
400 offset += 4;
404 /* Dissect SHIM6 data: control messages */
405 static int
406 dissect_shimctrl(packet_info *pinfo, tvbuff_t *tvb, int offset, unsigned type, proto_tree *shim_tree)
408 uint8_t tmp;
409 const char *sta;
410 unsigned probes_sent;
411 unsigned probes_rcvd;
413 switch (type)
415 case SHIM6_TYPE_I1:
416 dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
417 offset += 6;
418 proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
419 offset += 4;
420 break;
421 case SHIM6_TYPE_R1:
422 proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 2, ENC_NA);
423 offset += 2;
424 proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
425 offset += 4;
426 proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
427 offset += 4;
428 break;
429 case SHIM6_TYPE_I2:
430 dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
431 offset += 6;
432 proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
433 offset += 4;
434 proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
435 offset += 4;
436 proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 4, ENC_NA);
437 offset += 4;
438 break;
439 case SHIM6_TYPE_R2:
440 dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Responder Context Tag");
441 offset += 6;
442 proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
443 offset += 4;
444 break;
445 case SHIM6_TYPE_R1BIS:
446 dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Packet Context Tag");
447 offset += 6;
448 proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
449 offset += 4;
450 break;
451 case SHIM6_TYPE_I2BIS:
452 dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
453 offset += 6;
454 proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
455 offset += 4;
456 proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
457 offset += 4;
458 proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 6, ENC_NA);
459 offset += 6;
460 dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
461 offset += 6;
462 break;
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");
466 offset += 6;
467 proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
468 offset += 4;
469 break;
470 case SHIM6_TYPE_KEEPALIVE:
471 dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Receiver Context Tag");
472 offset += 6;
473 proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 4, ENC_NA);
474 offset += 4;
475 break;
476 case SHIM6_TYPE_PROBE:
477 dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Receiver Context Tag");
478 offset += 6;
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);
487 offset += 1;
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,
493 "%s", sta);
495 proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 3, ENC_NA);
496 offset += 3;
498 /* Probes Sent */
499 if (probes_sent) {
500 dissect_shim6_probes(shim_tree, tvb, offset, "Probes Sent",
501 probes_sent, false);
502 offset += 40 * probes_sent;
505 /* Probes Received */
506 if (probes_rcvd) {
507 dissect_shim6_probes(shim_tree, tvb, offset, "Probes Received",
508 probes_rcvd, true);
509 offset += 40 * probes_rcvd;
511 break;
512 default:
513 break;
515 return offset;
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" },
530 { 0, NULL }
533 static int
534 dissect_shim6(tvbuff_t *tvb, packet_info * pinfo, proto_tree *tree, void* data)
536 struct ip6_shim shim;
537 int offset = 0, len;
538 proto_tree *shim_tree, *root_tree;
539 proto_item *ti, *ti_len;
540 uint8_t tmp[5];
541 tvbuff_t *next_tvb;
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)");
550 else {
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);
561 /* Next Header */
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);
565 offset += 1;
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);
574 offset += 1;
576 /* P Field */
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,
588 offset, 6,
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]);
591 } else {
592 /* Control Message */
593 uint16_t csum;
594 int advance;
596 /* Message Type */
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);
601 offset++;
603 /* Checksum */
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);
607 if (csum != 0)
608 col_append_str(pinfo->cinfo, COL_INFO, " [Shim6 CHECKSUM INCORRECT]");
609 offset += 2;
611 /* Type specific data */
612 advance = dissect_shimctrl(pinfo, tvb, offset, shim.ip6s_p & SHIM6_BITMASK_TYPE, shim_tree);
613 offset += advance;
615 /* Options */
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);
626 void
627 proto_register_shim6(void)
629 static hf_register_info hf_shim6[] = {
630 { &hf_shim6_nxt,
631 { "Next Header", "shim6.nxt",
632 FT_UINT8, BASE_DEC, NULL, 0x0,
633 NULL, HFILL }
635 { &hf_shim6_len,
636 { "Length", "shim6.len",
637 FT_UINT8, BASE_DEC, NULL, 0x0,
638 "Extension header length in 8-octet words (minus 1)", HFILL }
640 { &hf_shim6_len_oct,
641 { "Length", "shim6.len_oct",
642 FT_UINT16, BASE_DEC, NULL, 0x0,
643 "Extension header length in octets", HFILL }
645 { &hf_shim6_p,
646 { "P Bit", "shim6.p",
647 FT_BOOLEAN, 8, NULL, SHIM6_BITMASK_P,
648 NULL, HFILL }
650 { &hf_shim6_ct,
651 { "Context Tag", "shim6.ct",
652 FT_NONE, BASE_NONE, NULL, 0x0,
653 NULL, HFILL }
655 { &hf_shim6_type,
656 { "Message Type", "shim6.type",
657 FT_UINT8, BASE_DEC, VALS(shimctrlvals), SHIM6_BITMASK_TYPE,
658 NULL, HFILL }
660 { &hf_shim6_proto,
661 { "Protocol", "shim6.proto",
662 FT_UINT8, BASE_DEC, VALS(shim6_protocol), SHIM6_BITMASK_PROTOCOL,
663 NULL, HFILL }
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,
673 NULL, HFILL }
675 { &hf_shim6_inonce,
676 { "Initiator Nonce", "shim6.inonce",
677 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
678 NULL, HFILL }
680 { &hf_shim6_rnonce,
681 { "Responder Nonce", "shim6.rnonce",
682 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
683 NULL, HFILL }
685 { &hf_shim6_reserved,
686 { "Reserved", "shim6.reserved",
687 FT_BYTES, BASE_NONE, NULL, 0x0,
688 NULL, HFILL }
690 { &hf_shim6_reserved2,
691 { "Reserved2", "shim6.reserved2",
692 FT_BYTES, BASE_NONE, NULL, 0x0,
693 NULL, HFILL }
695 { &hf_shim6_precvd,
696 { "Probes Received", "shim6.precvd",
697 FT_UINT8, BASE_DEC, NULL, SHIM6_BITMASK_PRECVD,
698 NULL, HFILL }
700 { &hf_shim6_psent,
701 { "Probes Sent", "shim6.psent",
702 FT_UINT8, BASE_DEC, NULL, SHIM6_BITMASK_PSENT,
703 NULL, HFILL }
705 { &hf_shim6_psrc,
706 { "Source Address", "shim6.psrc",
707 FT_IPv6, BASE_NONE, NULL, 0x0,
708 "Shim6 Probe Source Address", HFILL }
710 { &hf_shim6_pdst,
711 { "Destination Address", "shim6.pdst",
712 FT_IPv6, BASE_NONE, NULL, 0x0,
713 "Shim6 Probe Destination Address", HFILL }
715 { &hf_shim6_pnonce,
716 { "Nonce", "shim6.pnonce",
717 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
718 "Shim6 Probe Nonce", HFILL }
720 { &hf_shim6_pdata,
721 { "Data", "shim6.pdata",
722 FT_UINT32, BASE_HEX, NULL, 0x0,
723 "Shim6 Probe Data", HFILL }
725 { &hf_shim6_sulid,
726 { "Sender ULID", "shim6.sulid",
727 FT_IPv6, BASE_NONE, NULL, 0x0,
728 "Shim6 Sender ULID", HFILL }
730 { &hf_shim6_rulid,
731 { "Receiver ULID", "shim6.rulid",
732 FT_IPv6, BASE_NONE, NULL, 0x0,
733 "Shim6 Receiver ULID", HFILL }
735 { &hf_shim6_reap,
736 { "REAP State", "shim6.reap",
737 FT_UINT8, BASE_DEC, NULL, 0x0,
738 NULL, HFILL }
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 }
750 { &hf_shim6_opt_len,
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,
768 NULL, HFILL }
770 { &hf_shim6_locator,
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 }
800 { &hf_shim6_opt_fii,
801 { "Forked Instance Identifier", "shim6.opt.fii",
802 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
803 NULL, HFILL }
805 { &hf_shim6_validator,
806 { "Validator", "shim6.validator",
807 FT_BYTES, BASE_NONE, NULL, 0x0,
808 NULL, HFILL }
810 { &hf_shim6_cga_parameter_data_structure,
811 { "CGA Parameter Data Structure", "shim6.cga_parameter_data_structure",
812 FT_BYTES, BASE_NONE, NULL, 0x0,
813 NULL, HFILL }
815 { &hf_shim6_cga_signature,
816 { "CGA Signature", "shim6.cga_signature",
817 FT_BYTES, BASE_NONE, NULL, 0x0,
818 NULL, HFILL }
820 { &hf_shim6_padding,
821 { "Padding", "shim6.padding",
822 FT_BYTES, BASE_NONE, NULL, 0x0,
823 NULL, HFILL }
827 static int *ett_shim6[] = {
828 &ett_shim6_proto,
829 &ett_shim6_option,
830 &ett_shim6_locators,
831 &ett_shim6_verif_methods,
832 &ett_shim6_loc_pref,
833 &ett_shim6_probes_sent,
834 &ett_shim6_probes_rcvd,
835 &ett_shim6_probe_sent,
836 &ett_shim6_probe_rcvd,
837 &ett_shim6_cksum
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);
861 void
862 proto_reg_handoff_shim6(void)
864 dissector_add_uint("ip.proto", IP_PROTO_SHIM6, shim6_handle);
868 * Editor modelines
870 * Local Variables:
871 * c-basic-offset: 4
872 * tab-width: 8
873 * indent-tabs-mode: nil
874 * End:
876 * ex: set shiftwidth=4 tabstop=8 expandtab:
877 * :indentSize=4:tabSize=8:noTabs=true: