Coverage Report

Created: 2025-12-27 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
22
#include "packet-ip.h"
23
#include "packet-iana-data.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
4
#define SHIM6_TYPE_I1           0x01    /* 0 000 0001 */
40
4
#define SHIM6_TYPE_R1           0x02    /* 0 000 0010 */
41
2
#define SHIM6_TYPE_I2           0x03    /* 0 000 0011 */
42
5
#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
2
#define SHIM6_TYPE_KEEPALIVE    0x42    /* 0 100 0010 = 66 */
48
14
#define SHIM6_TYPE_PROBE        0x43    /* 0 100 0011 = 67 */
49
50
/* SHIM6 Options */
51
1
#define SHIM6_OPT_RESPVAL       0x01    /* 0 000 0001 */
52
15
#define SHIM6_OPT_LOCLIST       0x02    /* 0 000 0010 */
53
12
#define SHIM6_OPT_LOCPREF       0x03    /* 0 000 0011 */
54
3
#define SHIM6_OPT_CGAPDM        0x04    /* 0 000 0100 */
55
2
#define SHIM6_OPT_CGASIG        0x05    /* 0 000 0101 */
56
2
#define SHIM6_OPT_ULIDPAIR      0x06    /* 0 000 0110 */
57
2
#define SHIM6_OPT_FII           0x07    /* 0 000 0111 */
58
59
/* SHIM6 Bitmasks */
60
260
#define SHIM6_BITMASK_P         0x80    /* 1 000 0000 */
61
242
#define SHIM6_BITMASK_TYPE      0x7F    /* 0 111 1111 */
62
14
#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
163
#define SHIM6_BITMASK_OPT_TYPE  0xFFFE  /* 1 111 1111    1 111 1110 */
67
14
#define SHIM6_BITMASK_CRITICAL  0x01    /* 0 000 0001 */
68
28
#define SHIM6_BITMASK_PRECVD    0xF0    /* 1 111 0000 */
69
28
#define SHIM6_BITMASK_PSENT     0x0F    /* 0 000 1111 */
70
28
#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
15
{
182
15
    proto_tree *subtree;
183
15
    unsigned    count;
184
15
    unsigned    optlen;
185
186
15
    proto_tree_add_item(opt_tree, hf_shim6_opt_loclist, tvb, *offset, 4, ENC_BIG_ENDIAN);
187
15
    *offset += 4;
188
189
15
    optlen = tvb_get_uint8(tvb, *offset);
190
15
    proto_tree_add_item(opt_tree, hf_shim6_opt_locnum, tvb, *offset, 1, ENC_BIG_ENDIAN);
191
15
    *offset += 1;
192
193
    /* Verification Methods */
194
15
    subtree = proto_tree_add_subtree(opt_tree, tvb, *offset, optlen,
195
15
                             ett_shim6_verif_methods, NULL, "Locator Verification Methods");
196
197
1.55k
    for (count=0; count < optlen; count++)
198
1.53k
        proto_tree_add_item(subtree, hf_shim6_opt_loc_verif_methods, tvb,
199
1.53k
                            *offset+count, 1, ENC_BIG_ENDIAN);
200
15
    *offset += optlen;
201
202
    /* Padding, included in length field */
203
15
    if ((7 - optlen % 8) > 0) {
204
10
        proto_tree_add_item(opt_tree, hf_shim6_padding, tvb, *offset, (7 - optlen % 8), ENC_NA);
205
10
        *offset += (7 - optlen % 8);
206
10
    }
207
208
    /* Locators */
209
15
    subtree = proto_tree_add_subtree(opt_tree, tvb, *offset, 16 * optlen, ett_shim6_locators, NULL, "Locators");
210
211
118
    for (count=0; count < optlen; count++) {
212
103
        proto_tree_add_item(subtree, hf_shim6_locator, tvb, *offset, 16, ENC_NA);
213
103
        *offset += 16;
214
103
    }
215
15
}
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.28k
    while (*offset < len) {
243
3.28k
        subtree = proto_tree_add_subtree_format(opt_tree, tvb, *offset, optlen, ett_shim6_loc_pref, NULL,
244
3.28k
                                                "Locator Preferences %u", count);
245
246
        /* Flags */
247
3.28k
        if (optlen >= 1)
248
3.28k
            proto_tree_add_item(subtree, hf_shim6_loc_flag, tvb, *offset, 1, ENC_BIG_ENDIAN);
249
        /* Priority */
250
3.28k
        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.28k
        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.28k
        *offset += optlen;
263
3.28k
        count++;
264
3.28k
    }
265
9
}
266
267
268
static int
269
dissect_shimopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo)
270
149
{
271
149
    int          len, total_len;
272
149
    int          padding;
273
149
    proto_tree  *opt_tree;
274
149
    proto_item  *ti;
275
276
149
    offset += 4;
277
278
149
    len = tvb_get_ntohs(tvb, offset+2);
279
149
    padding = 7 - ((len + 3) % 8);
280
149
    total_len = 4 + len + padding;
281
282
149
    if (tree)
283
149
    {
284
        /* Option Type */
285
149
        opt_tree = proto_tree_add_subtree(tree, tvb, offset, total_len, ett_shim6_option, NULL,
286
149
                            val_to_str_const( (tvb_get_ntohs(tvb, offset) & SHIM6_BITMASK_OPT_TYPE) >> 1, shimoptvals, "Unknown Option Type"));
287
288
149
        proto_tree_add_item(opt_tree, hf_shim6_opt_type, tvb, offset, 2, ENC_BIG_ENDIAN);
289
290
        /* Critical */
291
149
        proto_tree_add_item(opt_tree, hf_shim6_opt_critical, tvb, offset+1, 1, ENC_BIG_ENDIAN);
292
293
        /* Content Length */
294
149
        proto_tree_add_item(opt_tree, hf_shim6_opt_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
295
149
        ti = proto_tree_add_uint(opt_tree, hf_shim6_opt_total_len, tvb, offset+2, 2, total_len);
296
149
        proto_item_set_generated(ti);
297
298
        /* Option Type Specific */
299
149
        switch (tvb_get_ntohs(tvb, offset) >> 1)
300
149
        {
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
15
        case SHIM6_OPT_LOCLIST:
308
15
            dissect_shim6_opt_loclist(opt_tree, tvb, &offset);
309
15
            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
3
        case SHIM6_OPT_CGAPDM:
316
3
            proto_tree_add_item(opt_tree, hf_shim6_cga_parameter_data_structure, tvb, offset, len, ENC_NA);
317
3
            offset += len;
318
3
            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
3
            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
2
        case SHIM6_OPT_ULIDPAIR:
328
2
            proto_tree_add_item(opt_tree, hf_shim6_reserved, tvb, offset, 4, ENC_NA);
329
2
            offset += 4;
330
2
            proto_tree_add_item(opt_tree, hf_shim6_sulid, tvb, offset, 16, ENC_NA);
331
2
            offset += 16;
332
2
            proto_tree_add_item(opt_tree, hf_shim6_rulid, tvb, offset, 16, ENC_NA);
333
2
            offset += 16;
334
2
            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
112
        default:
340
112
            break;
341
149
        }
342
149
    }
343
129
    return total_len;
344
149
}
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
41
{
349
41
    uint8_t tmp[6];
350
41
    const char *ct_str;
351
352
41
    tmp[0] = tvb_get_uint8(tvb, offset++);
353
41
    tmp[1] = tvb_get_uint8(tvb, offset++);
354
41
    tmp[2] = tvb_get_uint8(tvb, offset++);
355
41
    tmp[3] = tvb_get_uint8(tvb, offset++);
356
41
    tmp[4] = tvb_get_uint8(tvb, offset++);
357
41
    tmp[5] = tvb_get_uint8(tvb, offset++);
358
359
41
    ct_str = wmem_strdup_printf(pinfo->pool,
360
41
                                "%s: %02X %02X %02X %02X %02X %02X", label,
361
41
                                tmp[0] & SHIM6_BITMASK_CT, tmp[1], tmp[2],
362
41
                                tmp[3], tmp[4], tmp[5]
363
41
        );
364
41
    proto_tree_add_none_format(shim_tree, hf_item, tvb, offset - 6, 6, "%s", ct_str);
365
41
}
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
15
{
372
15
    proto_tree *probes_tree;
373
15
    proto_tree *probe_tree;
374
15
    int         ett_probes;
375
15
    int         ett_probe;
376
15
    unsigned    count;
377
378
15
    if (probes_rcvd) {
379
5
        ett_probes = ett_shim6_probes_rcvd;
380
5
        ett_probe = ett_shim6_probe_rcvd;
381
10
    } else {
382
10
        ett_probes = ett_shim6_probes_sent;
383
10
        ett_probe = ett_shim6_probe_sent;
384
10
    }
385
15
    probes_tree = proto_tree_add_subtree(shim_tree, tvb, offset, 40 * nbr_probe, ett_probes, NULL, label);
386
387
55
    for (count=0; count < nbr_probe; count++) {
388
40
        probe_tree = proto_tree_add_subtree_format(probes_tree, tvb, offset, 40,
389
40
                                            ett_probe, NULL, "Probe %u", count+1);
390
391
40
        proto_tree_add_item(probe_tree, hf_shim6_psrc, tvb, offset, 16, ENC_NA);
392
40
        offset += 16;
393
40
        proto_tree_add_item(probe_tree, hf_shim6_pdst, tvb, offset, 16, ENC_NA);
394
40
        offset += 16;
395
396
40
        proto_tree_add_item(probe_tree, hf_shim6_pnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
397
40
        offset += 4;
398
399
40
        proto_tree_add_item(probe_tree, hf_shim6_pdata, tvb, offset, 4, ENC_BIG_ENDIAN);
400
40
        offset += 4;
401
40
    }
402
15
}
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
108
{
408
108
    uint8_t      tmp;
409
108
    const char *sta;
410
108
    unsigned     probes_sent;
411
108
    unsigned     probes_rcvd;
412
413
108
    switch (type)
414
108
    {
415
4
    case SHIM6_TYPE_I1:
416
4
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
417
4
        offset += 6;
418
4
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
419
4
        offset += 4;
420
4
        break;
421
4
    case SHIM6_TYPE_R1:
422
4
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 2, ENC_NA);
423
4
        offset += 2;
424
4
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
425
4
        offset += 4;
426
4
        proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
427
4
        offset += 4;
428
4
        break;
429
2
    case SHIM6_TYPE_I2:
430
2
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Initiator Context Tag");
431
2
        offset += 6;
432
2
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
433
2
        offset += 4;
434
2
        proto_tree_add_item(shim_tree, hf_shim6_rnonce, tvb, offset, 4, ENC_BIG_ENDIAN);
435
2
        offset += 4;
436
2
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 4, ENC_NA);
437
2
        offset += 4;
438
2
        break;
439
5
    case SHIM6_TYPE_R2:
440
5
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Responder Context Tag");
441
5
        offset += 6;
442
5
        proto_tree_add_item(shim_tree, hf_shim6_inonce, tvb, offset, 4, ENC_BIG_ENDIAN);
443
5
        offset += 4;
444
5
        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
2
    case SHIM6_TYPE_KEEPALIVE:
471
2
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Receiver Context Tag");
472
2
        offset += 6;
473
2
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 4, ENC_NA);
474
2
        offset += 4;
475
2
        break;
476
14
    case SHIM6_TYPE_PROBE:
477
14
        dissect_shim6_ct(pinfo, shim_tree, hf_shim6_ct, tvb, offset, "Receiver Context Tag");
478
14
        offset += 6;
479
480
14
        tmp = tvb_get_uint8(tvb, offset);
481
14
        probes_sent = tmp & SHIM6_BITMASK_PSENT;
482
14
        probes_rcvd = (tmp & SHIM6_BITMASK_PRECVD) >> 4;
483
14
        proto_tree_add_item(shim_tree, hf_shim6_psent, tvb,
484
14
                            offset, 1, ENC_BIG_ENDIAN);
485
14
        proto_tree_add_item(shim_tree, hf_shim6_precvd, tvb,
486
14
                            offset, 1, ENC_BIG_ENDIAN);
487
14
        offset += 1;
488
489
14
        sta = val_to_str_const((tvb_get_uint8(tvb, offset) & SHIM6_BITMASK_STA) >> 6,
490
14
                               shimreapstates, "Unknown REAP State");
491
14
        proto_tree_add_uint_format_value(shim_tree, hf_shim6_reap, tvb,
492
14
                                         offset, 1, (tvb_get_uint8(tvb, offset) & SHIM6_BITMASK_STA) >> 6,
493
14
                                         "%s", sta);
494
495
14
        proto_tree_add_item(shim_tree, hf_shim6_reserved2, tvb, offset, 3, ENC_NA);
496
14
        offset += 3;
497
498
        /* Probes Sent */
499
14
        if (probes_sent) {
500
10
            dissect_shim6_probes(shim_tree, tvb, offset, "Probes Sent",
501
10
                                 probes_sent, false);
502
10
            offset += 40 * probes_sent;
503
10
        }
504
505
        /* Probes Received */
506
14
        if (probes_rcvd) {
507
5
            dissect_shim6_probes(shim_tree, tvb, offset, "Probes Received",
508
5
                                 probes_rcvd, true);
509
5
            offset += 40 * probes_rcvd;
510
5
        }
511
14
        break;
512
67
    default:
513
67
        break;
514
108
    }
515
91
    return offset;
516
108
}
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
123
{
536
123
    struct ip6_shim  shim;
537
123
    int              offset = 0, len;
538
123
    proto_tree      *shim_tree, *root_tree;
539
123
    proto_item      *ti, *ti_len;
540
123
    uint8_t          tmp[5];
541
123
    tvbuff_t        *next_tvb;
542
543
123
    tvb_memcpy(tvb, (uint8_t *)&shim, offset, sizeof(shim));
544
123
    len = (shim.ip6s_len + 1) << 3;
545
546
547
123
    if (shim.ip6s_p & SHIM6_BITMASK_P) {
548
9
        col_append_sep_str(pinfo->cinfo, COL_INFO, " , ", "Shim6 (Payload)");
549
9
    }
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
123
    root_tree = p_ipv6_pinfo_select_root(pinfo, tree);
556
123
    p_ipv6_pinfo_add_len(pinfo, len);
557
558
123
    ti = proto_tree_add_item(root_tree, proto_shim6, tvb, offset, len, ENC_NA);
559
123
    shim_tree = proto_item_add_subtree(ti, ett_shim6_proto);
560
561
    /* Next Header */
562
123
    proto_tree_add_uint_format_value(shim_tree, hf_shim6_nxt, tvb,
563
123
                                     offset, 1, shim.ip6s_nxt,
564
123
                                     "%s (%u)", ipprotostr(shim.ip6s_nxt), shim.ip6s_nxt);
565
123
    offset += 1;
566
567
    /* Header Extension Length */
568
123
    ti_len = proto_tree_add_item(shim_tree, hf_shim6_len, tvb, offset, 1, ENC_BIG_ENDIAN);
569
123
    ti = proto_tree_add_uint(shim_tree, hf_shim6_len_oct, tvb, offset, 1, len);
570
123
    proto_item_append_text(ti, " bytes");
571
123
    proto_item_set_generated(ti);
572
123
    proto_item_set_hidden(ti);
573
123
    proto_item_append_text(ti_len, " (%d bytes)", len);
574
123
    offset += 1;
575
576
    /* P Field */
577
123
    proto_tree_add_item(shim_tree, hf_shim6_p, tvb, offset, 1, ENC_BIG_ENDIAN);
578
579
123
    if (shim.ip6s_p & SHIM6_BITMASK_P) {
580
9
        tmp[0] = tvb_get_uint8(tvb, offset+1);
581
9
        tmp[1] = tvb_get_uint8(tvb, offset+2);
582
9
        tmp[2] = tvb_get_uint8(tvb, offset+3);
583
9
        tmp[3] = tvb_get_uint8(tvb, offset+4);
584
9
        tmp[4] = tvb_get_uint8(tvb, offset+5);
585
586
        /* Payload Extension Header */
587
9
        proto_tree_add_none_format(shim_tree, hf_shim6_ct, tvb,
588
9
                                   offset, 6,
589
9
                                   "Receiver Context Tag: %02x %02x %02x %02x %02x %02x",
590
9
                                   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
107
            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
263
        while (offset < len) {
617
149
            offset += dissect_shimopts(tvb, offset, shim_tree, pinfo);
618
149
        }
619
114
    }
620
621
123
    next_tvb = tvb_new_subset_remaining(tvb, len);
622
123
    ipv6_dissect_next(shim.ip6s_nxt, next_tvb, pinfo, tree, (ws_ip6 *)data);
623
123
    return tvb_captured_length(tvb);
624
123
}
625
626
void
627
proto_register_shim6(void)
628
14
{
629
14
    static hf_register_info hf_shim6[] = {
630
14
        { &hf_shim6_nxt,
631
14
            { "Next Header", "shim6.nxt",
632
14
                FT_UINT8, BASE_DEC, NULL, 0x0,
633
14
                NULL, HFILL }
634
14
        },
635
14
        { &hf_shim6_len,
636
14
            { "Length", "shim6.len",
637
14
                FT_UINT8, BASE_DEC, NULL, 0x0,
638
14
                "Extension header length in 8-octet words (minus 1)", HFILL }
639
14
        },
640
14
        { &hf_shim6_len_oct,
641
14
            { "Length", "shim6.len_oct",
642
14
                FT_UINT16, BASE_DEC, NULL, 0x0,
643
14
                "Extension header length in octets", HFILL }
644
14
        },
645
14
        { &hf_shim6_p,
646
14
            { "P Bit", "shim6.p",
647
14
                FT_BOOLEAN, 8, NULL, SHIM6_BITMASK_P,
648
14
                NULL, HFILL }
649
14
        },
650
14
        { &hf_shim6_ct,
651
14
            { "Context Tag", "shim6.ct",
652
14
                FT_NONE, BASE_NONE, NULL, 0x0,
653
14
                NULL, HFILL }
654
14
        },
655
14
        { &hf_shim6_type,
656
14
            { "Message Type", "shim6.type",
657
14
                FT_UINT8, BASE_DEC, VALS(shimctrlvals), SHIM6_BITMASK_TYPE,
658
14
                NULL, HFILL }
659
14
        },
660
14
        { &hf_shim6_proto,
661
14
            { "Protocol", "shim6.proto",
662
14
                FT_UINT8, BASE_DEC, VALS(shim6_protocol), SHIM6_BITMASK_PROTOCOL,
663
14
                NULL, HFILL }
664
14
        },
665
14
        { &hf_shim6_checksum,
666
14
            { "Checksum", "shim6.checksum",
667
14
                FT_UINT16, BASE_HEX, NULL, 0x0,
668
14
                "Shim6 Checksum", HFILL }
669
14
        },
670
14
        { &hf_shim6_checksum_status,
671
14
            { "Checksum Status", "shim6.checksum.status",
672
14
                FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
673
14
                NULL, HFILL }
674
14
        },
675
14
        { &hf_shim6_inonce,
676
14
            { "Initiator Nonce", "shim6.inonce",
677
14
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
678
14
                NULL, HFILL }
679
14
        },
680
14
        { &hf_shim6_rnonce,
681
14
            { "Responder Nonce", "shim6.rnonce",
682
14
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
683
14
                NULL, HFILL }
684
14
        },
685
14
        { &hf_shim6_reserved,
686
14
            { "Reserved", "shim6.reserved",
687
14
                FT_BYTES, BASE_NONE, NULL, 0x0,
688
14
                NULL, HFILL }
689
14
        },
690
14
        { &hf_shim6_reserved2,
691
14
            { "Reserved2", "shim6.reserved2",
692
14
                FT_BYTES, BASE_NONE, NULL, 0x0,
693
14
                NULL, HFILL }
694
14
        },
695
14
        { &hf_shim6_precvd,
696
14
            { "Probes Received", "shim6.precvd",
697
14
                FT_UINT8, BASE_DEC, NULL, SHIM6_BITMASK_PRECVD,
698
14
                NULL, HFILL }
699
14
        },
700
14
        { &hf_shim6_psent,
701
14
            { "Probes Sent", "shim6.psent",
702
14
                FT_UINT8, BASE_DEC, NULL, SHIM6_BITMASK_PSENT,
703
14
                NULL, HFILL }
704
14
        },
705
14
        { &hf_shim6_psrc,
706
14
            { "Source Address", "shim6.psrc",
707
14
                FT_IPv6, BASE_NONE, NULL, 0x0,
708
14
                "Shim6 Probe Source Address", HFILL }
709
14
        },
710
14
        { &hf_shim6_pdst,
711
14
            { "Destination Address", "shim6.pdst",
712
14
                FT_IPv6, BASE_NONE, NULL, 0x0,
713
14
                "Shim6 Probe Destination Address", HFILL }
714
14
        },
715
14
        { &hf_shim6_pnonce,
716
14
            { "Nonce", "shim6.pnonce",
717
14
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
718
14
                "Shim6 Probe Nonce", HFILL }
719
14
        },
720
14
        { &hf_shim6_pdata,
721
14
            { "Data", "shim6.pdata",
722
14
                FT_UINT32, BASE_HEX, NULL, 0x0,
723
14
                "Shim6 Probe Data", HFILL }
724
14
        },
725
14
        { &hf_shim6_sulid,
726
14
            { "Sender ULID", "shim6.sulid",
727
14
                FT_IPv6, BASE_NONE, NULL, 0x0,
728
14
                "Shim6 Sender ULID", HFILL }
729
14
        },
730
14
        { &hf_shim6_rulid,
731
14
            { "Receiver ULID", "shim6.rulid",
732
14
                FT_IPv6, BASE_NONE, NULL, 0x0,
733
14
                "Shim6 Receiver ULID", HFILL }
734
14
        },
735
14
        { &hf_shim6_reap,
736
14
            { "REAP State", "shim6.reap",
737
14
                FT_UINT8, BASE_DEC, NULL, 0x0,
738
14
                NULL, HFILL }
739
14
        },
740
14
        { &hf_shim6_opt_type,
741
14
            { "Option Type", "shim6.opt.type",
742
14
                FT_UINT16, BASE_DEC, VALS(shimoptvals), SHIM6_BITMASK_OPT_TYPE,
743
14
                "Shim6 Option Type", HFILL }
744
14
        },
745
14
        { &hf_shim6_opt_critical,
746
14
            { "Option Critical Bit", "shim6.opt.critical",
747
14
                FT_BOOLEAN, 8, TFS(&tfs_yes_no), SHIM6_BITMASK_CRITICAL,
748
14
                "true: option is critical, false: option is not critical", HFILL }
749
14
        },
750
14
        { &hf_shim6_opt_len,
751
14
            { "Content Length", "shim6.opt.len",
752
14
                FT_UINT16, BASE_DEC, NULL, 0x0,
753
14
                "Content Length Option", HFILL }
754
14
        },
755
14
        { &hf_shim6_opt_total_len,
756
14
            { "Total Length", "shim6.opt.total_len",
757
14
                FT_UINT16, BASE_DEC, NULL, 0x0,
758
14
                "Total Option Length", HFILL }
759
14
        },
760
14
        { &hf_shim6_opt_loc_verif_methods,
761
14
            { "Verification Method", "shim6.opt.verif_method",
762
14
                FT_UINT8, BASE_DEC, VALS(shimverifmethods), 0x0,
763
14
                "Locator Verification Method", HFILL }
764
14
        },
765
14
        { &hf_shim6_opt_loclist,
766
14
            { "Locator List Generation", "shim6.opt.loclist",
767
14
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
768
14
                NULL, HFILL }
769
14
        },
770
14
        { &hf_shim6_locator,
771
14
            { "Locator", "shim6.locator",
772
14
                FT_IPv6, BASE_NONE, NULL, 0x0,
773
14
                "Shim6 Locator", HFILL }
774
14
        },
775
14
        { &hf_shim6_opt_locnum,
776
14
            { "Num Locators", "shim6.opt.locnum",
777
14
                FT_UINT8, BASE_DEC, NULL, 0x0,
778
14
                "Number of locators in Locator List", HFILL }
779
14
        },
780
14
        { &hf_shim6_opt_elemlen,
781
14
            { "Element Length", "shim6.opt.elemlen",
782
14
                FT_UINT8, BASE_DEC, NULL, 0x0,
783
14
                "Length of Elements in Locator Preferences Option", HFILL }
784
14
        },
785
14
        { &hf_shim6_loc_flag,
786
14
            { "Flags", "shim6.loc.flags",
787
14
                FT_UINT8, BASE_DEC, NULL, 0x0,
788
14
                "Locator Preferences Flags", HFILL }
789
14
        },
790
14
        { &hf_shim6_loc_prio,
791
14
            { "Priority", "shim6.loc.prio",
792
14
                FT_UINT8, BASE_DEC, NULL, 0x0,
793
14
                "Locator Preferences Priority", HFILL }
794
14
        },
795
14
        { &hf_shim6_loc_weight,
796
14
            { "Weight", "shim6.loc.weight",
797
14
                FT_UINT8, BASE_DEC, NULL, 0x0,
798
14
                "Locator Preferences Weight", HFILL }
799
14
        },
800
14
        { &hf_shim6_opt_fii,
801
14
            { "Forked Instance Identifier", "shim6.opt.fii",
802
14
                FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
803
14
                NULL, HFILL }
804
14
        },
805
14
        { &hf_shim6_validator,
806
14
            { "Validator", "shim6.validator",
807
14
                FT_BYTES, BASE_NONE, NULL, 0x0,
808
14
                NULL, HFILL }
809
14
        },
810
14
        { &hf_shim6_cga_parameter_data_structure,
811
14
            { "CGA Parameter Data Structure", "shim6.cga_parameter_data_structure",
812
14
                FT_BYTES, BASE_NONE, NULL, 0x0,
813
14
                NULL, HFILL }
814
14
        },
815
14
        { &hf_shim6_cga_signature,
816
14
            { "CGA Signature", "shim6.cga_signature",
817
14
                FT_BYTES, BASE_NONE, NULL, 0x0,
818
14
                NULL, HFILL }
819
14
        },
820
14
        { &hf_shim6_padding,
821
14
            { "Padding", "shim6.padding",
822
14
                FT_BYTES, BASE_NONE, NULL, 0x0,
823
14
                NULL, HFILL }
824
14
        }
825
14
    };
826
827
14
    static int *ett_shim6[] = {
828
14
        &ett_shim6_proto,
829
14
        &ett_shim6_option,
830
14
        &ett_shim6_locators,
831
14
        &ett_shim6_verif_methods,
832
14
        &ett_shim6_loc_pref,
833
14
        &ett_shim6_probes_sent,
834
14
        &ett_shim6_probes_rcvd,
835
14
        &ett_shim6_probe_sent,
836
14
        &ett_shim6_probe_rcvd,
837
14
        &ett_shim6_cksum
838
14
    };
839
840
14
    static ei_register_info ei_shim6[] = {
841
14
        { &ei_shim6_opt_elemlen_invalid,
842
14
            { "shim6.opt.elemlen.invalid", PI_MALFORMED, PI_ERROR,
843
14
                "Invalid element length", EXPFILL }
844
14
        },
845
14
        { &ei_shim6_checksum_bad,
846
14
            { "shim6.checksum_bad.expert", PI_CHECKSUM, PI_ERROR,
847
14
                "Bad checksum", EXPFILL }
848
14
        }
849
14
    };
850
851
14
    expert_module_t* expert_shim6;
852
853
14
    proto_shim6 = proto_register_protocol("Shim6 Protocol", "Shim6", "shim6");
854
14
    proto_register_field_array(proto_shim6, hf_shim6, array_length(hf_shim6));
855
14
    proto_register_subtree_array(ett_shim6, array_length(ett_shim6));
856
14
    expert_shim6 = expert_register_protocol(proto_shim6);
857
14
    expert_register_field_array(expert_shim6, ei_shim6, array_length(ei_shim6));
858
14
    shim6_handle = register_dissector("shim6", dissect_shim6, proto_shim6);
859
14
}
860
861
void
862
proto_reg_handoff_shim6(void)
863
14
{
864
14
    dissector_add_uint("ip.proto", IP_PROTO_SHIM6, shim6_handle);
865
14
}
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
 */