Coverage Report

Created: 2026-06-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-netlink-route.c
Line
Count
Source
1
/* packet-netlink-route.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
10
/* man 7 rtnetlink */
11
12
#include "config.h"
13
14
#include <epan/packet.h>
15
#include <epan/aftypes.h>
16
#include <epan/to_str.h>
17
#include <epan/tfs.h>
18
#include <wsutil/array.h>
19
20
#include "packet-arp.h"
21
#include "packet-netlink.h"
22
23
void proto_register_netlink_route(void);
24
void proto_reg_handoff_netlink_route(void);
25
26
/*
27
 * The "legacy" flag indicates that the packet is a legacy dump
28
 * request message.
29
 *
30
 * Some legacy tools, including iproute2 < 3.9, issue shorter RTM_GETLINK
31
 * and RTM_GETADDR dump queries which only contain struct rtgenmsg rather
32
 * than struct ifinfomsg. As noted in kernel comment in rtnl_dump_ifinfo(),
33
 * these legacy requests will be (even with attributes) always shorter than
34
 * struct ifinfomsg so that they are easy to detect.
35
 *
36
 * Similar problem can be observed with tools using nl_rtgen_request()
37
 * function from libnl3; this also affects other RTM_GET* types.
38
 *
39
 * If such legacy message is detected by length shorter than expected data
40
 * structure, we parse it as this legacy version with (1-byte) struct
41
 * rtgenmsg so that it's shown as intended rather than as malformed.
42
 *
43
 * The legacy messages appear, from looking at the iproute2 3.1.0 code,
44
 * to be a structure containing a struct nlmsghdr followed by a struct
45
 * rtgenmsg.
46
 *
47
 * struct rtgenmsg contains only a 1-byte address family value, as noted.
48
 * *However*, a struct nlmsghdr has a 4-byte length field, and is, as a
49
 * result, aligned on a 4-byte boundary, so the structure containing those
50
 * two structures is also aligned on a 4-byte boundary, and thus has a
51
 * length that's a multiple of 4 bytes.  Therefore, there are 3 bytes of
52
 * padding following the address family byte.
53
 *
54
 * The message length, however, doesn't include those bytes.
55
 *
56
 * Legacy messages don't include any attributes - they're not large enough
57
 * to contain anything other than the netlink message header and the one-byte
58
 * address family.  For legacy messages, the attribute we hand to
59
 * dissect_netlink_route_attributes() is not aligned on a 4-byte boundary,
60
 * as it's the offset right after the 1-byte address family value;
61
 * dissect_netlink_route_attributes() will try to align that on a 4-byte
62
 * boundary, but that will go past the "immediately after the end of
63
 * the packet" offset, which can cause problems if any checking is done
64
 * to make sure the offset is valid.  Therefore, we don't try to dissect
65
 * the attributes, rather than relying on the attributes dissector to
66
 * discover that there's nothing left in the packet.
67
 */
68
struct netlink_route_info {
69
  packet_info *pinfo;
70
  bool legacy;
71
};
72
73
enum {
74
/* rtnetlink values for nlmsghdr.nlmsg_type from <include/uapi/linux/rtnetlink.h> */
75
  WS_RTM_NEWLINK      = 16,
76
  WS_RTM_DELLINK      = 17,
77
  WS_RTM_GETLINK      = 18,
78
  WS_RTM_SETLINK      = 19,
79
  WS_RTM_NEWADDR      = 20,
80
  WS_RTM_DELADDR      = 21,
81
  WS_RTM_GETADDR      = 22,
82
  WS_RTM_NEWROUTE     = 24,
83
  WS_RTM_DELROUTE     = 25,
84
  WS_RTM_GETROUTE     = 26,
85
  WS_RTM_NEWNEIGH     = 28,
86
  WS_RTM_DELNEIGH     = 29,
87
  WS_RTM_GETNEIGH     = 30,
88
  WS_RTM_NEWRULE      = 32,
89
  WS_RTM_DELRULE      = 33,
90
  WS_RTM_GETRULE      = 34,
91
  WS_RTM_NEWQDISC     = 36,
92
  WS_RTM_DELQDISC     = 37,
93
  WS_RTM_GETQDISC     = 38,
94
  WS_RTM_NEWTCLASS    = 40,
95
  WS_RTM_DELTCLASS    = 41,
96
  WS_RTM_GETTCLASS    = 42,
97
  WS_RTM_NEWTFILTER   = 44,
98
  WS_RTM_DELTFILTER   = 45,
99
  WS_RTM_GETTFILTER   = 46,
100
  WS_RTM_NEWACTION    = 48,
101
  WS_RTM_DELACTION    = 49,
102
  WS_RTM_GETACTION    = 50,
103
  WS_RTM_NEWPREFIX    = 52,
104
  WS_RTM_GETMULTICAST = 58,
105
  WS_RTM_GETANYCAST   = 62,
106
  WS_RTM_NEWNEIGHTBL  = 64,
107
  WS_RTM_GETNEIGHTBL  = 66,
108
  WS_RTM_SETNEIGHTBL  = 67,
109
  WS_RTM_NEWNDUSEROPT = 68,
110
  WS_RTM_NEWADDRLABEL = 72,
111
  WS_RTM_DELADDRLABEL = 73,
112
  WS_RTM_GETADDRLABEL = 74,
113
  WS_RTM_GETDCB       = 78,
114
  WS_RTM_SETDCB       = 79,
115
  WS_RTM_NEWNETCONF   = 80,
116
  WS_RTM_DELNETCONF   = 81,
117
  WS_RTM_GETNETCONF   = 82,
118
  WS_RTM_NEWMDB       = 84,
119
  WS_RTM_DELMDB       = 85,
120
  WS_RTM_GETMDB       = 86,
121
  WS_RTM_NEWNSID      = 88,
122
  WS_RTM_DELNSID      = 89,
123
  WS_RTM_GETNSID      = 90,
124
  WS_RTM_NEWSTATS     = 92,
125
  WS_RTM_GETSTATS     = 94,
126
  WS_RTM_NEWCACHEREPORT = 96,
127
  WS_RTM_NEWCHAIN     = 100,
128
  WS_RTM_DELCHAIN     = 101,
129
  WS_RTM_GETCHAIN     = 102,
130
  WS_RTM_NEWNEXTHOP   = 104,
131
  WS_RTM_DELNEXTHOP   = 105,
132
  WS_RTM_GETNEXTHOP   = 106,
133
  WS_RTM_NEWLINKPROP  = 108,
134
  WS_RTM_DELLINKPROP  = 109,
135
  WS_RTM_GETLINKPROP  = 110,
136
  WS_RTM_NEWVLAN      = 112,
137
  WS_RTM_DELVLAN      = 113,
138
  WS_RTM_GETVLAN      = 114,
139
  WS_RTM_NEWNEXTHOPBUCKET = 116,
140
  WS_RTM_DELNEXTHOPBUCKET = 117,
141
  WS_RTM_GETNEXTHOPBUCKET = 118,
142
  WS_RTM_NEWTUNNEL    = 120,
143
  WS_RTM_DELTUNNEL    = 121,
144
  WS_RTM_GETTUNNEL    = 122,
145
};
146
147
/* values for rta_type (network interface) from </include/uapi/linux/if_link.h> */
148
enum ws_ifla_attr_type {
149
  WS_IFLA_UNSPEC          =  0,
150
  WS_IFLA_ADDRESS         =  1,
151
  WS_IFLA_BROADCAST       =  2,
152
  WS_IFLA_IFNAME          =  3,
153
  WS_IFLA_MTU             =  4,
154
  WS_IFLA_LINK            =  5,
155
  WS_IFLA_QDISC           =  6,
156
  WS_IFLA_STATS           =  7,
157
  WS_IFLA_COST            =  8,
158
  WS_IFLA_PRIORITY        =  9,
159
  WS_IFLA_MASTER          = 10,
160
  WS_IFLA_WIRELESS        = 11,
161
  WS_IFLA_PROTINFO        = 12,
162
  WS_IFLA_TXQLEN          = 13,
163
  WS_IFLA_MAP             = 14,
164
  WS_IFLA_WEIGHT          = 15,
165
  WS_IFLA_OPERSTATE       = 16,
166
  WS_IFLA_LINKMODE        = 17,
167
  WS_IFLA_LINKINFO        = 18,
168
  WS_IFLA_NET_NS_PID      = 19,
169
  WS_IFLA_IFALIAS         = 20,
170
  WS_IFLA_NUM_VF          = 21,
171
  WS_IFLA_VFINFO_LIST     = 22,
172
  WS_IFLA_STATS64         = 23,
173
  WS_IFLA_VF_PORTS        = 24,
174
  WS_IFLA_PORT_SELF       = 25,
175
  WS_IFLA_AF_SPEC         = 26,
176
  WS_IFLA_GROUP           = 27,
177
  WS_IFLA_NET_NS_FD       = 28,
178
  WS_IFLA_EXT_MASK        = 29,
179
  WS_IFLA_PROMISCUITY     = 30,
180
  WS_IFLA_NUM_TX_QUEUES   = 31,
181
  WS_IFLA_NUM_RX_QUEUES   = 32,
182
  WS_IFLA_CARRIER         = 33,
183
  WS_IFLA_PHYS_PORT_ID    = 34,
184
  WS_IFLA_CARRIER_CHANGES = 35,
185
  WS_IFLA_PHYS_SWITCH_ID  = 36,
186
  WS_IFLA_LINK_NETNSID    = 37,
187
  WS_IFLA_PHYS_PORT_NAME  = 38,
188
  WS_IFLA_PROTO_DOWN      = 39,
189
  WS_IFLA_GSO_MAX_SEGS    = 40,
190
  WS_IFLA_GSO_MAX_SIZE    = 41,
191
  WS_IFLA_PAD             = 42,
192
  WS_IFLA_XDP             = 43,
193
  WS_IFLA_EVENT           = 44,
194
  WS_IFLA_NEW_NETNSID     = 45,
195
  WS_IFLA_IF_NETNSID      = 46,
196
  WS_IFLA_CARRIER_UP_COUNT   = 47,
197
  WS_IFLA_CARRIER_DOWN_COUNT = 48,
198
  WS_IFLA_NEW_IFINDEX     = 49,
199
  WS_IFLA_MIN_MTU         = 50,
200
  WS_IFLA_MAX_MTU         = 51,
201
  WS_IFLA_PROP_LIST       = 52,
202
  WS_IFLA_ALT_IFNAME      = 53,
203
  WS_IFLA_PERM_ADDRESS    = 54,
204
  WS_IFLA_PROTO_DOWN_REASON = 55,
205
  WS_IFLA_PARENT_DEV_NAME = 56,
206
  WS_IFLA_PARENT_DEV_BUS_NAME = 57,
207
  WS_IFLA_GRO_MAX_SIZE    = 58,
208
  WS_IFLA_TSO_MAX_SIZE    = 59,
209
  WS_IFLA_TSO_MAX_SEGS    = 60,
210
  WS_IFLA_ALLMULTI        = 61,
211
};
212
213
/* values for rta_type (ip address) from <include/uapi/linux/if_addr.h> */
214
enum ws_ifa_attr_type {
215
  WS_IFA_UNSPEC      = 0,
216
  WS_IFA_ADDRESS     = 1,
217
  WS_IFA_LOCAL       = 2,
218
  WS_IFA_LABEL       = 3,
219
  WS_IFA_BROADCAST   = 4,
220
  WS_IFA_ANYCAST     = 5,
221
  WS_IFA_CACHEINFO   = 6,
222
  WS_IFA_MULTICAST   = 7,
223
  WS_IFA_FLAGS       = 8,
224
  WS_IFA_RT_PRIORITY = 9,
225
  WS_IFA_TARGET_NETNSID = 10,
226
  WS_IFA_PROTO       = 11,
227
};
228
229
/* values for rta_type (route) from <include/uapi/linux/rtnetlink.h> */
230
enum ws_rta_attr_type {
231
  WS_RTA_UNSPEC    =  0,
232
  WS_RTA_DST       =  1,
233
  WS_RTA_SRC       =  2,
234
  WS_RTA_IIF       =  3,
235
  WS_RTA_OIF       =  4,
236
  WS_RTA_GATEWAY   =  5,
237
  WS_RTA_PRIORITY  =  6,
238
  WS_RTA_PREFSRC   =  7,
239
  WS_RTA_METRICS   =  8,
240
  WS_RTA_MULTIPATH =  9,
241
  WS_RTA_PROTOINFO = 10,
242
  WS_RTA_FLOW      = 11,
243
  WS_RTA_CACHEINFO = 12,
244
  WS_RTA_SESSION   = 13,
245
  WS_RTA_MP_ALGO   = 14,
246
  WS_RTA_TABLE     = 15,
247
  WS_RTA_MARK      = 16,
248
  WS_RTA_MFC_STATS = 17,
249
  WS_RTA_VIA       = 18,
250
  WS_RTA_NEWDST    = 19,
251
  WS_RTA_PREF      = 20,
252
  WS_RTA_ENCAP_TYPE= 21,
253
  WS_RTA_ENCAP     = 22,
254
  WS_RTA_EXPIRES   = 23,
255
  WS_RTA_PAD       = 24,
256
  WS_RTA_UID       = 25,
257
  WS_RTA_TTL_PROPAGATE = 26,
258
  WS_RTA_IP_PROTO  = 27,
259
  WS_RTA_SPORT     = 28,
260
  WS_RTA_DPORT     = 29,
261
  WS_RTA_NH_ID     = 30,
262
};
263
264
265
/* values for rtmsg.rtm_protocol from <include/uapi/linux/rtnetlink.h> */
266
enum {
267
/* kernel */
268
  WS_RTPROT_UNSPEC   =  0,
269
  WS_RTPROT_REDIRECT =  1,
270
  WS_RTPROT_KERNEL   =  2,
271
  WS_RTPROT_BOOT     =  3,
272
  WS_RTPROT_STATIC   =  4,
273
/* user */
274
  WS_RTPROT_GATED    =  8,
275
  WS_RTPROT_RA       =  9,
276
  WS_RTPROT_MRT      = 10,
277
  WS_RTPROT_ZEBRA    = 11,
278
  WS_RTPROT_BIRD     = 12,
279
  WS_RTPROT_DNROUTED = 13,
280
  WS_RTPROT_XORP     = 14,
281
  WS_RTPROT_NTK      = 15,
282
  WS_RTPROT_DHCP     = 16,
283
  WS_RTPROT_MROUTED  = 17,
284
  WS_RTPROT_KEEPALIVED = 18,
285
  WS_RTPROT_BABEL    = 42,
286
  WS_RTPROT_OPENR    = 99,
287
  WS_RTPROT_BGP      = 186,
288
  WS_RTPROT_ISIS     = 187,
289
  WS_RTPROT_OSPF     = 188,
290
  WS_RTPROT_RIP      = 189,
291
  WS_RTPROT_EIGRP    = 192,
292
};
293
294
/* values for rtmsg.rtm_scope from <include/uapi/linux/rtnetlink.h> */
295
enum {
296
  WS_RT_SCOPE_UNIVERSE =  0,
297
/* ... user defined (/etc/iproute2/rt_scopes) ... */
298
  WS_RT_SCOPE_SITE    = 200,
299
  WS_RT_SCOPE_LINK    = 253,
300
  WS_RT_SCOPE_HOST    = 254,
301
  WS_RT_SCOPE_NOWHERE = 255
302
};
303
304
/* values for rtmsg.rtm_type from <include/uapi/linux/rtnetlink.h> */
305
enum {
306
  WS_RTN_UNSPEC      =  0,
307
  WS_RTN_UNICAST     =  1,
308
  WS_RTN_LOCAL       =  2,
309
  WS_RTN_BROADCAST   =  3,
310
  WS_RTN_ANYCAST     =  4,
311
  WS_RTN_MULTICAST   =  5,
312
  WS_RTN_BLACKHOLE   =  6,
313
  WS_RTN_UNREACHABLE =  7,
314
  WS_RTN_PROHIBIT    =  8,
315
  WS_RTN_THROW       =  9,
316
  WS_RTN_NAT         = 10,
317
  WS_RTN_XRESOLVE    = 11
318
};
319
320
/* values for ifinfomsg.ifi_flags <include/uapi/linux/if.h> */
321
enum {
322
  WS_IFF_UP          =     0x1,
323
  WS_IFF_BROADCAST   =     0x2,
324
  WS_IFF_DEBUG       =     0x4,
325
  WS_IFF_LOOPBACK    =     0x8,
326
  WS_IFF_POINTOPOINT =    0x10,
327
  WS_IFF_NOTRAILERS  =    0x20,
328
  WS_IFF_RUNNING     =    0x40,
329
  WS_IFF_NOARP       =    0x80,
330
  WS_IFF_PROMISC     =   0x100,
331
  WS_IFF_ALLMULTI    =   0x200,
332
  WS_IFF_MASTER      =   0x400,
333
  WS_IFF_SLAVE       =   0x800,
334
  WS_IFF_MULTICAST   =  0x1000,
335
  WS_IFF_PORTSEL     =  0x2000,
336
  WS_IFF_AUTOMEDIA   =  0x4000,
337
  WS_IFF_DYNAMIC     =  0x8000,
338
  WS_IFF_LOWER_UP    = 0x10000,
339
  WS_IFF_DORMANT     = 0x20000,
340
  WS_IFF_ECHO        = 0x40000
341
};
342
343
/* values for ifaddrmsg.ifa_flags <include/uapi/linux/if_addr.h> */
344
enum {
345
  WS_IFA_F_SECONDARY    = 0x01,
346
  WS_IFA_F_NODAD        = 0x02,
347
  WS_IFA_F_OPTIMISTIC   = 0x04,
348
  WS_IFA_F_DADFAILED    = 0x08,
349
  WS_IFA_F_HOMEADDRESS  = 0x10,
350
  WS_IFA_F_DEPRECATED   = 0x20,
351
  WS_IFA_F_TENTATIVE    = 0x40,
352
  WS_IFA_F_PERMANENT    = 0x80,
353
  WS_IFA_F_MANAGETEMPADDR = 0x100,
354
  WS_IFA_F_NOPREFIXROUTE  = 0x200,
355
  WS_IFA_F_MCAUTOJOIN     = 0x400,
356
  WS_IFA_F_STABLE_PRIVACY = 0x800,
357
};
358
359
/* values for ndmsg.ndm_state <include/uapi/linux/neighbour.h> */
360
enum {
361
  WS_NUD_INCOMPLETE       = 0x01,
362
  WS_NUD_REACHABLE        = 0x02,
363
  WS_NUD_STALE            = 0x04,
364
  WS_NUD_DELAY            = 0x08,
365
  WS_NUD_PROBE            = 0x10,
366
  WS_NUD_FAILED           = 0x20,
367
/* Dummy states */
368
  WS_NUD_NOARP            = 0x40,
369
  WS_NUD_PERMANENT        = 0x80,
370
  WS_NUD_NONE             = 0x00
371
};
372
373
/* values for ifla.operstate <include/uapi/linux/if.h> */
374
enum {
375
  WS_IF_OPER_UNKNOWN,
376
  WS_IF_OPER_NOTPRESENT,
377
  WS_IF_OPER_DOWN,
378
  WS_IF_OPER_LOWERLAYERDOWN,
379
  WS_IF_OPER_TESTING,
380
  WS_IF_OPER_DORMANT,
381
  WS_IF_OPER_UP,
382
};
383
384
static int proto_netlink_route;
385
386
static dissector_handle_t netlink_route_handle;
387
388
static int hf_netlink_route_ifa_addr4;
389
static int hf_netlink_route_ifa_addr6;
390
static int hf_netlink_route_ifa_attr_type;
391
static int hf_netlink_route_ifa_family;
392
static int hf_netlink_route_ifa_flags;
393
static int hf_netlink_route_ifa_flags32;
394
static int hf_netlink_route_ifa_index;
395
static int hf_netlink_route_ifa_label;
396
static int hf_netlink_route_ifa_prefixlen;
397
static int hf_netlink_route_ifa_scope;
398
static int hf_netlink_route_ifi_change;
399
static int hf_netlink_route_ifi_family;
400
static int hf_netlink_route_ifi_flags;
401
static int hf_netlink_route_ifi_flags_iff_broadcast;
402
static int hf_netlink_route_ifi_flags_iff_up;
403
static int hf_netlink_route_ifi_index;
404
static int hf_netlink_route_ifi_type;
405
static int hf_netlink_route_ifla_attr_type;
406
static int hf_netlink_route_ifla_broadcast;
407
static int hf_netlink_route_ifla_carrier;
408
static int hf_netlink_route_ifla_carrier_changes;
409
static int hf_netlink_route_ifla_carrier_down_count;
410
static int hf_netlink_route_ifla_carrier_up_count;
411
static int hf_netlink_route_ifla_group;
412
static int hf_netlink_route_ifla_gso_maxsegs;
413
static int hf_netlink_route_ifla_gso_maxsize;
414
static int hf_netlink_route_ifla_hwaddr;
415
static int hf_netlink_route_ifla_ifname;
416
static int hf_netlink_route_ifla_linkstats_collisions;
417
static int hf_netlink_route_ifla_linkstats_multicast;
418
static int hf_netlink_route_ifla_linkstats_rx_crc_errs;
419
static int hf_netlink_route_ifla_linkstats_rx_fifo_errs;
420
static int hf_netlink_route_ifla_linkstats_rx_frame_errs;
421
static int hf_netlink_route_ifla_linkstats_rx_len_errs;
422
static int hf_netlink_route_ifla_linkstats_rx_miss_errs;
423
static int hf_netlink_route_ifla_linkstats_rx_over_errs;
424
static int hf_netlink_route_ifla_linkstats_rxbytes;
425
static int hf_netlink_route_ifla_linkstats_rxdropped;
426
static int hf_netlink_route_ifla_linkstats_rxerrors;
427
static int hf_netlink_route_ifla_linkstats_rxpackets;
428
static int hf_netlink_route_ifla_linkstats_tx_abort_errs;
429
static int hf_netlink_route_ifla_linkstats_tx_carrier_errs;
430
static int hf_netlink_route_ifla_linkstats_tx_fifo_errs;
431
static int hf_netlink_route_ifla_linkstats_tx_heartbeat_errs;
432
static int hf_netlink_route_ifla_linkstats_tx_window_errs;
433
static int hf_netlink_route_ifla_linkstats_txbytes;
434
static int hf_netlink_route_ifla_linkstats_txdropped;
435
static int hf_netlink_route_ifla_linkstats_txerrors;
436
static int hf_netlink_route_ifla_linkstats_txpackets;
437
static int hf_netlink_route_ifla_map_baseaddr;
438
static int hf_netlink_route_ifla_map_dma;
439
static int hf_netlink_route_ifla_map_irq;
440
static int hf_netlink_route_ifla_map_memend;
441
static int hf_netlink_route_ifla_map_memstart;
442
static int hf_netlink_route_ifla_map_port;
443
static int hf_netlink_route_ifla_max_mtu;
444
static int hf_netlink_route_ifla_min_mtu;
445
static int hf_netlink_route_ifla_mtu;
446
static int hf_netlink_route_ifla_operstate;
447
static int hf_netlink_route_ifla_promiscuity;
448
static int hf_netlink_route_ifla_qdisc;
449
static int hf_netlink_route_ifla_rxqnum;
450
static int hf_netlink_route_ifla_txqlen;
451
static int hf_netlink_route_ifla_txqnum;
452
static int hf_netlink_route_nd_family;
453
static int hf_netlink_route_nd_flags;
454
static int hf_netlink_route_nd_index;
455
static int hf_netlink_route_nd_state;
456
static int hf_netlink_route_nd_type;
457
static int hf_netlink_route_nltype;
458
static int hf_netlink_route_rt_dst_len;
459
static int hf_netlink_route_rt_family;
460
static int hf_netlink_route_rt_flags;
461
static int hf_netlink_route_rt_protocol;
462
static int hf_netlink_route_rt_scope;
463
static int hf_netlink_route_rt_src_len;
464
static int hf_netlink_route_rt_table;
465
static int hf_netlink_route_rt_tos;
466
static int hf_netlink_route_rt_type;
467
static int hf_netlink_route_rta_attr_type;
468
static int hf_netlink_route_rta_iif;
469
static int hf_netlink_route_rta_oif;
470
471
static int ett_netlink_route;
472
static int ett_netlink_route_attr;
473
static int ett_netlink_route_if_flags;
474
static int ett_netlink_route_attr_linkstats;
475
static int ett_netlink_route_attr_linkstats_rxerrs;
476
static int ett_netlink_route_attr_linkstats_txerrs;
477
478
static void
479
_fill_label_value_string_bitmask(char *label, uint32_t value, const value_string *vals)
480
0
{
481
0
  char tmp[16];
482
483
0
  label[0] = '\0';
484
485
0
  while (vals->strptr) {
486
0
    if (value & vals->value) {
487
0
      value &= ~(vals->value);
488
0
      if (label[0])
489
0
        (void) g_strlcat(label, ", ", ITEM_LABEL_LENGTH);
490
491
0
      (void) g_strlcat(label, vals->strptr, ITEM_LABEL_LENGTH);
492
0
    }
493
494
0
    vals++;
495
0
  }
496
497
0
  if (value) {
498
0
    if (label[0])
499
0
      (void) g_strlcat(label, ", ", ITEM_LABEL_LENGTH);
500
0
    snprintf(tmp, sizeof(tmp), "0x%x", value);
501
0
    (void) g_strlcat(label, tmp, ITEM_LABEL_LENGTH);
502
0
  }
503
0
}
504
505
static int
506
dissect_netlink_route_attributes(tvbuff_t *tvb, int hf_type, struct netlink_route_info *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset, netlink_attributes_cb_t cb)
507
0
{
508
  /* XXX, it's *almost* the same:
509
   *  - rtnetlink is using struct rtattr with shorts
510
   *  - generic netlink is using struct nlattr with __u16
511
   */
512
513
  /* XXX, nice */
514
0
  return dissect_netlink_attributes_to_end(tvb, hf_type, ett_netlink_route_attr, info, nl_data, tree, offset, cb);
515
0
}
516
517
static void
518
hf_netlink_route_ifi_flags_label(char *label, uint32_t value)
519
0
{
520
0
  static const value_string iff_vals[] = {
521
0
    { WS_IFF_UP,          "UP" },
522
0
    { WS_IFF_BROADCAST,   "BROADCAST" },
523
0
    { WS_IFF_DEBUG,       "DEBUG" },
524
0
    { WS_IFF_LOOPBACK,    "LOOPBACK" },
525
0
    { WS_IFF_POINTOPOINT, "POINTOPOINT" },
526
0
    { WS_IFF_NOTRAILERS,  "NOTRAILERS" },
527
0
    { WS_IFF_RUNNING,     "RUNNING" },
528
0
    { WS_IFF_NOARP,       "NOARP" },
529
0
    { WS_IFF_PROMISC,     "PROMISC" },
530
0
    { WS_IFF_ALLMULTI,    "ALLMULTI" },
531
0
    { WS_IFF_MASTER,      "MASTER" },
532
0
    { WS_IFF_SLAVE,       "SLAVE" },
533
0
    { WS_IFF_MULTICAST,   "MULTICAST" },
534
0
    { WS_IFF_PORTSEL,     "PORTSEL" },
535
0
    { WS_IFF_AUTOMEDIA,   "AUTOMEDIA" },
536
0
    { WS_IFF_DYNAMIC,     "DYNAMIC" },
537
0
    { WS_IFF_LOWER_UP,    "LOWER_UP" },
538
0
    { WS_IFF_DORMANT,     "DORMANT" },
539
0
    { WS_IFF_ECHO,        "ECHO" },
540
0
    { 0, NULL }
541
0
  };
542
543
0
  char tmp[16];
544
545
0
  _fill_label_value_string_bitmask(label, value, iff_vals);
546
547
0
  snprintf(tmp, sizeof(tmp), " (0x%.8x)", value);
548
0
  (void) g_strlcat(label, tmp, ITEM_LABEL_LENGTH);
549
0
}
550
551
static int
552
dissect_netlink_route_ifinfomsg(tvbuff_t *tvb, struct netlink_route_info *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
553
0
{
554
0
  proto_item *ti;
555
0
  proto_tree *if_flags_tree;
556
557
0
  proto_tree_add_item(tree, hf_netlink_route_ifi_family, tvb, offset, 1, nl_data->encoding);
558
0
  offset += 1;
559
560
0
  if (info->legacy) {
561
    /*
562
     * See the comment for the netlink_route_info structure,
563
     * above.
564
     */
565
0
    return offset;
566
0
  }
567
568
  /* XXX padding, check if 0 */
569
0
  offset += 1;
570
571
0
  proto_tree_add_item(tree, hf_netlink_route_ifi_type, tvb, offset, 2, nl_data->encoding);
572
0
  offset += 2;
573
574
0
  proto_tree_add_item(tree, hf_netlink_route_ifi_index, tvb, offset, 4, nl_data->encoding);
575
0
  offset += 4;
576
577
0
  ti = proto_tree_add_item(tree, hf_netlink_route_ifi_flags, tvb, offset, 4, nl_data->encoding);
578
0
  if_flags_tree = proto_item_add_subtree(ti, ett_netlink_route_if_flags);
579
580
0
  if (if_flags_tree) {
581
0
    proto_tree_add_item(if_flags_tree, hf_netlink_route_ifi_flags_iff_up, tvb, offset, 4, nl_data->encoding);
582
0
    proto_tree_add_item(if_flags_tree, hf_netlink_route_ifi_flags_iff_broadcast, tvb, offset, 4, nl_data->encoding);
583
    /* XXX */
584
0
  }
585
0
  offset += 4;
586
587
0
  proto_tree_add_item(tree, hf_netlink_route_ifi_change, tvb, offset, 4, nl_data->encoding);
588
0
  offset += 4;
589
590
0
  return offset;
591
0
}
592
593
/* Interface Attributes */
594
595
static const value_string netlink_route_ifla_attr_vals[] = {
596
  { WS_IFLA_UNSPEC,         "Unspecified" },
597
  { WS_IFLA_ADDRESS,        "HW Address" },
598
  { WS_IFLA_BROADCAST,      "Broadcast" },
599
  { WS_IFLA_IFNAME,         "Device name" },
600
  { WS_IFLA_MTU,            "MTU" },
601
  { WS_IFLA_LINK,           "Link type" },
602
  { WS_IFLA_QDISC,          "Queueing discipline" },
603
  { WS_IFLA_STATS,          "Interface Statistics" },
604
  { WS_IFLA_COST,           "Cost" },
605
  { WS_IFLA_PRIORITY,       "Priority" },
606
  { WS_IFLA_MASTER,         "Master" },
607
  { WS_IFLA_WIRELESS,       "Wireless" },
608
  { WS_IFLA_PROTINFO,       "Prot info" },
609
  { WS_IFLA_TXQLEN,         "TxQueue length"},
610
  { WS_IFLA_MAP,            "Map"},
611
  { WS_IFLA_WEIGHT,         "Weight"},
612
  { WS_IFLA_OPERSTATE,      "Operstate"},
613
  { WS_IFLA_LINKMODE,       "Link mode"},
614
  { WS_IFLA_LINKINFO,       "Link info"},
615
  { WS_IFLA_NET_NS_PID,     "NetNs id"},
616
  { WS_IFLA_IFALIAS,        "Ifalias"},
617
  { WS_IFLA_NUM_VF,         "Num VF"},
618
  { WS_IFLA_VFINFO_LIST,    "VF Info"},
619
  { WS_IFLA_STATS64,        "Stats" },
620
  { WS_IFLA_VF_PORTS,       "VF ports" },
621
  { WS_IFLA_PORT_SELF,      "Port self" },
622
  { WS_IFLA_AF_SPEC,        "AF spec" },
623
  { WS_IFLA_GROUP,          "Group" },
624
  { WS_IFLA_NET_NS_FD,      "NetNs fd" },
625
  { WS_IFLA_EXT_MASK,       "Ext mask" },
626
  { WS_IFLA_PROMISCUITY,    "Promiscuity" },
627
  { WS_IFLA_NUM_TX_QUEUES,  "Number of Tx queues" },
628
  { WS_IFLA_NUM_RX_QUEUES,  "Number of Rx queues" },
629
  { WS_IFLA_CARRIER,        "Carrier" },
630
  { WS_IFLA_PHYS_PORT_ID,   "Physical port ID" },
631
  { WS_IFLA_CARRIER_CHANGES,"Carrier changes" },
632
  { WS_IFLA_PHYS_SWITCH_ID, "Physical switch ID" },
633
  { WS_IFLA_LINK_NETNSID,   "Link network namespace ID" },
634
  { WS_IFLA_PHYS_PORT_NAME, "Physical port name" },
635
  { WS_IFLA_PROTO_DOWN,     "IFLA_PROTO_DOWN" },
636
  { WS_IFLA_GSO_MAX_SEGS,   "Maximum GSO segment count" },
637
  { WS_IFLA_GSO_MAX_SIZE,   "Maximum GSO size" },
638
  { WS_IFLA_PAD,            "IFLA_PAD" },
639
  { WS_IFLA_XDP,            "IFLA_XDP" },
640
  { WS_IFLA_EVENT,          "IFLA_EVENT" },
641
  { WS_IFLA_NEW_NETNSID,    "IFLA_NEW_NETNSID" },
642
  { WS_IFLA_IF_NETNSID,     "IFLA_IF_NETNSID" },
643
  { WS_IFLA_CARRIER_UP_COUNT,   "Carrier up count" },
644
  { WS_IFLA_CARRIER_DOWN_COUNT, "Carrier down count" },
645
  { WS_IFLA_NEW_IFINDEX,    "IFLA_NEW_IFINDEX" },
646
  { WS_IFLA_MIN_MTU,        "Minimum MTU" },
647
  { WS_IFLA_MAX_MTU,        "Maximum MTU" },
648
  { WS_IFLA_PROP_LIST,      "Property list" },
649
  { WS_IFLA_ALT_IFNAME,     "Alternative ifname" },
650
  { WS_IFLA_PERM_ADDRESS,   "Permanent address" },
651
  { WS_IFLA_PROTO_DOWN_REASON, "Protocol down reason" },
652
  { WS_IFLA_PARENT_DEV_NAME, "Parent device name" },
653
  { WS_IFLA_PARENT_DEV_BUS_NAME, "Parent device bus name" },
654
  { WS_IFLA_GRO_MAX_SIZE,   "GRO maximum size" },
655
  { WS_IFLA_TSO_MAX_SIZE,   "TSO maximum size" },
656
  { WS_IFLA_TSO_MAX_SEGS,   "TSO maximum number of segments" },
657
  { WS_IFLA_ALLMULTI,       "Allmulti count" },
658
  { 0, NULL }
659
};
660
661
static const value_string netlink_route_ifla_operstate_vals[] = {
662
  { WS_IF_OPER_UNKNOWN,        "Unknown" },
663
  { WS_IF_OPER_NOTPRESENT,     "Not present" },
664
  { WS_IF_OPER_DOWN,           "Down" },
665
  { WS_IF_OPER_LOWERLAYERDOWN, "Lower layer down" },
666
  { WS_IF_OPER_TESTING,        "Testing" },
667
  { WS_IF_OPER_DORMANT,        "Dormant" },
668
  { WS_IF_OPER_UP,             "Up"},
669
  { 0, NULL }
670
};
671
672
static int *linkstat_root_hfs[] = {
673
  &hf_netlink_route_ifla_linkstats_rxpackets,
674
  &hf_netlink_route_ifla_linkstats_txpackets,
675
  &hf_netlink_route_ifla_linkstats_rxbytes,
676
  &hf_netlink_route_ifla_linkstats_txbytes,
677
  &hf_netlink_route_ifla_linkstats_rxerrors,
678
  &hf_netlink_route_ifla_linkstats_txerrors,
679
  &hf_netlink_route_ifla_linkstats_rxdropped,
680
  &hf_netlink_route_ifla_linkstats_txdropped,
681
  &hf_netlink_route_ifla_linkstats_multicast,
682
  &hf_netlink_route_ifla_linkstats_collisions,
683
};
684
685
686
static int *linkstat_rxerr_hfs[] = {
687
  &hf_netlink_route_ifla_linkstats_rx_len_errs,
688
  &hf_netlink_route_ifla_linkstats_rx_over_errs,
689
  &hf_netlink_route_ifla_linkstats_rx_crc_errs,
690
  &hf_netlink_route_ifla_linkstats_rx_frame_errs,
691
  &hf_netlink_route_ifla_linkstats_rx_fifo_errs,
692
  &hf_netlink_route_ifla_linkstats_rx_miss_errs,
693
};
694
695
696
static int *linkstat_txerr_hfs[] = {
697
  &hf_netlink_route_ifla_linkstats_tx_abort_errs,
698
  &hf_netlink_route_ifla_linkstats_tx_carrier_errs,
699
  &hf_netlink_route_ifla_linkstats_tx_fifo_errs,
700
  &hf_netlink_route_ifla_linkstats_tx_heartbeat_errs,
701
  &hf_netlink_route_ifla_linkstats_tx_window_errs,
702
};
703
704
static int
705
dissect_netlink_route_ifla_linkstats(tvbuff_t *tvb, struct netlink_route_info *info _U_, struct packet_netlink_data *nl_data, proto_tree *tree, int offset, int byte_size)
706
0
{
707
0
  proto_tree* rxerr_subtree;
708
0
  const int rxerr_hfs_len = array_length(linkstat_rxerr_hfs);
709
0
  proto_tree* txerr_subtree;
710
0
  const int txerr_hfs_len = array_length(linkstat_txerr_hfs);
711
712
0
  for (size_t i = 0; i < array_length(linkstat_root_hfs); i++) {
713
0
    proto_tree_add_item(tree, *linkstat_root_hfs[i], tvb, offset, byte_size, nl_data->encoding);
714
0
    offset += byte_size;
715
0
  }
716
717
0
  rxerr_subtree = proto_tree_add_subtree(tree, tvb, offset, byte_size * rxerr_hfs_len, ett_netlink_route_attr_linkstats_rxerrs, NULL, "Rx errors");
718
0
  for (int i = 0; i < rxerr_hfs_len; i++) {
719
0
    proto_tree_add_item(rxerr_subtree, *linkstat_rxerr_hfs[i], tvb, offset, byte_size, nl_data->encoding);
720
0
    offset += byte_size;
721
0
  }
722
723
0
  txerr_subtree = proto_tree_add_subtree(tree, tvb, offset, byte_size * txerr_hfs_len, ett_netlink_route_attr_linkstats_txerrs, NULL, "Tx errors");
724
0
  for (int i = 0; i < txerr_hfs_len; i++) {
725
0
    proto_tree_add_item(txerr_subtree, *linkstat_txerr_hfs[i], tvb, offset, byte_size, nl_data->encoding);
726
0
    offset += byte_size;
727
0
  }
728
729
730
0
  return 1;
731
0
}
732
733
static int
734
dissect_netlink_route_ifla_attrs(tvbuff_t *tvb, void *data, struct packet_netlink_data *nl_data, proto_tree *tree, int rta_type, int offset, int len)
735
0
{
736
0
  struct netlink_route_info *info = (struct netlink_route_info *)data;
737
0
  enum ws_ifla_attr_type type = (enum ws_ifla_attr_type) rta_type;
738
0
  const uint8_t* str;
739
0
  uint32_t value;
740
0
  bool flag;
741
0
  proto_tree* subtree;
742
0
  switch (type) {
743
0
    case WS_IFLA_IFNAME:
744
0
      proto_tree_add_item_ret_string(tree, hf_netlink_route_ifla_ifname, tvb, offset, len, ENC_ASCII | ENC_NA, info->pinfo->pool, &str);
745
0
      proto_item_append_text(tree, ": %s", str);
746
0
      return 1;
747
0
    case WS_IFLA_MTU:
748
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_mtu, tvb, offset, len, nl_data->encoding, &value);
749
0
      proto_item_append_text(tree, ": %u", value);
750
0
      return 1;
751
0
    case WS_IFLA_TXQLEN:
752
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_txqlen, tvb, offset, len, nl_data->encoding, &value);
753
0
      proto_item_append_text(tree, ": %u", value);
754
0
      return 1;
755
0
    case WS_IFLA_OPERSTATE:
756
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_operstate, tvb, offset, len, nl_data->encoding);
757
0
      return 1;
758
0
    case WS_IFLA_PROMISCUITY:
759
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_promiscuity, tvb, offset, len, nl_data->encoding, &value);
760
0
      proto_item_append_text(tree, ": %u", value);
761
0
      return 1;
762
0
    case WS_IFLA_NUM_TX_QUEUES:
763
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_txqnum, tvb, offset, len, nl_data->encoding, &value);
764
0
      proto_item_append_text(tree, ": %u", value);
765
0
      return 1;
766
0
    case WS_IFLA_NUM_RX_QUEUES:
767
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_rxqnum, tvb, offset, len, nl_data->encoding, &value);
768
0
      proto_item_append_text(tree, ": %u", value);
769
0
      return 1;
770
0
    case WS_IFLA_GROUP:
771
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_group, tvb, offset, len, nl_data->encoding, &value);
772
0
      proto_item_append_text(tree, ": %u", value);
773
0
      return 1;
774
0
    case WS_IFLA_GSO_MAX_SEGS:
775
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_gso_maxsegs, tvb, offset, len, nl_data->encoding, &value);
776
0
      proto_item_append_text(tree, ": %u", value);
777
0
      return 1;
778
0
    case WS_IFLA_GSO_MAX_SIZE:
779
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_gso_maxsize, tvb, offset, len, nl_data->encoding, &value);
780
0
      proto_item_append_text(tree, ": %u", value);
781
0
      return 1;
782
0
    case WS_IFLA_CARRIER:
783
0
      proto_tree_add_item_ret_boolean(tree, hf_netlink_route_ifla_carrier, tvb, offset, len, nl_data->encoding, &flag);
784
0
      proto_item_append_text(tree, ": %s", tfs_get_string(flag, &tfs_restricted_not_restricted));
785
0
      return 1;
786
0
    case WS_IFLA_CARRIER_CHANGES:
787
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_carrier_changes, tvb, offset, len, nl_data->encoding, &value);
788
0
      proto_item_append_text(tree, ": %u", value);
789
0
      return 1;
790
0
    case WS_IFLA_ADDRESS:
791
0
      proto_item_append_text(tree, ": %s", tvb_bytes_to_str_punct(info->pinfo->pool, tvb, offset, len, ':'));
792
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_hwaddr, tvb, offset, len, nl_data->encoding);
793
0
      return 1;
794
0
    case WS_IFLA_BROADCAST:
795
0
      proto_item_append_text(tree, ": %s", tvb_bytes_to_str_punct(info->pinfo->pool, tvb, offset, len, ':'));
796
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_broadcast, tvb, offset, len, nl_data->encoding);
797
0
      return 1;
798
0
    case WS_IFLA_STATS:
799
0
      subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_netlink_route_attr_linkstats, NULL, "Statistics");
800
0
      return dissect_netlink_route_ifla_linkstats(tvb, info, nl_data, subtree, offset, 4);
801
0
    case WS_IFLA_STATS64:
802
0
      subtree = proto_tree_add_subtree(tree, tvb, offset, len, ett_netlink_route_attr_linkstats, NULL, "Statistics");
803
0
      return dissect_netlink_route_ifla_linkstats(tvb, info, nl_data, subtree, offset, 8);
804
0
    case WS_IFLA_QDISC:
805
0
      proto_tree_add_item_ret_string(tree, hf_netlink_route_ifla_qdisc, tvb, offset, len, ENC_ASCII | ENC_NA, info->pinfo->pool, &str);
806
0
      proto_item_append_text(tree, ": %s", str);
807
0
      return 1;
808
0
    case WS_IFLA_MAP:
809
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_map_memstart, tvb, offset, 8, nl_data->encoding);
810
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_map_memend, tvb, offset + 8, 8, nl_data->encoding);
811
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_map_baseaddr, tvb, offset + 16, 8, nl_data->encoding);
812
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_map_irq, tvb, offset + 24, 2, nl_data->encoding);
813
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_map_dma, tvb, offset + 26, 1, nl_data->encoding);
814
0
      proto_tree_add_item(tree, hf_netlink_route_ifla_map_port, tvb, offset + 27, 1, nl_data->encoding);
815
0
      return 1;
816
0
    case WS_IFLA_CARRIER_UP_COUNT:
817
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_carrier_up_count, tvb, offset, len, nl_data->encoding, &value);
818
0
      proto_item_append_text(tree, ": %u", value);
819
0
      return 1;
820
0
    case WS_IFLA_CARRIER_DOWN_COUNT:
821
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_carrier_down_count, tvb, offset, len, nl_data->encoding, &value);
822
0
      proto_item_append_text(tree, ": %u", value);
823
0
      return 1;
824
0
    case WS_IFLA_MIN_MTU:
825
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_min_mtu, tvb, offset, len, nl_data->encoding, &value);
826
0
      proto_item_append_text(tree, ": %u", value);
827
0
      return 1;
828
0
    case WS_IFLA_MAX_MTU:
829
0
      proto_tree_add_item_ret_uint(tree, hf_netlink_route_ifla_max_mtu, tvb, offset, len, nl_data->encoding, &value);
830
0
      proto_item_append_text(tree, ": %u", value);
831
0
      return 1;
832
833
0
    default:
834
0
      return 0;
835
0
  }
836
0
}
837
838
/* IP address */
839
840
static void
841
netlink_route_ifa_flags_label(char *label, uint32_t value)
842
0
{
843
0
  static const value_string iff_vals[] = {
844
0
    { WS_IFA_F_SECONDARY,       "secondary/temporary" },
845
0
    { WS_IFA_F_NODAD,           "nodad" },
846
0
    { WS_IFA_F_OPTIMISTIC,      "optimistic" },
847
0
    { WS_IFA_F_DADFAILED,       "dadfailed" },
848
0
    { WS_IFA_F_HOMEADDRESS,     "homeaddress" },
849
0
    { WS_IFA_F_DEPRECATED,      "deprecated" },
850
0
    { WS_IFA_F_TENTATIVE,       "tentative" },
851
0
    { WS_IFA_F_PERMANENT,       "permanent" },
852
    /* 32-bit IFA_FLAGS (in attribute) */
853
0
    { WS_IFA_F_MANAGETEMPADDR,  "mngtmpaddr" },
854
0
    { WS_IFA_F_NOPREFIXROUTE,   "noprefixroute" },
855
0
    { WS_IFA_F_MCAUTOJOIN,      "autojoin" },
856
0
    { WS_IFA_F_STABLE_PRIVACY,  "stable_privacy" },
857
0
    { 0, NULL }
858
0
  };
859
860
0
  char tmp[16];
861
862
0
  _fill_label_value_string_bitmask(label, value, iff_vals);
863
864
0
  snprintf(tmp, sizeof(tmp), " (0x%.8x)", value);
865
0
  (void) g_strlcat(label, tmp, ITEM_LABEL_LENGTH);
866
0
}
867
868
static int
869
dissect_netlink_route_ifaddrmsg(tvbuff_t *tvb, struct netlink_route_info *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
870
0
{
871
0
  proto_tree_add_item(tree, hf_netlink_route_ifa_family,    tvb, offset, 1, ENC_NA);
872
0
  offset += 1;
873
874
0
  if (info->legacy) {
875
    /*
876
     * See the comment for the netlink_route_info structure,
877
     * above.
878
     */
879
0
    return offset;
880
0
  }
881
882
0
  proto_tree_add_item(tree, hf_netlink_route_ifa_prefixlen, tvb, offset, 1, ENC_NA);
883
0
  offset += 1;
884
885
0
  proto_tree_add_item(tree, hf_netlink_route_ifa_flags,     tvb, offset, 1, ENC_NA);
886
0
  offset += 1;
887
888
0
  proto_tree_add_item(tree, hf_netlink_route_ifa_scope,     tvb, offset, 1, ENC_NA);
889
0
  offset += 1;
890
891
0
  proto_tree_add_item(tree, hf_netlink_route_ifa_index,     tvb, offset, 4, nl_data->encoding);
892
0
  offset += 4;
893
894
0
  return offset;
895
0
}
896
897
/* IP address attributes */
898
899
static const value_string netlink_route_ifa_attr_vals[] = {
900
  { WS_IFA_UNSPEC,    "Unspecified" },
901
  { WS_IFA_ADDRESS,   "Interface address" },
902
  { WS_IFA_LOCAL,     "Local address" },
903
  { WS_IFA_LABEL,     "Name of interface" },
904
  { WS_IFA_BROADCAST, "Broadcast address" },
905
  { WS_IFA_ANYCAST,   "Anycast address" },
906
  { WS_IFA_CACHEINFO, "Address information" },
907
  { WS_IFA_MULTICAST, "Multicast address" },
908
  { WS_IFA_FLAGS,     "Address flags" },
909
  { WS_IFA_RT_PRIORITY, "IFA_RT_PRIORITY" },
910
  { WS_IFA_TARGET_NETNSID, "IFA_TARGET_NETNSID" },
911
  { WS_IFA_PROTO,     "IFA_PROTO" },
912
  { 0, NULL }
913
};
914
915
static int
916
dissect_netlink_route_ifa_attrs(tvbuff_t *tvb, void *data _U_, struct packet_netlink_data *nl_data, proto_tree *tree, int rta_type, int offset, int len)
917
0
{
918
0
  struct netlink_route_info* info = (struct netlink_route_info*)data;
919
0
  enum ws_ifa_attr_type type = (enum ws_ifa_attr_type) rta_type;
920
0
  const uint8_t* str;
921
922
0
  switch (type) {
923
0
    case WS_IFA_LABEL:
924
0
      proto_tree_add_item_ret_string(tree, hf_netlink_route_ifa_label, tvb, offset, len, ENC_ASCII | ENC_NA, info->pinfo->pool, &str);
925
0
      proto_item_append_text(tree, ": %s", str);
926
0
      return 1;
927
928
0
    case WS_IFA_FLAGS:
929
0
      proto_tree_add_item(tree, hf_netlink_route_ifa_flags32, tvb, offset, 4, nl_data->encoding);
930
0
      return 1;
931
0
    case WS_IFA_ADDRESS:
932
0
    case WS_IFA_LOCAL:
933
0
    case WS_IFA_BROADCAST:
934
0
      if (len == 4) {
935
0
        proto_item_append_text(tree, ": %s", tvb_ip_to_str(info->pinfo->pool, tvb, offset));
936
0
        proto_tree_add_item(tree, hf_netlink_route_ifa_addr4, tvb, offset, len, ENC_BIG_ENDIAN);
937
0
      } else {
938
0
        proto_item_append_text(tree, ": %s", tvb_ip6_to_str(info->pinfo->pool, tvb, offset));
939
0
        proto_tree_add_item(tree, hf_netlink_route_ifa_addr6, tvb, offset, len, ENC_NA);
940
0
      }
941
0
      return 1;
942
0
    default:
943
0
      return 0;
944
0
  }
945
0
}
946
947
/* Route */
948
949
static const value_string netlink_route_rt_protocol_vals[] = {
950
  { WS_RTPROT_UNSPEC,   "unknown" },
951
  { WS_RTPROT_REDIRECT, "ICMP redirects" },
952
  { WS_RTPROT_KERNEL,   "kernel" },
953
  { WS_RTPROT_BOOT,     "boot" },
954
  { WS_RTPROT_STATIC,   "static" },
955
  { WS_RTPROT_GATED,    "GateD" },
956
  { WS_RTPROT_RA,       "RDISC/ND router advertisements" },
957
  { WS_RTPROT_MRT,      "Merit MRT" },
958
  { WS_RTPROT_ZEBRA,    "Zebra" },
959
  { WS_RTPROT_BIRD,     "BIRD" },
960
  { WS_RTPROT_DNROUTED, "DECnet routing daemon" },
961
  { WS_RTPROT_XORP,     "XORP" },
962
  { WS_RTPROT_NTK,      "Netsukuku" },
963
  { WS_RTPROT_DHCP,     "DHCP client" },
964
  { WS_RTPROT_MROUTED,  "Multicast daemon" },
965
  { WS_RTPROT_KEEPALIVED, "Keepalived daemon" },
966
  { WS_RTPROT_BABEL,    "Babel daemon" },
967
  { WS_RTPROT_OPENR,    "Open Routing Routes" },
968
  { WS_RTPROT_BGP,      "BGP" },
969
  { WS_RTPROT_ISIS,     "ISIS" },
970
  { WS_RTPROT_OSPF,     "OSPF" },
971
  { WS_RTPROT_RIP,      "RIP" },
972
  { WS_RTPROT_EIGRP,    "EIGRP" },
973
  { 0, NULL }
974
};
975
static value_string_ext hf_netlink_route_rt_protocol_vals_ext =
976
  VALUE_STRING_EXT_INIT(netlink_route_rt_protocol_vals);
977
978
static const value_string netlink_route_rt_scope_vals[] = {
979
  { WS_RT_SCOPE_UNIVERSE, "global route" },
980
  { WS_RT_SCOPE_SITE,     "interior route in the local autonomous system" },
981
  { WS_RT_SCOPE_LINK,     "route on this link" },
982
  { WS_RT_SCOPE_HOST,     "route on the local host" },
983
  { WS_RT_SCOPE_NOWHERE,  "destination doesn't exist" },
984
  { 0, NULL }
985
};
986
987
static const value_string netlink_route_rt_type_vals[] = {
988
  { WS_RTN_UNSPEC,      "Unknown route" },
989
  { WS_RTN_UNICAST,     "Gateway or direct route" },
990
  { WS_RTN_LOCAL,       "Local interface route" },
991
  { WS_RTN_BROADCAST,   "Local broadcast route (send as broadcast)" },
992
  { WS_RTN_ANYCAST,     "Local broadcast route (send as unicast)" },
993
  { WS_RTN_MULTICAST,   "Multicast route" },
994
  { WS_RTN_BLACKHOLE,   "Drop" },
995
  { WS_RTN_UNREACHABLE, "Unreachable destination" },
996
  { WS_RTN_PROHIBIT,    "Administratively prohibited" },
997
  { WS_RTN_THROW,       "Routing lookup in another table" },
998
  { WS_RTN_NAT,         "Network address translation rule" },
999
  { WS_RTN_XRESOLVE,    "Use external resolver" },
1000
  { 0, NULL }
1001
};
1002
1003
static int
1004
dissect_netlink_route_rtmsg(tvbuff_t *tvb, struct netlink_route_info *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
1005
0
{
1006
0
  proto_tree_add_item(tree, hf_netlink_route_rt_family,   tvb, offset, 1, ENC_NA);
1007
0
  offset += 1;
1008
1009
0
  if (info->legacy) {
1010
    /*
1011
     * See the comment for the netlink_route_info structure,
1012
     * above.
1013
     */
1014
0
    return offset;
1015
0
  }
1016
1017
0
  proto_tree_add_item(tree, hf_netlink_route_rt_dst_len,  tvb, offset, 1, ENC_NA);
1018
0
  offset += 1;
1019
1020
0
  proto_tree_add_item(tree, hf_netlink_route_rt_src_len,  tvb, offset, 1, ENC_NA);
1021
0
  offset += 1;
1022
1023
0
  proto_tree_add_item(tree, hf_netlink_route_rt_tos,      tvb, offset, 1, ENC_NA);
1024
0
  offset += 1;
1025
1026
0
  proto_tree_add_item(tree, hf_netlink_route_rt_table,    tvb, offset, 1, ENC_NA);
1027
0
  offset += 1;
1028
1029
0
  proto_tree_add_item(tree, hf_netlink_route_rt_protocol, tvb, offset, 1, ENC_NA);
1030
0
  offset += 1;
1031
1032
0
  proto_tree_add_item(tree, hf_netlink_route_rt_scope,    tvb, offset, 1, ENC_NA);
1033
0
  offset += 1;
1034
1035
0
  proto_tree_add_item(tree, hf_netlink_route_rt_type,     tvb, offset, 1, ENC_NA);
1036
0
  offset += 1;
1037
1038
0
  proto_tree_add_item(tree, hf_netlink_route_rt_flags,    tvb, offset, 4, nl_data->encoding);
1039
0
  offset += 4;
1040
1041
0
  return offset;
1042
0
}
1043
1044
/* Route Attributes */
1045
1046
static const value_string netlink_route_rta_attr_vals[] = {
1047
  { WS_RTA_UNSPEC,    "Unspecified" },
1048
  { WS_RTA_DST,       "Route destination address" },
1049
  { WS_RTA_SRC,       "Route source address" },
1050
  { WS_RTA_IIF,       "Input interface index" },
1051
  { WS_RTA_OIF,       "Output interface index" },
1052
  { WS_RTA_GATEWAY,   "Gateway of the route" },
1053
  { WS_RTA_PRIORITY,  "RTA_PRIORITY" },
1054
  { WS_RTA_PREFSRC,   "RTA_PREFSRC" },
1055
  { WS_RTA_METRICS,   "RTA_METRICS" },
1056
  { WS_RTA_MULTIPATH, "RTA_MULTIPATH" },
1057
  { WS_RTA_PROTOINFO, "RTA_PROTOINFO" },
1058
  { WS_RTA_FLOW,      "RTA_FLOW" },
1059
  { WS_RTA_CACHEINFO, "RTA_CACHEINFO" },
1060
  { WS_RTA_SESSION,   "RTA_SESSION" },
1061
  { WS_RTA_MP_ALGO,   "RTA_MP_ALGO" },
1062
  { WS_RTA_TABLE,     "RTA_TABLE" },
1063
  { WS_RTA_MARK,      "RTA_MARK" },
1064
  { WS_RTA_MFC_STATS, "RTA_MFC_STATS" },
1065
  { WS_RTA_VIA,       "RTA_VIA" },
1066
  { WS_RTA_NEWDST,    "RTA_NEWDST" },
1067
  { WS_RTA_PREF,      "RTA_PREF" },
1068
  { WS_RTA_ENCAP_TYPE,"RTA_ENCAP_TYPE" },
1069
  { WS_RTA_ENCAP,     "RTA_ENCAP" },
1070
  { WS_RTA_EXPIRES,   "RTA_EXPIRES" },
1071
  { WS_RTA_PAD,       "RTA_PAD" },
1072
  { WS_RTA_UID,       "RTA_UID" },
1073
  { WS_RTA_TTL_PROPAGATE, "RTA_TTL_PROPAGATE" },
1074
  { WS_RTA_IP_PROTO,  "RTA_IP_PROTO" },
1075
  { WS_RTA_SPORT,     "RTA_SPORT" },
1076
  { WS_RTA_DPORT,     "RTA_DPORT" },
1077
  { WS_RTA_NH_ID,     "RTA_NH_ID" },
1078
  { 0, NULL }
1079
};
1080
1081
static int
1082
dissect_netlink_route_route_attrs(tvbuff_t *tvb, void *data _U_, struct packet_netlink_data *nl_data, proto_tree *tree, int rta_type, int offset, int len)
1083
0
{
1084
0
  enum ws_rta_attr_type type = (enum ws_rta_attr_type) rta_type;
1085
0
  uint32_t value;
1086
1087
0
  switch (type) {
1088
0
    case WS_RTA_IIF:
1089
0
      if (len == 4) {
1090
0
        proto_tree_add_item_ret_uint(tree, hf_netlink_route_rta_iif, tvb, offset, 4, nl_data->encoding, &value);
1091
0
        proto_item_append_text(tree, ": %u", value);
1092
0
        return 1;
1093
0
      }
1094
0
      return 0;
1095
1096
0
    case WS_RTA_OIF:
1097
0
      if (len == 4) {
1098
0
        proto_tree_add_item_ret_uint(tree, hf_netlink_route_rta_oif, tvb, offset, 4, nl_data->encoding, &value);
1099
0
        proto_item_append_text(tree, ": %u", value);
1100
0
        return 1;
1101
0
      }
1102
0
      return 0;
1103
1104
0
    default:
1105
0
      return 0;
1106
0
  }
1107
0
}
1108
1109
static void
1110
netlink_route_nd_states_label(char *label, uint32_t value)
1111
0
{
1112
0
  static const value_string flags_vals[] = {
1113
0
    { WS_NUD_NONE,       "NONE" },
1114
0
    { WS_NUD_INCOMPLETE, "INCOMPLETE" },
1115
0
    { WS_NUD_REACHABLE,  "REACHABLE" },
1116
0
    { WS_NUD_STALE,      "STALE" },
1117
0
    { WS_NUD_DELAY,      "DELAY" },
1118
0
    { WS_NUD_PROBE,      "PROBE" },
1119
0
    { WS_NUD_FAILED,     "FAILED" },
1120
0
    { WS_NUD_NOARP,      "NOARP" },
1121
0
    { WS_NUD_PERMANENT,  "PERMANENT" },
1122
0
    { 0, NULL }
1123
0
  };
1124
1125
0
  char tmp[16];
1126
1127
0
  _fill_label_value_string_bitmask(label, value, flags_vals);
1128
1129
0
  snprintf(tmp, sizeof(tmp), " (0x%.4x)", value);
1130
0
  (void) g_strlcat(label, tmp, ITEM_LABEL_LENGTH);
1131
0
}
1132
1133
static int
1134
dissect_netlink_route_ndmsg(tvbuff_t *tvb, struct netlink_route_info *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
1135
0
{
1136
0
  proto_tree_add_item(tree, hf_netlink_route_nd_family, tvb, offset, 1, ENC_NA);
1137
0
  offset += 1;
1138
1139
0
  if (info->legacy) {
1140
    /*
1141
     * See the comment for the netlink_route_info structure,
1142
     * above.
1143
     */
1144
0
    return offset;
1145
0
  }
1146
1147
  /* XXX, 3B padding */
1148
0
  offset += 3;
1149
1150
0
  proto_tree_add_item(tree, hf_netlink_route_nd_index, tvb, offset, 4, nl_data->encoding);
1151
0
  offset += 4;
1152
1153
0
  proto_tree_add_item(tree, hf_netlink_route_nd_state, tvb, offset, 2, nl_data->encoding);
1154
0
  offset += 2;
1155
1156
0
  proto_tree_add_item(tree, hf_netlink_route_nd_flags, tvb, offset, 1, ENC_NA);
1157
0
  offset += 1;
1158
1159
0
  proto_tree_add_item(tree, hf_netlink_route_nd_type, tvb, offset, 1, ENC_NA);
1160
0
  offset += 1;
1161
1162
0
  return offset;
1163
0
}
1164
1165
static const value_string netlink_route_type_vals[] = {
1166
  { WS_RTM_NEWLINK,       "Create network interface" },
1167
  { WS_RTM_DELLINK,       "Remove network interface" },
1168
  { WS_RTM_GETLINK,       "Get network interface info" },
1169
  { WS_RTM_SETLINK,       "Set network interface info" },
1170
  { WS_RTM_NEWADDR,       "Add IP address" },
1171
  { WS_RTM_DELADDR,       "Delete IP address" },
1172
  { WS_RTM_GETADDR,       "Get IP address" },
1173
  { WS_RTM_NEWROUTE,      "Add network route" },
1174
  { WS_RTM_DELROUTE,      "Delete network route" },
1175
  { WS_RTM_GETROUTE,      "Get network route" },
1176
  { WS_RTM_NEWNEIGH,      "Add neighbor table entry" },
1177
  { WS_RTM_DELNEIGH,      "Delete neighbor table entry" },
1178
  { WS_RTM_GETNEIGH,      "Get neighbor table entry" },
1179
  { WS_RTM_NEWRULE,       "Add routing rule" },
1180
  { WS_RTM_DELRULE,       "Delete routing rule" },
1181
  { WS_RTM_GETRULE,       "Get routing rule" },
1182
  { WS_RTM_NEWQDISC,      "Add queueing discipline" },
1183
  { WS_RTM_DELQDISC,      "Delete queueing discipline" },
1184
  { WS_RTM_GETQDISC,      "Get queueing discipline" },
1185
  { WS_RTM_NEWTCLASS,     "Add traffic class" },
1186
  { WS_RTM_DELTCLASS,     "Delete traffic class" },
1187
  { WS_RTM_GETTCLASS,     "Get traffic class" },
1188
  { WS_RTM_NEWTFILTER,    "Add traffic class" },
1189
  { WS_RTM_DELTFILTER,    "Delete traffic class" },
1190
  { WS_RTM_GETTFILTER,    "Get traffic class" },
1191
  { WS_RTM_NEWACTION,     "New Action" },
1192
  { WS_RTM_DELACTION,     "Delete Action" },
1193
  { WS_RTM_GETACTION,     "Get Action" },
1194
  { WS_RTM_NEWPREFIX,     "New IPv6 prefix" },
1195
  { WS_RTM_GETMULTICAST,  "Get multicast address" },
1196
  { WS_RTM_GETANYCAST,    "Get anycast address" },
1197
  { WS_RTM_NEWNEIGHTBL,   "New Neighbour tables" },
1198
  { WS_RTM_GETNEIGHTBL,   "Get Neighbour tables" },
1199
  { WS_RTM_SETNEIGHTBL,   "Set Neighbour tables" },
1200
  { WS_RTM_NEWNDUSEROPT,  "New ND Userland options" },
1201
  { WS_RTM_NEWADDRLABEL,  "New IPv6 Address Label" },
1202
  { WS_RTM_DELADDRLABEL,  "Delete IPv6 Address Label" },
1203
  { WS_RTM_GETADDRLABEL,  "Get IPv6 Address Label" },
1204
  { WS_RTM_GETDCB,        "Get Data Center Bridging" },
1205
  { WS_RTM_SETDCB,        "Set Data Center Bridging" },
1206
  { WS_RTM_NEWNETCONF,    "RTM_NEWNETCONF" },
1207
  { WS_RTM_DELNETCONF,    "RTM_DELNETCONF" },
1208
  { WS_RTM_GETNETCONF,    "RTM_GETNETCONF" },
1209
  { WS_RTM_NEWMDB,        "Add multicast database entry" },
1210
  { WS_RTM_DELMDB,        "Delete multicast database entry" },
1211
  { WS_RTM_GETMDB,        "Get multicast database" },
1212
  { WS_RTM_NEWNSID,       "New network namespace ID" },
1213
  { WS_RTM_DELNSID,       "Delete network namespace ID" },
1214
  { WS_RTM_GETNSID,       "Get network namespace ID" },
1215
  { WS_RTM_NEWSTATS,      "New link statistics" },
1216
  { WS_RTM_GETSTATS,      "Get link statistics" },
1217
  { WS_RTM_NEWCACHEREPORT,"New cache report" },
1218
  { WS_RTM_NEWCHAIN,      "New chain" },
1219
  { WS_RTM_DELCHAIN,      "Delete chain" },
1220
  { WS_RTM_GETCHAIN,      "Get chain" },
1221
  { WS_RTM_NEWNEXTHOP,    "New next hop" },
1222
  { WS_RTM_DELNEXTHOP,    "Delete next hop" },
1223
  { WS_RTM_GETNEXTHOP,    "Get next hop" },
1224
  { WS_RTM_NEWLINKPROP,   "New link property" },
1225
  { WS_RTM_DELLINKPROP,   "Delete link property" },
1226
  { WS_RTM_GETLINKPROP,   "Get link property" },
1227
  { WS_RTM_NEWVLAN,       "New VLAN" },
1228
  { WS_RTM_DELVLAN,       "Delete VLAN" },
1229
  { WS_RTM_GETVLAN,       "Get VLAN" },
1230
  { WS_RTM_NEWNEXTHOPBUCKET, "New next hop bucket" },
1231
  { WS_RTM_DELNEXTHOPBUCKET, "Delete next hop bucket" },
1232
  { WS_RTM_GETNEXTHOPBUCKET, "Get next hop bucket" },
1233
  { WS_RTM_NEWTUNNEL,     "New tunnel" },
1234
  { WS_RTM_DELTUNNEL,     "Delete tunnel" },
1235
  { WS_RTM_GETTUNNEL,     "Get tunnel" },
1236
  { 0, NULL }
1237
};
1238
static value_string_ext netlink_route_type_vals_ext = VALUE_STRING_EXT_INIT(netlink_route_type_vals);
1239
1240
static int
1241
dissect_netlink_route(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1242
0
{
1243
0
  struct netlink_route_info info;
1244
0
  struct packet_netlink_data *nl_data = (struct packet_netlink_data *)data;
1245
0
  proto_tree *nlmsg_tree;
1246
0
  proto_item *pi;
1247
0
  unsigned offset = 0;
1248
1249
0
  DISSECTOR_ASSERT(nl_data && nl_data->magic == PACKET_NETLINK_MAGIC);
1250
1251
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Netlink route");
1252
0
  col_clear(pinfo->cinfo, COL_INFO);
1253
1254
0
  pi = proto_tree_add_item(tree, proto_netlink_route, tvb, 0, -1, ENC_NA);
1255
0
  nlmsg_tree = proto_item_add_subtree(pi, ett_netlink_route);
1256
1257
  /* Netlink message header (nlmsghdr) */
1258
0
  offset = dissect_netlink_header(tvb, pinfo, nlmsg_tree, offset, nl_data->encoding, hf_netlink_route_nltype, NULL);
1259
1260
0
  info.pinfo = pinfo;
1261
1262
0
  switch (nl_data->type) {
1263
0
    case WS_RTM_NEWLINK:
1264
0
    case WS_RTM_DELLINK:
1265
0
    case WS_RTM_GETLINK:
1266
0
    case WS_RTM_SETLINK:
1267
      /*
1268
       * Backward compatibility with legacy tools; 16 is
1269
       * sizeof(struct ifinfomsg).
1270
       *
1271
       * See the comment for the netlink_route_info
1272
       * structure, above.
1273
       */
1274
0
      info.legacy = (nl_data->type == WS_RTM_GETLINK) && (tvb_reported_length_remaining(tvb, offset) < 16);
1275
0
      offset = dissect_netlink_route_ifinfomsg(tvb, &info, nl_data, nlmsg_tree, offset);
1276
      /* Optional attributes */
1277
0
      offset = dissect_netlink_route_attributes(tvb, hf_netlink_route_ifla_attr_type, &info, nl_data, nlmsg_tree, offset, dissect_netlink_route_ifla_attrs);
1278
0
      break;
1279
1280
0
    case WS_RTM_NEWADDR:
1281
0
    case WS_RTM_DELADDR:
1282
0
    case WS_RTM_GETADDR:
1283
      /*
1284
       * Backward compatibility with legacy tools; 8 is
1285
       * sizeof(struct ifaddrmsg).
1286
       *
1287
       * See the comment for the netlink_route_info
1288
       * structure, above.
1289
       */
1290
0
      info.legacy = (nl_data->type == WS_RTM_GETADDR) && (tvb_reported_length_remaining(tvb, offset) < 8);
1291
0
      offset = dissect_netlink_route_ifaddrmsg(tvb, &info, nl_data, nlmsg_tree, offset);
1292
0
      if (!info.legacy) {
1293
        /*
1294
         * Optional attributes.
1295
         *
1296
         * Not present in legacy-tool messages;
1297
         * again, see the comment above.
1298
         */
1299
0
        offset = dissect_netlink_route_attributes(tvb, hf_netlink_route_ifa_attr_type, &info, nl_data, nlmsg_tree, offset, dissect_netlink_route_ifa_attrs);
1300
0
      }
1301
0
      break;
1302
1303
0
    case WS_RTM_NEWROUTE:
1304
0
    case WS_RTM_DELROUTE:
1305
0
    case WS_RTM_GETROUTE:
1306
      /*
1307
       * Backward compatibility with legacy tools; 12 is
1308
       * sizeof(struct rtmsg).
1309
       *
1310
       * See the comment for the netlink_route_info
1311
       * structure, above.
1312
       */
1313
0
      info.legacy = (nl_data->type == WS_RTM_GETROUTE) && (tvb_reported_length_remaining(tvb, offset) < 12);
1314
0
      offset = dissect_netlink_route_rtmsg(tvb, &info, nl_data, nlmsg_tree, offset);
1315
      /* Optional attributes */
1316
0
      if (!info.legacy) {
1317
        /*
1318
         * Optional attributes.
1319
         *
1320
         * Not present in legacy-tool messages;
1321
         * again, see the comment above.
1322
         */
1323
0
        offset = dissect_netlink_route_attributes(tvb, hf_netlink_route_rta_attr_type, &info, nl_data, nlmsg_tree, offset, dissect_netlink_route_route_attrs);
1324
0
      }
1325
0
      break;
1326
1327
0
    case WS_RTM_NEWNEIGH:
1328
0
    case WS_RTM_DELNEIGH:
1329
0
    case WS_RTM_GETNEIGH:
1330
      /*
1331
       * Backward compatibility with legacy tools; 12 is
1332
       * sizeof(struct ndmsg).
1333
       *
1334
       * See the comment for the netlink_route_info
1335
       * structure, above.
1336
       */
1337
0
      info.legacy = (nl_data->type == WS_RTM_GETNEIGH) && (tvb_reported_length_remaining(tvb, offset) < 12);
1338
0
      if (!info.legacy) {
1339
        /*
1340
         * Optional attributes.
1341
         *
1342
         * Not present in legacy-tool messages;
1343
         * again, see the comment above.
1344
         */
1345
0
        offset = dissect_netlink_route_ndmsg(tvb, &info, nl_data, nlmsg_tree, offset);
1346
0
      }
1347
0
      break;
1348
0
  }
1349
1350
0
  return offset;
1351
0
}
1352
1353
void
1354
proto_register_netlink_route(void)
1355
14
{
1356
14
  static hf_register_info hf[] = {
1357
14
    { &hf_netlink_route_ifi_family,
1358
14
      { "Interface family", "netlink-route.ifi_family",
1359
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1360
14
        NULL, HFILL }
1361
14
    },
1362
14
    { &hf_netlink_route_ifi_type,
1363
14
      { "Device type", "netlink-route.ifi_type",
1364
14
        FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0x00,
1365
14
        NULL, HFILL }
1366
14
    },
1367
14
    { &hf_netlink_route_ifi_index,
1368
14
      { "Interface index", "netlink-route.ifi_index",
1369
14
        FT_INT32, BASE_DEC, NULL, 0x00,
1370
14
        NULL, HFILL }
1371
14
    },
1372
14
    { &hf_netlink_route_ifi_flags,
1373
14
      { "Device flags", "netlink-route.ifi_flags",
1374
14
        FT_UINT32, BASE_CUSTOM, CF_FUNC(hf_netlink_route_ifi_flags_label), 0x00,
1375
14
        NULL, HFILL }
1376
14
    },
1377
14
    { &hf_netlink_route_ifi_flags_iff_up,
1378
14
      { "Interface", "netlink-route.ifi_flags.iff_up",
1379
14
        FT_BOOLEAN, 32, TFS(&tfs_up_down), WS_IFF_UP,
1380
14
        NULL, HFILL }
1381
14
    },
1382
14
    { &hf_netlink_route_ifi_flags_iff_broadcast,
1383
14
      { "Broadcast", "netlink-route.ifi_flags.iff_broadcast",
1384
14
        FT_BOOLEAN, 32, TFS(&tfs_valid_invalid), WS_IFF_BROADCAST,
1385
14
        NULL, HFILL }
1386
14
    },
1387
14
    { &hf_netlink_route_ifi_change,
1388
14
      { "Device change flags", "netlink-route.ifi_change",
1389
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1390
14
        NULL, HFILL }
1391
14
    },
1392
14
    { &hf_netlink_route_ifla_attr_type,
1393
14
      { "Attribute type", "netlink-route.ifla_attr_type",
1394
14
        FT_UINT16, BASE_DEC, VALS(netlink_route_ifla_attr_vals), 0x00,
1395
14
        NULL, HFILL }
1396
14
    },
1397
14
    { &hf_netlink_route_ifla_ifname,
1398
14
      { "Device name", "netlink-route.ifla_ifname",
1399
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
1400
14
        NULL, HFILL }
1401
14
    },
1402
14
    { &hf_netlink_route_ifla_mtu,
1403
14
      { "MTU of device", "netlink-route.ifla_mtu",
1404
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1405
14
        NULL, HFILL }
1406
14
    },
1407
14
    { &hf_netlink_route_ifla_txqlen,
1408
14
      { "TxQueue length", "netlink-route.ifla_txqlen",
1409
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1410
14
        NULL, HFILL }
1411
14
    },
1412
14
    { &hf_netlink_route_ifla_operstate,
1413
14
      { "Operstate", "netlink-route.ifla_operstate",
1414
14
        FT_UINT8, BASE_DEC, VALS(netlink_route_ifla_operstate_vals), 0x00,
1415
14
        NULL, HFILL }
1416
14
    },
1417
14
    { &hf_netlink_route_ifla_promiscuity,
1418
14
      { "Promiscuity", "netlink-route.ifla_promiscuity",
1419
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1420
14
        NULL, HFILL }
1421
14
    },
1422
14
    { &hf_netlink_route_ifla_txqnum,
1423
14
      { "Number of Tx queues", "netlink-route.ifla_txqnum",
1424
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1425
14
        NULL, HFILL }
1426
14
    },
1427
14
    { &hf_netlink_route_ifla_rxqnum,
1428
14
      { "Number of Rx queues", "netlink-route.ifla_rxqnum",
1429
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1430
14
        NULL, HFILL }
1431
14
    },
1432
14
    { &hf_netlink_route_ifla_group,
1433
14
      { "Group", "netlink-route.ifla_group",
1434
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1435
14
        NULL, HFILL }
1436
14
    },
1437
14
    { &hf_netlink_route_ifla_gso_maxsize,
1438
14
      { "Maximum GSO size", "netlink-route.ifla_gso_maxsize",
1439
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1440
14
        NULL, HFILL }
1441
14
    },
1442
14
    { &hf_netlink_route_ifla_gso_maxsegs,
1443
14
      { "Maximum GSO segment count", "netlink-route.ifla_gso_maxsegs",
1444
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1445
14
        NULL, HFILL }
1446
14
    },
1447
14
    { &hf_netlink_route_ifla_carrier,
1448
14
      { "Carrier", "netlink-route.ifla_carrier",
1449
14
        FT_BOOLEAN, 32, TFS(&tfs_restricted_not_restricted), 0x00000001,
1450
14
        NULL, HFILL }
1451
14
    },
1452
14
    { &hf_netlink_route_ifla_qdisc,
1453
14
      { "Queueing discipline", "netlink-route.ifla_qdisc",
1454
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
1455
14
        NULL, HFILL }
1456
14
    },
1457
14
    { &hf_netlink_route_ifla_carrier_changes,
1458
14
      { "Carrier changes", "netlink-route.ifla_carrier_changes",
1459
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1460
14
        NULL, HFILL }
1461
14
    },
1462
14
    { &hf_netlink_route_ifla_hwaddr,
1463
14
      { "HW Address", "netlink-route.ifla_hwaddr",
1464
14
        FT_BYTES, SEP_COLON, NULL, 0x00,
1465
14
        NULL, HFILL }
1466
14
    },
1467
14
    { &hf_netlink_route_ifla_broadcast,
1468
14
      { "Broadcast", "netlink-route.ifla_broadcast",
1469
14
        FT_BYTES, SEP_COLON, NULL, 0x00,
1470
14
        NULL, HFILL }
1471
14
    },
1472
14
    { &hf_netlink_route_ifla_carrier_up_count,
1473
14
      { "Carrier changes to up", "netlink-route.ifla_carrier_up_count",
1474
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1475
14
        NULL, HFILL }
1476
14
    },
1477
14
    { &hf_netlink_route_ifla_carrier_down_count,
1478
14
      { "Carrier changes to down", "netlink-route.ifla_carrier_down_count",
1479
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1480
14
        NULL, HFILL }
1481
14
    },
1482
14
    { &hf_netlink_route_ifla_min_mtu,
1483
14
      { "Minimum MTU of device", "netlink-route.ifla_min_mtu",
1484
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1485
14
        NULL, HFILL }
1486
14
    },
1487
14
    { &hf_netlink_route_ifla_max_mtu,
1488
14
      { "Maximum MTU of device", "netlink-route.ifla_max_mtu",
1489
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1490
14
        NULL, HFILL }
1491
14
    },
1492
14
    { &hf_netlink_route_ifla_map_memstart,
1493
14
      { "Memory start", "netlink-route.ifla_map.mem_start",
1494
14
        FT_UINT64, BASE_HEX, NULL, 0x00,
1495
14
        NULL, HFILL }
1496
14
    },
1497
14
    { &hf_netlink_route_ifla_map_memend,
1498
14
      { "Memory end", "netlink-route.ifla_map.mem_end",
1499
14
        FT_UINT64, BASE_HEX, NULL, 0x00,
1500
14
        NULL, HFILL }
1501
14
    },
1502
14
    { &hf_netlink_route_ifla_map_baseaddr,
1503
14
      { "Base address", "netlink-route.ifla_map.base_addr",
1504
14
        FT_UINT64, BASE_HEX, NULL, 0x00,
1505
14
        NULL, HFILL }
1506
14
    },
1507
14
    { &hf_netlink_route_ifla_map_irq,
1508
14
      { "IRQ", "netlink-route.ifla_map.irq",
1509
14
        FT_UINT16, BASE_DEC, NULL, 0x00,
1510
14
        NULL, HFILL }
1511
14
    },
1512
14
    { &hf_netlink_route_ifla_map_dma,
1513
14
      { "DMA", "netlink-route.ifla_map.dma",
1514
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1515
14
        NULL, HFILL }
1516
14
    },
1517
14
    { &hf_netlink_route_ifla_map_port,
1518
14
      { "Port", "netlink-route.ifla_map.port",
1519
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1520
14
        NULL, HFILL }
1521
14
    },
1522
14
    { &hf_netlink_route_ifla_linkstats_rxpackets,
1523
14
      { "Rx packets", "netlink-route.ifla_linkstats.rxpackets",
1524
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1525
14
        NULL, HFILL }
1526
14
    },
1527
14
    { &hf_netlink_route_ifla_linkstats_txpackets,
1528
14
      { "Tx packets", "netlink-route.ifla_linkstats.txpackets",
1529
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1530
14
        NULL, HFILL }
1531
14
    },
1532
14
    { &hf_netlink_route_ifla_linkstats_rxbytes,
1533
14
      { "Rx bytes", "netlink-route.ifla_linkstats.rxbytes",
1534
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1535
14
        NULL, HFILL }
1536
14
    },
1537
14
    { &hf_netlink_route_ifla_linkstats_txbytes,
1538
14
      { "Tx packets", "netlink-route.ifla_linkstats.txbytes",
1539
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1540
14
        NULL, HFILL }
1541
14
    },
1542
14
    { &hf_netlink_route_ifla_linkstats_rxerrors,
1543
14
      { "Rx errors", "netlink-route.ifla_linkstats.rxerrors",
1544
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1545
14
        NULL, HFILL }
1546
14
    },
1547
14
    { &hf_netlink_route_ifla_linkstats_txerrors,
1548
14
      { "Tx errors", "netlink-route.ifla_linkstats.txerrors",
1549
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1550
14
        NULL, HFILL }
1551
14
    },
1552
14
    { &hf_netlink_route_ifla_linkstats_rxdropped,
1553
14
      { "Rx dropped", "netlink-route.ifla_linkstats.rxdropped",
1554
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1555
14
        NULL, HFILL }
1556
14
    },
1557
14
    { &hf_netlink_route_ifla_linkstats_txdropped,
1558
14
      { "Tx dropped", "netlink-route.ifla_linkstats.txdropped",
1559
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1560
14
        NULL, HFILL }
1561
14
    },
1562
14
    { &hf_netlink_route_ifla_linkstats_multicast,
1563
14
      { "Multicast Rx", "netlink-route.ifla_linkstats.multicast",
1564
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1565
14
        NULL, HFILL }
1566
14
    },
1567
14
    { &hf_netlink_route_ifla_linkstats_collisions,
1568
14
      { "Collisions", "netlink-route.ifla_linkstats.collisions",
1569
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1570
14
        NULL, HFILL }
1571
14
    },
1572
14
    { &hf_netlink_route_ifla_linkstats_rx_len_errs,
1573
14
      { "Length errors", "netlink-route.ifla_linkstats.rx_errors.length_errs",
1574
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1575
14
        NULL, HFILL }
1576
14
    },
1577
14
    { &hf_netlink_route_ifla_linkstats_rx_over_errs,
1578
14
      { "Ring buffer overflow errors", "netlink-route.ifla_linkstats.rx_errors.over_errs",
1579
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1580
14
        NULL, HFILL }
1581
14
    },
1582
14
    { &hf_netlink_route_ifla_linkstats_rx_crc_errs,
1583
14
      { "CRC errors", "netlink-route.ifla_linkstats.rx_errors.crc_errs",
1584
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1585
14
        NULL, HFILL }
1586
14
    },
1587
14
    { &hf_netlink_route_ifla_linkstats_rx_frame_errs,
1588
14
      { "Frame alignment errors", "netlink-route.ifla_linkstats.rx_errors.frame_errs",
1589
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1590
14
        NULL, HFILL }
1591
14
    },
1592
14
    { &hf_netlink_route_ifla_linkstats_rx_fifo_errs,
1593
14
      { "FIFO overrun errors", "netlink-route.ifla_linkstats.rx_errors.fifo_errs",
1594
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1595
14
        NULL, HFILL }
1596
14
    },
1597
14
    { &hf_netlink_route_ifla_linkstats_rx_miss_errs,
1598
14
      { "Missed packet errors", "netlink-route.ifla_linkstats.rx_errors.miss_errs",
1599
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1600
14
        NULL, HFILL }
1601
14
    },
1602
14
    { &hf_netlink_route_ifla_linkstats_tx_abort_errs,
1603
14
      { "Abort errors", "netlink-route.ifla_linkstats.rx_errors.abort_errs",
1604
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1605
14
        NULL, HFILL }
1606
14
    },
1607
14
    { &hf_netlink_route_ifla_linkstats_tx_carrier_errs,
1608
14
      { "Carrier errors", "netlink-route.ifla_linkstats.rx_errors.carrier_errs",
1609
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1610
14
        NULL, HFILL }
1611
14
    },
1612
14
    { &hf_netlink_route_ifla_linkstats_tx_fifo_errs,
1613
14
      { "FIFO errors", "netlink-route.ifla_linkstats.rx_errors.fifo_errs",
1614
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1615
14
        NULL, HFILL }
1616
14
    },
1617
14
    { &hf_netlink_route_ifla_linkstats_tx_heartbeat_errs,
1618
14
      { "Heartbeat errors", "netlink-route.ifla_linkstats.rx_errors.heartbeat_errs",
1619
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1620
14
        NULL, HFILL }
1621
14
    },
1622
14
    { &hf_netlink_route_ifla_linkstats_tx_window_errs,
1623
14
      { "Window errors", "netlink-route.ifla_linkstats.rx_errors.window_errs",
1624
14
        FT_UINT64, BASE_DEC, NULL, 0x00,
1625
14
        NULL, HFILL }
1626
14
    },
1627
14
    { &hf_netlink_route_ifa_family,
1628
14
      { "Address type", "netlink-route.ifa_family",
1629
14
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &linux_af_vals_ext, 0x00,
1630
14
        NULL, HFILL }
1631
14
    },
1632
14
    { &hf_netlink_route_ifa_prefixlen,
1633
14
      { "Address prefixlength", "netlink-route.ifa_prefixlen",
1634
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1635
14
        NULL, HFILL }
1636
14
    },
1637
14
    { &hf_netlink_route_ifa_flags,
1638
14
      { "Address flags", "netlink-route.ifa_flags",
1639
14
        FT_UINT8, BASE_CUSTOM, CF_FUNC(netlink_route_ifa_flags_label), 0x00,
1640
14
        NULL, HFILL }
1641
14
    },
1642
14
    { &hf_netlink_route_ifa_scope,
1643
14
      { "Address scope", "netlink-route.ifa_scope",
1644
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1645
14
        NULL, HFILL }
1646
14
    },
1647
14
    { &hf_netlink_route_ifa_index,
1648
14
      { "Interface index", "netlink-route.ifa_index",
1649
14
        FT_INT32, BASE_DEC, NULL, 0x00,
1650
14
        NULL, HFILL }
1651
14
    },
1652
14
    { &hf_netlink_route_ifa_attr_type,
1653
14
      { "Attribute type", "netlink-route.ifa_attr_type",
1654
14
        FT_UINT16, BASE_DEC, VALS(netlink_route_ifa_attr_vals), 0x00,
1655
14
        NULL, HFILL }
1656
14
    },
1657
14
    { &hf_netlink_route_ifa_label,
1658
14
      { "Interface name", "netlink-route.ifa_label",
1659
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
1660
14
        NULL, HFILL }
1661
14
    },
1662
14
    { &hf_netlink_route_ifa_flags32,
1663
14
      { "Address flags", "netlink-route.ifa_flags32",
1664
14
        FT_UINT32, BASE_CUSTOM, CF_FUNC(netlink_route_ifa_flags_label), 0x00,
1665
14
        NULL, HFILL }
1666
14
    },
1667
14
    { &hf_netlink_route_ifa_addr6,
1668
14
      { "Address", "netlink-route.ifa_address.ipv6",
1669
14
        FT_IPv6, BASE_NONE, NULL, 0x00,
1670
14
        NULL, HFILL }
1671
14
    },
1672
14
    { &hf_netlink_route_ifa_addr4,
1673
14
      { "Address", "netlink-route.ifa_address.ipv4",
1674
14
        FT_IPv4, BASE_NONE, NULL, 0x00,
1675
14
        NULL, HFILL }
1676
14
    },
1677
14
    { &hf_netlink_route_rt_family,
1678
14
      { "Address family", "netlink-route.rt_family",
1679
14
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &linux_af_vals_ext, 0x00,
1680
14
        NULL, HFILL }
1681
14
    },
1682
14
    { &hf_netlink_route_rt_dst_len,
1683
14
      { "Length of destination", "netlink-route.rt_dst_len",
1684
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1685
14
        NULL, HFILL }
1686
14
    },
1687
14
    { &hf_netlink_route_rt_src_len,
1688
14
      { "Length of source", "netlink-route.rt_src_len",
1689
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1690
14
        NULL, HFILL }
1691
14
    },
1692
14
    { &hf_netlink_route_rt_tos,
1693
14
      { "TOS filter", "netlink-route.rt_tos",
1694
14
        FT_UINT8, BASE_HEX, NULL, 0x00,
1695
14
        NULL, HFILL }
1696
14
    },
1697
14
    { &hf_netlink_route_rt_table,
1698
14
      { "Routing table ID", "netlink-route.rt_table",
1699
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1700
14
        NULL, HFILL }
1701
14
    },
1702
14
    { &hf_netlink_route_rt_protocol,
1703
14
      { "Routing protocol", "netlink-route.rt_protocol",
1704
14
        FT_UINT8, BASE_HEX | BASE_EXT_STRING, &hf_netlink_route_rt_protocol_vals_ext, 0x00,
1705
14
        NULL, HFILL }
1706
14
    },
1707
14
    { &hf_netlink_route_rt_scope,
1708
14
      { "Route origin", "netlink-route.rt_scope",
1709
14
        FT_UINT8, BASE_HEX, VALS(netlink_route_rt_scope_vals), 0x00,
1710
14
        NULL, HFILL }
1711
14
    },
1712
14
    { &hf_netlink_route_rt_type,
1713
14
      { "Route type", "netlink-route.rt_type",
1714
14
        FT_UINT8, BASE_HEX, VALS(netlink_route_rt_type_vals), 0x00,
1715
14
        NULL, HFILL }
1716
14
    },
1717
14
    { &hf_netlink_route_rt_flags,
1718
14
      { "Route flags", "netlink-route.rt_flags",
1719
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1720
14
        NULL, HFILL }
1721
14
    },
1722
14
    { &hf_netlink_route_rta_attr_type,
1723
14
      { "Attribute type", "netlink-route.rta_attr_type",
1724
14
        FT_UINT16, BASE_DEC, VALS(netlink_route_rta_attr_vals), 0x00,
1725
14
        NULL, HFILL }
1726
14
    },
1727
14
    { &hf_netlink_route_rta_iif,
1728
14
      { "Input interface index", "netlink-route.rta_iif",
1729
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1730
14
        NULL, HFILL }
1731
14
    },
1732
14
    { &hf_netlink_route_rta_oif,
1733
14
      { "Output interface index", "netlink-route.rta_oif",
1734
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1735
14
        NULL, HFILL }
1736
14
    },
1737
14
    { &hf_netlink_route_nd_family,
1738
14
      { "Family", "netlink-route.nd_family",
1739
14
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &linux_af_vals_ext, 0x00,
1740
14
        NULL, HFILL }
1741
14
    },
1742
14
    { &hf_netlink_route_nd_index,
1743
14
      { "Interface index", "netlink-route.nd_index",
1744
14
        FT_INT32, BASE_DEC, NULL, 0x00,
1745
14
        NULL, HFILL }
1746
14
    },
1747
14
    { &hf_netlink_route_nd_state,
1748
14
      { "State", "netlink-route.nd_state",
1749
14
        FT_UINT16, BASE_CUSTOM, CF_FUNC(netlink_route_nd_states_label), 0x00,
1750
14
        NULL, HFILL }
1751
14
    },
1752
14
    { &hf_netlink_route_nd_flags,
1753
14
      { "Flags", "netlink-route.nd_flags",
1754
14
        FT_UINT8, BASE_HEX, NULL, 0x00,
1755
14
        NULL, HFILL }
1756
14
    },
1757
14
    { &hf_netlink_route_nd_type,
1758
14
      { "Type", "netlink-route.nd_type",
1759
14
        FT_UINT8, BASE_HEX, NULL, 0x00,
1760
14
        NULL, HFILL }
1761
14
    },
1762
14
    { &hf_netlink_route_nltype,
1763
14
      { "Message type", "netlink-route.nltype",
1764
14
        FT_UINT16, BASE_DEC | BASE_EXT_STRING, &netlink_route_type_vals_ext, 0x00,
1765
14
        NULL, HFILL }
1766
14
    },
1767
14
  };
1768
1769
14
  static int *ett[] = {
1770
14
    &ett_netlink_route,
1771
14
    &ett_netlink_route_attr,
1772
14
    &ett_netlink_route_if_flags,
1773
14
    &ett_netlink_route_attr_linkstats,
1774
14
    &ett_netlink_route_attr_linkstats_rxerrs,
1775
14
    &ett_netlink_route_attr_linkstats_txerrs,
1776
14
  };
1777
1778
14
  proto_netlink_route = proto_register_protocol("Linux rtnetlink (route netlink) protocol", "rtnetlink", "netlink-route" );
1779
14
  proto_register_field_array(proto_netlink_route, hf, array_length(hf));
1780
14
  proto_register_subtree_array(ett, array_length(ett));
1781
1782
14
  netlink_route_handle = register_dissector("netlink-route", dissect_netlink_route, proto_netlink_route);
1783
14
}
1784
1785
void
1786
proto_reg_handoff_netlink_route(void)
1787
14
{
1788
14
  dissector_add_uint("netlink.protocol", WS_NETLINK_ROUTE, netlink_route_handle);
1789
14
}
1790
1791
/*
1792
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1793
 *
1794
 * Local variables:
1795
 * c-basic-offset: 8
1796
 * tab-width: 8
1797
 * indent-tabs-mode: t
1798
 * End:
1799
 *
1800
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1801
 * :indentSize=8:tabSize=8:noTabs=false:
1802
 */