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-netlink-sock_diag.c
Line
Count
Source
1
/* packet-netlink-sock_diag.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
#include "config.h"
11
12
#include <epan/packet.h>
13
#include <epan/aftypes.h>
14
#include <epan/etypes.h>
15
#include <epan/strutil.h>
16
#include <epan/tfs.h>
17
#include <wsutil/array.h>
18
#include "packet-netlink.h"
19
#include "packet-iana-data.h"
20
21
void proto_register_netlink_sock_diag(void);
22
void proto_reg_handoff_netlink_sock_diag(void);
23
24
typedef struct {
25
  packet_info *pinfo;
26
} netlink_sock_diag_info_t;
27
28
static int proto_netlink_sock_diag;
29
30
static dissector_handle_t netlink_sock_diag_handle;
31
32
enum {
33
/* sock diag values for nlmsghdr.nlmsg_type from: */
34
35
  /* <include/uapi/linux/inet_diag.h> (compat) */
36
  WS_TCPDIAG_GETSOCK     = 18,
37
  WS_DCCPDIAG_GETSOCK    = 19,
38
39
  /* <include/uapi/linux/sock_diag.h> */
40
  WS_SOCK_DIAG_BY_FAMILY = 20,
41
  WS_SOCK_DESTROY        = 21
42
};
43
44
enum {
45
  /* </usr/include/<platform>/bits/socket_type.h> */
46
  WS_SOCK_STREAM    =  1,
47
  WS_SOCK_DGRAM     =  2,
48
  WS_SOCK_RAW       =  3,
49
  WS_SOCK_RDM       =  4,
50
  WS_SOCK_SEQPACKET =  5,
51
  WS_SOCK_DCCP      =  6,
52
  WS_SOCK_PACKET    = 10
53
};
54
55
/*  SOCK_CLOEXEC = 02000000 */
56
/* SOCK_NONBLOCK = 00004000 */
57
58
enum ws_unix_diag_show_mask {
59
  /* show mask for unix diag from <include/uapi/linux/unix_diag.h> */
60
  WS_UDIAG_SHOW_NAME     = 0x00000001,
61
  WS_UDIAG_SHOW_VFS      = 0x00000002,
62
  WS_UDIAG_SHOW_PEER     = 0x00000004,
63
  WS_UDIAG_SHOW_ICONS    = 0x00000008,
64
  WS_UDIAG_SHOW_RQLEN    = 0x00000010,
65
  WS_UDIAG_SHOW_MEMINFO  = 0x00000020,
66
  WS_UDIAG_SHOW_UID      = 0x00000040
67
};
68
69
enum ws_unix_diag_attr_type {
70
  /* netlink attributes for unix diag from <include/uapi/linux/unix_diag.h> */
71
  WS_UNIX_DIAG_NAME     = 0,
72
  WS_UNIX_DIAG_VFS      = 1,
73
  WS_UNIX_DIAG_PEER     = 2,
74
  WS_UNIX_DIAG_ICONS    = 3,
75
  WS_UNIX_DIAG_RQLEN    = 4,
76
  WS_UNIX_DIAG_MEMINFO  = 5,
77
  WS_UNIX_DIAG_SHUTDOWN = 6,
78
  WS_UNIX_DIAG_UID      = 7
79
};
80
81
enum ws_inet_diag_attr_type {
82
  /* netlink attributes for inet diag from <include/uapi/linux/inet_diag.h> */
83
  WS_INET_DIAG_NONE      = 0,
84
  WS_INET_DIAG_MEMINFO   = 1,
85
  WS_INET_DIAG_INFO      = 2,
86
  WS_INET_DIAG_VEGASINFO = 3,
87
  WS_INET_DIAG_CONG      = 4,
88
  WS_INET_DIAG_TOS       = 5,
89
  WS_INET_DIAG_TCLASS    = 6,
90
  WS_INET_DIAG_SKMEMINFO = 7,
91
  WS_INET_DIAG_SHUTDOWN  = 8,
92
  WS_INET_DIAG_DCTCPINFO = 9,
93
  WS_INET_DIAG_PROTOCOL  = 10,
94
  WS_INET_DIAG_SKV6ONLY  = 11,
95
  WS_INET_DIAG_LOCALS    = 12,
96
  WS_INET_DIAG_PEERS     = 13,
97
  WS_INET_DIAG_PAD       = 14,
98
  WS_INET_DIAG_MARK      = 15,
99
  WS_INET_DIAG_BBRINFO   = 16,
100
  WS_INET_DIAG_CLASS_ID  = 17,
101
  WS_INET_DIAG_MD5SIG    = 18,
102
  WS_INET_DIAG_ULP_INFO  = 19,
103
  WS_INET_DIAG_SK_BPF_STORAGES = 20,
104
  WS_INET_DIAG_CGROUP_ID = 21,
105
  WS_INET_DIAG_SOCKOPT   = 22,
106
};
107
108
enum ws_netlink_diag_show_type {
109
  /* show mask for netlink diag from <include/uapi/linux/netlink_diag.h> */
110
  WS_NDIAG_SHOW_MEMINFO   = 0x00000001,
111
  WS_NDIAG_SHOW_GROUPS    = 0x00000002,
112
  WS_NDIAG_SHOW_RING_CFG  = 0x00000004,
113
  WS_NDIAG_SHOW_FLAGS     = 0x00000008,
114
};
115
116
enum ws_netlink_diag_attr_type {
117
  /* netlink attributes for netlink diag from <include/uapi/linux/netlink_diag.h> */
118
  WS_NETLINK_DIAG_MEMINFO = 0,
119
  WS_NETLINK_DIAG_GROUPS  = 1,
120
  WS_NETLINK_DIAG_RX_RING = 2,
121
  WS_NETLINK_DIAG_TX_RING = 3,
122
  WS_NETLINK_DIAG_FLAGS   = 4,
123
};
124
125
enum ws_packet_diag_show_mask {
126
  /* show mask for packet diag from <include/uapi/linux/packet_diag.h> */
127
  WS_PACKET_SHOW_INFO        = 0x00000001,
128
  WS_PACKET_SHOW_MCLIST      = 0x00000002,
129
  WS_PACKET_SHOW_RING_CFG    = 0x00000004,
130
  WS_PACKET_SHOW_FANOUT      = 0x00000008,
131
  WS_PACKET_SHOW_MEMINFO     = 0x00000010,
132
  WS_PACKET_SHOW_FILTER      = 0x00000020
133
};
134
135
enum ws_packet_diag_attr_type {
136
  /* netlink attributes for packet diag from <include/uapi/linux/packet_diag.h> */
137
  WS_PACKET_DIAG_INFO     = 0,
138
  WS_PACKET_DIAG_MCLIST   = 1,
139
  WS_PACKET_DIAG_RX_RING  = 2,
140
  WS_PACKET_DIAG_TX_RING  = 3,
141
  WS_PACKET_DIAG_FANOUT   = 4,
142
  WS_PACKET_DIAG_UID      = 5,
143
  WS_PACKET_DIAG_MEMINFO  = 6,
144
  WS_PACKET_DIAG_FILTER   = 7
145
};
146
147
enum {
148
  /* based on kernel include <include/net/tcp_states.h> with WS_ without TCP_ (it's not only used by tcp) */
149
  WS_ESTABLISHED = 1,
150
  WS_SYN_SENT    = 2,
151
  WS_SYN_RECV    = 3,
152
  WS_FIN_WAIT1   = 4,
153
  WS_FIN_WAIT2   = 5,
154
  WS_TIME_WAIT   = 6,
155
  WS_CLOSE       = 7,
156
  WS_CLOSE_WAIT  = 8,
157
  WS_LAST_ACK    = 9,
158
  WS_LISTEN      = 10,
159
  WS_CLOSING     = 11,
160
  WS_NEW_SYNC_RECV = 12
161
};
162
163
static int hf_netlink_sock_diag_cookie;
164
static int hf_netlink_sock_diag_family;
165
static int hf_netlink_sock_diag_fwd_alloc;
166
static int hf_netlink_sock_diag_inet_attr;
167
static int hf_netlink_sock_diag_inet_dport;
168
static int hf_netlink_sock_diag_inet_dst_ip4;
169
static int hf_netlink_sock_diag_inet_dst_ip6;
170
static int hf_netlink_sock_diag_inet_extended;
171
static int hf_netlink_sock_diag_inet_interface;
172
static int hf_netlink_sock_diag_inet_padding;
173
static int hf_netlink_sock_diag_inet_proto;
174
static int hf_netlink_sock_diag_inet_sport;
175
static int hf_netlink_sock_diag_inet_src_ip4;
176
static int hf_netlink_sock_diag_inet_src_ip6;
177
static int hf_netlink_sock_diag_inet_states;
178
static int hf_netlink_sock_diag_inode;
179
static int hf_netlink_sock_diag_netlink_attr;
180
static int hf_netlink_sock_diag_netlink_dst_port_id;
181
static int hf_netlink_sock_diag_netlink_port_id;
182
static int hf_netlink_sock_diag_netlink_proto;
183
static int hf_netlink_sock_diag_netlink_show;
184
static int hf_netlink_sock_diag_netlink_show_groups;
185
static int hf_netlink_sock_diag_netlink_show_meminfo;
186
static int hf_netlink_sock_diag_netlink_show_ring_cfg;
187
static int hf_netlink_sock_diag_nltype;
188
static int hf_netlink_sock_diag_packet_attr;
189
static int hf_netlink_sock_diag_packet_proto;
190
static int hf_netlink_sock_diag_packet_show;
191
static int hf_netlink_sock_diag_packet_show_fanout;
192
static int hf_netlink_sock_diag_packet_show_filter;
193
static int hf_netlink_sock_diag_packet_show_info;
194
static int hf_netlink_sock_diag_packet_show_mclist;
195
static int hf_netlink_sock_diag_packet_show_meminfo;
196
static int hf_netlink_sock_diag_packet_show_ring_cfg;
197
static int hf_netlink_sock_diag_rcvbuf;
198
static int hf_netlink_sock_diag_rmem_alloc;
199
static int hf_netlink_sock_diag_rqueue;
200
static int hf_netlink_sock_diag_shutdown;
201
static int hf_netlink_sock_diag_sndbuf;
202
static int hf_netlink_sock_diag_state;
203
static int hf_netlink_sock_diag_type;
204
static int hf_netlink_sock_diag_unix_attr;
205
static int hf_netlink_sock_diag_unix_name;
206
static int hf_netlink_sock_diag_unix_peer_inode;
207
static int hf_netlink_sock_diag_unix_show;
208
static int hf_netlink_sock_diag_unix_show_icons;
209
static int hf_netlink_sock_diag_unix_show_meminfo;
210
static int hf_netlink_sock_diag_unix_show_name;
211
static int hf_netlink_sock_diag_unix_show_peer;
212
static int hf_netlink_sock_diag_unix_show_rqlen;
213
static int hf_netlink_sock_diag_unix_show_vfs;
214
static int hf_netlink_sock_diag_wmem_alloc;
215
static int hf_netlink_sock_diag_wmem_queued;
216
static int hf_netlink_sock_diag_wqueue;
217
218
static int ett_netlink_sock_diag;
219
static int ett_netlink_sock_diag_show;
220
static int ett_netlink_sock_diag_attr;
221
222
static const true_false_string _tfs_show_do_not_show = { "Show", "Don't show" };
223
224
static const value_string socket_type_vals[] = {
225
  { WS_SOCK_STREAM, "SOCK_STREAM" },
226
  { WS_SOCK_DGRAM,  "SOCK_DGRAM" },
227
  { WS_SOCK_RAW,    "SOCK_RAW" },
228
  { WS_SOCK_RDM,    "SOCK_RDM" },
229
  { WS_SOCK_SEQPACKET,  "SOCK_SEQPACKET" },
230
  { WS_SOCK_DCCP,   "SOCK_DCCP" },
231
  { WS_SOCK_PACKET, "SOCK_PACKET" },
232
  { 0, NULL }
233
};
234
235
static const value_string socket_state_vals[] = {
236
  { WS_ESTABLISHED, "ESTABLISHED" },
237
  { WS_SYN_SENT,    "SYN_SENT" },
238
  { WS_SYN_RECV,    "SYN_RECV" },
239
  { WS_FIN_WAIT1,   "FIN_WAIT1" },
240
  { WS_FIN_WAIT2,   "FIN_WAIT2" },
241
  { WS_TIME_WAIT,   "TIME_WAIT" },
242
  { WS_CLOSE,       "CLOSE" },
243
  { WS_CLOSE_WAIT,  "CLOSE_WAIT" },
244
  { WS_LAST_ACK,    "LAST_ACK" },
245
  { WS_LISTEN,      "LISTEN" },
246
  { WS_CLOSING,     "CLOSING" },
247
  { WS_NEW_SYNC_RECV, "NEW_SYNC_RECV" },
248
  { 0, NULL }
249
};
250
251
/* Generic */
252
253
static int
254
_tvb_check_if_zeros(tvbuff_t *tvb, int offset, int len)
255
0
{
256
  /* padding, all bytes should be 0, if not display as unknown */
257
0
  while (len >= 0) {
258
0
    if (tvb_get_uint8(tvb, offset) != 0)
259
0
      return 1;
260
261
0
    offset++;
262
0
    len--;
263
0
  }
264
0
  return 0;
265
0
}
266
267
static void
268
_dissect_padding(proto_tree *tree _U_, tvbuff_t *tvb, int offset, int len)
269
0
{
270
0
  if (_tvb_check_if_zeros(tvb, offset, len)) {
271
    /* XXX, tree, expert info */
272
0
  }
273
0
}
274
275
/* Sock diag meminfo */
276
277
static int
278
dissect_sock_diag_meminfo(proto_tree *tree, netlink_sock_diag_info_t *info _U_, struct packet_netlink_data *nl_data, tvbuff_t *tvb, int offset, int len)
279
0
{
280
0
  static int *hfs[] = {
281
0
    &hf_netlink_sock_diag_rmem_alloc,
282
0
    &hf_netlink_sock_diag_rcvbuf,
283
0
    &hf_netlink_sock_diag_wmem_alloc,
284
0
    &hf_netlink_sock_diag_sndbuf,
285
0
    &hf_netlink_sock_diag_fwd_alloc,
286
0
    &hf_netlink_sock_diag_wmem_queued,
287
    /* XXX OPTMEM */
288
    /* XXX BACKLOG */
289
0
  };
290
291
0
  unsigned i;
292
293
0
  if (len == 0 || (len % 4) != 0)
294
0
    return 0;
295
296
0
  for (i = 0; len >= 4 && i < G_N_ELEMENTS(hfs); i++) {
297
0
    proto_tree_add_item(tree, *hfs[i], tvb, offset, 4, nl_data->encoding);
298
0
    offset += 4; len -= 4;
299
0
  }
300
301
0
  if (len != 0) {
302
    /* XXX, unknown */
303
0
  }
304
305
0
  return 1;
306
0
}
307
308
/* Sock diag Cookie */
309
310
static void
311
sock_diag_proto_tree_add_cookie(proto_tree *tree, netlink_sock_diag_info_t *info _U_, struct packet_netlink_data *nl_data _U_, tvbuff_t *tvb, int offset)
312
0
{
313
0
  uint64_t cookie;
314
315
0
  cookie = tvb_get_letohl(tvb, offset + 4);
316
0
  cookie <<= 32;
317
0
  cookie |= tvb_get_letohl(tvb, offset);
318
319
  /* XXX support for INET_DIAG_NOCOOKIE (~0) */
320
321
0
  proto_tree_add_uint64(tree, hf_netlink_sock_diag_cookie, tvb, offset, 8, cookie);
322
0
}
323
324
static const value_string netlink_sock_diag_shutdown_flags_vals[] = {
325
  { 0, "No shutdown" },
326
  { 1, "Receptions disallowed" },
327
  { 2, "Transmissions disallowed" },
328
  { 3, "Receptions and transmissions disallowed" },
329
  { 0, NULL }
330
};
331
332
static void
333
sock_diag_proto_tree_add_shutdown(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, int offset)
334
0
{
335
0
  uint32_t how;
336
337
0
  proto_tree_add_item_ret_uint(tree, hf_netlink_sock_diag_shutdown, tvb, offset, 1, ENC_NA, &how);
338
339
0
  proto_item_append_text(tree, ": %s", val_to_str(pinfo->pool, how, netlink_sock_diag_shutdown_flags_vals, "Invalid how value (%x)"));
340
0
}
341
342
/* AF_UNIX attributes */
343
344
static const value_string netlink_sock_diag_unix_attr_vals[] = {
345
  { WS_UNIX_DIAG_NAME, "Name" },
346
  { WS_UNIX_DIAG_VFS,  "VFS" },
347
  { WS_UNIX_DIAG_PEER, "Peer" },
348
  { WS_UNIX_DIAG_ICONS, "Icons" },
349
  { WS_UNIX_DIAG_RQLEN, "RQ len" },
350
  { WS_UNIX_DIAG_MEMINFO, "meminfo" },
351
  { WS_UNIX_DIAG_SHUTDOWN, "shutdown" },
352
  { 0, NULL }
353
};
354
355
static int
356
dissect_netlink_unix_sock_diag_reply_attrs(tvbuff_t *tvb, void *data, struct packet_netlink_data *nl_data, proto_tree *tree, int nla_type, int offset, int len)
357
0
{
358
0
  enum ws_unix_diag_attr_type type = (enum ws_unix_diag_attr_type) nla_type;
359
0
  netlink_sock_diag_info_t *info = (netlink_sock_diag_info_t *) data;
360
361
0
  switch (type) {
362
0
    case WS_UNIX_DIAG_NAME:
363
0
    {
364
0
      const char *name;
365
366
      /* XXX make it nicer */
367
0
      if (len > 0 && tvb_get_uint8(tvb, offset) == '\0') {
368
0
        name = wmem_strconcat(info->pinfo->pool,
369
0
          "@",
370
0
          tvb_get_string_enc(info->pinfo->pool, tvb, offset+1, len-1, ENC_ASCII | ENC_NA),
371
0
          NULL);
372
0
      } else
373
0
        name = (char*)tvb_get_string_enc(info->pinfo->pool, tvb, offset, len, ENC_ASCII | ENC_NA);
374
375
0
      proto_item_append_text(tree, ": %s", name);
376
0
      proto_tree_add_string(tree, hf_netlink_sock_diag_unix_name, tvb, offset, len, name);
377
0
      return 1;
378
0
    }
379
380
0
    case WS_UNIX_DIAG_PEER:
381
0
      if (len == 4) {
382
0
        uint32_t value;
383
0
        proto_tree_add_item_ret_uint(tree, hf_netlink_sock_diag_unix_peer_inode, tvb, offset, 4, nl_data->encoding, &value);
384
0
        proto_item_append_text(tree, ": Peer inode %u", value);
385
0
        return 1;
386
0
      }
387
0
      return 0;
388
389
0
    case WS_UNIX_DIAG_RQLEN:
390
0
      if (len == 8) {
391
        /* XXX, if socket in WS_LISTEN it's reporting sk->sk_receive_queue.qlen, sk->sk_max_ack_backlog */
392
0
        proto_tree_add_item(tree, hf_netlink_sock_diag_rqueue, tvb, offset, 4, nl_data->encoding);
393
0
        proto_tree_add_item(tree, hf_netlink_sock_diag_wqueue, tvb, offset, 4, nl_data->encoding);
394
0
        return 1;
395
0
      }
396
0
      return 0;
397
398
0
    case WS_UNIX_DIAG_MEMINFO:
399
0
      return dissect_sock_diag_meminfo(tree, info, nl_data, tvb, offset, len);
400
401
0
    case WS_UNIX_DIAG_SHUTDOWN:
402
0
      if (len == 1)
403
0
        sock_diag_proto_tree_add_shutdown(tree, info->pinfo, tvb, offset);
404
0
      return 0;
405
406
0
    case WS_UNIX_DIAG_VFS:
407
0
    case WS_UNIX_DIAG_ICONS:
408
0
    default:
409
0
      return 0;
410
0
  }
411
0
}
412
413
/* AF_UNIX */
414
415
static int
416
dissect_sock_diag_unix_reply(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
417
0
{
418
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_family, tvb, offset, 1, ENC_NA);
419
0
  offset += 1;
420
421
  /* XXX, validate: SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET */
422
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_type, tvb, offset, 1, ENC_NA);
423
0
  offset += 1;
424
425
  /* XXX, validate */
426
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_state, tvb, offset, 1, ENC_NA);
427
0
  offset += 1;
428
429
0
  _dissect_padding(tree, tvb, offset, 1);
430
0
  offset += 1;
431
432
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inode, tvb, offset, 4, nl_data->encoding);
433
0
  offset += 4;
434
435
0
  sock_diag_proto_tree_add_cookie(tree, info, nl_data, tvb, offset);
436
0
  offset += 8;
437
438
0
  return dissect_netlink_attributes_to_end(tvb, hf_netlink_sock_diag_unix_attr, ett_netlink_sock_diag_attr, info, nl_data, tree, offset, dissect_netlink_unix_sock_diag_reply_attrs);
439
0
}
440
441
/* AF_UNIX request */
442
443
static int
444
dissect_sock_diag_unix_request_show(tvbuff_t *tvb, netlink_sock_diag_info_t *info _U_, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
445
0
{
446
0
  proto_item *ti;
447
0
  proto_tree *flags_tree;
448
449
0
  ti = proto_tree_add_item(tree, hf_netlink_sock_diag_unix_show, tvb, offset, 4, nl_data->encoding);
450
0
  flags_tree = proto_item_add_subtree(ti, ett_netlink_sock_diag_show);
451
452
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_unix_show_name, tvb, offset, 4, nl_data->encoding);
453
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_unix_show_vfs, tvb, offset, 4, nl_data->encoding);
454
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_unix_show_peer, tvb, offset, 4, nl_data->encoding);
455
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_unix_show_icons, tvb, offset, 4, nl_data->encoding);
456
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_unix_show_rqlen, tvb, offset, 4, nl_data->encoding);
457
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_unix_show_meminfo, tvb, offset, 4, nl_data->encoding);
458
  /* XXX, unknown */
459
460
0
  offset += 4;
461
462
0
  return offset;
463
0
}
464
465
static int
466
dissect_sock_diag_unix_request(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
467
0
{
468
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_family, tvb, offset, 1, ENC_NA);
469
0
  offset += 1;
470
471
  /* XXX, AF_UNIX don't have protocols - 0 */
472
0
  offset += 1;
473
474
0
  _dissect_padding(tree, tvb, offset, 2);
475
0
  offset += 2;
476
477
  /* states */
478
0
  offset += 4;
479
480
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inode, tvb, offset, 4, nl_data->encoding);
481
0
  offset += 4;
482
483
0
  offset = dissect_sock_diag_unix_request_show(tvb, info, nl_data, tree, offset);
484
485
0
  sock_diag_proto_tree_add_cookie(tree, info, nl_data, tvb, offset);
486
0
  offset += 8;
487
488
0
  return offset;
489
0
}
490
491
/* AF_INET attributes */
492
493
static const value_string netlink_sock_diag_inet_attr_vals[] = {
494
  { WS_INET_DIAG_MEMINFO,    "meminfo" },
495
  { WS_INET_DIAG_INFO,       "info" },
496
  { WS_INET_DIAG_VEGASINFO,  "vegasinfo" },
497
  { WS_INET_DIAG_CONG,       "cong" },
498
  { WS_INET_DIAG_TOS,        "tos" },
499
  { WS_INET_DIAG_TCLASS,     "tclass" },
500
  { WS_INET_DIAG_SKMEMINFO,  "skmeminfo" },
501
  { WS_INET_DIAG_SHUTDOWN,   "shutdown" },
502
  { WS_INET_DIAG_DCTCPINFO,  "dctcpinfo" },
503
  { WS_INET_DIAG_PROTOCOL,   "protocol" },
504
  { WS_INET_DIAG_SKV6ONLY,   "skv6only" },
505
  { WS_INET_DIAG_LOCALS,     "locals" },
506
  { WS_INET_DIAG_PEERS,      "peers" },
507
  { WS_INET_DIAG_PAD,        "pad" },
508
  { WS_INET_DIAG_MARK,       "mark" },
509
  { WS_INET_DIAG_BBRINFO,    "bbrinfo" },
510
  { WS_INET_DIAG_CLASS_ID,   "class_id" },
511
  { WS_INET_DIAG_MD5SIG,     "md5sig" },
512
  { WS_INET_DIAG_ULP_INFO,   "ulp_info" },
513
  { WS_INET_DIAG_SK_BPF_STORAGES, "sk_bpf_storages" },
514
  { WS_INET_DIAG_CGROUP_ID,  "cgroup_id" },
515
  { WS_INET_DIAG_SOCKOPT,    "sockopt" },
516
  { 0, NULL }
517
};
518
519
static int
520
dissect_sock_diag_inet_attributes(tvbuff_t *tvb, void *data, struct packet_netlink_data *nl_data, proto_tree *tree, int nla_type, int offset, int len)
521
0
{
522
0
  enum ws_inet_diag_attr_type type = (enum ws_inet_diag_attr_type) nla_type;
523
0
  netlink_sock_diag_info_t *info = (netlink_sock_diag_info_t *) data;
524
525
0
  switch (type) {
526
0
    case WS_INET_DIAG_MEMINFO:
527
0
      if (len == 16) {
528
0
        proto_tree_add_item(tree, hf_netlink_sock_diag_rmem_alloc, tvb, offset, 4, nl_data->encoding);
529
0
        offset += 4;
530
531
0
        proto_tree_add_item(tree, hf_netlink_sock_diag_wmem_queued, tvb, offset, 4, nl_data->encoding);
532
0
        offset += 4;
533
534
0
        proto_tree_add_item(tree, hf_netlink_sock_diag_fwd_alloc, tvb, offset, 4, nl_data->encoding);
535
0
        offset += 4;
536
537
0
        proto_tree_add_item(tree, hf_netlink_sock_diag_wmem_alloc, tvb, offset, 4, nl_data->encoding);
538
        /*offset += 4;*/
539
540
0
        return 1;
541
0
      }
542
0
      return 0;
543
544
0
    case WS_INET_DIAG_SKMEMINFO:
545
0
      return dissect_sock_diag_meminfo(tree, info, nl_data, tvb, offset, len);
546
547
0
    case WS_INET_DIAG_SHUTDOWN:
548
0
      if (len == 1)
549
0
        sock_diag_proto_tree_add_shutdown(tree, info->pinfo, tvb, offset);
550
0
      return 0;
551
552
0
    case WS_INET_DIAG_INFO:
553
0
    case WS_INET_DIAG_VEGASINFO:
554
0
    case WS_INET_DIAG_CONG:
555
0
    case WS_INET_DIAG_TOS:
556
0
    case WS_INET_DIAG_TCLASS:
557
0
    case WS_INET_DIAG_DCTCPINFO:
558
0
    case WS_INET_DIAG_PROTOCOL:
559
0
    case WS_INET_DIAG_SKV6ONLY:
560
0
    case WS_INET_DIAG_LOCALS:
561
0
    case WS_INET_DIAG_PEERS:
562
0
    case WS_INET_DIAG_PAD:
563
0
    case WS_INET_DIAG_MARK:
564
0
    case WS_INET_DIAG_BBRINFO:
565
0
    default:
566
0
      return 0;
567
0
  }
568
0
}
569
570
/* AF_INET sockid */
571
572
static int
573
dissect_sock_diag_inet_sockid(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset, int family)
574
0
{
575
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inet_sport, tvb, offset, 2, ENC_BIG_ENDIAN);
576
0
  offset += 2;
577
578
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inet_dport, tvb, offset, 2, ENC_BIG_ENDIAN);
579
0
  offset += 2;
580
581
0
  switch (family) {
582
0
    case LINUX_AF_INET:
583
0
      proto_tree_add_item(tree, hf_netlink_sock_diag_inet_src_ip4, tvb, offset, 4, ENC_BIG_ENDIAN);
584
0
      offset += 4;
585
586
0
      _dissect_padding(tree, tvb, offset, 12);
587
0
      offset += 12;
588
589
0
      proto_tree_add_item(tree, hf_netlink_sock_diag_inet_dst_ip4, tvb, offset, 4, ENC_BIG_ENDIAN);
590
0
      offset += 4;
591
592
0
      _dissect_padding(tree, tvb, offset, 12);
593
0
      offset += 12;
594
0
      break;
595
596
0
    case LINUX_AF_INET6:
597
0
      proto_tree_add_item(tree, hf_netlink_sock_diag_inet_src_ip6, tvb, offset, 16, ENC_NA);
598
0
      offset += 16;
599
600
0
      proto_tree_add_item(tree, hf_netlink_sock_diag_inet_dst_ip6, tvb, offset, 16, ENC_NA);
601
0
      offset += 16;
602
0
      break;
603
604
0
    default:
605
0
      DISSECTOR_ASSERT_NOT_REACHED();
606
0
      break;
607
0
  }
608
609
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inet_interface, tvb, offset, 4, nl_data->encoding);
610
0
  offset += 4;
611
612
0
  sock_diag_proto_tree_add_cookie(tree, info, nl_data, tvb, offset);
613
0
  offset += 8;
614
615
0
  return offset;
616
0
}
617
618
/* AF_INET */
619
620
static int
621
dissect_sock_diag_inet_reply(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
622
0
{
623
0
  uint8_t af_family;
624
625
0
  af_family = tvb_get_uint8(tvb, offset);
626
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_family, tvb, offset, 1, ENC_NA);
627
0
  offset += 1;
628
629
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_state, tvb, offset, 1, ENC_NA);
630
0
  offset += 1;
631
632
  /* XXX timer retrans */
633
0
  offset += 2;
634
635
0
  offset = dissect_sock_diag_inet_sockid(tvb, info, nl_data, tree, offset, af_family);
636
637
  /* XXX expires */
638
0
  offset += 4;
639
640
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_rqueue, tvb, offset, 4, nl_data->encoding);
641
0
  offset += 4;
642
643
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_wqueue, tvb, offset, 4, nl_data->encoding);
644
0
  offset += 4;
645
646
  /* XXX uid */
647
0
  offset += 4;
648
649
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inode, tvb, offset, 4, nl_data->encoding);
650
0
  offset += 4;
651
652
0
  return dissect_netlink_attributes_to_end(tvb, hf_netlink_sock_diag_inet_attr, ett_netlink_sock_diag_attr, info, nl_data, tree, offset, dissect_sock_diag_inet_attributes);
653
0
}
654
655
/* AF_INET request */
656
657
static int
658
dissect_sock_diag_inet_request(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
659
0
{
660
0
  uint8_t af_family;
661
662
0
  af_family = tvb_get_uint8(tvb, offset);
663
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_family, tvb, offset, 1, ENC_NA);
664
0
  offset += 1;
665
666
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inet_proto, tvb, offset, 1, ENC_NA);
667
0
  offset += 1;
668
669
  /* XXX ext: INET_DIAG_MEMINFO, INET_DIAG_INFO, ... */
670
671
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inet_extended, tvb, offset, 1, ENC_NA);
672
0
  offset += 1;
673
674
  /* padding for backwards compatibility */
675
0
  _dissect_padding(tree, tvb, offset, 1);
676
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inet_padding, tvb, offset, 1, ENC_NA);
677
0
  offset += 1;
678
679
  /* XXX states (bit of sk_state) */
680
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inet_states, tvb, offset, 4, ENC_BIG_ENDIAN);
681
0
  offset += 4;
682
683
0
  offset = dissect_sock_diag_inet_sockid(tvb, info, nl_data, tree, offset, af_family);
684
685
0
  return offset;
686
0
}
687
688
/* AF_NETLINK attributes */
689
690
static const value_string netlink_sock_diag_netlink_vals[] = {
691
  { WS_NETLINK_DIAG_MEMINFO,  "Memory info" },
692
  { WS_NETLINK_DIAG_GROUPS,   "groups" },
693
  { WS_NETLINK_DIAG_RX_RING,  "RX ring configuration" },
694
  { WS_NETLINK_DIAG_TX_RING,  "TX ring configuration" },
695
  { 0, NULL }
696
};
697
698
static int
699
dissect_sock_diag_netlink_attributes(tvbuff_t *tvb, void *data, struct packet_netlink_data *nl_data, proto_tree *tree, int nla_type, int offset, int len)
700
0
{
701
0
  enum ws_netlink_diag_attr_type type = (enum ws_netlink_diag_attr_type) nla_type;
702
0
  netlink_sock_diag_info_t *info = (netlink_sock_diag_info_t *) data;
703
704
0
  switch (type) {
705
0
    case WS_NETLINK_DIAG_MEMINFO:
706
0
      return dissect_sock_diag_meminfo(tree, info, nl_data, tvb, offset, len);
707
708
0
    case WS_NETLINK_DIAG_GROUPS:
709
0
    case WS_NETLINK_DIAG_RX_RING:
710
0
    case WS_NETLINK_DIAG_TX_RING:
711
0
    default:
712
0
      return 0;
713
0
  }
714
0
}
715
716
/* AF_NETLINK */
717
718
static int
719
dissect_sock_diag_netlink_reply(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
720
0
{
721
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_family, tvb, offset, 1, ENC_NA);
722
0
  offset += 1;
723
724
0
  /* ti = */ proto_tree_add_item(tree, hf_netlink_sock_diag_type, tvb, offset, 1, ENC_NA);
725
0
  switch (tvb_get_uint8(tvb, offset)) {
726
0
    case WS_SOCK_DGRAM:
727
0
    case WS_SOCK_RAW:
728
0
      break;
729
0
    default:
730
      /* XXX expert_add_info(info->pinfo, ti, &ei_netlink_sock_diag_incorrect_type); */
731
0
      break;
732
0
  }
733
0
  offset += 1;
734
735
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_netlink_proto, tvb, offset, 1, ENC_NA);
736
0
  offset += 1;
737
738
  /* XXX, validate */
739
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_state, tvb, offset, 1, ENC_NA);
740
0
  offset += 1;
741
742
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_netlink_port_id, tvb, offset, 4, nl_data->encoding);
743
0
  offset += 4;
744
745
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_netlink_dst_port_id, tvb, offset, 4, nl_data->encoding);
746
0
  offset += 4;
747
748
  /* XXX dst group */
749
0
  offset += 4;
750
751
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inode, tvb, offset, 4, nl_data->encoding);
752
0
  offset += 4;
753
754
0
  sock_diag_proto_tree_add_cookie(tree, info, nl_data, tvb, offset);
755
0
  offset += 8;
756
757
0
  return dissect_netlink_attributes_to_end(tvb, hf_netlink_sock_diag_netlink_attr, ett_netlink_sock_diag_attr, info, nl_data, tree, offset, dissect_sock_diag_netlink_attributes);
758
0
}
759
760
/* AF_NETLINK request */
761
762
static int
763
dissect_sock_diag_netlink_request_show(tvbuff_t *tvb, netlink_sock_diag_info_t *info _U_, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
764
0
{
765
0
  proto_item *ti;
766
0
  proto_tree *flags_tree;
767
768
0
  ti = proto_tree_add_item(tree, hf_netlink_sock_diag_netlink_show, tvb, offset, 4, nl_data->encoding);
769
0
  flags_tree = proto_item_add_subtree(ti, ett_netlink_sock_diag_show);
770
771
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_netlink_show_meminfo, tvb, offset, 4, nl_data->encoding);
772
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_netlink_show_groups, tvb, offset, 4, nl_data->encoding);
773
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_netlink_show_ring_cfg, tvb, offset, 4, nl_data->encoding);
774
  /* XXX, unknown */
775
776
0
  offset += 4;
777
778
0
  return offset;
779
0
}
780
781
static int
782
dissect_sock_diag_netlink_request(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
783
0
{
784
  /* XXX, 255 for all */
785
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_family, tvb, offset, 1, ENC_NA);
786
0
  offset += 1;
787
788
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_netlink_proto, tvb, offset, 1, ENC_NA);
789
0
  offset += 1;
790
791
0
  _dissect_padding(tree, tvb, offset, 2);
792
0
  offset += 2;
793
794
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inode, tvb, offset, 4, nl_data->encoding);
795
0
  offset += 4;
796
797
0
  offset = dissect_sock_diag_netlink_request_show(tvb, info, nl_data, tree, offset);
798
799
0
  sock_diag_proto_tree_add_cookie(tree, info, nl_data, tvb, offset);
800
0
  offset += 8;
801
802
0
  return offset;
803
0
}
804
805
/* AF_PACKET attributes */
806
807
static int
808
dissect_netlink_packet_sock_diag_reply_attrs(tvbuff_t *tvb, void *data, struct packet_netlink_data *nl_data, proto_tree *tree, int nla_type, int offset, int len)
809
0
{
810
0
  enum ws_packet_diag_attr_type type = (enum ws_packet_diag_attr_type) nla_type;
811
0
  netlink_sock_diag_info_t *info = (netlink_sock_diag_info_t *) data;
812
813
0
  switch (type) {
814
0
    case WS_PACKET_DIAG_MEMINFO:
815
0
      return dissect_sock_diag_meminfo(tree, info, nl_data, tvb, offset, len);
816
817
0
    case WS_PACKET_DIAG_INFO:
818
0
    case WS_PACKET_DIAG_MCLIST:
819
0
    case WS_PACKET_DIAG_RX_RING:
820
0
    case WS_PACKET_DIAG_TX_RING:
821
0
    case WS_PACKET_DIAG_FANOUT:
822
0
    case WS_PACKET_DIAG_UID:
823
0
    case WS_PACKET_DIAG_FILTER:
824
0
    default:
825
0
      return 0;
826
0
  }
827
0
}
828
829
static const value_string netlink_sock_diag_packet_vals[] = {
830
  { WS_PACKET_DIAG_INFO,    "info" },
831
  { WS_PACKET_DIAG_MCLIST,  "mclist" },
832
  { WS_PACKET_DIAG_RX_RING, "rxring" },
833
  { WS_PACKET_DIAG_TX_RING, "txring" },
834
  { WS_PACKET_DIAG_FANOUT,  "fanout" },
835
  { WS_PACKET_DIAG_UID,     "uid" },
836
  { WS_PACKET_DIAG_MEMINFO, "meminfo" },
837
  { WS_PACKET_DIAG_FILTER,  "filter" },
838
  { 0, NULL }
839
};
840
841
/* AF_PACKET */
842
843
static int
844
dissect_sock_diag_packet_reply(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
845
0
{
846
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_family, tvb, offset, 1, ENC_NA);
847
0
  offset += 1;
848
849
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_type, tvb, offset, 1, ENC_NA);
850
0
  offset += 1;
851
852
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_packet_proto, tvb, offset, 2, nl_data->encoding);
853
0
  offset += 2;
854
855
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inode, tvb, offset, 4, nl_data->encoding);
856
0
  offset += 4;
857
858
0
  sock_diag_proto_tree_add_cookie(tree, info, nl_data, tvb, offset);
859
0
  offset += 8;
860
861
0
  return dissect_netlink_attributes_to_end(tvb, hf_netlink_sock_diag_packet_attr, ett_netlink_sock_diag_attr, info, nl_data, tree, offset, dissect_netlink_packet_sock_diag_reply_attrs);
862
0
}
863
864
/* AF_PACKET request */
865
866
static int
867
dissect_sock_diag_packet_request_show(tvbuff_t *tvb, netlink_sock_diag_info_t *info _U_, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
868
0
{
869
0
  proto_item *ti;
870
0
  proto_tree *flags_tree;
871
872
0
  ti = proto_tree_add_item(tree, hf_netlink_sock_diag_packet_show, tvb, offset, 4, nl_data->encoding);
873
0
  flags_tree = proto_item_add_subtree(ti, ett_netlink_sock_diag_show);
874
875
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_packet_show_info, tvb, offset, 4, nl_data->encoding);
876
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_packet_show_mclist, tvb, offset, 4, nl_data->encoding);
877
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_packet_show_ring_cfg, tvb, offset, 4, nl_data->encoding);
878
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_packet_show_fanout, tvb, offset, 4, nl_data->encoding);
879
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_packet_show_meminfo, tvb, offset, 4, nl_data->encoding);
880
0
  proto_tree_add_item(flags_tree, hf_netlink_sock_diag_packet_show_filter, tvb, offset, 4, nl_data->encoding);
881
  /* XXX, unknown */
882
883
0
  offset += 4;
884
885
0
  return offset;
886
0
}
887
888
static int
889
dissect_sock_diag_packet_request(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
890
0
{
891
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_family, tvb, offset, 1, ENC_NA);
892
0
  offset += 1;
893
894
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_packet_proto, tvb, offset, 1, ENC_BIG_ENDIAN);
895
0
  offset += 1;
896
897
0
  _dissect_padding(tree, tvb, offset, 2);
898
0
  offset += 2;
899
900
0
  proto_tree_add_item(tree, hf_netlink_sock_diag_inode, tvb, offset, 4, nl_data->encoding);
901
0
  offset += 4;
902
903
0
  offset = dissect_sock_diag_packet_request_show(tvb, info, nl_data, tree, offset);
904
905
0
  sock_diag_proto_tree_add_cookie(tree, info, nl_data, tvb, offset);
906
0
  offset += 8;
907
908
0
  return offset;
909
0
}
910
911
/* WS_SOCK_DIAG_BY_FAMILY dissection */
912
913
static int
914
dissect_sock_diag_by_family(tvbuff_t *tvb, netlink_sock_diag_info_t *info, struct packet_netlink_data *nl_data, proto_tree *tree, int offset)
915
0
{
916
0
  const bool is_req = (info->pinfo->p2p_dir == P2P_DIR_SENT);
917
0
  uint8_t af_family;
918
919
0
  af_family = tvb_get_uint8(tvb, offset);
920
921
0
  switch (af_family) {
922
0
    case LINUX_AF_LOCAL:
923
0
      offset = (is_req) ?
924
0
        dissect_sock_diag_unix_request(tvb, info, nl_data, tree, offset) :
925
0
        dissect_sock_diag_unix_reply(tvb, info, nl_data, tree, offset);
926
0
      break;
927
928
0
    case LINUX_AF_INET:
929
0
    case LINUX_AF_INET6:
930
0
      offset = (is_req) ?
931
0
        dissect_sock_diag_inet_request(tvb, info, nl_data, tree, offset) :
932
0
        dissect_sock_diag_inet_reply(tvb, info, nl_data, tree, offset);
933
0
      break;
934
935
0
    case LINUX_AF_NETLINK:
936
0
      offset = (is_req) ?
937
0
        dissect_sock_diag_netlink_request(tvb, info, nl_data, tree, offset) :
938
0
        dissect_sock_diag_netlink_reply(tvb, info, nl_data, tree, offset);
939
0
      break;
940
941
0
    case LINUX_AF_PACKET:
942
0
      offset = (is_req) ?
943
0
        dissect_sock_diag_packet_request(tvb, info, nl_data, tree, offset) :
944
0
        dissect_sock_diag_packet_reply(tvb, info, nl_data, tree, offset);
945
0
      break;
946
0
  }
947
948
0
  return offset;
949
0
}
950
951
static const value_string netlink_sock_diag_type_vals[] = {
952
  { WS_TCPDIAG_GETSOCK,     "TCPDIAG_GETSOCK" },
953
  { WS_DCCPDIAG_GETSOCK,    "DCCPDIAG_GETSOCK" },
954
  { WS_SOCK_DIAG_BY_FAMILY, "SOCK_DIAG_BY_FAMILY" },
955
  { WS_SOCK_DESTROY,        "SOCK_DESTROY" },
956
  { 0, NULL }
957
};
958
959
static int
960
dissect_netlink_sock_diag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
961
0
{
962
0
  struct packet_netlink_data *nl_data = (struct packet_netlink_data *)data;
963
0
  netlink_sock_diag_info_t info;
964
0
  proto_tree *nlmsg_tree;
965
0
  proto_item *pi;
966
0
  int offset = 0;
967
968
0
  DISSECTOR_ASSERT(nl_data && nl_data->magic == PACKET_NETLINK_MAGIC);
969
970
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Netlink sock diag");
971
0
  col_clear(pinfo->cinfo, COL_INFO);
972
973
0
  pi = proto_tree_add_item(tree, proto_netlink_sock_diag, tvb, 0, -1, ENC_NA);
974
0
  nlmsg_tree = proto_item_add_subtree(pi, ett_netlink_sock_diag);
975
976
  /* Netlink message header (nlmsghdr) */
977
0
  offset = dissect_netlink_header(tvb, pinfo, nlmsg_tree, offset, nl_data->encoding, hf_netlink_sock_diag_nltype, NULL);
978
979
0
  info.pinfo = pinfo;
980
981
0
  switch (nl_data->type) {
982
0
    case WS_TCPDIAG_GETSOCK:
983
0
    case WS_DCCPDIAG_GETSOCK:
984
      /* XXX, inet_diag_rcv_msg_compat */
985
0
      break;
986
987
0
    case WS_SOCK_DIAG_BY_FAMILY:
988
0
      offset = dissect_sock_diag_by_family(tvb, &info, nl_data, nlmsg_tree, offset);
989
0
      break;
990
0
  }
991
992
0
  return offset;
993
0
}
994
995
void
996
proto_register_netlink_sock_diag(void)
997
14
{
998
14
  static hf_register_info hf[] = {
999
14
    { &hf_netlink_sock_diag_family,
1000
14
      { "Family", "netlink-sock_diag.family",
1001
14
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &linux_af_vals_ext, 0x00,
1002
14
        NULL, HFILL }
1003
14
    },
1004
14
    { &hf_netlink_sock_diag_type,
1005
14
      { "Type", "netlink-sock_diag.type",
1006
14
        FT_UINT8, BASE_DEC, VALS(socket_type_vals), 0x00,
1007
14
        NULL, HFILL }
1008
14
    },
1009
14
    { &hf_netlink_sock_diag_state,
1010
14
      { "State", "netlink-sock_diag.state",
1011
14
        FT_UINT8, BASE_DEC, VALS(socket_state_vals), 0x00,
1012
14
        NULL, HFILL }
1013
14
    },
1014
14
    { &hf_netlink_sock_diag_inode,
1015
14
      { "Inode", "netlink-sock_diag.inode",
1016
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1017
14
        NULL, HFILL }
1018
14
    },
1019
14
    { &hf_netlink_sock_diag_rqueue,
1020
14
      { "Recv Queue", "netlink-sock_diag.recv_queue",
1021
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1022
14
        NULL, HFILL }
1023
14
    },
1024
14
    { &hf_netlink_sock_diag_wqueue,
1025
14
      { "Send Queue", "netlink-sock_diag.send_queue",
1026
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1027
14
        NULL, HFILL }
1028
14
    },
1029
14
    { &hf_netlink_sock_diag_rmem_alloc,
1030
14
      { "Read allocation", "netlink-sock_diag.rmem_alloc",
1031
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1032
14
        NULL, HFILL }
1033
14
    },
1034
14
    { &hf_netlink_sock_diag_rcvbuf,
1035
14
      { "Recv buffer", "netlink-sock_diag.rcvbuf",
1036
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1037
14
        NULL, HFILL }
1038
14
    },
1039
14
    { &hf_netlink_sock_diag_wmem_alloc,
1040
14
      { "Write allocation", "netlink-sock_diag.wmem_alloc",
1041
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1042
14
        NULL, HFILL }
1043
14
    },
1044
14
    { &hf_netlink_sock_diag_sndbuf,
1045
14
      { "Send buffer", "netlink-sock_diag.sndbuf",
1046
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1047
14
        NULL, HFILL }
1048
14
    },
1049
14
    { &hf_netlink_sock_diag_fwd_alloc,
1050
14
      { "Forward allocation", "netlink-sock_diag.fwd_alloc",
1051
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1052
14
        NULL, HFILL }
1053
14
    },
1054
14
    { &hf_netlink_sock_diag_wmem_queued,
1055
14
      { "Write allocation queued", "netlink-sock_diag.wmem_queued",
1056
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1057
14
        NULL, HFILL }
1058
14
    },
1059
14
    { &hf_netlink_sock_diag_cookie,
1060
14
      { "Cookie", "netlink-sock_diag.cookie",
1061
14
        FT_UINT64, BASE_HEX, NULL, 0x00,
1062
14
        NULL, HFILL }
1063
14
    },
1064
14
    { &hf_netlink_sock_diag_shutdown,
1065
14
      { "Shutdown flag", "netlink-sock_diag.shutdown",
1066
14
        FT_UINT8, BASE_HEX, VALS(netlink_sock_diag_shutdown_flags_vals), 0x00,
1067
14
        NULL, HFILL }
1068
14
    },
1069
14
    { &hf_netlink_sock_diag_unix_attr,
1070
14
      { "Type", "netlink-sock_diag.unix_attr",
1071
14
        FT_UINT16, BASE_DEC, VALS(netlink_sock_diag_unix_attr_vals), NLA_TYPE_MASK,
1072
14
        NULL, HFILL }
1073
14
    },
1074
14
    { &hf_netlink_sock_diag_unix_name,
1075
14
      { "Name", "netlink-sock_diag.unix_name",
1076
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
1077
14
        NULL, HFILL }
1078
14
    },
1079
14
    { &hf_netlink_sock_diag_unix_peer_inode,
1080
14
      { "Peer inode", "netlink-sock_diag.unix_peer_inode",
1081
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1082
14
        NULL, HFILL }
1083
14
    },
1084
14
    { &hf_netlink_sock_diag_unix_show,
1085
14
      { "Show", "netlink-sock_diag.unix_show",
1086
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1087
14
        NULL, HFILL }
1088
14
    },
1089
14
    { &hf_netlink_sock_diag_unix_show_name,
1090
14
      { "Name", "netlink-sock_diag.unix_show.name",
1091
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_UDIAG_SHOW_NAME,
1092
14
        NULL, HFILL }
1093
14
    },
1094
14
    { &hf_netlink_sock_diag_unix_show_vfs,
1095
14
      { "VFS inode info", "netlink-sock_diag.unix_show.vfs",
1096
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_UDIAG_SHOW_VFS,
1097
14
        NULL, HFILL }
1098
14
    },
1099
14
    { &hf_netlink_sock_diag_unix_show_peer,
1100
14
      { "Peer socket info", "netlink-sock_diag.unix_show.peer",
1101
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_UDIAG_SHOW_PEER,
1102
14
        NULL, HFILL }
1103
14
    },
1104
14
    { &hf_netlink_sock_diag_unix_show_icons,
1105
14
      { "Pending connections", "netlink-sock_diag.unix_show.icons",
1106
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_UDIAG_SHOW_ICONS,
1107
14
        NULL, HFILL }
1108
14
    },
1109
14
    { &hf_netlink_sock_diag_unix_show_rqlen,
1110
14
      { "skb receive queue len", "netlink-sock_diag.unix_show.rqlen",
1111
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_UDIAG_SHOW_RQLEN,
1112
14
        NULL, HFILL }
1113
14
    },
1114
14
    { &hf_netlink_sock_diag_unix_show_meminfo,
1115
14
      { "Memory info of a socket", "netlink-sock_diag.unix_show.meminfo",
1116
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_UDIAG_SHOW_MEMINFO,
1117
14
        NULL, HFILL }
1118
14
    },
1119
14
    { &hf_netlink_sock_diag_inet_attr,
1120
14
      { "Type", "netlink-sock_diag.inet_attr",
1121
14
        FT_UINT16, BASE_DEC, VALS(netlink_sock_diag_inet_attr_vals), NLA_TYPE_MASK,
1122
14
        NULL, HFILL }
1123
14
    },
1124
14
    { &hf_netlink_sock_diag_inet_sport,
1125
14
      { "Source port", "netlink-sock_diag.inet_sport",
1126
14
        FT_UINT16, BASE_DEC, NULL, 0x00,
1127
14
        NULL, HFILL }
1128
14
    },
1129
14
    { &hf_netlink_sock_diag_inet_dport,
1130
14
      { "Dest port", "netlink-sock_diag.inet_dport",
1131
14
        FT_UINT16, BASE_DEC, NULL, 0x00,
1132
14
        NULL, HFILL }
1133
14
    },
1134
14
    { &hf_netlink_sock_diag_inet_src_ip4,
1135
14
      { "Source IP", "netlink-sock_diag.inet_src_ip4",
1136
14
        FT_IPv4, BASE_NONE, NULL, 0x00,
1137
14
        NULL, HFILL }
1138
14
    },
1139
14
    { &hf_netlink_sock_diag_inet_dst_ip4,
1140
14
      { "Dest IP", "netlink-sock_diag.inet_dest_ip4",
1141
14
        FT_IPv4, BASE_NONE, NULL, 0x00,
1142
14
        NULL, HFILL }
1143
14
    },
1144
14
    { &hf_netlink_sock_diag_inet_src_ip6,
1145
14
      { "Source IP", "netlink-sock_diag.inet_src_ip6",
1146
14
        FT_IPv6, BASE_NONE, NULL, 0x00,
1147
14
        NULL, HFILL }
1148
14
    },
1149
14
    { &hf_netlink_sock_diag_inet_dst_ip6,
1150
14
      { "Dest IP", "netlink-sock_diag.inet_dest_ip6",
1151
14
        FT_IPv6, BASE_NONE, NULL, 0x00,
1152
14
        NULL, HFILL }
1153
14
    },
1154
14
    { &hf_netlink_sock_diag_inet_interface,
1155
14
      { "Interface", "netlink-sock_diag.inet_interface",
1156
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1157
14
        NULL, HFILL }
1158
14
    },
1159
14
    { &hf_netlink_sock_diag_inet_proto,
1160
14
      { "Protocol", "netlink-sock_diag.inet_protocol",
1161
14
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0x00,
1162
14
        NULL, HFILL }
1163
14
    },
1164
14
    { &hf_netlink_sock_diag_inet_extended,
1165
14
      { "Requested info", "netlink-sock_diag.inet_extended",
1166
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1167
14
        NULL, HFILL }
1168
14
    },
1169
14
    { &hf_netlink_sock_diag_inet_padding,
1170
14
      { "v2 Padding or v1 info", "netlink-sock_diag.inet_padding",
1171
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1172
14
        NULL, HFILL }
1173
14
    },
1174
14
    { &hf_netlink_sock_diag_inet_states,
1175
14
      { "State filter", "netlink-sock_diag.inet_states",
1176
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1177
14
        NULL, HFILL }
1178
14
    },
1179
14
    { &hf_netlink_sock_diag_netlink_attr,
1180
14
      { "Type", "netlink-sock_diag.netlink_attr",
1181
14
        FT_UINT16, BASE_DEC, VALS(netlink_sock_diag_netlink_vals), NLA_TYPE_MASK,
1182
14
        NULL, HFILL }
1183
14
    },
1184
14
    { &hf_netlink_sock_diag_netlink_proto,
1185
14
      { "Protocol", "netlink-sock_diag.netlink_protocol",
1186
14
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &netlink_family_vals_ext, 0x00,
1187
14
        NULL, HFILL }
1188
14
    },
1189
14
    { &hf_netlink_sock_diag_netlink_port_id,
1190
14
      { "Port ID", "netlink-sock_diag.netlink_portid",
1191
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1192
14
        NULL, HFILL }
1193
14
    },
1194
14
    { &hf_netlink_sock_diag_netlink_dst_port_id,
1195
14
      { "Dest Port ID", "netlink-sock_diag.netlink_dst_portid",
1196
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1197
14
        NULL, HFILL }
1198
14
    },
1199
14
    { &hf_netlink_sock_diag_netlink_show,
1200
14
      { "Show", "netlink-sock_diag.netlink_show",
1201
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1202
14
        NULL, HFILL }
1203
14
    },
1204
14
    { &hf_netlink_sock_diag_netlink_show_meminfo,
1205
14
      { "Memory info of a socket", "netlink-sock_diag.netlink_show.meminfo",
1206
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_NDIAG_SHOW_MEMINFO,
1207
14
        NULL, HFILL }
1208
14
    },
1209
14
    { &hf_netlink_sock_diag_netlink_show_groups,
1210
14
      { "Groups of a netlink socket", "netlink-sock_diag.netlink_show.groups",
1211
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_NDIAG_SHOW_GROUPS,
1212
14
        NULL, HFILL }
1213
14
    },
1214
14
    { &hf_netlink_sock_diag_netlink_show_ring_cfg,
1215
14
      { "Ring configuration", "netlink-sock_diag.netlink_show.ring_cfg",
1216
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_NDIAG_SHOW_RING_CFG,
1217
14
        NULL, HFILL }
1218
14
    },
1219
14
    { &hf_netlink_sock_diag_packet_attr,
1220
14
      { "Type", "netlink-sock_diag.netlink_attr",
1221
14
        FT_UINT16, BASE_DEC, VALS(netlink_sock_diag_packet_vals), NLA_TYPE_MASK,
1222
14
        NULL, HFILL }
1223
14
    },
1224
14
    { &hf_netlink_sock_diag_packet_proto,
1225
14
      { "Protocol", "netlink-sock_diag.packet_protocol",
1226
14
        FT_UINT16, BASE_HEX, VALS(etype_vals) /* XXX + Linux specific */, 0x00,
1227
14
        NULL, HFILL }
1228
14
    },
1229
14
    { &hf_netlink_sock_diag_packet_show,
1230
14
      { "Show", "netlink-sock_diag.packet_show",
1231
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1232
14
        NULL, HFILL }
1233
14
    },
1234
14
    { &hf_netlink_sock_diag_packet_show_info,
1235
14
      { "Basic packet_sk information", "netlink-sock_diag.packet_show.info",
1236
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_PACKET_SHOW_INFO,
1237
14
        NULL, HFILL }
1238
14
    },
1239
14
    { &hf_netlink_sock_diag_packet_show_mclist,
1240
14
      { "Set of packet_diag_mclist-s", "netlink-sock_diag.packet_show.mclist",
1241
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_PACKET_SHOW_MCLIST,
1242
14
        NULL, HFILL }
1243
14
    },
1244
14
    { &hf_netlink_sock_diag_packet_show_ring_cfg,
1245
14
      { "Rings configuration parameters", "netlink-sock_diag.packet_show.ring_cfg",
1246
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_PACKET_SHOW_RING_CFG,
1247
14
        NULL, HFILL }
1248
14
    },
1249
14
    { &hf_netlink_sock_diag_packet_show_fanout,
1250
14
      { "Fanout", "netlink-sock_diag.packet_show.fanout",
1251
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_PACKET_SHOW_FANOUT,
1252
14
        NULL, HFILL }
1253
14
    },
1254
14
    { &hf_netlink_sock_diag_packet_show_meminfo,
1255
14
      { "memory info", "netlink-sock_diag.packet_show.meminfo",
1256
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_PACKET_SHOW_MEMINFO,
1257
14
        NULL, HFILL }
1258
14
    },
1259
14
    { &hf_netlink_sock_diag_packet_show_filter,
1260
14
      { "Filter", "netlink-sock_diag.packet_show.filter",
1261
14
        FT_BOOLEAN, 32, TFS(&_tfs_show_do_not_show), WS_PACKET_SHOW_FILTER,
1262
14
        NULL, HFILL }
1263
14
    },
1264
14
    { &hf_netlink_sock_diag_nltype,
1265
14
      { "Message type", "netlink-sock_diag.nltype",
1266
14
        FT_UINT16, BASE_DEC, VALS(netlink_sock_diag_type_vals), 0x00,
1267
14
        NULL, HFILL }
1268
14
    },
1269
14
  };
1270
1271
14
  static int *ett[] = {
1272
14
    &ett_netlink_sock_diag,
1273
14
    &ett_netlink_sock_diag_show,
1274
14
    &ett_netlink_sock_diag_attr
1275
14
  };
1276
1277
14
  proto_netlink_sock_diag = proto_register_protocol("Linux netlink sock diag protocol", "sock_diag", "netlink-sock_diag" );
1278
14
  proto_register_field_array(proto_netlink_sock_diag, hf, array_length(hf));
1279
14
  proto_register_subtree_array(ett, array_length(ett));
1280
1281
14
  netlink_sock_diag_handle = register_dissector("netlink-sock_diag", dissect_netlink_sock_diag, proto_netlink_sock_diag);
1282
14
}
1283
1284
void
1285
proto_reg_handoff_netlink_sock_diag(void)
1286
14
{
1287
14
  dissector_add_uint("netlink.protocol", WS_NETLINK_SOCK_DIAG, netlink_sock_diag_handle);
1288
14
}
1289
1290
/*
1291
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1292
 *
1293
 * Local variables:
1294
 * c-basic-offset: 8
1295
 * tab-width: 8
1296
 * indent-tabs-mode: t
1297
 * End:
1298
 *
1299
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1300
 * :indentSize=8:tabSize=8:noTabs=false:
1301
 */