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-ilnp.c
Line
Count
Source
1
/* packet-ilnp.c
2
 * Routines for ILNP dissection
3
 * Copyright 2025, Shubh Sinhal <shubh.sinhal@gmail.com>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
/*
13
 * ILNP is an extension on IPv6 which changes the addressing semantics to
14
 * treat the Identifier (Node Identifier - 64 bits) and the Locator (Network
15
 * address - 64 bits) to improve mobility and multi-homing support
16
 *
17
 * RFC 6740 - ILNP Architectural Description
18
 * RFC 6741 - ILNP Engineering Considerations
19
 *
20
 * More information about ILNP can be found at "https://ilnp.cs.st-andrews.ac.uk/"
21
 *
22
 * This dissector was developed using the IPv6 dissector as a reference base
23
 */
24
25
#include "config.h"
26
#include <epan/packet.h>
27
#include <epan/address_types.h>
28
#include <epan/to_str.h>
29
#include <epan/proto.h>
30
#include <epan/tap.h>
31
#include <epan/conversation_table.h>
32
#include <epan/conversation_filter.h>
33
#include <epan/stats_tree.h>
34
35
void proto_register_ilnp(void);
36
37
/* Conversation data */
38
struct ilnp_analysis {
39
    uint32_t initial_frame; // Initial frame starting this conversation
40
    uint32_t stream;        // Stream ID
41
};
42
43
typedef struct _ilnp_tap_info_t {
44
    address ilnp_src_l64;     /* source l64*/
45
    address ilnp_src_nid;     /* source nid */
46
    address ilnp_dst_l64;     /* destination l64*/
47
    address ilnp_dst_nid;     /* destination nid */
48
    address ilnp_src_ilv;     /* source ilv */
49
    address ilnp_dst_ilv;     /* destination ilv */
50
    uint32_t ilnp_stream;     /* track conversations */
51
} ilnp_tap_info_t;
52
53
static int proto_ilnp;
54
55
/* Header fields */
56
static int hf_ilnp_nonce;
57
static int hf_ilnp_src_l64;
58
static int hf_ilnp_dst_l64;
59
static int hf_ilnp_src_nid;
60
static int hf_ilnp_dst_nid;
61
static int hf_ilnp_src_ilv;
62
static int hf_ilnp_dst_ilv;
63
static int hf_ilnp_l64;
64
static int hf_ilnp_nid;
65
static int hf_ilnp_ilv;
66
static int hf_ilnp_stream;
67
68
static int ett_ilnp;
69
70
static dissector_handle_t ilnp_handle;
71
72
// Global ILNP Stream counter
73
static uint32_t ilnp_stream_count;
74
75
/* ILNP tap handle */
76
static int ilnp_tap;
77
78
79
/***********************************************************************************************************************************
80
 *
81
 * CONVERSATIONS
82
 *
83
 ***********************************************************************************************************************************/
84
85
static const char* ilnp_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
86
0
{
87
0
    if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == AT_ILNP_NID))
88
0
        return "ilnp.src_nid";
89
90
0
    if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == AT_ILNP_NID))
91
0
        return "ilnp.dst_nid";
92
93
0
    if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == AT_ILNP_NID))
94
0
        return "ilnp.nid";
95
96
0
    return CONV_FILTER_INVALID;
97
0
}
98
99
static ct_dissector_info_t ilnp_ct_dissector_info = {&ilnp_conv_get_filter_type};
100
101
// Callback to add an ilnp conversation to the Statistics->Conversations->ILNP table
102
static tap_packet_status
103
ilnp_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip, tap_flags_t flags)
104
0
{
105
0
    conv_hash_t *hash = (conv_hash_t*) pct;
106
0
    hash->flags = flags;
107
108
0
    const ilnp_tap_info_t *ilnp_tap_info = (const ilnp_tap_info_t *)vip;
109
110
0
    add_conversation_table_data_with_conv_id(hash, &ilnp_tap_info->ilnp_src_nid, &ilnp_tap_info->ilnp_dst_nid, 0, 0,
111
0
            (conv_id_t)ilnp_tap_info->ilnp_stream, 1, pinfo->fd->pkt_len,
112
0
            &pinfo->rel_ts, &pinfo->abs_ts, &ilnp_ct_dissector_info, CONVERSATION_ILNP);
113
114
0
    return TAP_PACKET_REDRAW;
115
0
}
116
117
static const char* ilnp_endpoint_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter)
118
0
{
119
0
    if ((filter == CONV_FT_ANY_ADDRESS) && (endpoint->myaddress.type == AT_ILNP_NID))
120
0
        return "ilnp.nid";
121
122
0
    return CONV_FILTER_INVALID;
123
0
}
124
125
static et_dissector_info_t ilnp_endpoint_dissector_info = {&ilnp_endpoint_get_filter_type};
126
127
// Callback to add an ilnp nids to the Statistics->Endpoints->ILNP table
128
static tap_packet_status
129
ilnp_endpoint_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip, tap_flags_t flags)
130
0
{
131
0
    conv_hash_t *hash = (conv_hash_t*) pit;
132
0
    hash->flags = flags;
133
134
0
    const ilnp_tap_info_t *ilnp_tap_info = (const ilnp_tap_info_t *)vip;
135
136
0
    add_endpoint_table_data(hash, &ilnp_tap_info->ilnp_src_nid, 0, true, 1,
137
0
                pinfo->fd->pkt_len, &ilnp_endpoint_dissector_info, ENDPOINT_ILNP);
138
0
    add_endpoint_table_data(hash, &ilnp_tap_info->ilnp_dst_nid, 0, false, 1,
139
0
                pinfo->fd->pkt_len, &ilnp_endpoint_dissector_info, ENDPOINT_ILNP);
140
141
0
    return TAP_PACKET_REDRAW;
142
0
}
143
144
static bool
145
ilnp_filter_valid(packet_info *pinfo, void *user_data _U_)
146
0
{
147
0
    return proto_is_frame_protocol(pinfo->layers, "ilnp");
148
0
}
149
150
static char*
151
ilnp_build_filter(packet_info *pinfo, void *user_data _U_)
152
0
{
153
0
    address src_nid, dst_nid;
154
155
0
    alloc_address_wmem(pinfo->pool, &src_nid, AT_ILNP_NID, 8, pinfo->net_src.data);
156
0
    alloc_address_wmem(pinfo->pool, &dst_nid, AT_ILNP_NID, 8, pinfo->net_dst.data);
157
158
0
    return ws_strdup_printf("ilnp.nid eq %s and ilnp.nid eq %s",
159
0
                address_to_str(pinfo->pool, &src_nid),
160
0
                address_to_str(pinfo->pool, &dst_nid));
161
0
}
162
163
164
static struct ilnp_analysis*
165
12
init_ilnp_conversation_data(packet_info *pinfo) {
166
12
    struct ilnp_analysis *ilnpd;
167
168
    /* Initialize the ip protocol data structure to add to the ilnp conversation */
169
12
    ilnpd=wmem_new0(wmem_file_scope(), struct ilnp_analysis);
170
171
12
    ilnpd->initial_frame = pinfo->num;
172
12
    ilnpd->stream = ilnp_stream_count++;
173
174
12
    return ilnpd;
175
12
}
176
177
static struct ilnp_analysis*
178
31
get_ilnp_conversation_data(conversation_t *conv, packet_info *pinfo) {
179
31
    struct ilnp_analysis *ilnpd;
180
181
    /* Get the data for this conversation */
182
31
    ilnpd = (struct ilnp_analysis *) conversation_get_proto_data(conv, proto_ilnp);
183
31
    if (!ilnpd) { // if it doesn't exist, initialise new one
184
12
        ilnpd = init_ilnp_conversation_data(pinfo);
185
12
        conversation_add_proto_data(conv, proto_ilnp, ilnpd);
186
12
    }
187
188
31
    return ilnpd;
189
31
}
190
191
192
193
/***********************************************************************************************************************************
194
 *
195
 * STATISTICS
196
 *
197
 ***********************************************************************************************************************************/
198
199
static int st_node_ilnp_nids = -1;
200
static int st_node_ilnp_src_nid = -1;
201
static int st_node_ilnp_dst_nid = -1;
202
static const char* st_str_ilnp_nid = "ILNP Statistics" STATS_TREE_MENU_SEPARATOR "All Node Identifiers";
203
static const char* st_str_ilnp_srcdst_nid = "ILNP Statistics" STATS_TREE_MENU_SEPARATOR "Source and Destination Node Identifier Addresses";
204
static const char* st_str_ilnp_src_nid = "Source ILNP Node Identifiers";
205
static const char* st_str_ilnp_dst_nid = "Destination ILNP Node Identifiers";
206
207
static int st_node_ilnp_l64s = -1;
208
static int st_node_ilnp_src_l64 = -1;
209
static int st_node_ilnp_dst_l64 = -1;
210
static const char* st_str_ilnp_l64 = "ILNP Statistics" STATS_TREE_MENU_SEPARATOR "All Locators";
211
static const char* st_str_ilnp_srcdst_l64 = "ILNP Statistics" STATS_TREE_MENU_SEPARATOR "Source and Destination Locator Addresses";
212
static const char* st_str_ilnp_src_l64 = "Source ILNP Locators";
213
static const char* st_str_ilnp_dst_l64 = "Destination ILNP Locators";
214
215
static int st_node_ilnp_ilvs = -1;
216
static int st_node_ilnp_src_ilv = -1;
217
static int st_node_ilnp_dst_ilv = -1;
218
static const char* st_str_ilnp_ilv = "ILNP Statistics" STATS_TREE_MENU_SEPARATOR "All Identifier-Locator Vectors";
219
static const char* st_str_ilnp_srcdst_ilv = "ILNP Statistics" STATS_TREE_MENU_SEPARATOR "Source and Destination Identifier-Locator Vector Addresses";
220
static const char* st_str_ilnp_src_ilv = "Source ILNP Identifier-Locator Vectors";
221
static const char* st_str_ilnp_dst_ilv = "Destination ILNP Identifier-Locator Vectors";
222
223
static int st_node_ilnp_ptype = -1;
224
static const char* st_str_ilnp_ptype = "ILNP Statistics" STATS_TREE_MENU_SEPARATOR "IP Protocol Types";
225
226
227
0
static void ilnp_nids_stats_tree_init(stats_tree* st) {
228
0
    st_node_ilnp_nids = stats_tree_create_node(st, st_str_ilnp_nid, 0, STAT_DT_INT, true);
229
0
}
230
231
0
static void ilnp_l64s_stats_tree_init(stats_tree* st) {
232
0
    st_node_ilnp_l64s = stats_tree_create_node(st, st_str_ilnp_l64, 0, STAT_DT_INT, true);
233
0
}
234
235
0
static void ilnp_ilvs_stats_tree_init(stats_tree* st) {
236
0
    st_node_ilnp_ilvs = stats_tree_create_node(st, st_str_ilnp_ilv, 0, STAT_DT_INT, true);
237
0
}
238
239
static tap_packet_status ilnp_nids_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p _U_, tap_flags_t flags _U_)
240
0
{
241
0
    const ilnp_tap_info_t* ilnpt = (const ilnp_tap_info_t*)p;
242
0
    tick_stat_node(st, st_str_ilnp_nid, 0, false);
243
0
    tick_stat_node(st, address_to_str(pinfo->pool, &ilnpt->ilnp_src_nid), st_node_ilnp_nids, false);
244
0
    tick_stat_node(st, address_to_str(pinfo->pool, &ilnpt->ilnp_dst_nid), st_node_ilnp_nids, false);
245
0
    return TAP_PACKET_REDRAW;
246
0
}
247
248
static tap_packet_status ilnp_l64s_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p _U_, tap_flags_t flags _U_)
249
0
{
250
0
    const ilnp_tap_info_t* ilnpt = (const ilnp_tap_info_t*)p;
251
0
    tick_stat_node(st, st_str_ilnp_l64, 0, false);
252
0
    tick_stat_node(st, address_to_str(pinfo->pool, &ilnpt->ilnp_src_l64), st_node_ilnp_l64s, false);
253
0
    tick_stat_node(st, address_to_str(pinfo->pool, &ilnpt->ilnp_dst_l64), st_node_ilnp_l64s, false);
254
0
    return TAP_PACKET_REDRAW;
255
0
}
256
257
static tap_packet_status ilnp_ilvs_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p _U_, tap_flags_t flags _U_)
258
0
{
259
0
    const ilnp_tap_info_t* ilnpt = (const ilnp_tap_info_t*)p;
260
0
    tick_stat_node(st, st_str_ilnp_ilv, 0, false);
261
0
    tick_stat_node(st, address_to_str(pinfo->pool, &ilnpt->ilnp_src_ilv), st_node_ilnp_ilvs, false);
262
0
    tick_stat_node(st, address_to_str(pinfo->pool, &ilnpt->ilnp_dst_ilv), st_node_ilnp_ilvs, false);
263
0
    return TAP_PACKET_REDRAW;
264
0
}
265
266
//Same as ip_srcdst_stats_tree_init
267
static void ilnp_srcdst_stats_tree_init(stats_tree* st,
268
    const char* st_str_src, int* st_node_src_ptr,
269
    const char* st_str_dst, int* st_node_dst_ptr)
270
0
{
271
    /* create one tree branch for source */
272
0
    *st_node_src_ptr = stats_tree_create_node(st, st_str_src, 0, STAT_DT_INT, true);
273
    /* set flag so this branch will always be sorted to top of tree */
274
0
    stat_node_set_flags(st, st_str_src, 0, false, ST_FLG_SORT_TOP);
275
    /* create another top level node for destination branch */
276
0
    *st_node_dst_ptr = stats_tree_create_node(st, st_str_dst, 0, STAT_DT_INT, true);
277
    /* set flag so this branch will not be expanded by default */
278
0
    stat_node_set_flags(st, st_str_dst, 0, false, ST_FLG_DEF_NOEXPAND);
279
0
}
280
281
static void
282
ilnp_srcdst_nid_stats_tree_init(stats_tree* st)
283
0
{
284
0
    ilnp_srcdst_stats_tree_init(st, st_str_ilnp_src_nid, &st_node_ilnp_src_nid, st_str_ilnp_dst_nid, &st_node_ilnp_dst_nid);
285
0
}
286
static void ilnp_srcdst_l64_stats_tree_init(stats_tree* st)
287
0
{
288
0
    ilnp_srcdst_stats_tree_init(st, st_str_ilnp_src_l64, &st_node_ilnp_src_l64, st_str_ilnp_dst_l64, &st_node_ilnp_dst_l64);
289
0
}
290
291
static void ilnp_srcdst_ilv_stats_tree_init(stats_tree* st)
292
0
{
293
0
    ilnp_srcdst_stats_tree_init(st, st_str_ilnp_src_ilv, &st_node_ilnp_src_ilv, st_str_ilnp_dst_ilv, &st_node_ilnp_dst_ilv);
294
0
}
295
296
static tap_packet_status ilnp_srcdst_stats_tree_packet(stats_tree* st,
297
    packet_info* pinfo,
298
    const address* src_addr,
299
    const address* dst_addr,
300
    int st_node_src,
301
    const char* st_str_src,
302
    int st_node_dst,
303
    const char* st_str_dst)
304
0
{
305
    /* update source branch */
306
0
    tick_stat_node(st, st_str_src, 0, false);
307
0
    tick_stat_node(st, address_to_str(pinfo->pool, src_addr), st_node_src, false);
308
    /* update destination branch */
309
0
    tick_stat_node(st, st_str_dst, 0, false);
310
0
    tick_stat_node(st, address_to_str(pinfo->pool, dst_addr), st_node_dst, false);
311
0
    return TAP_PACKET_REDRAW;
312
0
}
313
314
static tap_packet_status ilnp_srcdst_nid_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p _U_, tap_flags_t flags _U_)
315
0
{
316
0
    const ilnp_tap_info_t* ilnpt = (const ilnp_tap_info_t*)p;
317
0
    return ilnp_srcdst_stats_tree_packet(st, pinfo, &ilnpt->ilnp_src_nid, &ilnpt->ilnp_dst_nid, st_node_ilnp_src_nid, st_str_ilnp_src_nid, st_node_ilnp_dst_nid, st_str_ilnp_dst_nid);
318
0
}
319
320
static tap_packet_status ilnp_srcdst_l64_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p _U_, tap_flags_t flags _U_)
321
0
{
322
0
    const ilnp_tap_info_t* ilnpt = (const ilnp_tap_info_t*)p;
323
0
    return ilnp_srcdst_stats_tree_packet(st, pinfo, &ilnpt->ilnp_src_l64, &ilnpt->ilnp_dst_l64, st_node_ilnp_src_l64, st_str_ilnp_src_l64, st_node_ilnp_dst_l64, st_str_ilnp_dst_l64);
324
0
}
325
326
static tap_packet_status ilnp_srcdst_ilv_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p _U_, tap_flags_t flags _U_)
327
0
{
328
0
    const ilnp_tap_info_t* ilnpt = (const ilnp_tap_info_t*)p;
329
0
    return ilnp_srcdst_stats_tree_packet(st, pinfo, &ilnpt->ilnp_src_ilv, &ilnpt->ilnp_dst_ilv, st_node_ilnp_src_ilv, st_str_ilnp_src_ilv, st_node_ilnp_dst_ilv, st_str_ilnp_dst_ilv);
330
0
}
331
332
static void ilnp_ptype_stats_tree_init(stats_tree* st)
333
0
{
334
0
    st_node_ilnp_ptype = stats_tree_create_pivot(st, st_str_ilnp_ptype, 0);
335
0
}
336
337
static tap_packet_status ilnp_ptype_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p _U_, tap_flags_t flags _U_)
338
0
{
339
0
    stats_tree_tick_pivot(st, st_node_ilnp_ptype, port_type_to_str(pinfo->ptype));
340
0
    return TAP_PACKET_REDRAW;
341
0
}
342
343
/***********************************************************************************************************************************
344
 *
345
 * DISSECTION
346
 *
347
 ***********************************************************************************************************************************/
348
349
static int
350
dissect_ilnp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
351
44
{
352
44
    proto_tree *ilnp_tree;
353
44
    proto_item *ilnp_item, *ti;
354
44
    const char *str_ilnp_src_nid, *str_ilnp_src_l64,
355
44
               *str_ilnp_dst_nid, *str_ilnp_dst_l64,
356
44
               *str_ilnp_src_ilv, *str_ilnp_dst_ilv;
357
44
    conversation_t* conv;
358
44
    struct ilnp_analysis* ilnpd;
359
44
    ilnp_tap_info_t* ilnph;
360
361
    //ILNP works on top of IPv6 only (as it "repurposes" the address data)
362
44
    if ((pinfo->net_src.type != AT_IPv6) || (pinfo->net_dst.type != AT_IPv6))
363
13
        return 0;
364
365
31
    ilnph = wmem_new0(pinfo->pool, ilnp_tap_info_t);
366
367
    // Define ilnp tree and add it as a subtree to the main proto tree
368
31
    ilnp_item = proto_tree_add_item(tree, proto_ilnp, tvb, 0, -1, ENC_NA);
369
31
    ilnp_tree = proto_item_add_subtree(ilnp_item, ett_ilnp);
370
371
    // Add ILNP Nonce to subtree
372
31
    proto_tree_add_item(ilnp_tree, hf_ilnp_nonce, tvb, 0, -1, ENC_NA);
373
374
    //Set the NID as source and destination addresses of the packet
375
31
    alloc_address_wmem(pinfo->pool, &pinfo->src, AT_ILNP_NID, 8, ((uint8_t*)pinfo->net_src.data)+8);
376
31
    alloc_address_wmem(pinfo->pool, &pinfo->dst, AT_ILNP_NID, 8, ((uint8_t*)pinfo->net_dst.data)+8);
377
378
    //Get address data from the current network layer and put into tap data
379
31
    alloc_address_wmem(pinfo->pool, &ilnph->ilnp_src_l64, AT_ILNP_L64, 8, pinfo->net_src.data);
380
31
    alloc_address_wmem(pinfo->pool, &ilnph->ilnp_src_nid, AT_ILNP_NID, 8, ((uint8_t*)pinfo->net_src.data)+8);
381
31
    alloc_address_wmem(pinfo->pool, &ilnph->ilnp_dst_l64, AT_ILNP_L64, 8, pinfo->net_dst.data);
382
31
    alloc_address_wmem(pinfo->pool, &ilnph->ilnp_dst_nid, AT_ILNP_NID, 8, ((uint8_t*)pinfo->net_dst.data)+8);
383
31
    alloc_address_wmem(pinfo->pool, &ilnph->ilnp_src_ilv, AT_ILNP_ILV, 16, pinfo->net_src.data);
384
31
    alloc_address_wmem(pinfo->pool, &ilnph->ilnp_dst_ilv, AT_ILNP_ILV, 16, pinfo->net_dst.data);
385
386
    //Add tap data to the dissection tree
387
388
    // convert all addresses to strings for display
389
31
    str_ilnp_src_nid = address_to_str(pinfo->pool, &ilnph->ilnp_src_nid);
390
31
    str_ilnp_src_l64 = address_to_str(pinfo->pool, &ilnph->ilnp_src_l64);
391
31
    str_ilnp_dst_nid = address_to_str(pinfo->pool, &ilnph->ilnp_dst_nid);
392
31
    str_ilnp_dst_l64 = address_to_str(pinfo->pool, &ilnph->ilnp_dst_l64);
393
31
    str_ilnp_src_ilv = address_to_str(pinfo->pool, &ilnph->ilnp_src_ilv);
394
31
    str_ilnp_dst_ilv = address_to_str(pinfo->pool, &ilnph->ilnp_dst_ilv);
395
396
    // Add address fields to ILNP subtree.  Some fields without specifying src or dst for added filter options
397
31
    proto_tree_add_string(ilnp_tree, hf_ilnp_src_l64, tvb, 0, 0, str_ilnp_src_l64);
398
31
    ti = proto_tree_add_string(ilnp_tree, hf_ilnp_l64, tvb, 0, 0, str_ilnp_src_l64);
399
31
    proto_item_set_hidden(ti);
400
31
    proto_tree_add_string(ilnp_tree, hf_ilnp_src_nid, tvb, 0, 0, str_ilnp_src_nid);
401
31
    ti = proto_tree_add_string(ilnp_tree, hf_ilnp_nid, tvb, 0, 0, str_ilnp_src_nid);
402
31
    proto_item_set_hidden(ti);
403
31
    ti = proto_tree_add_string(ilnp_tree, hf_ilnp_src_ilv, tvb, 0, 0, str_ilnp_src_ilv);
404
31
    proto_item_set_hidden(ti);
405
31
    ti = proto_tree_add_string(ilnp_tree, hf_ilnp_ilv, tvb, 0, 0, str_ilnp_src_ilv);
406
31
    proto_item_set_hidden(ti);
407
31
    proto_tree_add_string(ilnp_tree, hf_ilnp_dst_l64, tvb, 0, 0, str_ilnp_dst_l64);
408
31
    ti = proto_tree_add_string(ilnp_tree, hf_ilnp_l64, tvb, 0, 0, str_ilnp_dst_l64);
409
31
    proto_item_set_hidden(ti);
410
31
    proto_tree_add_string(ilnp_tree, hf_ilnp_dst_nid, tvb, 0, 0, str_ilnp_dst_nid);
411
31
    ti = proto_tree_add_string(ilnp_tree, hf_ilnp_nid, tvb, 0, 0, str_ilnp_dst_nid);
412
31
    proto_item_set_hidden(ti);
413
31
    ti = proto_tree_add_string(ilnp_tree, hf_ilnp_dst_ilv, tvb, 0, 0, str_ilnp_dst_ilv);
414
31
    proto_item_set_hidden(ti);
415
31
    ti = proto_tree_add_string(ilnp_tree, hf_ilnp_ilv, tvb, 0, 0, str_ilnp_dst_ilv);
416
31
    proto_item_set_hidden(ti);
417
418
    // Add test to the main ILNP dropdown in the packet details pane.
419
31
    proto_item_append_text(ilnp_item, ", Src: %s, Dst: %s", str_ilnp_src_ilv, str_ilnp_dst_ilv);
420
421
    // does not use nonce or l64
422
31
    conv = find_conversation_strat(pinfo, CONVERSATION_ILNP, NO_PORT_X, false);
423
31
    if (!conv) { // if no conversation exists
424
12
        conv = conversation_new_strat(pinfo, CONVERSATION_ILNP, NO_PORTS);
425
12
    }
426
19
    else {    // otherwise add to existing conversation
427
19
        if (!(pinfo->fd->visited)) {
428
19
            if (pinfo->num > conv->last_frame) {
429
3
                conv->last_frame = pinfo->num;
430
3
            }
431
19
        }
432
19
    }
433
434
    // Get stream id for display
435
31
    ilnpd = get_ilnp_conversation_data(conv, pinfo);
436
31
    if (ilnpd) {
437
        // set stream id in tap info struct
438
31
        ilnph->ilnp_stream = ilnpd->stream;
439
        // add to protocol tree
440
31
        ti = proto_tree_add_uint(ilnp_tree, hf_ilnp_stream, tvb, 0, 0, ilnpd->stream);
441
31
        proto_item_set_generated(ti);
442
31
    }
443
444
    // queue packet to trigger linked tap listeners
445
31
    tap_queue_packet(ilnp_tap, pinfo, ilnph);
446
447
31
    return tvb_captured_length(tvb);
448
44
}
449
450
// Initialise the ILNP dissector with a stream count starting at 0
451
14
static void ilnp_init(void) {
452
14
    ilnp_stream_count = 0;
453
14
}
454
455
14
void proto_register_ilnp(void) {
456
457
14
    static hf_register_info hf[] = {
458
14
        { &hf_ilnp_nonce,
459
14
            { "ILNP Nonce Value", "ilnp.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
460
14
                NULL, HFILL }
461
14
        },
462
14
        { &hf_ilnp_src_l64,
463
14
            { "Source L64", "ilnp.src_l64", FT_STRING, BASE_NONE, NULL, 0x0,
464
14
                "ILNP Source Locator", HFILL}
465
14
        },
466
14
        { &hf_ilnp_src_nid,
467
14
            { "Source NID", "ilnp.src_nid", FT_STRING, BASE_NONE, NULL, 0x0,
468
14
                "ILNP Source Node Identifier", HFILL}
469
14
        },
470
14
        { &hf_ilnp_dst_l64,
471
14
            { "Destination L64", "ilnp.dst_l64", FT_STRING, BASE_NONE, NULL, 0x0,
472
14
                "ILNP Destination Locator", HFILL}
473
14
        },
474
14
        { &hf_ilnp_dst_nid,
475
14
            { "Destination NID", "ilnp.dst_nid", FT_STRING, BASE_NONE, NULL, 0x0,
476
14
                "ILNP Destination Node Identifier", HFILL}
477
14
        },
478
14
        { &hf_ilnp_src_ilv,
479
14
            { "Source ILV", "ilnp.src_ilv", FT_STRING, BASE_NONE, NULL, 0x0,
480
14
                "ILNP Source Identifier-Locator Vector", HFILL}
481
14
        },
482
14
        { &hf_ilnp_dst_ilv,
483
14
            { "Destination ILV", "ilnp.dst_ilv", FT_STRING, BASE_NONE, NULL, 0x0,
484
14
                "ILNP Destination Identifier-Locator Vector", HFILL}
485
14
        },
486
14
        { &hf_ilnp_ilv,
487
14
            { "Source or Destination ILV", "ilnp.ilv", FT_STRING, BASE_NONE, NULL, 0x0,
488
14
                "ILNP Source or Destination Identifier-Locator Vector", HFILL}
489
14
        },
490
14
        { &hf_ilnp_nid,
491
14
            { "Source or Destination NID", "ilnp.nid", FT_STRING, BASE_NONE, NULL, 0x0,
492
14
                "ILNP Source or Destination Node Identifier", HFILL}
493
14
        },
494
14
        { &hf_ilnp_l64,
495
14
            { "Source or Destination L64", "ilnp.l64", FT_STRING, BASE_NONE, NULL, 0x0,
496
14
                "ILNP Source or Destination Locator", HFILL}
497
14
        },
498
14
        { &hf_ilnp_stream,
499
14
            { "Stream index", "ilnp.stream",
500
14
                FT_UINT32, BASE_DEC, NULL, 0x0,
501
14
                NULL, HFILL }
502
14
        },
503
14
    };
504
505
14
    static int* ett[] = {
506
14
        &ett_ilnp,
507
14
    };
508
509
14
    proto_ilnp = proto_register_protocol("Identifier-Locator Network Protocol", "ILNP", "ilnp");
510
14
    proto_register_field_array(proto_ilnp, hf, array_length(hf));
511
14
    proto_register_subtree_array(ett, array_length(ett));
512
513
14
    register_init_routine(ilnp_init);
514
515
14
    ilnp_handle = register_dissector("ilnp", dissect_ilnp, proto_ilnp);
516
517
14
    ilnp_tap = register_tap("ilnp");
518
519
14
    register_conversation_table(proto_ilnp, true, ilnp_conversation_packet, ilnp_endpoint_packet);
520
14
    register_conversation_filter("ilnp", "ILNP", ilnp_filter_valid, ilnp_build_filter, NULL);
521
522
    /* XXX - This isn't really a plugin, but the non-plugin version requires GUI changes */
523
14
    stats_tree_register_plugin("ilnp", "ilnp_nids", st_str_ilnp_nid, 0, ilnp_nids_stats_tree_packet, ilnp_nids_stats_tree_init, NULL);
524
14
    stats_tree_register_plugin("ilnp", "ilnp_l64s", st_str_ilnp_l64, 0, ilnp_l64s_stats_tree_packet, ilnp_l64s_stats_tree_init, NULL);
525
14
    stats_tree_register_plugin("ilnp", "ilnp_ilvs", st_str_ilnp_ilv, 0, ilnp_ilvs_stats_tree_packet, ilnp_ilvs_stats_tree_init, NULL);
526
14
    stats_tree_register_plugin("ilnp", "ilnp_ptype", st_str_ilnp_ptype, 0, ilnp_ptype_stats_tree_packet, ilnp_ptype_stats_tree_init, NULL);
527
14
    stats_tree_register_plugin("ilnp", "ilnp_srcdst_nid", st_str_ilnp_srcdst_nid, 0, ilnp_srcdst_nid_stats_tree_packet, ilnp_srcdst_nid_stats_tree_init, NULL);
528
14
    stats_tree_register_plugin("ilnp", "ilnp_srcdst_l64", st_str_ilnp_srcdst_l64, 0, ilnp_srcdst_l64_stats_tree_packet, ilnp_srcdst_l64_stats_tree_init, NULL);
529
    stats_tree_register_plugin("ilnp", "ilnp_srcdst_ilv", st_str_ilnp_srcdst_ilv, 0, ilnp_srcdst_ilv_stats_tree_packet, ilnp_srcdst_ilv_stats_tree_init, NULL);
530
14
}