Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-shim6.c
Line
Count
Source
1
/* packet-shim6.c
2
 *
3
 * Wireshark - Network traffic analyzer
4
 * By Gerald Combs <gerald@wireshark.org>
5
 * Copyright 1998 Gerald Combs
6
 *
7
 * SPDX-License-Identifier: GPL-2.0-or-later
8
 *
9
 * RFC 5533
10
 *
11
 * SHIM6 support added by Matthijs Mekking <matthijs@NLnetLabs.nl>
12
 */
13
14
#include "config.h"
15
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/iana-info.h>
22
23
#include "packet-ip.h"
24
25
void proto_register_shim6(void);
26
void proto_reg_handoff_shim6(void);
27
28
static dissector_handle_t shim6_handle;
29
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*/
36
};
37
38
/* SHIM6 control message types */
39
5
#define SHIM6_TYPE_I1           0x01    /* 0 000 0001 */
40
2
#define SHIM6_TYPE_R1           0x02    /* 0 000 0010 */
41
3
#define SHIM6_TYPE_I2           0x03    /* 0 000 0011 */
42
10
#define SHIM6_TYPE_R2           0x04    /* 0 000 0100 */
43
1
#define SHIM6_TYPE_R1BIS        0x05    /* 0 000 0101 */
44
4
#define SHIM6_TYPE_I2BIS        0x06    /* 0 000 0110 */
45
3
#define SHIM6_TYPE_UPD_REQ      0x40    /* 0 100 0000 = 64 */
46
5
#define SHIM6_TYPE_UPD_ACK      0x41    /* 0 100 0001 = 65 */
47
1
#define SHIM6_TYPE_KEEPALIVE    0x42    /* 0 100 0010 = 66 */
48
8
#define SHIM6_TYPE_PROBE        0x43    /* 0 100 0011 = 67 */
49
50
/* SHIM6 Options */
51
1
#define SHIM6_OPT_RESPVAL       0x01    /* 0 000 0001 */
52
24
#define SHIM6_OPT_LOCLIST       0x02    /* 0 000 0010 */
53
12
#define SHIM6_OPT_LOCPREF       0x03    /* 0 000 0011 */
54
2
#define SHIM6_OPT_CGAPDM        0x04    /* 0 000 0100 */
55
2
#define SHIM6_OPT_CGASIG        0x05    /* 0 000 0101 */
56
1
#define SHIM6_OPT_ULIDPAIR      0x06    /* 0 000 0110 */
57
2
#define SHIM6_OPT_FII           0x07    /* 0 000 0111 */
58
59
/* SHIM6 Bitmasks */
60
264
#define SHIM6_BITMASK_P         0x80    /* 1 000 0000 */
61
244
#define SHIM6_BITMASK_TYPE      0x7F    /* 0 111 1111 */
62
16
#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
50
#define SHIM6_BITMASK_CT        0x7F    /* 0 111 1111 */
66
284
#define SHIM6_BITMASK_OPT_TYPE  0xFFFE  /* 1 111 1111    1 111 1110 */
67
16
#define SHIM6_BITMASK_CRITICAL  0x01    /* 0 000 0001 */
68
24
#define SHIM6_BITMASK_PRECVD    0xF0    /* 1 111 0000 */
69
24
#define SHIM6_BITMASK_PSENT     0x0F    /* 0 000 1111 */
70
16
#define SHIM6_BITMASK_STA       0xC0    /* 1 100 0000 */
71
72
/* SHIM6 Verification Methods */
73
#define SHIM6_VERIF_HBA         0x01    /* 0 000 0001 */
74
#define SHIM6_VERIF_CGA         0x02    /* 0 000 0010 */
75
76
/* SHIM6 Flags */
77
#define SHIM6_FLAG_BROKEN       0x01    /* 0 000 0001 */
78
#define SHIM6_FLAG_TEMPORARY    0x02    /* 0 000 0010 */
79
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 */
84
85
static int proto_shim6;
86
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;
127
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;
138
139
static expert_field ei_shim6_opt_elemlen_invalid;
140
static expert_field ei_shim6_checksum_bad;
141
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 }
151
};
152
153
static const value_string shimverifmethods[] = {
154
    { SHIM6_VERIF_HBA, "HBA" },
155
    { SHIM6_VERIF_CGA, "CGA" },
156
    { 0, NULL }
157
};
158
159
static const value_string shimflags[] _U_ = {
160
    { SHIM6_FLAG_BROKEN,    "BROKEN" },
161
    { SHIM6_FLAG_TEMPORARY, "TEMPORARY" },
162
    { 0, NULL }
163
};
164
165
static const value_string shimreapstates[] = {
166
    { SHIM6_REAP_OPERATIONAL, "Operational" },
167
    { SHIM6_REAP_EXPLORING,   "Exploring" },
168
    { SHIM6_REAP_INBOUNDOK,   "InboundOK" },
169
    { 0, NULL }
170
};
171
172
static const value_string shim6_protocol[] = {
173
    { 0, "SHIM6" },
174
    { 1, "HIP" },
175
    { 0, NULL }
176
};
177
178
179
static void
180
dissect_shim6_opt_loclist(proto_tree * opt_tree, tvbuff_t * tvb, int *offset)
181
24
{
182
24
    proto_tree *subtree;
183
24
    unsigned    count;
184
24
    unsigned    optlen;
185
186
24
    proto_tree_add_item(opt_tree, hf_shim6_opt_loclist, tvb, *offset, 4, ENC_BIG_ENDIAN);
187
24
    *offset += 4;
188
189
24
    optlen = tvb_get_uint8(tvb, *offset);
190
24
    proto_tree_add_item(opt_tree, hf_shim6_opt_locnum, tvb, *offset, 1, ENC_BIG_ENDIAN);
191
24
    *offset += 1;
192
193
    /* Verification Methods */
194
24
    subtree = proto_tree_add_subtree(opt_tree, tvb, *offset, optlen,
195
24
                             ett_shim6_verif_methods, NULL, "Locator Verification Methods");
196
197
1.49k
    for (count=0; count < optlen; count++)
198
1.47k
        proto_tree_add_item(subtree, hf_shim6_opt_loc_verif_methods, tvb,
199
1.47k
                            *offset+count, 1, ENC_BIG_ENDIAN);
200
24
    *offset += optlen;
201
202
    /* Padding, included in length field */
203
24
    if ((7 - optlen % 8) > 0) {
204
20
        proto_tree_add_item(opt_tree, hf_shim6_padding, tvb, *offset, (7 - optlen % 8), ENC_NA);
205
20
        *offset += (7 - optlen % 8);
206
20
    }
207
208
    /* Locators */
209
24
    subtree = proto_tree_add_subtree(opt_tree, tvb, *offset, 16 * optlen, ett_shim6_locators, NULL, "Locators");
210
211
231
    for (count=0; count < optlen; count++) {
212
207
        proto_tree_add_item(subtree, hf_shim6_locator, tvb, *offset, 16, ENC_NA);
213
207
        *offset += 16;
214
207
    }
215
24
}
216
217
static void
218
dissect_shim6_opt_loc_pref(proto_tree * opt_tree, tvbuff_t * tvb, int *offset, int len, packet_info *pinfo)
219
12
{
220
12
    proto_tree *subtree;
221
222
12
    int         optlen;
223
12
    int         count;
224
225
226
12
    proto_tree_add_item(opt_tree, hf_shim6_opt_loclist, tvb, *offset, 4, ENC_BIG_ENDIAN);
227
12
    *offset += 4;
228
229
12
    optlen = tvb_get_uint8(tvb, *offset);
230
12
    proto_tree_add_item(opt_tree, hf_shim6_opt_elemlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
231
232
12
    if (optlen < 1 || optlen > 3) {
233
3
        proto_tree_add_expert_format(opt_tree, pinfo, &ei_shim6_opt_elemlen_invalid, tvb, *offset, 1,
234
3
                                     "Invalid element length: %u", optlen);
235
3
        return;
236
3
    }
237
238
9
    *offset += 1;
239
240
    /* Locator Preferences */
241
9
    count = 1;
242
3.09k
    while (*offset < len) {
243
3.08k
        subtree = proto_tree_add_subtree_format(opt_tree, tvb, *offset, optlen, ett_shim6_loc_pref, NULL,
244
3.08k
                                                "Locator Preferences %u", count);
245
246
        /* Flags */
247
3.08k
        if (optlen >= 1)
248
3.07k
            proto_tree_add_item(subtree, hf_shim6_loc_flag, tvb, *offset, 1, ENC_BIG_ENDIAN);
249
        /* Priority */
250
3.08k
        if (optlen >= 2)
251
0
            proto_tree_add_item(subtree, hf_shim6_loc_prio, tvb, *offset+1, 1, ENC_BIG_ENDIAN);
252
        /* Weight */
253
3.08k
        if (optlen >= 3)
254
0
            proto_tree_add_item(subtree, hf_shim6_loc_weight, tvb, *offset+2, 1, ENC_BIG_ENDIAN);
255
        /*
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.
261
         */
262
3.08k
        *offset += optlen;
263
3.08k
        count++;
264
3.08k
    }
265
9
}
266
267
268
static int
269
dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo)
270
268
{
271
268
    int          len, total_len;
272
268
    int          padding;
273
268
    proto_tree  *opt_tree;
274
268
    proto_item  *ti;
275
276
268
    offset += 4;
277
278
268
    len = tvb_get_ntohs(tvb, offset+2);
279
268
    padding = 7 - ((len + 3) % 8);
280
268
    total_len = 4 + len + padding;
281
282
268
    if (tree)
283
268
    {
284
        /* Option Type */
285
268
        opt_tree = proto_tree_add_subtree(tree, tvb, offset, total_len, ett_shim6_option, NULL,
286
268
                            val_to_str_const( (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, shimoptvals, "Unknown Option Type"));
287
288
268
        proto_tree_add_item(opt_tree, hf_shim6_opt_type, tvb, offset, 2, ENC_BIG_ENDIAN);
289
290
        /* Critical */
291
268
        proto_tree_add_item(opt_tree, hf_shim6_opt_critical, tvb, offset+1, 1, ENC_BIG_ENDIAN);
292
293
        /* Content Length */
294
268
        proto_tree_add_item(opt_tree, hf_shim6_opt_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
295
268
        ti = proto_tree_add_uint(opt_tree, hf_shim6_opt_total_len, tvb, offset+2, 2, total_len);
296
268
        proto_item_set_generated(ti);
297
298
        /* Option Type Specific */
299
268
        switch (tvb_get_ntohs(tvb, offset) >> 1)
300
268
        {
301
1
        case SHIM6_OPT_RESPVAL:
302
1
            proto_tree_add_item(opt_tree, hf_shim6_validator, tvb, offset, len, ENC_NA);
303
1
            offset += len;
304
1
            if (total_len-(len+4) > 0)
305
1
                proto_tree_add_item(opt_tree, hf_shim6_padding, tvb, offset, total_len-(len+4), ENC_NA);
306
1
            break;
307
24
        case SHIM6_OPT_LOCLIST:
308
24
            dissect_shim6_opt_loclist(opt_tree, tvb, &offset);
309
24
            break;
310
12
        case SHIM6_OPT_LOCPREF:
311
12
            dissect_shim6_opt_loc_pref(opt_tree, tvb, &offset, offset+len+4, pinfo);
312
12
            if (total_len-(len+4) > 0)
313
4
                proto_tree_add_item(opt_tree, hf_shim6_padding, tvb, offset, total_len-(len+4), ENC_NA);
314
12
            break;
315
2
        case SHIM6_OPT_CGAPDM:
316
2
            proto_tree_add_item(opt_tree, hf_shim6_cga_parameter_data_structure, tvb, offset, len, ENC_NA);
317
2
            offset += len;
318
2
            if (total_len-(len+4) > 0)
319
2
                proto_tree_add_item(opt_tree, hf_shim6_padding, tvb, offset, total_len-(len+4), ENC_NA);
320
2
            break;
321
2
        case SHIM6_OPT_CGASIG:
322
2
            proto_tree_add_item(opt_tree, hf_shim6_cga_signature, tvb, offset, len, ENC_NA);
323
2
            offset += len;
324
2
            if (total_len-(len+4) > 0)
325
1
                proto_tree_add_item(opt_tree, hf_shim6_padding, tvb, offset, total_len-(len+4), ENC_NA);
326
2
            break;
327
1
        case SHIM6_OPT_ULIDPAIR:
328
1
            proto_tree_add_item(opt_tree, hf_shim6_reserved, tvb, offset, 4, ENC_NA);
329
1
            offset += 4;
330
1
            proto_tree_add_item(opt_tree, hf_shim6_sulid, tvb, offset, 16, ENC_NA);
331
1
            offset += 16;
332
1
            proto_tree_add_item(opt_tree, hf_shim6_rulid, tvb, offset, 16, ENC_NA);
333
1
            offset += 16;
334
1
            break;
335
2
        case SHIM6_OPT_FII:
336
2
            proto_tree_add_item(opt_tree, hf_shim6_opt_fii, tvb, offset, 4, ENC_BIG_ENDIAN);
337
2
            offset += 4;
338
2
            break;
339
224
        default:
340
224
            break;
341
268
        }
342
268
    }
343
244
    return total_len;
344
268
}
345
346
static void
347
dissect_shim6_ct(packet_info *pinfo, proto_tree * shim_tree, int hf_item, tvbuff_t * tvb, int offset, const char * label)
348
40
{
349
40
    uint8_t tmp[6];
350
40
    const char *ct_str;
351
352
40
    tmp[0] = tvb_get_uint8(tvb, offset++);
353
40
    tmp[1] = tvb_get_uint8(tvb, offset++);
354
40
    tmp[2] = tvb_get_uint8(tvb, offset++);
355
40
    tmp[3] = tvb_get_uint8(tvb, offset++);
356
40
    tmp[4] = tvb_get_uint8(tvb, offset++);
357
40
    tmp[5] = tvb_get_uint8(tvb, offset++);
358
359
40
    ct_str = wmem_strdup_printf(pinfo->pool,
360
40
                                "%s: %02X %02X %02X %02X %02X %02X", label,
361
40
                                tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2],
362
40
                                tmp[3], tmp[4], tmp[5]
363
40
        );
364
40
    proto_tree_add_none_format(shim_tree, hf_item, tvb, offset - 6, 6, "%s", ct_str);
365
40
}
366
367
static void
368
dissect_shim6_probes(proto_tree * shim_tree, tvbuff_t * tvb, int offset,
369
                     const char * label, unsigned nbr_probe,
370
                     bool probes_rcvd)
371
9
{
372
9
    proto_tree *probes_tree;
373
9
    proto_tree *probe_tree;
374
9
    int         ett_probes;
375
9
    int         ett_probe;
376
9
    unsigned    count;
377
378
9
    if (probes_rcvd) {
379
2
        ett_probes = ett_shim6_probes_rcvd;
380
2
        ett_probe = ett_shim6_probe_rcvd;
381
7
    } else {
382
7
        ett_probes = ett_shim6_probes_sent;
383
7
        ett_probe = ett_shim6_probe_sent;
384
7
    }
385
9
    probes_tree = proto_tree_add_subtree(shim_tree, tvb, offset, 40 * nbr_probe, ett_probes, NULL, label);
386
387
44
    for (count=0; count < nbr_probe; count++) {
388
35
        probe_tree = proto_tree_add_subtree_format(probes_tree, tvb, offset, 40,
389
35
                                            ett_probe, NULL, "Probe %u", count+1);
390
391
35
        proto_tree_add_item(probe_tree, hf_shim6_psrc, tvb, offset, 16, ENC_NA);
392
35
        offset += 16;
393
35
        proto_tree_add_item(probe_tree, hf_shim6_pdst, tvb, offset, 16, ENC_NA);
394
35
        offset += 16;
395
396
35
        proto_tree_add_item(probe_tree, hf_shim6_pnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
397
35
        offset += 4;
398
399
35
        proto_tree_add_item(probe_tree, hf_shim6_pdata, tvb, offset, 4, ENC_BIG_ENDIAN);
400
35
        offset += 4;
401
35
    }
402
9
}
403
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)
407
112
{
408
112
    uint8_t      tmp;
409
112
    const char *sta;
410
112
    unsigned     probes_sent;
411
112
    unsigned     probes_rcvd;
412
413
112
    switch (type)
414
112
    {
415
5
    case SHIM6_TYPE_I1:
416
5
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
417
5
        offset += 6;
418
5
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
419
5
        offset += 4;
420
5
        break;
421
2
    case SHIM6_TYPE_R1:
422
2
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 2, ENC_NA);
423
2
        offset += 2;
424
2
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
425
2
        offset += 4;
426
2
        proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
427
2
        offset += 4;
428
2
        break;
429
3
    case SHIM6_TYPE_I2:
430
3
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
431
3
        offset += 6;
432
3
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
433
3
        offset += 4;
434
3
        proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
435
3
        offset += 4;
436
3
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 4, ENC_NA);
437
3
        offset += 4;
438
3
        break;
439
10
    case SHIM6_TYPE_R2:
440
10
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Responder Context Tag");
441
10
        offset += 6;
442
10
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
443
10
        offset += 4;
444
10
        break;
445
1
    case SHIM6_TYPE_R1BIS:
446
1
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Packet Context Tag");
447
1
        offset += 6;
448
1
        proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
449
1
        offset += 4;
450
1
        break;
451
4
    case SHIM6_TYPE_I2BIS:
452
4
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
453
4
        offset += 6;
454
4
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
455
4
        offset += 4;
456
4
        proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
457
4
        offset += 4;
458
4
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 6, ENC_NA);
459
4
        offset += 6;
460
4
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
461
4
        offset += 6;
462
4
        break;
463
3
    case SHIM6_TYPE_UPD_REQ:
464
5
    case SHIM6_TYPE_UPD_ACK:
465
5
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Receiver Context Tag");
466
5
        offset += 6;
467
5
        proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
468
5
        offset += 4;
469
5
        break;
470
1
    case SHIM6_TYPE_KEEPALIVE:
471
1
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Receiver Context Tag");
472
1
        offset += 6;
473
1
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 4, ENC_NA);
474
1
        offset += 4;
475
1
        break;
476
8
    case SHIM6_TYPE_PROBE:
477
8
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Receiver Context Tag");
478
8
        offset += 6;
479
480
8
        tmp = tvb_get_uint8(tvb, offset);
481
8
        probes_sent = tmp & SHIM6_BITMASK_PSENT;
482
8
        probes_rcvd = (tmp & SHIM6_BITMASK_PRECVD) >> 4;
483
8
        proto_tree_add_item(shim_tree, hf_shim6_psent, tvb,
484
8
                            offset, 1, ENC_BIG_ENDIAN);
485
8
        proto_tree_add_item(shim_tree, hf_shim6_precvd, tvb,
486
8
                            offset, 1, ENC_BIG_ENDIAN);
487
8
        offset += 1;
488
489
8
        sta = val_to_str_const((tvb_get_uint8(tvb, offset) & SHIM6_BITMASK_STA) >> 6,
490
8
                               shimreapstates, "Unknown REAP State");
491
8
        proto_tree_add_uint_format_value(shim_tree, hf_shim6_reap, tvb,
492
8
                                         offset, 1, (tvb_get_uint8(tvb, offset) & SHIM6_BITMASK_STA) >> 6,
493
8
                                         "%s", sta);
494
495
8
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 3, ENC_NA);
496
8
        offset += 3;
497
498
        /* Probes Sent */
499
8
        if (probes_sent) {
500
7
            dissect_shim6_probes(shim_tree, tvb, offset, "Probes Sent",
501
7
                                 probes_sent, false);
502
7
            offset += 40 * probes_sent;
503
7
        }
504
505
        /* Probes Received */
506
8
        if (probes_rcvd) {
507
2
            dissect_shim6_probes(shim_tree, tvb, offset, "Probes Received",
508
2
                                 probes_rcvd, true);
509
2
            offset += 40 * probes_rcvd;
510
2
        }
511
8
        break;
512
73
    default:
513
73
        break;
514
112
    }
515
100
    return offset;
516
112
}
517
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 }
531
};
532
533
static int
534
dissect_shim6(tvbuff_t *tvb, packet_info * pinfo, proto_tree *tree, void* data)
535
124
{
536
124
    struct ip6_shim  shim;
537
124
    int              offset = 0, len;
538
124
    proto_tree      *shim_tree, *root_tree;
539
124
    proto_item      *ti, *ti_len;
540
124
    uint8_t          tmp[5];
541
124
    tvbuff_t        *next_tvb;
542
543
124
    tvb_memcpy(tvb, (uint8_t *)&shim, offset, sizeof(shim));
544
124
    len = (shim.ip6s_len + 1) << 3;
545
546
547
124
    if (shim.ip6s_p & SHIM6_BITMASK_P) {
548
10
        col_append_sep_str(pinfo->cinfo, COL_INFO, " , ", "Shim6 (Payload)");
549
10
    }
550
114
    else {
551
114
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " , ", "Shim6 (%s)",
552
114
                        val_to_str_const(shim.ip6s_p & SHIM6_BITMASK_TYPE, shimctrlvals, "Unknown"));
553
114
    }
554
555
124
    root_tree = p_ipv6_pinfo_select_root(pinfo, tree);
556
124
    p_ipv6_pinfo_add_len(pinfo, len);
557
558
124
    ti = proto_tree_add_item(root_tree, proto_shim6, tvb, offset, len, ENC_NA);
559
124
    shim_tree = proto_item_add_subtree(ti, ett_shim6_proto);
560
561
    /* Next Header */
562
124
    proto_tree_add_uint_format_value(shim_tree, hf_shim6_nxt, tvb,
563
124
                                     offset, 1, shim.ip6s_nxt,
564
124
                                     "%s (%u)", ipprotostr(shim.ip6s_nxt), shim.ip6s_nxt);
565
124
    offset += 1;
566
567
    /* Header Extension Length */
568
124
    ti_len = proto_tree_add_item(shim_tree, hf_shim6_len, tvb, offset, 1, ENC_BIG_ENDIAN);
569
124
    ti = proto_tree_add_uint(shim_tree, hf_shim6_len_oct, tvb, offset, 1, len);
570
124
    proto_item_append_text(ti, " bytes");
571
124
    proto_item_set_generated(ti);
572
124
    proto_item_set_hidden(ti);
573
124
    proto_item_append_text(ti_len, " (%d bytes)", len);
574
124
    offset += 1;
575
576
    /* P Field */
577
124
    proto_tree_add_item(shim_tree, hf_shim6_p, tvb, offset, 1, ENC_BIG_ENDIAN);
578
579
124
    if (shim.ip6s_p & SHIM6_BITMASK_P) {
580
10
        tmp[0] = tvb_get_uint8(tvb, offset+1);
581
10
        tmp[1] = tvb_get_uint8(tvb, offset+2);
582
10
        tmp[2] = tvb_get_uint8(tvb, offset+3);
583
10
        tmp[3] = tvb_get_uint8(tvb, offset+4);
584
10
        tmp[4] = tvb_get_uint8(tvb, offset+5);
585
586
        /* Payload Extension Header */
587
10
        proto_tree_add_none_format(shim_tree, hf_shim6_ct, tvb,
588
10
                                   offset, 6,
589
10
                                   "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
590
10
                                   shim.ip6s_p & SHIM6_BITMASK_CT, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]);
591
114
    } else {
592
        /* Control Message */
593
114
        uint16_t csum;
594
114
        int advance;
595
596
        /* Message Type */
597
114
        proto_tree_add_item(shim_tree, hf_shim6_type, tvb, offset, 1, ENC_BIG_ENDIAN);
598
599
        /* Protocol bit (Must be zero for SHIM6) */
600
114
        proto_tree_add_item(shim_tree, hf_shim6_proto, tvb, offset, 1, ENC_BIG_ENDIAN);
601
114
        offset++;
602
603
        /* Checksum */
604
114
        csum = ip_checksum_tvb(tvb, 0, len);
605
114
        proto_tree_add_checksum(shim_tree, tvb, offset, hf_shim6_checksum, hf_shim6_checksum_status, &ei_shim6_checksum_bad, pinfo, csum,
606
114
                                ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM);
607
114
        if (csum != 0)
608
111
            col_append_str(pinfo->cinfo, COL_INFO, " [Shim6 CHECKSUM INCORRECT]");
609
114
        offset += 2;
610
611
        /* Type specific data */
612
114
        advance = dissect_shimctrl(pinfo, tvb, offset, shim.ip6s_p & SHIM6_BITMASK_TYPE, shim_tree);
613
114
        offset += advance;
614
615
        /* Options */
616
382
        while (offset < len) {
617
268
            offset += dissect_shimopts(tvb, offset, shim_tree, pinfo);
618
268
        }
619
114
    }
620
621
124
    next_tvb = tvb_new_subset_remaining(tvb, len);
622
124
    ipv6_dissect_next(shim.ip6s_nxt, next_tvb, pinfo, tree, (ws_ip6 *)data);
623
124
    return tvb_captured_length(tvb);
624
124
}
625
626
void
627
proto_register_shim6(void)
628
16
{
629
16
    static hf_register_info hf_shim6[] = {
630
16
        { &hf_shim6_nxt,
631
16
            { "Next Header", "shim6.nxt",
632
16
                FT_UINT8, BASE_DEC, NULL, 0x0,
633
16
                NULL, HFILL }
634
16
        },
635
16
        { &hf_shim6_len,
636
16
            { "Length", "shim6.len",
637
16
                FT_UINT8, BASE_DEC, NULL, 0x0,
638
16
                "Extension header length in 8-octet words (minus 1)", HFILL }
639
16
        },
640
16
        { &hf_shim6_len_oct,
641
16
            { "Length", "shim6.len_oct",
642
16
                FT_UINT16, BASE_DEC, NULL, 0x0,
643
16
                "Extension header length in octets", HFILL }
644
16
        },
645
16
        { &hf_shim6_p,
646
16
            { "P Bit", "shim6.p",
647
16
                FT_BOOLEAN, 8, NULL, SHIM6_BITMASK_P,
648
16
                NULL, HFILL }
649
16
        },
650
16
        { &hf_shim6_ct,
651
16
            { "Context Tag", "shim6.ct",
652
16
                FT_NONE, BASE_NONE, NULL, 0x0,
653
16
                NULL, HFILL }
654
16
        },
655
16
        { &hf_shim6_type,
656
16
            { "Message Type", "shim6.type",
657
16
                FT_UINT8, BASE_DEC, VALS(shimctrlvals), SHIM6_BITMASK_TYPE,
658
16
                NULL, HFILL }
659
16
        },
660
16
        { &hf_shim6_proto,
661
16
            { "Protocol", "shim6.proto",
662
16
                FT_UINT8, BASE_DEC, VALS(shim6_protocol), SHIM6_BITMASK_PROTOCOL,
663
16
                NULL, HFILL }
664
16
        },
665
16
        { &hf_shim6_checksum,
666
16
            { "Checksum", "shim6.checksum",
667
16
                FT_UINT16, BASE_HEX, NULL, 0x0,
668
16
                "Shim6 Checksum", HFILL }
669
16
        },
670
16
        { &hf_shim6_checksum_status,
671
16
            { "Checksum Status", "shim6.checksum.status",
672
16
                FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
673
16
                NULL, HFILL }
674
16
        },
675
16
        { &hf_shim6_inonce,
676
16
            { "Initiator Nonce", "shim6.inonce",
677
16
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
678
16
                NULL, HFILL }
679
16
        },
680
16
        { &hf_shim6_rnonce,
681
16
            { "Responder Nonce", "shim6.rnonce",
682
16
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
683
16
                NULL, HFILL }
684
16
        },
685
16
        { &hf_shim6_reserved,
686
16
            { "Reserved", "shim6.reserved",
687
16
                FT_BYTES, BASE_NONE, NULL, 0x0,
688
16
                NULL, HFILL }
689
16
        },
690
16
        { &hf_shim6_reserved2,
691
16
            { "Reserved2", "shim6.reserved2",
692
16
                FT_BYTES, BASE_NONE, NULL, 0x0,
693
16
                NULL, HFILL }
694
16
        },
695
16
        { &hf_shim6_precvd,
696
16
            { "Probes Received", "shim6.precvd",
697
16
                FT_UINT8, BASE_DEC, NULL, SHIM6_BITMASK_PRECVD,
698
16
                NULL, HFILL }
699
16
        },
700
16
        { &hf_shim6_psent,
701
16
            { "Probes Sent", "shim6.psent",
702
16
                FT_UINT8, BASE_DEC, NULL, SHIM6_BITMASK_PSENT,
703
16
                NULL, HFILL }
704
16
        },
705
16
        { &hf_shim6_psrc,
706
16
            { "Source Address", "shim6.psrc",
707
16
                FT_IPv6, BASE_NONE, NULL, 0x0,
708
16
                "Shim6 Probe Source Address", HFILL }
709
16
        },
710
16
        { &hf_shim6_pdst,
711
16
            { "Destination Address", "shim6.pdst",
712
16
                FT_IPv6, BASE_NONE, NULL, 0x0,
713
16
                "Shim6 Probe Destination Address", HFILL }
714
16
        },
715
16
        { &hf_shim6_pnonce,
716
16
            { "Nonce", "shim6.pnonce",
717
16
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
718
16
                "Shim6 Probe Nonce", HFILL }
719
16
        },
720
16
        { &hf_shim6_pdata,
721
16
            { "Data", "shim6.pdata",
722
16
                FT_UINT32, BASE_HEX, NULL, 0x0,
723
16
                "Shim6 Probe Data", HFILL }
724
16
        },
725
16
        { &hf_shim6_sulid,
726
16
            { "Sender ULID", "shim6.sulid",
727
16
                FT_IPv6, BASE_NONE, NULL, 0x0,
728
16
                "Shim6 Sender ULID", HFILL }
729
16
        },
730
16
        { &hf_shim6_rulid,
731
16
            { "Receiver ULID", "shim6.rulid",
732
16
                FT_IPv6, BASE_NONE, NULL, 0x0,
733
16
                "Shim6 Receiver ULID", HFILL }
734
16
        },
735
16
        { &hf_shim6_reap,
736
16
            { "REAP State", "shim6.reap",
737
16
                FT_UINT8, BASE_DEC, NULL, 0x0,
738
16
                NULL, HFILL }
739
16
        },
740
16
        { &hf_shim6_opt_type,
741
16
            { "Option Type", "shim6.opt.type",
742
16
                FT_UINT16, BASE_DEC, VALS(shimoptvals), SHIM6_BITMASK_OPT_TYPE,
743
16
                "Shim6 Option Type", HFILL }
744
16
        },
745
16
        { &hf_shim6_opt_critical,
746
16
            { "Option Critical Bit", "shim6.opt.critical",
747
16
                FT_BOOLEAN, 8, TFS(&tfs_yes_no), SHIM6_BITMASK_CRITICAL,
748
16
                "true: option is critical, false: option is not critical", HFILL }
749
16
        },
750
16
        { &hf_shim6_opt_len,
751
16
            { "Content Length", "shim6.opt.len",
752
16
                FT_UINT16, BASE_DEC, NULL, 0x0,
753
16
                "Content Length Option", HFILL }
754
16
        },
755
16
        { &hf_shim6_opt_total_len,
756
16
            { "Total Length", "shim6.opt.total_len",
757
16
                FT_UINT16, BASE_DEC, NULL, 0x0,
758
16
                "Total Option Length", HFILL }
759
16
        },
760
16
        { &hf_shim6_opt_loc_verif_methods,
761
16
            { "Verification Method", "shim6.opt.verif_method",
762
16
                FT_UINT8, BASE_DEC, VALS(shimverifmethods), 0x0,
763
16
                "Locator Verification Method", HFILL }
764
16
        },
765
16
        { &hf_shim6_opt_loclist,
766
16
            { "Locator List Generation", "shim6.opt.loclist",
767
16
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
768
16
                NULL, HFILL }
769
16
        },
770
16
        { &hf_shim6_locator,
771
16
            { "Locator", "shim6.locator",
772
16
                FT_IPv6, BASE_NONE, NULL, 0x0,
773
16
                "Shim6 Locator", HFILL }
774
16
        },
775
16
        { &hf_shim6_opt_locnum,
776
16
            { "Num Locators", "shim6.opt.locnum",
777
16
                FT_UINT8, BASE_DEC, NULL, 0x0,
778
16
                "Number of locators in Locator List", HFILL }
779
16
        },
780
16
        { &hf_shim6_opt_elemlen,
781
16
            { "Element Length", "shim6.opt.elemlen",
782
16
                FT_UINT8, BASE_DEC, NULL, 0x0,
783
16
                "Length of Elements in Locator Preferences Option", HFILL }
784
16
        },
785
16
        { &hf_shim6_loc_flag,
786
16
            { "Flags", "shim6.loc.flags",
787
16
                FT_UINT8, BASE_DEC, NULL, 0x0,
788
16
                "Locator Preferences Flags", HFILL }
789
16
        },
790
16
        { &hf_shim6_loc_prio,
791
16
            { "Priority", "shim6.loc.prio",
792
16
                FT_UINT8, BASE_DEC, NULL, 0x0,
793
16
                "Locator Preferences Priority", HFILL }
794
16
        },
795
16
        { &hf_shim6_loc_weight,
796
16
            { "Weight", "shim6.loc.weight",
797
16
                FT_UINT8, BASE_DEC, NULL, 0x0,
798
16
                "Locator Preferences Weight", HFILL }
799
16
        },
800
16
        { &hf_shim6_opt_fii,
801
16
            { "Forked Instance Identifier", "shim6.opt.fii",
802
16
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
803
16
                NULL, HFILL }
804
16
        },
805
16
        { &hf_shim6_validator,
806
16
            { "Validator", "shim6.validator",
807
16
                FT_BYTES, BASE_NONE, NULL, 0x0,
808
16
                NULL, HFILL }
809
16
        },
810
16
        { &hf_shim6_cga_parameter_data_structure,
811
16
            { "CGA Parameter Data Structure", "shim6.cga_parameter_data_structure",
812
16
                FT_BYTES, BASE_NONE, NULL, 0x0,
813
16
                NULL, HFILL }
814
16
        },
815
16
        { &hf_shim6_cga_signature,
816
16
            { "CGA Signature", "shim6.cga_signature",
817
16
                FT_BYTES, BASE_NONE, NULL, 0x0,
818
16
                NULL, HFILL }
819
16
        },
820
16
        { &hf_shim6_padding,
821
16
            { "Padding", "shim6.padding",
822
16
                FT_BYTES, BASE_NONE, NULL, 0x0,
823
16
                NULL, HFILL }
824
16
        }
825
16
    };
826
827
16
    static int *ett_shim6[] = {
828
16
        &ett_shim6_proto,
829
16
        &ett_shim6_option,
830
16
        &ett_shim6_locators,
831
16
        &ett_shim6_verif_methods,
832
16
        &ett_shim6_loc_pref,
833
16
        &ett_shim6_probes_sent,
834
16
        &ett_shim6_probes_rcvd,
835
16
        &ett_shim6_probe_sent,
836
16
        &ett_shim6_probe_rcvd,
837
16
        &ett_shim6_cksum
838
16
    };
839
840
16
    static ei_register_info ei_shim6[] = {
841
16
        { &ei_shim6_opt_elemlen_invalid,
842
16
            { "shim6.opt.elemlen.invalid", PI_MALFORMED, PI_ERROR,
843
16
                "Invalid element length", EXPFILL }
844
16
        },
845
16
        { &ei_shim6_checksum_bad,
846
16
            { "shim6.checksum_bad.expert", PI_CHECKSUM, PI_ERROR,
847
16
                "Bad checksum", EXPFILL }
848
16
        }
849
16
    };
850
851
16
    expert_module_t* expert_shim6;
852
853
16
    proto_shim6 = proto_register_protocol("Shim6 Protocol", "Shim6", "shim6");
854
16
    proto_register_field_array(proto_shim6, hf_shim6, array_length(hf_shim6));
855
16
    proto_register_subtree_array(ett_shim6, array_length(ett_shim6));
856
16
    expert_shim6 = expert_register_protocol(proto_shim6);
857
16
    expert_register_field_array(expert_shim6, ei_shim6, array_length(ei_shim6));
858
16
    shim6_handle = register_dissector("shim6", dissect_shim6, proto_shim6);
859
16
}
860
861
void
862
proto_reg_handoff_shim6(void)
863
16
{
864
16
    dissector_add_uint("ip.proto", IP_PROTO_SHIM6, shim6_handle);
865
16
}
866
867
/*
868
 * Editor modelines
869
 *
870
 * Local Variables:
871
 * c-basic-offset: 4
872
 * tab-width: 8
873
 * indent-tabs-mode: nil
874
 * End:
875
 *
876
 * ex: set shiftwidth=4 tabstop=8 expandtab:
877
 * :indentSize=4:tabSize=8:noTabs=true:
878
 */