Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-rpcap.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-rpcap.c
2
 *
3
 * Routines for RPCAP message formats.
4
 *
5
 * Copyright 2008, Stig Bjorlykke <stig@bjorlykke.org>, Thales Norway AS
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
#include "config.h"
15
16
#include <epan/packet.h>
17
#include <epan/aftypes.h>
18
#include <epan/prefs.h>
19
#include <epan/to_str.h>
20
#include <epan/expert.h>
21
#include <epan/exceptions.h>
22
#include <epan/show_exception.h>
23
#include <epan/tfs.h>
24
#include <wsutil/array.h>
25
#include <wsutil/str_util.h>
26
27
#include "packet-frame.h"
28
#include "packet-pcap_pktdata.h"
29
#include "packet-tcp.h"
30
31
14
#define PNAME  "Remote Packet Capture"
32
19
#define PSNAME "RPCAP"
33
42
#define PFNAME "rpcap"
34
35
48
#define RPCAP_MSG_ERROR               0x01
36
28
#define RPCAP_MSG_FINDALLIF_REQ       0x02
37
15
#define RPCAP_MSG_OPEN_REQ            0x03
38
18
#define RPCAP_MSG_STARTCAP_REQ        0x04
39
24
#define RPCAP_MSG_UPDATEFILTER_REQ    0x05
40
4
#define RPCAP_MSG_CLOSE               0x06
41
2
#define RPCAP_MSG_PACKET              0x07
42
52
#define RPCAP_MSG_AUTH_REQ            0x08
43
3
#define RPCAP_MSG_STATS_REQ           0x09
44
12
#define RPCAP_MSG_ENDCAP_REQ          0x0A
45
6
#define RPCAP_MSG_SETSAMPLING_REQ     0x0B
46
47
25
#define RPCAP_MSG_FINDALLIF_REPLY     (0x80+RPCAP_MSG_FINDALLIF_REQ)
48
0
#define RPCAP_MSG_OPEN_REPLY          (0x80+RPCAP_MSG_OPEN_REQ)
49
0
#define RPCAP_MSG_STARTCAP_REPLY      (0x80+RPCAP_MSG_STARTCAP_REQ)
50
3
#define RPCAP_MSG_UPDATEFILTER_REPLY  (0x80+RPCAP_MSG_UPDATEFILTER_REQ)
51
26
#define RPCAP_MSG_AUTH_REPLY          (0x80+RPCAP_MSG_AUTH_REQ)
52
0
#define RPCAP_MSG_STATS_REPLY         (0x80+RPCAP_MSG_STATS_REQ)
53
6
#define RPCAP_MSG_ENDCAP_REPLY        (0x80+RPCAP_MSG_ENDCAP_REQ)
54
5
#define RPCAP_MSG_SETSAMPLING_REPLY   (0x80+RPCAP_MSG_SETSAMPLING_REQ)
55
56
#define RPCAP_ERR_NETW            1
57
#define RPCAP_ERR_INITTIMEOUT     2
58
#define RPCAP_ERR_AUTH            3
59
#define RPCAP_ERR_FINDALLIF       4
60
#define RPCAP_ERR_NOREMOTEIF      5
61
#define RPCAP_ERR_OPEN            6
62
#define RPCAP_ERR_UPDATEFILTER    7
63
#define RPCAP_ERR_GETSTATS        8
64
#define RPCAP_ERR_READEX          9
65
#define RPCAP_ERR_HOSTNOAUTH      10
66
#define RPCAP_ERR_REMOTEACCEPT    11
67
#define RPCAP_ERR_STARTCAPTURE    12
68
#define RPCAP_ERR_ENDCAPTURE      13
69
#define RPCAP_ERR_RUNTIMETIMEOUT  14
70
#define RPCAP_ERR_SETSAMPLING     15
71
#define RPCAP_ERR_WRONGMSG        16
72
#define RPCAP_ERR_WRONGVER        17
73
74
0
#define RPCAP_SAMP_NOSAMP            0
75
0
#define RPCAP_SAMP_1_EVERY_N         1
76
0
#define RPCAP_SAMP_FIRST_AFTER_N_MS  2
77
78
0
#define RPCAP_RMTAUTH_NULL  0
79
0
#define RPCAP_RMTAUTH_PWD   1
80
81
14
#define FLAG_PROMISC     0x0001
82
14
#define FLAG_DGRAM       0x0002
83
14
#define FLAG_SERVEROPEN  0x0004
84
14
#define FLAG_INBOUND     0x0008
85
14
#define FLAG_OUTBOUND    0x0010
86
87
void proto_register_rpcap (void);
88
void proto_reg_handoff_rpcap (void);
89
90
static int proto_rpcap;
91
92
static int hf_version;
93
static int hf_type;
94
static int hf_value;
95
static int hf_plen;
96
97
static int hf_error;
98
static int hf_error_value;
99
100
static int hf_packet;
101
static int hf_timestamp;
102
static int hf_caplen;
103
static int hf_len;
104
static int hf_npkt;
105
106
static int hf_auth_request;
107
static int hf_auth_type;
108
static int hf_auth_slen1;
109
static int hf_auth_slen2;
110
static int hf_auth_username;
111
static int hf_auth_password;
112
113
static int hf_auth_reply;
114
static int hf_auth_minvers;
115
static int hf_auth_maxvers;
116
117
static int hf_open_request;
118
119
static int hf_open_reply;
120
static int hf_linktype;
121
static int hf_tzoff;
122
123
static int hf_startcap_request;
124
static int hf_snaplen;
125
static int hf_read_timeout;
126
static int hf_flags;
127
static int hf_flags_promisc;
128
static int hf_flags_dgram;
129
static int hf_flags_serveropen;
130
static int hf_flags_inbound;
131
static int hf_flags_outbound;
132
static int hf_client_port;
133
static int hf_startcap_reply;
134
static int hf_bufsize;
135
static int hf_server_port;
136
static int hf_dummy;
137
138
static int hf_filter;
139
static int hf_filtertype;
140
static int hf_nitems;
141
142
static int hf_filterbpf_insn;
143
static int hf_code;
144
static int hf_code_class;
145
static int hf_code_fields;
146
static int hf_code_ld_size;
147
static int hf_code_ld_mode;
148
static int hf_code_alu_op;
149
static int hf_code_jmp_op;
150
static int hf_code_src;
151
static int hf_code_rval;
152
static int hf_code_misc_op;
153
static int hf_jt;
154
static int hf_jf;
155
static int hf_instr_value;
156
157
static int hf_stats_reply;
158
static int hf_ifrecv;
159
static int hf_ifdrop;
160
static int hf_krnldrop;
161
static int hf_srvcapt;
162
163
static int hf_findalldevs_reply;
164
static int hf_findalldevs_if;
165
static int hf_namelen;
166
static int hf_desclen;
167
static int hf_if_flags;
168
static int hf_naddr;
169
static int hf_if_name;
170
static int hf_if_desc;
171
172
static int hf_findalldevs_ifaddr;
173
static int hf_if_addr;
174
static int hf_if_netmask;
175
static int hf_if_broadaddr;
176
static int hf_if_dstaddr;
177
static int hf_if_af;
178
static int hf_if_port;
179
static int hf_if_ipv4;
180
static int hf_if_flowinfo;
181
static int hf_if_ipv6;
182
static int hf_if_scopeid;
183
static int hf_if_padding;
184
static int hf_if_unknown;
185
186
static int hf_sampling_request;
187
static int hf_sampling_method;
188
static int hf_sampling_dummy1;
189
static int hf_sampling_dummy2;
190
static int hf_sampling_value;
191
192
static int ett_rpcap;
193
static int ett_error;
194
static int ett_packet;
195
static int ett_auth_request;
196
static int ett_auth_reply;
197
static int ett_open_reply;
198
static int ett_startcap_request;
199
static int ett_startcap_reply;
200
static int ett_startcap_flags;
201
static int ett_filter;
202
static int ett_filterbpf_insn;
203
static int ett_filterbpf_insn_code;
204
static int ett_stats_reply;
205
static int ett_findalldevs_reply;
206
static int ett_findalldevs_if;
207
static int ett_findalldevs_ifaddr;
208
static int ett_ifaddr;
209
static int ett_sampling_request;
210
211
static expert_field ei_error;
212
static expert_field ei_if_unknown;
213
static expert_field ei_no_more_data;
214
static expert_field ei_caplen_too_big;
215
216
static dissector_handle_t pcap_pktdata_handle;
217
static dissector_handle_t rpcap_tcp_handle;
218
219
/* User definable values */
220
static bool rpcap_desegment = true;
221
static bool decode_content = true;
222
static int global_linktype = -1;
223
224
/* Global variables */
225
static int linktype = -1;
226
static bool info_added;
227
228
static const value_string message_type[] = {
229
  { RPCAP_MSG_ERROR,              "Error"                       },
230
  { RPCAP_MSG_FINDALLIF_REQ,      "Find all interfaces request" },
231
  { RPCAP_MSG_OPEN_REQ,           "Open request"                },
232
  { RPCAP_MSG_STARTCAP_REQ,       "Start capture request"       },
233
  { RPCAP_MSG_UPDATEFILTER_REQ,   "Update filter request"       },
234
  { RPCAP_MSG_CLOSE,              "Close"                       },
235
  { RPCAP_MSG_PACKET,             "Packet"                      },
236
  { RPCAP_MSG_AUTH_REQ,           "Authentication request"      },
237
  { RPCAP_MSG_STATS_REQ,          "Statistics request"          },
238
  { RPCAP_MSG_ENDCAP_REQ,         "End capture request"         },
239
  { RPCAP_MSG_SETSAMPLING_REQ,    "Set sampling request"        },
240
  { RPCAP_MSG_FINDALLIF_REPLY,    "Find all interfaces reply"   },
241
  { RPCAP_MSG_OPEN_REPLY,         "Open reply"                  },
242
  { RPCAP_MSG_STARTCAP_REPLY,     "Start capture reply"         },
243
  { RPCAP_MSG_UPDATEFILTER_REPLY, "Update filter reply"         },
244
  { RPCAP_MSG_AUTH_REPLY,         "Authentication reply"        },
245
  { RPCAP_MSG_STATS_REPLY,        "Statistics reply"            },
246
  { RPCAP_MSG_ENDCAP_REPLY,       "End capture reply"           },
247
  { RPCAP_MSG_SETSAMPLING_REPLY,  "Set sampling reply"          },
248
  { 0,   NULL }
249
};
250
251
static const value_string error_codes[] = {
252
  { RPCAP_ERR_NETW,            "Network error"                        },
253
  { RPCAP_ERR_INITTIMEOUT,     "Initial timeout has expired"          },
254
  { RPCAP_ERR_AUTH,            "Authentication error"                 },
255
  { RPCAP_ERR_FINDALLIF,       "Generic findalldevs error"            },
256
  { RPCAP_ERR_NOREMOTEIF,      "No remote interfaces"                 },
257
  { RPCAP_ERR_OPEN,            "Generic pcap_open error"              },
258
  { RPCAP_ERR_UPDATEFILTER,    "Generic updatefilter error"           },
259
  { RPCAP_ERR_GETSTATS,        "Generic pcap_stats error"             },
260
  { RPCAP_ERR_READEX,          "Generic pcap_next_ex error"           },
261
  { RPCAP_ERR_HOSTNOAUTH,      "The host is not authorized"           },
262
  { RPCAP_ERR_REMOTEACCEPT,    "Generic pcap_remoteaccept error"      },
263
  { RPCAP_ERR_STARTCAPTURE,    "Generic pcap_startcapture error"      },
264
  { RPCAP_ERR_ENDCAPTURE,      "Generic pcap_endcapture error"        },
265
  { RPCAP_ERR_RUNTIMETIMEOUT,  "Runtime timeout has expired"          },
266
  { RPCAP_ERR_SETSAMPLING,     "Error in setting sampling parameters" },
267
  { RPCAP_ERR_WRONGMSG,        "Unrecognized message"                 },
268
  { RPCAP_ERR_WRONGVER,        "Incompatible version"                 },
269
  { 0,   NULL }
270
};
271
272
static const value_string sampling_method[] = {
273
  { RPCAP_SAMP_NOSAMP,            "No sampling"      },
274
  { RPCAP_SAMP_1_EVERY_N,         "1 every N"        },
275
  { RPCAP_SAMP_FIRST_AFTER_N_MS,  "First after N ms" },
276
  { 0,   NULL }
277
};
278
279
static const value_string auth_type[] = {
280
  { RPCAP_RMTAUTH_NULL, "None"     },
281
  { RPCAP_RMTAUTH_PWD,  "Password" },
282
  { 0,   NULL }
283
};
284
285
static const value_string bpf_class[] = {
286
  { 0x00, "ld"   },
287
  { 0x01, "ldx"  },
288
  { 0x02, "st"   },
289
  { 0x03, "stx"  },
290
  { 0x04, "alu"  },
291
  { 0x05, "jmp"  },
292
  { 0x06, "ret"  },
293
  { 0x07, "misc" },
294
  { 0, NULL }
295
};
296
297
static const value_string bpf_size[] = {
298
  { 0x00, "w" },
299
  { 0x01, "h" },
300
  { 0x02, "b" },
301
  { 0, NULL }
302
};
303
304
static const value_string bpf_mode[] = {
305
  { 0x00, "imm" },
306
  { 0x01, "abs" },
307
  { 0x02, "ind" },
308
  { 0x03, "mem" },
309
  { 0x04, "len" },
310
  { 0x05, "msh" },
311
  { 0, NULL }
312
};
313
314
static const value_string bpf_alu_op[] = {
315
  { 0x00, "add" },
316
  { 0x01, "sub" },
317
  { 0x02, "mul" },
318
  { 0x03, "div" },
319
  { 0x04, "or"  },
320
  { 0x05, "and" },
321
  { 0x06, "lsh" },
322
  { 0x07, "rsh" },
323
  { 0x08, "neg" },
324
  { 0, NULL }
325
};
326
327
static const value_string bpf_jmp_op[] = {
328
  { 0x00, "ja"   },
329
  { 0x01, "jeq"  },
330
  { 0x02, "jgt"  },
331
  { 0x03, "jge"  },
332
  { 0x04, "jset" },
333
  { 0, NULL }
334
};
335
336
static const value_string bpf_src[] = {
337
  { 0x00, "k" },
338
  { 0x01, "x" },
339
  { 0, NULL }
340
};
341
342
static const value_string bpf_rval[] = {
343
  { 0x00, "k" },
344
  { 0x01, "x" },
345
  { 0x02, "a" },
346
  { 0, NULL }
347
};
348
349
static const value_string bpf_misc_op[] = {
350
  { 0x00, "tax" },
351
  { 0x10, "txa" },
352
  { 0, NULL }
353
};
354
355
356
static void rpcap_frame_end (void)
357
0
{
358
0
  info_added = false;
359
0
}
360
361
362
static void
363
dissect_rpcap_error (tvbuff_t *tvb, packet_info *pinfo,
364
                     proto_tree *parent_tree, int offset)
365
3
{
366
3
  proto_item *ti;
367
3
  int len;
368
3
  char *str;
369
370
3
  len = tvb_reported_length_remaining (tvb, offset);
371
3
  if (len <= 0)
372
0
    return;
373
374
3
  ti = proto_tree_add_item_ret_display_string(parent_tree, hf_error, tvb, offset, len, ENC_ASCII, pinfo->pool, &str);
375
3
  expert_add_info_format(pinfo, ti, &ei_error, "Error: %s", str);
376
3
  col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", str);
377
3
}
378
379
/*
380
 * There's some painful history with this part of a findalldevs reply.
381
 *
382
 * Older RPCAPDs sent the addresses over the wire in the OS's native
383
 * structure format.  For most OSes, this looks like the over-the-wire
384
 * format, but might have a different value for AF_INET6 than the value
385
 * on the machine receiving the reply.  For OSes with the newer BSD-style
386
 * sockaddr structures, this has, instead of a 2-byte address family,
387
 * a 1-byte structure length followed by a 1-byte address family.  The
388
 * RPCAPD code would put the address family in network byte order before
389
 * sending it; that would set it to 0 on a little-endian machine, as
390
 * htons() of any value between 1 and 255 would result in a value > 255,
391
 * with its lower 8 bits zero, so putting that back into a 1-byte field
392
 * would set it to 0.
393
 *
394
 * Therefore, for older RPCAPDs running on an OS with newer BSD-style
395
 * sockaddr structures, the family field, if treated as a big-endian
396
 * (network byte order) 16-bit field, would be:
397
 *
398
 *  (length << 8) | family if sent by a big-endian machine
399
 *  (length << 8) if sent by a little-endian machine
400
 *
401
 * For current RPCAPDs, and for older RPCAPDs running on an OS with
402
 * older BSD-style sockaddr structures, the family field, if treated
403
 * as a big-endian 16-bit field, would just contain the family.
404
 *
405
 * (An additional bit of pain was that the structure was sent over the
406
 * wire as a network-byte-order struct sockaddr_storage, which does
407
 * *not* have the same size on all platforms.  On most platforms, the
408
 * structure is 128 bytes long; on Solaris, however, it's 256 bytes
409
 * long.  Neither the rpcap client code in libpcap, nor we, try to
410
 * detect Solaris addresses and deal with them.)
411
 *
412
 * The current rpcapd serializes the socket addresses as 128-byte
413
 * structures, containing:
414
 *
415
 *  a 2-octet address family value, in network byte order;
416
 *
417
 *  a 4-octet IPv4 address, if the address family value is 2
418
 *  (the AF_INET value on all supported platforms);
419
 *
420
 *  a 16-octet IPv6 address, if the address family value is
421
 *  23 (the Windows AF_INET6 value, chosen because Windows
422
 *  was, before rpcap was changed to standardize the format,
423
 *  the only platform for which precompiled binaries for
424
 *  rpcapd were generally available);
425
 *
426
 *  padding up to 128 bytes.
427
 *
428
 * The rpcap client code, and we, check for those address family values,
429
 * as well as other values that might have been produced by the old
430
 * code on various platforms.
431
 */
432
433
/*
434
 * Possible IPv4 family values other than the designated over-the-wire value,
435
 * which is 2 (because everybody uses 2 for AF_INET4).
436
 */
437
0
#define SOCKADDR_IN_LEN   16  /* length of struct sockaddr_in */
438
0
#define NEW_BSD_AF_INET_BE  ((SOCKADDR_IN_LEN << 8) | BSD_AF_INET)
439
0
#define NEW_BSD_AF_INET_LE  (SOCKADDR_IN_LEN << 8)
440
441
/*
442
 * Possible IPv6 family values other than the designated over-the-wire value,
443
 * which is 23 (because that's what Windows uses, and most RPCAP servers
444
 * out there are probably running Windows, as WinPcap includes the server
445
 * but few if any UN*Xes build and ship it).  Some are defined in
446
 * <epan/aftypes.h>.
447
 *
448
 * The new BSD sockaddr structure format was in place before 4.4-Lite, so
449
 * all the free-software BSDs use it.
450
 */
451
0
#define SOCKADDR_IN6_LEN  28  /* length of struct sockaddr_in6 */
452
0
#define NEW_BSD_AF_INET6_BSD_BE   ((SOCKADDR_IN6_LEN << 8) | BSD_AF_INET6_BSD)  /* NetBSD, OpenBSD, BSD/OS */
453
0
#define NEW_BSD_AF_INET6_FREEBSD_BE ((SOCKADDR_IN6_LEN << 8) | BSD_AF_INET6_FREEBSD)  /* FreeBSD, DragonFly BSD */
454
0
#define NEW_BSD_AF_INET6_DARWIN_BE  ((SOCKADDR_IN6_LEN << 8) | BSD_AF_INET6_DARWIN)  /* macOS, iOS, anything else Darwin-based */
455
0
#define NEW_BSD_AF_INET6_LE   (SOCKADDR_IN6_LEN << 8)
456
0
#define HPUX_AF_INET6     22
457
0
#define AIX_AF_INET6      24
458
459
static const value_string address_family[] = {
460
  { COMMON_AF_UNSPEC,            "AF_UNSPEC" },
461
  { COMMON_AF_INET,              "AF_INET"   },
462
  { NEW_BSD_AF_INET_BE,          "AF_INET (old server code on big-endian 4.4-Lite-based OS)" },
463
  { NEW_BSD_AF_INET_LE,          "AF_INET (old server code on little-endian 4.4-Lite-based OS)" },
464
  { WINSOCK_AF_INET6,            "AF_INET6"  },
465
  { NEW_BSD_AF_INET6_BSD_BE,     "AF_INET6 (old server code on big-endian NetBSD, OpenBSD, BSD/OS)"  },
466
  { NEW_BSD_AF_INET6_FREEBSD_BE, "AF_INET6 (old server code on big-endian FreeBSD)"  },
467
  { NEW_BSD_AF_INET6_DARWIN_BE,  "AF_INET6 (old server code on big-endian Mac OS X)"  },
468
  { NEW_BSD_AF_INET6_LE,         "AF_INET6 (old server code on little-endian 4.4-Lite-based OS)" },
469
  { LINUX_AF_INET6,              "AF_INET6 (old server code on Linux)"  },
470
  { HPUX_AF_INET6,               "AF_INET6 (old server code on HP-UX)"  },
471
  { AIX_AF_INET6,                "AF_INET6 (old server code on AIX)"  },
472
  { SOLARIS_AF_INET6,            "AF_INET6 (old server code on Solaris)"  },
473
  { 0,   NULL }
474
};
475
476
static int
477
dissect_rpcap_ifaddr (tvbuff_t *tvb, packet_info *pinfo,
478
                      proto_tree *parent_tree, int offset, int hf_id,
479
                      proto_item *parent_item)
480
0
{
481
0
  proto_tree *tree;
482
0
  proto_item *ti;
483
0
  uint16_t af;
484
0
  ws_in4_addr ipv4;
485
0
  ws_in6_addr ipv6;
486
0
  char ipaddr[MAX_ADDR_STR_LEN];
487
488
0
  ti = proto_tree_add_item (parent_tree, hf_id, tvb, offset, 128, ENC_BIG_ENDIAN);
489
0
  tree = proto_item_add_subtree (ti, ett_ifaddr);
490
491
0
  af = tvb_get_ntohs (tvb, offset);
492
0
  proto_tree_add_item (tree, hf_if_af, tvb, offset, 2, ENC_BIG_ENDIAN);
493
0
  offset += 2;
494
495
0
  switch (af) {
496
497
0
  case COMMON_AF_INET:
498
0
  case NEW_BSD_AF_INET_BE:
499
0
  case NEW_BSD_AF_INET_LE:
500
0
    proto_tree_add_item (tree, hf_if_port, tvb, offset, 2, ENC_BIG_ENDIAN);
501
0
    offset += 2;
502
503
0
    ipv4 = tvb_get_ipv4 (tvb, offset);
504
0
    ip_addr_to_str_buf(&ipv4, ipaddr, MAX_ADDR_STR_LEN);
505
0
    proto_item_append_text (ti, ": %s", ipaddr);
506
0
    if (parent_item) {
507
0
      proto_item_append_text (parent_item, ": %s", ipaddr);
508
0
    }
509
0
    proto_tree_add_item (tree, hf_if_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
510
0
    offset += 4;
511
512
0
    proto_tree_add_item (tree, hf_if_padding, tvb, offset, 120, ENC_NA);
513
0
    offset += 120;
514
0
    break;
515
516
0
  case WINSOCK_AF_INET6:
517
0
  case NEW_BSD_AF_INET6_BSD_BE:
518
0
  case NEW_BSD_AF_INET6_FREEBSD_BE:
519
0
  case NEW_BSD_AF_INET6_DARWIN_BE:
520
0
  case NEW_BSD_AF_INET6_LE:
521
0
  case LINUX_AF_INET6:
522
0
  case HPUX_AF_INET6:
523
0
  case AIX_AF_INET6:
524
0
  case SOLARIS_AF_INET6:
525
0
    proto_tree_add_item (tree, hf_if_port, tvb, offset, 2, ENC_BIG_ENDIAN);
526
0
    offset += 2;
527
528
0
    proto_tree_add_item (tree, hf_if_flowinfo, tvb, offset, 4, ENC_BIG_ENDIAN);
529
0
    offset += 4;
530
531
0
    tvb_get_ipv6 (tvb, offset, &ipv6);
532
0
    ip6_to_str_buf(&ipv6, ipaddr, MAX_ADDR_STR_LEN);
533
0
    proto_item_append_text (ti, ": %s", ipaddr);
534
0
    if (parent_item) {
535
0
      proto_item_append_text (parent_item, ": %s", ipaddr);
536
0
    }
537
0
    proto_tree_add_item (tree, hf_if_ipv6, tvb, offset, 16, ENC_NA);
538
0
    offset += 16;
539
540
0
    proto_tree_add_item (tree, hf_if_scopeid, tvb, offset, 4, ENC_BIG_ENDIAN);
541
0
    offset += 4;
542
543
0
    proto_tree_add_item (tree, hf_if_padding, tvb, offset, 108, ENC_NA);
544
0
    offset += 100;
545
0
    break;
546
547
0
  default:
548
0
    ti = proto_tree_add_item (tree, hf_if_unknown, tvb, offset, 126, ENC_NA);
549
0
    if (af != COMMON_AF_UNSPEC) {
550
0
      expert_add_info_format(pinfo, ti, &ei_if_unknown,
551
0
                             "Unknown address family: %d", af);
552
0
    }
553
0
    offset += 126;
554
0
    break;
555
0
  }
556
557
0
  return offset;
558
0
}
559
560
561
static int
562
dissect_rpcap_findalldevs_ifaddr (tvbuff_t *tvb, packet_info *pinfo _U_,
563
                                  proto_tree *parent_tree, int offset)
564
0
{
565
0
  proto_tree *tree;
566
0
  proto_item *ti;
567
0
  int boffset = offset;
568
569
0
  ti = proto_tree_add_item (parent_tree, hf_findalldevs_ifaddr, tvb, offset, -1, ENC_NA);
570
0
  tree = proto_item_add_subtree (ti, ett_findalldevs_ifaddr);
571
572
0
  offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_addr, ti);
573
0
  offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_netmask, NULL);
574
0
  offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_broadaddr, NULL);
575
0
  offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_dstaddr, NULL);
576
577
0
  proto_item_set_len (ti, offset - boffset);
578
579
0
  return offset;
580
0
}
581
582
583
static int
584
dissect_rpcap_findalldevs_if (tvbuff_t *tvb, packet_info *pinfo _U_,
585
                              proto_tree *parent_tree, int offset)
586
0
{
587
0
  proto_tree *tree;
588
0
  proto_item *ti;
589
0
  uint16_t namelen, desclen, naddr, i;
590
0
  int boffset = offset;
591
592
0
  ti = proto_tree_add_item (parent_tree, hf_findalldevs_if, tvb, offset, -1, ENC_NA);
593
0
  tree = proto_item_add_subtree (ti, ett_findalldevs_if);
594
595
0
  namelen = tvb_get_ntohs (tvb, offset);
596
0
  proto_tree_add_item (tree, hf_namelen, tvb, offset, 2, ENC_BIG_ENDIAN);
597
0
  offset += 2;
598
599
0
  desclen = tvb_get_ntohs (tvb, offset);
600
0
  proto_tree_add_item (tree, hf_desclen, tvb, offset, 2, ENC_BIG_ENDIAN);
601
0
  offset += 2;
602
603
0
  proto_tree_add_item (tree, hf_if_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
604
0
  offset += 4;
605
606
0
  naddr = tvb_get_ntohs (tvb, offset);
607
0
  proto_tree_add_item (tree, hf_naddr, tvb, offset, 2, ENC_BIG_ENDIAN);
608
0
  offset += 2;
609
610
0
  proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
611
0
  offset += 2;
612
613
0
  if (namelen) {
614
0
    const uint8_t* name;
615
0
    proto_tree_add_item_ret_string(tree, hf_if_name, tvb, offset, namelen, ENC_ASCII|ENC_NA, pinfo->pool, &name);
616
0
    proto_item_append_text (ti, ": %s", name);
617
0
    offset += namelen;
618
0
  }
619
620
0
  if (desclen) {
621
0
    proto_tree_add_item (tree, hf_if_desc, tvb, offset, desclen, ENC_ASCII);
622
0
    offset += desclen;
623
0
  }
624
625
0
  for (i = 0; i < naddr; i++) {
626
0
    offset = dissect_rpcap_findalldevs_ifaddr (tvb, pinfo, tree, offset);
627
0
    if (tvb_reported_length_remaining (tvb, offset) < 0) {
628
      /* No more data in packet */
629
0
      expert_add_info(pinfo, ti, &ei_no_more_data);
630
0
      break;
631
0
    }
632
0
  }
633
634
0
  proto_item_set_len (ti, offset - boffset);
635
636
0
  return offset;
637
0
}
638
639
640
static void
641
dissect_rpcap_findalldevs_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
642
                                 proto_tree *parent_tree, int offset, uint16_t no_devs)
643
0
{
644
0
  proto_tree *tree;
645
0
  proto_item *ti;
646
0
  uint16_t i;
647
648
0
  ti = proto_tree_add_item (parent_tree, hf_findalldevs_reply, tvb, offset, -1, ENC_NA);
649
0
  tree = proto_item_add_subtree (ti, ett_findalldevs_reply);
650
651
0
  for (i = 0; i < no_devs; i++) {
652
0
    offset = dissect_rpcap_findalldevs_if (tvb, pinfo, tree, offset);
653
0
    if (tvb_reported_length_remaining (tvb, offset) < 0) {
654
      /* No more data in packet */
655
0
      expert_add_info(pinfo, ti, &ei_no_more_data);
656
0
      break;
657
0
    }
658
0
  }
659
660
0
  proto_item_append_text (ti, ", %d item%s", no_devs, plurality (no_devs, "", "s"));
661
0
}
662
663
664
static int
665
dissect_rpcap_filterbpf_insn (tvbuff_t *tvb, packet_info *pinfo _U_,
666
                              proto_tree *parent_tree, int offset)
667
0
{
668
0
  proto_tree *tree, *code_tree;
669
0
  proto_item *ti, *code_ti;
670
0
  uint8_t inst_class;
671
672
0
  ti = proto_tree_add_item (parent_tree, hf_filterbpf_insn, tvb, offset, 8, ENC_NA);
673
0
  tree = proto_item_add_subtree (ti, ett_filterbpf_insn);
674
675
0
  code_ti = proto_tree_add_item (tree, hf_code, tvb, offset, 2, ENC_BIG_ENDIAN);
676
0
  code_tree = proto_item_add_subtree (code_ti, ett_filterbpf_insn_code);
677
0
  proto_tree_add_item (code_tree, hf_code_class, tvb, offset, 2, ENC_BIG_ENDIAN);
678
0
  inst_class = tvb_get_uint8 (tvb, offset + 1) & 0x07;
679
0
  proto_item_append_text (ti, ": %s", val_to_str_const (inst_class, bpf_class, ""));
680
0
  switch (inst_class) {
681
0
  case 0x00: /* ld */
682
0
  case 0x01: /* ldx */
683
0
    proto_tree_add_item (code_tree, hf_code_ld_size, tvb, offset, 2, ENC_BIG_ENDIAN);
684
0
    proto_tree_add_item (code_tree, hf_code_ld_mode, tvb, offset, 2, ENC_BIG_ENDIAN);
685
0
    break;
686
0
  case 0x04: /* alu */
687
0
    proto_tree_add_item (code_tree, hf_code_src, tvb, offset, 2, ENC_BIG_ENDIAN);
688
0
    proto_tree_add_item (code_tree, hf_code_alu_op, tvb, offset, 2, ENC_BIG_ENDIAN);
689
0
    break;
690
0
  case 0x05: /* jmp */
691
0
    proto_tree_add_item (code_tree, hf_code_src, tvb, offset, 2, ENC_BIG_ENDIAN);
692
0
    proto_tree_add_item (code_tree, hf_code_jmp_op, tvb, offset, 2, ENC_BIG_ENDIAN);
693
0
    break;
694
0
  case 0x06: /* ret */
695
0
    proto_tree_add_item (code_tree, hf_code_rval, tvb, offset, 2, ENC_BIG_ENDIAN);
696
0
    break;
697
0
  case 0x07: /* misc */
698
0
    proto_tree_add_item (code_tree, hf_code_misc_op, tvb, offset, 2, ENC_BIG_ENDIAN);
699
0
    break;
700
0
  default:
701
0
    proto_tree_add_item (code_tree, hf_code_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
702
0
    break;
703
0
  }
704
0
  offset += 2;
705
706
0
  proto_tree_add_item (tree, hf_jt, tvb, offset, 1, ENC_BIG_ENDIAN);
707
0
  offset += 1;
708
709
0
  proto_tree_add_item (tree, hf_jf, tvb, offset, 1, ENC_BIG_ENDIAN);
710
0
  offset += 1;
711
712
0
  proto_tree_add_item (tree, hf_instr_value, tvb, offset, 4, ENC_BIG_ENDIAN);
713
0
  offset += 4;
714
715
0
  return offset;
716
0
}
717
718
719
static void
720
dissect_rpcap_filter (tvbuff_t *tvb, packet_info *pinfo,
721
                      proto_tree *parent_tree, int offset)
722
0
{
723
0
  proto_tree *tree;
724
0
  proto_item *ti;
725
0
  uint32_t nitems, i;
726
727
0
  ti = proto_tree_add_item (parent_tree, hf_filter, tvb, offset, -1, ENC_NA);
728
0
  tree = proto_item_add_subtree (ti, ett_filter);
729
730
0
  proto_tree_add_item (tree, hf_filtertype, tvb, offset, 2, ENC_BIG_ENDIAN);
731
0
  offset += 2;
732
733
0
  proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
734
0
  offset += 2;
735
736
0
  nitems = tvb_get_ntohl (tvb, offset);
737
0
  proto_tree_add_item (tree, hf_nitems, tvb, offset, 4, ENC_BIG_ENDIAN);
738
0
  offset += 4;
739
740
0
  for (i = 0; i < nitems; i++) {
741
0
    offset = dissect_rpcap_filterbpf_insn (tvb, pinfo, tree, offset);
742
0
    if (tvb_reported_length_remaining (tvb, offset) < 0) {
743
      /* No more data in packet */
744
0
      expert_add_info(pinfo, ti, &ei_no_more_data);
745
0
      break;
746
0
    }
747
0
  }
748
0
}
749
750
751
static int
752
dissect_rpcap_auth_request (tvbuff_t *tvb, packet_info *pinfo _U_,
753
                            proto_tree *parent_tree, int offset)
754
0
{
755
0
  proto_tree *tree;
756
0
  proto_item *ti;
757
0
  uint16_t type, slen1, slen2;
758
759
0
  ti = proto_tree_add_item (parent_tree, hf_auth_request, tvb, offset, -1, ENC_NA);
760
0
  tree = proto_item_add_subtree (ti, ett_auth_request);
761
762
0
  type = tvb_get_ntohs (tvb, offset);
763
0
  proto_tree_add_item (tree, hf_auth_type, tvb, offset, 2, ENC_BIG_ENDIAN);
764
0
  offset += 2;
765
766
0
  proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
767
0
  offset += 2;
768
769
0
  slen1 = tvb_get_ntohs (tvb, offset);
770
0
  proto_tree_add_item (tree, hf_auth_slen1, tvb, offset, 2, ENC_BIG_ENDIAN);
771
0
  offset += 2;
772
773
0
  slen2 = tvb_get_ntohs (tvb, offset);
774
0
  proto_tree_add_item (tree, hf_auth_slen2, tvb, offset, 2, ENC_BIG_ENDIAN);
775
0
  offset += 2;
776
777
0
  if (type == RPCAP_RMTAUTH_NULL) {
778
0
    proto_item_append_text (ti, " (none)");
779
0
  } else if (type == RPCAP_RMTAUTH_PWD) {
780
0
    const uint8_t *username, *password;
781
782
0
    proto_tree_add_item_ret_string(tree, hf_auth_username, tvb, offset, slen1, ENC_ASCII|ENC_NA, pinfo->pool, &username);
783
0
    offset += slen1;
784
785
0
    proto_tree_add_item_ret_string(tree, hf_auth_password, tvb, offset, slen2, ENC_ASCII|ENC_NA, pinfo->pool, &password);
786
0
    offset += slen2;
787
788
0
    proto_item_append_text (ti, " (%s/%s)", username, password);
789
0
  }
790
0
  return offset;
791
0
}
792
793
794
static void
795
dissect_rpcap_auth_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
796
                          proto_tree *parent_tree, int offset)
797
0
{
798
0
  proto_tree *tree;
799
0
  proto_item *ti;
800
0
  uint32_t minvers, maxvers;
801
802
  /*
803
   * Authentication replies from older servers have no payload.
804
   * Replies from newer servers have a payload.
805
   * Dissect the payload if we have any.
806
   */
807
0
  if (tvb_reported_length_remaining(tvb, offset) != 0) {
808
0
    ti = proto_tree_add_item (parent_tree, hf_auth_reply, tvb, offset, -1, ENC_NA);
809
0
    tree = proto_item_add_subtree (ti, ett_auth_reply);
810
811
0
    proto_tree_add_item_ret_uint (tree, hf_auth_minvers, tvb, offset, 1, ENC_BIG_ENDIAN, &minvers);
812
0
    offset += 1;
813
814
0
    proto_tree_add_item_ret_uint (tree, hf_auth_maxvers, tvb, offset, 1, ENC_BIG_ENDIAN, &maxvers);
815
816
0
    proto_item_append_text (ti, ", minimum version %u, maximum version %u", minvers, maxvers);
817
0
  }
818
0
}
819
820
821
static void
822
dissect_rpcap_open_request (tvbuff_t *tvb, packet_info *pinfo _U_,
823
                            proto_tree *parent_tree, int offset)
824
0
{
825
0
  int len;
826
827
0
  len = tvb_reported_length_remaining (tvb, offset);
828
0
  proto_tree_add_item (parent_tree, hf_open_request, tvb, offset, len, ENC_ASCII);
829
0
}
830
831
832
static void
833
dissect_rpcap_open_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
834
                          proto_tree *parent_tree, int offset)
835
0
{
836
0
  proto_tree *tree;
837
0
  proto_item *ti;
838
839
0
  ti = proto_tree_add_item (parent_tree, hf_open_reply, tvb, offset, -1, ENC_NA);
840
0
  tree = proto_item_add_subtree (ti, ett_open_reply);
841
842
0
  linktype = tvb_get_ntohl (tvb, offset);
843
0
  proto_tree_add_item (tree, hf_linktype, tvb, offset, 4, ENC_BIG_ENDIAN);
844
0
  offset += 4;
845
846
0
  proto_tree_add_item (tree, hf_tzoff, tvb, offset, 4, ENC_BIG_ENDIAN);
847
0
}
848
849
850
static void
851
dissect_rpcap_startcap_request (tvbuff_t *tvb, packet_info *pinfo,
852
                                proto_tree *parent_tree, int offset)
853
1
{
854
1
  proto_tree *tree, *field_tree;
855
1
  proto_item *ti, *field_ti;
856
1
  uint16_t flags;
857
858
1
  ti = proto_tree_add_item (parent_tree, hf_startcap_request, tvb, offset, -1, ENC_NA);
859
1
  tree = proto_item_add_subtree (ti, ett_startcap_request);
860
861
1
  proto_tree_add_item (tree, hf_snaplen, tvb, offset, 4, ENC_BIG_ENDIAN);
862
1
  offset += 4;
863
864
1
  proto_tree_add_item (tree, hf_read_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
865
1
  offset += 4;
866
867
1
  flags = tvb_get_ntohs (tvb, offset);
868
1
  field_ti = proto_tree_add_uint_format (tree, hf_flags, tvb, offset, 2, flags, "Flags");
869
1
  field_tree = proto_item_add_subtree (field_ti, ett_startcap_flags);
870
1
  proto_tree_add_item (field_tree, hf_flags_promisc, tvb, offset, 2, ENC_BIG_ENDIAN);
871
1
  proto_tree_add_item (field_tree, hf_flags_dgram, tvb, offset, 2, ENC_BIG_ENDIAN);
872
1
  proto_tree_add_item (field_tree, hf_flags_serveropen, tvb, offset, 2, ENC_BIG_ENDIAN);
873
1
  proto_tree_add_item (field_tree, hf_flags_inbound, tvb, offset, 2, ENC_BIG_ENDIAN);
874
1
  proto_tree_add_item (field_tree, hf_flags_outbound, tvb, offset, 2, ENC_BIG_ENDIAN);
875
876
1
  if (flags & 0x1F) {
877
0
    char *flagstr = wmem_strdup_printf (pinfo->pool, "%s%s%s%s%s",
878
0
          (flags & FLAG_PROMISC)    ? ", Promiscuous" : "",
879
0
          (flags & FLAG_DGRAM)      ? ", Datagram"    : "",
880
0
          (flags & FLAG_SERVEROPEN) ? ", ServerOpen"  : "",
881
0
          (flags & FLAG_INBOUND)    ? ", Inbound"     : "",
882
0
          (flags & FLAG_OUTBOUND)   ? ", Outbound"    : "");
883
0
    proto_item_append_text (field_ti, ":%s", &flagstr[1]);
884
1
  } else {
885
1
    proto_item_append_text (field_ti, " (none)");
886
1
  }
887
1
  offset += 2;
888
889
1
  proto_tree_add_item (tree, hf_client_port, tvb, offset, 2, ENC_BIG_ENDIAN);
890
1
  offset += 2;
891
892
1
  dissect_rpcap_filter (tvb, pinfo, tree, offset);
893
1
}
894
895
896
static void
897
dissect_rpcap_startcap_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
898
                              proto_tree *parent_tree, int offset)
899
0
{
900
0
  proto_tree *tree;
901
0
  proto_item *ti;
902
903
0
  ti = proto_tree_add_item (parent_tree, hf_startcap_reply, tvb, offset, -1, ENC_NA);
904
0
  tree = proto_item_add_subtree (ti, ett_startcap_reply);
905
906
0
  proto_tree_add_item (tree, hf_bufsize, tvb, offset, 4, ENC_BIG_ENDIAN);
907
0
  offset += 4;
908
909
0
  proto_tree_add_item (tree, hf_server_port, tvb, offset, 2, ENC_BIG_ENDIAN);
910
0
  offset += 2;
911
912
0
  proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
913
0
}
914
915
916
static void
917
dissect_rpcap_stats_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
918
                           proto_tree *parent_tree, int offset)
919
0
{
920
0
  proto_tree *tree;
921
0
  proto_item *ti;
922
923
0
  ti = proto_tree_add_item (parent_tree, hf_stats_reply, tvb, offset, 16, ENC_NA);
924
0
  tree = proto_item_add_subtree (ti, ett_stats_reply);
925
926
0
  proto_tree_add_item (tree, hf_ifrecv, tvb, offset, 4, ENC_BIG_ENDIAN);
927
0
  offset += 4;
928
929
0
  proto_tree_add_item (tree, hf_ifdrop, tvb, offset, 4, ENC_BIG_ENDIAN);
930
0
  offset += 4;
931
932
0
  proto_tree_add_item (tree, hf_krnldrop, tvb, offset, 4, ENC_BIG_ENDIAN);
933
0
  offset += 4;
934
935
0
  proto_tree_add_item (tree, hf_srvcapt, tvb, offset, 4, ENC_BIG_ENDIAN);
936
0
}
937
938
939
static int
940
dissect_rpcap_sampling_request (tvbuff_t *tvb, packet_info *pinfo _U_,
941
                                proto_tree *parent_tree, int offset)
942
0
{
943
0
  proto_tree *tree;
944
0
  proto_item *ti;
945
0
  uint32_t value;
946
0
  uint8_t method;
947
948
0
  ti = proto_tree_add_item (parent_tree, hf_sampling_request, tvb, offset, -1, ENC_NA);
949
0
  tree = proto_item_add_subtree (ti, ett_sampling_request);
950
951
0
  method = tvb_get_uint8 (tvb, offset);
952
0
  proto_tree_add_item (tree, hf_sampling_method, tvb, offset, 1, ENC_BIG_ENDIAN);
953
0
  offset += 1;
954
955
0
  proto_tree_add_item (tree, hf_sampling_dummy1, tvb, offset, 1, ENC_BIG_ENDIAN);
956
0
  offset += 1;
957
958
0
  proto_tree_add_item (tree, hf_sampling_dummy2, tvb, offset, 2, ENC_BIG_ENDIAN);
959
0
  offset += 2;
960
961
0
  value = tvb_get_ntohl (tvb, offset);
962
0
  proto_tree_add_item (tree, hf_sampling_value, tvb, offset, 4, ENC_BIG_ENDIAN);
963
0
  offset += 4;
964
965
0
  switch (method) {
966
0
  case RPCAP_SAMP_NOSAMP:
967
0
    proto_item_append_text (ti, ": None");
968
0
    break;
969
0
  case RPCAP_SAMP_1_EVERY_N:
970
0
    proto_item_append_text (ti, ": 1 every %d", value);
971
0
    break;
972
0
  case RPCAP_SAMP_FIRST_AFTER_N_MS:
973
0
    proto_item_append_text (ti, ": First after %d ms", value);
974
0
    break;
975
0
  default:
976
0
    break;
977
0
  }
978
0
  return offset;
979
0
}
980
981
982
static void
983
dissect_rpcap_packet (tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree,
984
                      proto_tree *parent_tree, int offset, proto_item *top_item)
985
0
{
986
0
  proto_tree *tree;
987
0
  proto_item *ti;
988
0
  tvbuff_t *new_tvb;
989
0
  unsigned caplen, len, frame_no;
990
0
  int reported_length_remaining;
991
992
0
  ti = proto_tree_add_item (parent_tree, hf_packet, tvb, offset, 20, ENC_NA);
993
0
  tree = proto_item_add_subtree (ti, ett_packet);
994
995
0
  proto_tree_add_item(tree, hf_timestamp, tvb, offset, 8, ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN);
996
0
  offset += 8;
997
998
0
  caplen = tvb_get_ntohl (tvb, offset);
999
0
  ti = proto_tree_add_item (tree, hf_caplen, tvb, offset, 4, ENC_BIG_ENDIAN);
1000
0
  offset += 4;
1001
1002
0
  len = tvb_get_ntohl (tvb, offset);
1003
0
  proto_tree_add_item (tree, hf_len, tvb, offset, 4, ENC_BIG_ENDIAN);
1004
0
  offset += 4;
1005
1006
0
  frame_no = tvb_get_ntohl (tvb, offset);
1007
0
  proto_tree_add_item (tree, hf_npkt, tvb, offset, 4, ENC_BIG_ENDIAN);
1008
0
  offset += 4;
1009
1010
0
  proto_item_append_text (ti, ", Frame %u", frame_no);
1011
0
  proto_item_append_text (top_item, " Frame %u", frame_no);
1012
1013
  /*
1014
   * reported_length_remaining should not be -1, as offset is at
1015
   * most right past the end of the available data in the packet.
1016
   */
1017
0
  reported_length_remaining = tvb_reported_length_remaining (tvb, offset);
1018
0
  if (caplen > (unsigned)reported_length_remaining) {
1019
0
    expert_add_info(pinfo, ti, &ei_caplen_too_big);
1020
0
    return;
1021
0
  }
1022
1023
0
  new_tvb = tvb_new_subset_length_caplen (tvb, offset, caplen, len);
1024
0
  if (decode_content && linktype != -1) {
1025
0
    TRY {
1026
0
      call_dissector_with_data(pcap_pktdata_handle, new_tvb, pinfo, top_tree, &linktype);
1027
0
    }
1028
0
    CATCH_BOUNDS_ERRORS {
1029
0
      show_exception(tvb, pinfo, top_tree, EXCEPT_CODE, GET_MESSAGE);
1030
0
    }
1031
0
    ENDTRY;
1032
1033
0
    if (!info_added) {
1034
      /* Only indicate when not added before */
1035
      /* Indicate RPCAP in the protocol column */
1036
0
      col_prepend_fence_fstr(pinfo->cinfo, COL_PROTOCOL, "R|");
1037
1038
      /* Indicate RPCAP in the info column */
1039
0
      col_prepend_fence_fstr (pinfo->cinfo, COL_INFO, "Remote | ");
1040
0
      info_added = true;
1041
0
      register_frame_end_routine(pinfo, rpcap_frame_end);
1042
0
    }
1043
0
  } else {
1044
0
    if (linktype == -1) {
1045
0
      proto_item_append_text (ti, ", Unknown link-layer type");
1046
0
    }
1047
0
    call_data_dissector(new_tvb, pinfo, top_tree);
1048
0
  }
1049
0
}
1050
1051
1052
static int
1053
dissect_rpcap (tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, void* data _U_)
1054
5
{
1055
5
  proto_tree *tree;
1056
5
  proto_item *ti;
1057
5
  tvbuff_t *new_tvb;
1058
5
  int len, offset = 0;
1059
5
  uint8_t msg_type;
1060
5
  uint16_t msg_value;
1061
1062
5
  col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME);
1063
1064
5
  col_clear(pinfo->cinfo, COL_INFO);
1065
1066
5
  ti = proto_tree_add_item (top_tree, proto_rpcap, tvb, offset, -1, ENC_NA);
1067
5
  tree = proto_item_add_subtree (ti, ett_rpcap);
1068
1069
5
  proto_tree_add_item (tree, hf_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1070
5
  offset++;
1071
1072
5
  msg_type = tvb_get_uint8 (tvb, offset);
1073
5
  proto_tree_add_item (tree, hf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1074
5
  offset++;
1075
1076
5
  col_append_str (pinfo->cinfo, COL_INFO,
1077
5
                     val_to_str (msg_type, message_type, "Unknown: 0x%02x"));
1078
1079
5
  proto_item_append_text (ti, ", %s", val_to_str (msg_type, message_type, "Unknown: 0x%02x"));
1080
1081
5
  msg_value = tvb_get_ntohs (tvb, offset);
1082
5
  if (msg_type == RPCAP_MSG_ERROR) {
1083
3
    proto_tree_add_item (tree, hf_error_value, tvb, offset, 2, ENC_BIG_ENDIAN);
1084
3
  } else {
1085
2
    proto_tree_add_item (tree, hf_value, tvb, offset, 2, ENC_BIG_ENDIAN);
1086
2
  }
1087
5
  offset += 2;
1088
1089
5
  proto_tree_add_item (tree, hf_plen, tvb, offset, 4, ENC_BIG_ENDIAN);
1090
5
  offset += 4;
1091
1092
1093
5
  switch (msg_type) {
1094
3
  case RPCAP_MSG_ERROR:
1095
3
    dissect_rpcap_error (tvb, pinfo, tree, offset);
1096
3
    break;
1097
0
  case RPCAP_MSG_OPEN_REQ:
1098
0
    dissect_rpcap_open_request (tvb, pinfo, tree, offset);
1099
0
    break;
1100
1
  case RPCAP_MSG_STARTCAP_REQ:
1101
1
    dissect_rpcap_startcap_request (tvb, pinfo, tree, offset);
1102
1
    break;
1103
0
  case RPCAP_MSG_UPDATEFILTER_REQ:
1104
0
    dissect_rpcap_filter (tvb, pinfo, tree, offset);
1105
0
    break;
1106
0
  case RPCAP_MSG_PACKET:
1107
0
    proto_item_set_len (ti, 28);
1108
0
    dissect_rpcap_packet (tvb, pinfo, top_tree, tree, offset, ti);
1109
0
    break;
1110
0
  case RPCAP_MSG_AUTH_REQ:
1111
0
    dissect_rpcap_auth_request (tvb, pinfo, tree, offset);
1112
0
    break;
1113
0
  case RPCAP_MSG_SETSAMPLING_REQ:
1114
0
    dissect_rpcap_sampling_request (tvb, pinfo, tree, offset);
1115
0
    break;
1116
0
  case RPCAP_MSG_AUTH_REPLY:
1117
0
    dissect_rpcap_auth_reply (tvb, pinfo, tree, offset);
1118
0
    break;
1119
0
  case RPCAP_MSG_FINDALLIF_REPLY:
1120
0
    dissect_rpcap_findalldevs_reply (tvb, pinfo, tree, offset, msg_value);
1121
0
    break;
1122
0
  case RPCAP_MSG_OPEN_REPLY:
1123
0
    dissect_rpcap_open_reply (tvb, pinfo, tree, offset);
1124
0
    break;
1125
0
  case RPCAP_MSG_STARTCAP_REPLY:
1126
0
    dissect_rpcap_startcap_reply (tvb, pinfo, tree, offset);
1127
0
    break;
1128
0
  case RPCAP_MSG_STATS_REPLY:
1129
0
    dissect_rpcap_stats_reply (tvb, pinfo, tree, offset);
1130
0
    break;
1131
1
  default:
1132
1
    len = tvb_reported_length_remaining (tvb, offset);
1133
1
    if (len) {
1134
      /* Yet unknown, dump as data */
1135
1
      proto_item_set_len (ti, 8);
1136
1
      new_tvb = tvb_new_subset_remaining (tvb, offset);
1137
1
      call_data_dissector(new_tvb, pinfo, top_tree);
1138
1
    }
1139
1
    break;
1140
5
  }
1141
1142
4
  return tvb_captured_length(tvb);
1143
5
}
1144
1145
1146
static bool
1147
check_rpcap_heur (tvbuff_t *tvb, bool tcp)
1148
2.90k
{
1149
2.90k
  int offset = 0;
1150
2.90k
  uint8_t version, msg_type;
1151
2.90k
  uint16_t msg_value;
1152
2.90k
  uint32_t plen, len, caplen;
1153
1154
2.90k
  if (tvb_captured_length (tvb) < 8)
1155
    /* Too short */
1156
286
    return false;
1157
1158
2.61k
  version = tvb_get_uint8 (tvb, offset);
1159
2.61k
  if (version != 0)
1160
    /* Incorrect version */
1161
2.15k
    return false;
1162
465
  offset++;
1163
1164
465
  msg_type = tvb_get_uint8 (tvb, offset);
1165
465
  if (!tcp && msg_type != 7) {
1166
    /* UDP is only used for packets */
1167
97
    return false;
1168
97
  }
1169
368
  if (try_val_to_str(msg_type, message_type) == NULL)
1170
    /* Unknown message type */
1171
308
    return false;
1172
60
  offset++;
1173
1174
60
  msg_value = tvb_get_ntohs (tvb, offset);
1175
60
  if (msg_value > 0) {
1176
29
    if (msg_type == RPCAP_MSG_ERROR) {
1177
      /* Must have a valid error code */
1178
7
      if (try_val_to_str(msg_value, error_codes) == NULL)
1179
6
        return false;
1180
22
    } else if (msg_type != RPCAP_MSG_FINDALLIF_REPLY) {
1181
19
      return false;
1182
19
    }
1183
29
  }
1184
35
  offset += 2;
1185
1186
35
  plen = tvb_get_ntohl (tvb, offset);
1187
35
  offset += 4;
1188
35
  len = (uint32_t) tvb_reported_length_remaining (tvb, offset);
1189
1190
35
  switch (msg_type) {
1191
1192
3
  case RPCAP_MSG_FINDALLIF_REQ:
1193
3
  case RPCAP_MSG_UPDATEFILTER_REPLY:
1194
3
  case RPCAP_MSG_STATS_REQ:
1195
4
  case RPCAP_MSG_CLOSE:
1196
5
  case RPCAP_MSG_SETSAMPLING_REPLY:
1197
6
  case RPCAP_MSG_ENDCAP_REQ:
1198
6
  case RPCAP_MSG_ENDCAP_REPLY:
1199
    /* Empty payload */
1200
6
    if (plen != 0 || len != 0)
1201
6
      return false;
1202
0
    break;
1203
1204
0
  case RPCAP_MSG_OPEN_REPLY:
1205
0
  case RPCAP_MSG_STARTCAP_REPLY:
1206
1
  case RPCAP_MSG_SETSAMPLING_REQ:
1207
    /* Always 8 bytes */
1208
1
    if (plen != 8 || len != 8)
1209
1
      return false;
1210
0
    break;
1211
1212
0
  case RPCAP_MSG_STATS_REPLY:
1213
    /* Always 16 bytes */
1214
0
    if (plen != 16 || len != 16)
1215
0
      return false;
1216
0
    break;
1217
1218
2
  case RPCAP_MSG_PACKET:
1219
    /* Must have the frame header */
1220
2
    if (plen < 20)
1221
1
      return false;
1222
1223
    /* Check if capture length is valid */
1224
1
    caplen = tvb_get_ntohl (tvb, offset+8);
1225
    /* Always 20 bytes less than packet length */
1226
1
    if (caplen != (plen - 20) || caplen > 65535)
1227
1
      return false;
1228
0
    break;
1229
1230
3
  case RPCAP_MSG_FINDALLIF_REPLY:
1231
11
  case RPCAP_MSG_ERROR:
1232
15
  case RPCAP_MSG_OPEN_REQ:
1233
17
  case RPCAP_MSG_STARTCAP_REQ:
1234
21
  case RPCAP_MSG_UPDATEFILTER_REQ:
1235
26
  case RPCAP_MSG_AUTH_REQ:
1236
26
  case RPCAP_MSG_AUTH_REPLY:
1237
    /* Variable length */
1238
26
    if (plen != len)
1239
23
      return false;
1240
3
    break;
1241
3
  default:
1242
    /* Unknown message type */
1243
0
    return false;
1244
35
  }
1245
1246
3
  return true;
1247
35
}
1248
1249
1250
static unsigned
1251
get_rpcap_pdu_len (packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1252
5
{
1253
5
  return tvb_get_ntohl (tvb, offset + 4) + 8;
1254
5
}
1255
1256
1257
static int
1258
dissect_rpcap_tcp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1259
2
{
1260
2
  tcp_dissect_pdus (tvb, pinfo, tree, rpcap_desegment, 8,
1261
2
                    get_rpcap_pdu_len, dissect_rpcap, data);
1262
2
  return tvb_captured_length (tvb);
1263
2
}
1264
1265
static bool
1266
dissect_rpcap_heur_tcp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1267
1.99k
{
1268
1.99k
  if (check_rpcap_heur (tvb, true)) {
1269
    /*
1270
     * This is probably a rpcap TCP packet.
1271
     * Make the dissector for this conversation the non-heuristic
1272
     * rpcap dissector, so that malformed rpcap packets are reported
1273
     * as such.
1274
     */
1275
3
    conversation_t *conversation = find_conversation_pinfo (pinfo, 0);
1276
3
    if (conversation)
1277
3
      conversation_set_dissector_from_frame_number (conversation,
1278
3
                                                  pinfo->num,
1279
3
                                                  rpcap_tcp_handle);
1280
3
    tcp_dissect_pdus (tvb, pinfo, tree, rpcap_desegment, 8,
1281
3
                      get_rpcap_pdu_len, dissect_rpcap, data);
1282
1283
3
    return true;
1284
3
  }
1285
1286
1.98k
  return false;
1287
1.99k
}
1288
1289
1290
static bool
1291
dissect_rpcap_heur_udp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1292
912
{
1293
912
  if (check_rpcap_heur (tvb, false)) {
1294
    /* This is probably a rpcap udp package */
1295
0
    dissect_rpcap (tvb, pinfo, tree, data);
1296
1297
0
    return true;
1298
0
  }
1299
1300
912
  return false;
1301
912
}
1302
1303
1304
void
1305
proto_register_rpcap (void)
1306
14
{
1307
14
  static hf_register_info hf[] = {
1308
    /* Common header for all messages */
1309
14
    { &hf_version,
1310
14
      { "Version", "rpcap.version", FT_UINT8, BASE_DEC,
1311
14
        NULL, 0x0, NULL, HFILL } },
1312
14
    { &hf_type,
1313
14
      { "Message type", "rpcap.type", FT_UINT8, BASE_HEX,
1314
14
        VALS(message_type), 0x0, NULL, HFILL } },
1315
14
    { &hf_value,
1316
14
      { "Message value", "rpcap.value", FT_UINT16, BASE_DEC,
1317
14
        NULL, 0x0, NULL, HFILL } },
1318
14
    { &hf_plen,
1319
14
      { "Payload length", "rpcap.len", FT_UINT32, BASE_DEC,
1320
14
        NULL, 0x0, NULL, HFILL } },
1321
1322
    /* Error */
1323
14
    { &hf_error,
1324
14
      { "Error", "rpcap.error", FT_STRING, BASE_STR_WSP,
1325
14
        NULL, 0x0, "Error text", HFILL } },
1326
14
    { &hf_error_value,
1327
14
      { "Error value", "rpcap.error_value", FT_UINT16, BASE_DEC,
1328
14
        VALS(error_codes), 0x0, NULL, HFILL } },
1329
1330
    /* Packet header */
1331
14
    { &hf_packet,
1332
14
      { "Packet", "rpcap.packet", FT_NONE, BASE_NONE,
1333
14
        NULL, 0x0, "Packet data", HFILL } },
1334
14
    { &hf_timestamp,
1335
14
      { "Arrival time", "rpcap.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
1336
14
        NULL, 0x0, NULL, HFILL } },
1337
14
    { &hf_caplen,
1338
14
      { "Capture length", "rpcap.cap_len", FT_UINT32, BASE_DEC,
1339
14
        NULL, 0x0, NULL, HFILL } },
1340
14
    { &hf_len,
1341
14
      { "Frame length", "rpcap.len", FT_UINT32, BASE_DEC,
1342
14
        NULL, 0x0, "Frame length (off wire)", HFILL } },
1343
14
    { &hf_npkt,
1344
14
      { "Frame number", "rpcap.number", FT_UINT32, BASE_DEC,
1345
14
        NULL, 0x0, NULL, HFILL } },
1346
1347
    /* Authentication request */
1348
14
    { &hf_auth_request,
1349
14
      { "Authentication request", "rpcap.auth_request", FT_NONE, BASE_NONE,
1350
14
        NULL, 0x0, NULL, HFILL } },
1351
14
    { &hf_auth_type,
1352
14
      { "Authentication type", "rpcap.auth_type", FT_UINT16, BASE_DEC,
1353
14
        VALS(auth_type), 0x0, NULL, HFILL } },
1354
14
    { &hf_auth_slen1,
1355
14
      { "Authentication item length 1", "rpcap.auth_len1", FT_UINT16, BASE_DEC,
1356
14
        NULL, 0x0, NULL, HFILL } },
1357
14
    { &hf_auth_slen2,
1358
14
      { "Authentication item length 2", "rpcap.auth_len2", FT_UINT16, BASE_DEC,
1359
14
        NULL, 0x0, NULL, HFILL } },
1360
14
    { &hf_auth_username,
1361
14
      { "Username", "rpcap.username", FT_STRING, BASE_NONE,
1362
14
        NULL, 0x0, NULL, HFILL } },
1363
14
    { &hf_auth_password,
1364
14
      { "Password", "rpcap.password", FT_STRING, BASE_NONE,
1365
14
        NULL, 0x0, NULL, HFILL } },
1366
1367
    /* Authentication reply */
1368
14
    { &hf_auth_reply,
1369
14
      { "Authentication reply", "rpcap.auth_reply", FT_NONE, BASE_NONE,
1370
14
        NULL, 0x0, NULL, HFILL } },
1371
14
    { &hf_auth_minvers,
1372
14
      { "Minimum version number supported", "rpcap.auth_minvers", FT_UINT8, BASE_DEC,
1373
14
        NULL, 0x0, NULL, HFILL } },
1374
14
    { &hf_auth_maxvers,
1375
14
      { "Maximum version number supported", "rpcap.auth_maxvers", FT_UINT8, BASE_DEC,
1376
14
        NULL, 0x0, NULL, HFILL } },
1377
1378
    /* Open request */
1379
14
    { &hf_open_request,
1380
14
      { "Open request", "rpcap.open_request", FT_STRING, BASE_NONE,
1381
14
        NULL, 0x0, NULL, HFILL } },
1382
1383
    /* Open reply */
1384
14
    { &hf_open_reply,
1385
14
      { "Open reply", "rpcap.open_reply", FT_NONE, BASE_NONE,
1386
14
        NULL, 0x0, NULL, HFILL } },
1387
    /*
1388
     * XXX - the code probably sends a DLT_ value over the wire, but
1389
     * it should really send a LINKTYPE_ value, so that if the client
1390
     * and server are running OSes that disagree on the numerical value
1391
     * of that DLT_, they won't get confused (LINKTYPE_ values aren't
1392
     * platform-dependent).  The vast majority of LINKTYPE_ values and
1393
     * DLT_ values are the same for the same link-layer type.
1394
     */
1395
14
    { &hf_linktype,
1396
14
      { "Link type", "rpcap.linktype", FT_UINT32, BASE_DEC,
1397
14
        VALS(link_type_vals), 0x0, NULL, HFILL } },
1398
14
    { &hf_tzoff,
1399
14
      { "Timezone offset", "rpcap.tzoff", FT_UINT32, BASE_DEC,
1400
14
        NULL, 0x0, NULL, HFILL } },
1401
1402
    /* Start capture request */
1403
14
    { &hf_startcap_request,
1404
14
      { "Start capture request", "rpcap.startcap_request", FT_NONE, BASE_NONE,
1405
14
        NULL, 0x0, NULL, HFILL } },
1406
14
    { &hf_snaplen,
1407
14
      { "Snap length", "rpcap.snaplen", FT_UINT32, BASE_DEC,
1408
14
        NULL, 0x0, NULL, HFILL } },
1409
14
    { &hf_read_timeout,
1410
14
      { "Read timeout", "rpcap.read_timeout", FT_UINT32, BASE_DEC,
1411
14
        NULL, 0x0, NULL, HFILL } },
1412
14
    { &hf_flags,
1413
14
      { "Flags", "rpcap.flags", FT_UINT16, BASE_DEC,
1414
14
        NULL, 0x0, "Capture flags", HFILL } },
1415
14
    { &hf_flags_promisc,
1416
14
      { "Promiscuous mode", "rpcap.flags.promisc", FT_BOOLEAN, 16,
1417
14
        TFS(&tfs_enabled_disabled), FLAG_PROMISC, NULL, HFILL } },
1418
14
    { &hf_flags_dgram,
1419
14
      { "Use Datagram", "rpcap.flags.dgram", FT_BOOLEAN, 16,
1420
14
        TFS(&tfs_yes_no), FLAG_DGRAM, NULL, HFILL } },
1421
14
    { &hf_flags_serveropen,
1422
14
      { "Server open", "rpcap.flags.serveropen", FT_BOOLEAN, 16,
1423
14
        TFS(&tfs_open_closed), FLAG_SERVEROPEN, NULL, HFILL } },
1424
14
    { &hf_flags_inbound,
1425
14
      { "Inbound", "rpcap.flags.inbound", FT_BOOLEAN, 16,
1426
14
        TFS(&tfs_yes_no), FLAG_INBOUND, NULL, HFILL } },
1427
14
    { &hf_flags_outbound,
1428
14
      { "Outbound", "rpcap.flags.outbound", FT_BOOLEAN, 16,
1429
14
        TFS(&tfs_yes_no), FLAG_OUTBOUND, NULL, HFILL } },
1430
14
    { &hf_client_port,
1431
14
      { "Client Port", "rpcap.client_port", FT_UINT16, BASE_DEC,
1432
14
        NULL, 0x0, NULL, HFILL } },
1433
1434
    /* Start capture reply */
1435
14
    { &hf_startcap_reply,
1436
14
      { "Start capture reply", "rpcap.startcap_reply", FT_NONE, BASE_NONE,
1437
14
        NULL, 0x0, NULL, HFILL } },
1438
14
    { &hf_bufsize,
1439
14
      { "Buffer size", "rpcap.bufsize", FT_UINT32, BASE_DEC,
1440
14
        NULL, 0x0, NULL, HFILL } },
1441
14
    { &hf_server_port,
1442
14
      { "Server port", "rpcap.server_port", FT_UINT16, BASE_DEC,
1443
14
        NULL, 0x0, NULL, HFILL } },
1444
14
    { &hf_dummy,
1445
14
      { "Dummy", "rpcap.dummy", FT_UINT16, BASE_DEC,
1446
14
        NULL, 0x0, NULL, HFILL } },
1447
1448
    /* Filter */
1449
14
    { &hf_filter,
1450
14
      { "Filter", "rpcap.filter", FT_NONE, BASE_NONE,
1451
14
        NULL, 0x0, NULL, HFILL } },
1452
14
    { &hf_filtertype,
1453
14
      { "Filter type", "rpcap.filtertype", FT_UINT16, BASE_DEC,
1454
14
        NULL, 0x0, "Filter type (BPF)", HFILL } },
1455
14
    { &hf_nitems,
1456
14
      { "Number of items", "rpcap.nitems", FT_UINT32, BASE_DEC,
1457
14
        NULL, 0x0, NULL, HFILL } },
1458
1459
    /* Filter BPF instruction */
1460
14
    { &hf_filterbpf_insn,
1461
14
      { "Filter BPF instruction", "rpcap.filterbpf_insn", FT_NONE, BASE_NONE,
1462
14
        NULL, 0x0, NULL, HFILL } },
1463
14
    { &hf_code,
1464
14
      { "Op code", "rpcap.opcode", FT_UINT16, BASE_HEX,
1465
14
        NULL, 0x0, "Operation code", HFILL } },
1466
14
    { &hf_code_class,
1467
14
      { "Class", "rpcap.opcode.class", FT_UINT16, BASE_HEX,
1468
14
        VALS(bpf_class), 0x07, "Instruction Class", HFILL } },
1469
14
    { &hf_code_fields,
1470
14
      { "Fields", "rpcap.opcode.fields", FT_UINT16, BASE_HEX,
1471
14
        NULL, 0xF8, "Class Fields", HFILL } },
1472
14
    { &hf_code_ld_size,
1473
14
      { "Size", "rpcap.opcode.size", FT_UINT16, BASE_HEX,
1474
14
        VALS(bpf_size), 0x18, NULL, HFILL } },
1475
14
    { &hf_code_ld_mode,
1476
14
      { "Mode", "rpcap.opcode.mode", FT_UINT16, BASE_HEX,
1477
14
        VALS(bpf_mode), 0xE0, NULL, HFILL } },
1478
14
    { &hf_code_alu_op,
1479
14
      { "Op", "rpcap.opcode.aluop", FT_UINT16, BASE_HEX,
1480
14
        VALS(bpf_alu_op), 0xF0, NULL, HFILL } },
1481
14
    { &hf_code_jmp_op,
1482
14
      { "Op", "rpcap.opcode.jmpop", FT_UINT16, BASE_HEX,
1483
14
        VALS(bpf_jmp_op), 0xF0, NULL, HFILL } },
1484
14
    { &hf_code_src,
1485
14
      { "Src", "rpcap.opcode.src", FT_UINT16, BASE_HEX,
1486
14
        VALS(bpf_src), 0x08, NULL, HFILL } },
1487
14
    { &hf_code_rval,
1488
14
      { "Rval", "rpcap.opcode.rval", FT_UINT16, BASE_HEX,
1489
14
        VALS(bpf_rval), 0x18, NULL, HFILL } },
1490
14
    { &hf_code_misc_op,
1491
14
      { "Op", "rpcap.opcode.miscop", FT_UINT16, BASE_HEX,
1492
14
        VALS(bpf_misc_op), 0xF8, NULL, HFILL } },
1493
14
    { &hf_jt,
1494
14
      { "JT", "rpcap.jt", FT_UINT8, BASE_DEC,
1495
14
        NULL, 0x0, NULL, HFILL } },
1496
14
    { &hf_jf,
1497
14
      { "JF", "rpcap.jf", FT_UINT8, BASE_DEC,
1498
14
        NULL, 0x0, NULL, HFILL } },
1499
14
    { &hf_instr_value,
1500
14
      { "Instruction value", "rpcap.instr_value", FT_UINT32, BASE_DEC,
1501
14
        NULL, 0x0, "Instruction-Dependent value", HFILL } },
1502
1503
    /* Statistics reply */
1504
14
    { &hf_stats_reply,
1505
14
      { "Statistics", "rpcap.stats_reply", FT_NONE, BASE_NONE,
1506
14
        NULL, 0x0, "Statistics reply data", HFILL } },
1507
14
    { &hf_ifrecv,
1508
14
      { "Received by kernel filter", "rpcap.ifrecv", FT_UINT32, BASE_DEC,
1509
14
        NULL, 0x0, NULL, HFILL } },
1510
14
    { &hf_ifdrop,
1511
14
      { "Dropped by network interface", "rpcap.ifdrop", FT_UINT32, BASE_DEC,
1512
14
        NULL, 0x0, NULL, HFILL } },
1513
14
    { &hf_krnldrop,
1514
14
      { "Dropped by kernel filter", "rpcap.krnldrop", FT_UINT32, BASE_DEC,
1515
14
        NULL, 0x0, NULL, HFILL } },
1516
14
    { &hf_srvcapt,
1517
14
      { "Captured by rpcapd", "rpcap.srvcapt", FT_UINT32, BASE_DEC,
1518
14
        NULL, 0x0, "Captured by RPCAP daemon", HFILL } },
1519
1520
    /* Find all devices reply */
1521
14
    { &hf_findalldevs_reply,
1522
14
      { "Find all devices", "rpcap.findalldevs_reply", FT_NONE, BASE_NONE,
1523
14
        NULL, 0x0, NULL, HFILL } },
1524
14
    { &hf_findalldevs_if,
1525
14
      { "Interface", "rpcap.if", FT_NONE, BASE_NONE,
1526
14
        NULL, 0x0, NULL, HFILL } },
1527
14
    { &hf_namelen,
1528
14
      { "Name length", "rpcap.namelen", FT_UINT16, BASE_DEC,
1529
14
        NULL, 0x0, NULL, HFILL } },
1530
14
    { &hf_desclen,
1531
14
      { "Description length", "rpcap.desclen", FT_UINT32, BASE_DEC,
1532
14
        NULL, 0x0, NULL, HFILL } },
1533
14
    { &hf_if_flags,
1534
14
      { "Interface flags", "rpcap.if.flags", FT_UINT32, BASE_DEC,
1535
14
        NULL, 0x0, NULL, HFILL } },
1536
14
    { &hf_naddr,
1537
14
      { "Number of addresses", "rpcap.naddr", FT_UINT32, BASE_DEC,
1538
14
        NULL, 0x0, NULL, HFILL } },
1539
14
    { &hf_if_name,
1540
14
      { "Name", "rpcap.ifname", FT_STRING, BASE_NONE,
1541
14
        NULL, 0x0, "Interface name", HFILL } },
1542
14
    { &hf_if_desc,
1543
14
      { "Description", "rpcap.ifdesc", FT_STRING, BASE_NONE,
1544
14
        NULL, 0x0, "Interface description", HFILL } },
1545
1546
    /* Find all devices / Interface addresses */
1547
14
    { &hf_findalldevs_ifaddr,
1548
14
      { "Interface address", "rpcap.ifaddr", FT_NONE, BASE_NONE,
1549
14
        NULL, 0x0, NULL, HFILL } },
1550
14
    { &hf_if_addr,
1551
14
      { "Address", "rpcap.addr", FT_NONE, BASE_NONE,
1552
14
        NULL, 0x0, "Network address", HFILL } },
1553
14
    { &hf_if_netmask,
1554
14
      { "Netmask", "rpcap.netmask", FT_NONE, BASE_NONE,
1555
14
        NULL, 0x0, NULL, HFILL } },
1556
14
    { &hf_if_broadaddr,
1557
14
      { "Broadcast", "rpcap.broadaddr", FT_NONE, BASE_NONE,
1558
14
        NULL, 0x0, NULL, HFILL } },
1559
14
    { &hf_if_dstaddr,
1560
14
      { "P2P destination address", "rpcap.dstaddr", FT_NONE, BASE_NONE,
1561
14
        NULL, 0x0, NULL, HFILL } },
1562
14
    { &hf_if_af,
1563
14
      { "Address family", "rpcap.if.af", FT_UINT16, BASE_HEX,
1564
14
        VALS(address_family), 0x0, NULL, HFILL } },
1565
14
    { &hf_if_port,
1566
14
      { "Port", "rpcap.if.port", FT_UINT16, BASE_DEC,
1567
14
        NULL, 0x0, "Port number", HFILL } },
1568
14
    { &hf_if_ipv4,
1569
14
      { "IPv4 address", "rpcap.if.ipv4", FT_IPv4, BASE_NONE,
1570
14
        NULL, 0x0, NULL, HFILL } },
1571
14
    { &hf_if_flowinfo,
1572
14
      { "Flow information", "rpcap.if.flowinfo", FT_UINT32, BASE_HEX,
1573
14
        NULL, 0x0, NULL, HFILL } },
1574
14
    { &hf_if_ipv6,
1575
14
      { "IPv6 address", "rpcap.if.ipv6", FT_IPv6, BASE_NONE,
1576
14
        NULL, 0x0, NULL, HFILL } },
1577
14
    { &hf_if_scopeid,
1578
14
      { "Scope ID", "rpcap.if.scopeid", FT_UINT32, BASE_HEX,
1579
14
        NULL, 0x0, NULL, HFILL } },
1580
14
    { &hf_if_padding,
1581
14
      { "Padding", "rpcap.if.padding", FT_BYTES, BASE_NONE,
1582
14
        NULL, 0x0, NULL, HFILL } },
1583
14
    { &hf_if_unknown,
1584
14
      { "Unknown address", "rpcap.if.unknown", FT_BYTES, BASE_NONE,
1585
14
        NULL, 0x0, NULL, HFILL } },
1586
1587
    /* Sampling request */
1588
14
    { &hf_sampling_request,
1589
14
      { "Sampling", "rpcap.sampling_request", FT_NONE, BASE_NONE,
1590
14
        NULL, 0x0, NULL, HFILL } },
1591
14
    { &hf_sampling_method,
1592
14
      { "Method", "rpcap.sampling_method", FT_UINT8, BASE_DEC,
1593
14
        VALS(sampling_method), 0x0, "Sampling method", HFILL } },
1594
14
    { &hf_sampling_dummy1,
1595
14
      { "Dummy1", "rpcap.dummy", FT_UINT8, BASE_DEC,
1596
14
        NULL, 0x0, NULL, HFILL } },
1597
14
    { &hf_sampling_dummy2,
1598
14
      { "Dummy2", "rpcap.dummy", FT_UINT16, BASE_DEC,
1599
14
        NULL, 0x0, NULL, HFILL } },
1600
14
    { &hf_sampling_value,
1601
14
      { "Value", "rpcap.sampling_value", FT_UINT32, BASE_DEC,
1602
14
        NULL, 0x0, NULL, HFILL } },
1603
14
  };
1604
1605
14
  static int *ett[] = {
1606
14
    &ett_rpcap,
1607
14
    &ett_error,
1608
14
    &ett_packet,
1609
14
    &ett_auth_request,
1610
14
    &ett_auth_reply,
1611
14
    &ett_open_reply,
1612
14
    &ett_startcap_request,
1613
14
    &ett_startcap_reply,
1614
14
    &ett_startcap_flags,
1615
14
    &ett_filter,
1616
14
    &ett_filterbpf_insn,
1617
14
    &ett_filterbpf_insn_code,
1618
14
    &ett_stats_reply,
1619
14
    &ett_findalldevs_reply,
1620
14
    &ett_findalldevs_if,
1621
14
    &ett_findalldevs_ifaddr,
1622
14
    &ett_ifaddr,
1623
14
    &ett_sampling_request
1624
14
  };
1625
1626
14
  static ei_register_info ei[] = {
1627
14
     { &ei_error, { "rpcap.error.expert", PI_SEQUENCE, PI_NOTE, "Error", EXPFILL }},
1628
14
     { &ei_if_unknown, { "rpcap.if_unknown", PI_SEQUENCE, PI_NOTE, "Unknown address family", EXPFILL }},
1629
14
     { &ei_no_more_data, { "rpcap.no_more_data", PI_MALFORMED, PI_ERROR, "No more data in packet", EXPFILL }},
1630
14
     { &ei_caplen_too_big, { "rpcap.caplen_too_big", PI_MALFORMED, PI_ERROR, "Caplen is bigger than the remaining message length", EXPFILL }},
1631
14
  };
1632
1633
14
  module_t *rpcap_module;
1634
14
  expert_module_t* expert_rpcap;
1635
1636
14
  proto_rpcap = proto_register_protocol (PNAME, PSNAME, PFNAME);
1637
14
  register_dissector (PFNAME, dissect_rpcap, proto_rpcap);
1638
14
  rpcap_tcp_handle = register_dissector(PFNAME ".tcp", dissect_rpcap_tcp, proto_rpcap);
1639
14
  expert_rpcap = expert_register_protocol(proto_rpcap);
1640
14
  expert_register_field_array(expert_rpcap, ei, array_length(ei));
1641
1642
14
  proto_register_field_array (proto_rpcap, hf, array_length (hf));
1643
14
  proto_register_subtree_array (ett, array_length (ett));
1644
1645
  /* Register our configuration options */
1646
14
  rpcap_module = prefs_register_protocol (proto_rpcap, proto_reg_handoff_rpcap);
1647
1648
14
  prefs_register_bool_preference (rpcap_module, "desegment_pdus",
1649
14
                                  "Reassemble PDUs spanning multiple TCP segments",
1650
14
                                  "Whether the RPCAP dissector should reassemble PDUs"
1651
14
                                  " spanning multiple TCP segments."
1652
14
                                  " To use this option, you must also enable \"Allow subdissectors"
1653
14
                                  " to reassemble TCP streams\" in the TCP protocol settings.",
1654
14
                                  &rpcap_desegment);
1655
14
  prefs_register_bool_preference (rpcap_module, "decode_content",
1656
14
                                  "Decode content according to link-layer type",
1657
14
                                  "Whether the packets should be decoded according to"
1658
14
                                  " the link-layer type.",
1659
14
                                  &decode_content);
1660
14
  prefs_register_uint_preference (rpcap_module, "linktype",
1661
14
                                  "Default link-layer type",
1662
14
                                  "Default link-layer type to use if an Open Reply packet"
1663
14
                                  " has not been captured.",
1664
14
                                  10, &global_linktype);
1665
14
}
1666
1667
void
1668
proto_reg_handoff_rpcap (void)
1669
14
{
1670
14
  static bool rpcap_prefs_initialized = false;
1671
1672
14
  if (!rpcap_prefs_initialized) {
1673
14
    pcap_pktdata_handle = find_dissector_add_dependency("pcap_pktdata", proto_rpcap);
1674
14
    rpcap_prefs_initialized = true;
1675
1676
14
    heur_dissector_add ("tcp", dissect_rpcap_heur_tcp, "RPCAP over TCP", "rpcap_tcp", proto_rpcap, HEURISTIC_ENABLE);
1677
14
    heur_dissector_add ("udp", dissect_rpcap_heur_udp, "RPCAP over UDP", "rpcap_udp", proto_rpcap, HEURISTIC_ENABLE);
1678
14
  }
1679
1680
14
  info_added = false;
1681
14
  linktype = global_linktype;
1682
14
}
1683
1684
/*
1685
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1686
 *
1687
 * Local Variables:
1688
 * c-basic-offset: 2
1689
 * tab-width: 8
1690
 * indent-tabs-mode: nil
1691
 * End:
1692
 *
1693
 * ex: set shiftwidth=2 tabstop=8 expandtab:
1694
 * :indentSize=2:tabSize=8:noTabs=true:
1695
 */