Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-rpcap.c
blob23c79eca971d93403915e8c0d1327dff4540b0c9
1 /* packet-rpcap.c
3 * Routines for RPCAP message formats.
5 * Copyright 2008, Stig Bjorlykke <stig@bjorlykke.org>, Thales Norway AS
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
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>
27 #include "packet-frame.h"
28 #include "packet-pcap_pktdata.h"
29 #include "packet-tcp.h"
31 #define PNAME "Remote Packet Capture"
32 #define PSNAME "RPCAP"
33 #define PFNAME "rpcap"
35 #define RPCAP_MSG_ERROR 0x01
36 #define RPCAP_MSG_FINDALLIF_REQ 0x02
37 #define RPCAP_MSG_OPEN_REQ 0x03
38 #define RPCAP_MSG_STARTCAP_REQ 0x04
39 #define RPCAP_MSG_UPDATEFILTER_REQ 0x05
40 #define RPCAP_MSG_CLOSE 0x06
41 #define RPCAP_MSG_PACKET 0x07
42 #define RPCAP_MSG_AUTH_REQ 0x08
43 #define RPCAP_MSG_STATS_REQ 0x09
44 #define RPCAP_MSG_ENDCAP_REQ 0x0A
45 #define RPCAP_MSG_SETSAMPLING_REQ 0x0B
47 #define RPCAP_MSG_FINDALLIF_REPLY (0x80+RPCAP_MSG_FINDALLIF_REQ)
48 #define RPCAP_MSG_OPEN_REPLY (0x80+RPCAP_MSG_OPEN_REQ)
49 #define RPCAP_MSG_STARTCAP_REPLY (0x80+RPCAP_MSG_STARTCAP_REQ)
50 #define RPCAP_MSG_UPDATEFILTER_REPLY (0x80+RPCAP_MSG_UPDATEFILTER_REQ)
51 #define RPCAP_MSG_AUTH_REPLY (0x80+RPCAP_MSG_AUTH_REQ)
52 #define RPCAP_MSG_STATS_REPLY (0x80+RPCAP_MSG_STATS_REQ)
53 #define RPCAP_MSG_ENDCAP_REPLY (0x80+RPCAP_MSG_ENDCAP_REQ)
54 #define RPCAP_MSG_SETSAMPLING_REPLY (0x80+RPCAP_MSG_SETSAMPLING_REQ)
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
74 #define RPCAP_SAMP_NOSAMP 0
75 #define RPCAP_SAMP_1_EVERY_N 1
76 #define RPCAP_SAMP_FIRST_AFTER_N_MS 2
78 #define RPCAP_RMTAUTH_NULL 0
79 #define RPCAP_RMTAUTH_PWD 1
81 #define FLAG_PROMISC 0x0001
82 #define FLAG_DGRAM 0x0002
83 #define FLAG_SERVEROPEN 0x0004
84 #define FLAG_INBOUND 0x0008
85 #define FLAG_OUTBOUND 0x0010
87 void proto_register_rpcap (void);
88 void proto_reg_handoff_rpcap (void);
90 static int proto_rpcap;
92 static int hf_version;
93 static int hf_type;
94 static int hf_value;
95 static int hf_plen;
97 static int hf_error;
98 static int hf_error_value;
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;
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;
113 static int hf_auth_reply;
114 static int hf_auth_minvers;
115 static int hf_auth_maxvers;
117 static int hf_open_request;
119 static int hf_open_reply;
120 static int hf_linktype;
121 static int hf_tzoff;
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;
138 static int hf_filter;
139 static int hf_filtertype;
140 static int hf_nitems;
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;
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;
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;
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;
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;
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;
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;
216 static dissector_handle_t pcap_pktdata_handle;
217 static dissector_handle_t rpcap_tcp_handle;
219 /* User definable values */
220 static bool rpcap_desegment = true;
221 static bool decode_content = true;
222 static int global_linktype = -1;
224 /* Global variables */
225 static int linktype = -1;
226 static bool info_added;
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 }
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 }
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 }
279 static const value_string auth_type[] = {
280 { RPCAP_RMTAUTH_NULL, "None" },
281 { RPCAP_RMTAUTH_PWD, "Password" },
282 { 0, NULL }
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 }
297 static const value_string bpf_size[] = {
298 { 0x00, "w" },
299 { 0x01, "h" },
300 { 0x02, "b" },
301 { 0, NULL }
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 }
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 }
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 }
336 static const value_string bpf_src[] = {
337 { 0x00, "k" },
338 { 0x01, "x" },
339 { 0, NULL }
342 static const value_string bpf_rval[] = {
343 { 0x00, "k" },
344 { 0x01, "x" },
345 { 0x02, "a" },
346 { 0, NULL }
349 static const value_string bpf_misc_op[] = {
350 { 0x00, "tax" },
351 { 0x10, "txa" },
352 { 0, NULL }
356 static void rpcap_frame_end (void)
358 info_added = false;
362 static void
363 dissect_rpcap_error (tvbuff_t *tvb, packet_info *pinfo,
364 proto_tree *parent_tree, int offset)
366 proto_item *ti;
367 int len;
368 char *str;
370 len = tvb_reported_length_remaining (tvb, offset);
371 if (len <= 0)
372 return;
374 ti = proto_tree_add_item_ret_display_string(parent_tree, hf_error, tvb, offset, len, ENC_ASCII, pinfo->pool, &str);
375 expert_add_info_format(pinfo, ti, &ei_error, "Error: %s", str);
376 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", str);
380 * There's some painful history with this part of a findalldevs reply.
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.
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:
398 * (length << 8) | family if sent by a big-endian machine
399 * (length << 8) if sent by a little-endian machine
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.
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.)
412 * The current rpcapd serializes the socket addresses as 128-byte
413 * structures, containing:
415 * a 2-octet address family value, in network byte order;
417 * a 4-octet IPv4 address, if the address family value is 2
418 * (the AF_INET value on all supported platforms);
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);
426 * padding up to 128 bytes.
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.
434 * Possible IPv4 family values other than the designated over-the-wire value,
435 * which is 2 (because everybody uses 2 for AF_INET4).
437 #define SOCKADDR_IN_LEN 16 /* length of struct sockaddr_in */
438 #define NEW_BSD_AF_INET_BE ((SOCKADDR_IN_LEN << 8) | BSD_AF_INET)
439 #define NEW_BSD_AF_INET_LE (SOCKADDR_IN_LEN << 8)
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>.
448 * The new BSD sockaddr structure format was in place before 4.4-Lite, so
449 * all the free-software BSDs use it.
451 #define SOCKADDR_IN6_LEN 28 /* length of struct sockaddr_in6 */
452 #define NEW_BSD_AF_INET6_BSD_BE ((SOCKADDR_IN6_LEN << 8) | BSD_AF_INET6_BSD) /* NetBSD, OpenBSD, BSD/OS */
453 #define NEW_BSD_AF_INET6_FREEBSD_BE ((SOCKADDR_IN6_LEN << 8) | BSD_AF_INET6_FREEBSD) /* FreeBSD, DragonFly BSD */
454 #define NEW_BSD_AF_INET6_DARWIN_BE ((SOCKADDR_IN6_LEN << 8) | BSD_AF_INET6_DARWIN) /* macOS, iOS, anything else Darwin-based */
455 #define NEW_BSD_AF_INET6_LE (SOCKADDR_IN6_LEN << 8)
456 #define HPUX_AF_INET6 22
457 #define AIX_AF_INET6 24
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 }
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)
481 proto_tree *tree;
482 proto_item *ti;
483 uint16_t af;
484 ws_in4_addr ipv4;
485 ws_in6_addr ipv6;
486 char ipaddr[MAX_ADDR_STR_LEN];
488 ti = proto_tree_add_item (parent_tree, hf_id, tvb, offset, 128, ENC_BIG_ENDIAN);
489 tree = proto_item_add_subtree (ti, ett_ifaddr);
491 af = tvb_get_ntohs (tvb, offset);
492 proto_tree_add_item (tree, hf_if_af, tvb, offset, 2, ENC_BIG_ENDIAN);
493 offset += 2;
495 switch (af) {
497 case COMMON_AF_INET:
498 case NEW_BSD_AF_INET_BE:
499 case NEW_BSD_AF_INET_LE:
500 proto_tree_add_item (tree, hf_if_port, tvb, offset, 2, ENC_BIG_ENDIAN);
501 offset += 2;
503 ipv4 = tvb_get_ipv4 (tvb, offset);
504 ip_addr_to_str_buf(&ipv4, ipaddr, MAX_ADDR_STR_LEN);
505 proto_item_append_text (ti, ": %s", ipaddr);
506 if (parent_item) {
507 proto_item_append_text (parent_item, ": %s", ipaddr);
509 proto_tree_add_item (tree, hf_if_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
510 offset += 4;
512 proto_tree_add_item (tree, hf_if_padding, tvb, offset, 120, ENC_NA);
513 offset += 120;
514 break;
516 case WINSOCK_AF_INET6:
517 case NEW_BSD_AF_INET6_BSD_BE:
518 case NEW_BSD_AF_INET6_FREEBSD_BE:
519 case NEW_BSD_AF_INET6_DARWIN_BE:
520 case NEW_BSD_AF_INET6_LE:
521 case LINUX_AF_INET6:
522 case HPUX_AF_INET6:
523 case AIX_AF_INET6:
524 case SOLARIS_AF_INET6:
525 proto_tree_add_item (tree, hf_if_port, tvb, offset, 2, ENC_BIG_ENDIAN);
526 offset += 2;
528 proto_tree_add_item (tree, hf_if_flowinfo, tvb, offset, 4, ENC_BIG_ENDIAN);
529 offset += 4;
531 tvb_get_ipv6 (tvb, offset, &ipv6);
532 ip6_to_str_buf(&ipv6, ipaddr, MAX_ADDR_STR_LEN);
533 proto_item_append_text (ti, ": %s", ipaddr);
534 if (parent_item) {
535 proto_item_append_text (parent_item, ": %s", ipaddr);
537 proto_tree_add_item (tree, hf_if_ipv6, tvb, offset, 16, ENC_NA);
538 offset += 16;
540 proto_tree_add_item (tree, hf_if_scopeid, tvb, offset, 4, ENC_BIG_ENDIAN);
541 offset += 4;
543 proto_tree_add_item (tree, hf_if_padding, tvb, offset, 108, ENC_NA);
544 offset += 100;
545 break;
547 default:
548 ti = proto_tree_add_item (tree, hf_if_unknown, tvb, offset, 126, ENC_NA);
549 if (af != COMMON_AF_UNSPEC) {
550 expert_add_info_format(pinfo, ti, &ei_if_unknown,
551 "Unknown address family: %d", af);
553 offset += 126;
554 break;
557 return offset;
561 static int
562 dissect_rpcap_findalldevs_ifaddr (tvbuff_t *tvb, packet_info *pinfo _U_,
563 proto_tree *parent_tree, int offset)
565 proto_tree *tree;
566 proto_item *ti;
567 int boffset = offset;
569 ti = proto_tree_add_item (parent_tree, hf_findalldevs_ifaddr, tvb, offset, -1, ENC_NA);
570 tree = proto_item_add_subtree (ti, ett_findalldevs_ifaddr);
572 offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_addr, ti);
573 offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_netmask, NULL);
574 offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_broadaddr, NULL);
575 offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_dstaddr, NULL);
577 proto_item_set_len (ti, offset - boffset);
579 return offset;
583 static int
584 dissect_rpcap_findalldevs_if (tvbuff_t *tvb, packet_info *pinfo _U_,
585 proto_tree *parent_tree, int offset)
587 proto_tree *tree;
588 proto_item *ti;
589 uint16_t namelen, desclen, naddr, i;
590 int boffset = offset;
592 ti = proto_tree_add_item (parent_tree, hf_findalldevs_if, tvb, offset, -1, ENC_NA);
593 tree = proto_item_add_subtree (ti, ett_findalldevs_if);
595 namelen = tvb_get_ntohs (tvb, offset);
596 proto_tree_add_item (tree, hf_namelen, tvb, offset, 2, ENC_BIG_ENDIAN);
597 offset += 2;
599 desclen = tvb_get_ntohs (tvb, offset);
600 proto_tree_add_item (tree, hf_desclen, tvb, offset, 2, ENC_BIG_ENDIAN);
601 offset += 2;
603 proto_tree_add_item (tree, hf_if_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
604 offset += 4;
606 naddr = tvb_get_ntohs (tvb, offset);
607 proto_tree_add_item (tree, hf_naddr, tvb, offset, 2, ENC_BIG_ENDIAN);
608 offset += 2;
610 proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
611 offset += 2;
613 if (namelen) {
614 const uint8_t* name;
615 proto_tree_add_item_ret_string(tree, hf_if_name, tvb, offset, namelen, ENC_ASCII|ENC_NA, pinfo->pool, &name);
616 proto_item_append_text (ti, ": %s", name);
617 offset += namelen;
620 if (desclen) {
621 proto_tree_add_item (tree, hf_if_desc, tvb, offset, desclen, ENC_ASCII);
622 offset += desclen;
625 for (i = 0; i < naddr; i++) {
626 offset = dissect_rpcap_findalldevs_ifaddr (tvb, pinfo, tree, offset);
627 if (tvb_reported_length_remaining (tvb, offset) < 0) {
628 /* No more data in packet */
629 expert_add_info(pinfo, ti, &ei_no_more_data);
630 break;
634 proto_item_set_len (ti, offset - boffset);
636 return offset;
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)
644 proto_tree *tree;
645 proto_item *ti;
646 uint16_t i;
648 ti = proto_tree_add_item (parent_tree, hf_findalldevs_reply, tvb, offset, -1, ENC_NA);
649 tree = proto_item_add_subtree (ti, ett_findalldevs_reply);
651 for (i = 0; i < no_devs; i++) {
652 offset = dissect_rpcap_findalldevs_if (tvb, pinfo, tree, offset);
653 if (tvb_reported_length_remaining (tvb, offset) < 0) {
654 /* No more data in packet */
655 expert_add_info(pinfo, ti, &ei_no_more_data);
656 break;
660 proto_item_append_text (ti, ", %d item%s", no_devs, plurality (no_devs, "", "s"));
664 static int
665 dissect_rpcap_filterbpf_insn (tvbuff_t *tvb, packet_info *pinfo _U_,
666 proto_tree *parent_tree, int offset)
668 proto_tree *tree, *code_tree;
669 proto_item *ti, *code_ti;
670 uint8_t inst_class;
672 ti = proto_tree_add_item (parent_tree, hf_filterbpf_insn, tvb, offset, 8, ENC_NA);
673 tree = proto_item_add_subtree (ti, ett_filterbpf_insn);
675 code_ti = proto_tree_add_item (tree, hf_code, tvb, offset, 2, ENC_BIG_ENDIAN);
676 code_tree = proto_item_add_subtree (code_ti, ett_filterbpf_insn_code);
677 proto_tree_add_item (code_tree, hf_code_class, tvb, offset, 2, ENC_BIG_ENDIAN);
678 inst_class = tvb_get_uint8 (tvb, offset + 1) & 0x07;
679 proto_item_append_text (ti, ": %s", val_to_str_const (inst_class, bpf_class, ""));
680 switch (inst_class) {
681 case 0x00: /* ld */
682 case 0x01: /* ldx */
683 proto_tree_add_item (code_tree, hf_code_ld_size, tvb, offset, 2, ENC_BIG_ENDIAN);
684 proto_tree_add_item (code_tree, hf_code_ld_mode, tvb, offset, 2, ENC_BIG_ENDIAN);
685 break;
686 case 0x04: /* alu */
687 proto_tree_add_item (code_tree, hf_code_src, tvb, offset, 2, ENC_BIG_ENDIAN);
688 proto_tree_add_item (code_tree, hf_code_alu_op, tvb, offset, 2, ENC_BIG_ENDIAN);
689 break;
690 case 0x05: /* jmp */
691 proto_tree_add_item (code_tree, hf_code_src, tvb, offset, 2, ENC_BIG_ENDIAN);
692 proto_tree_add_item (code_tree, hf_code_jmp_op, tvb, offset, 2, ENC_BIG_ENDIAN);
693 break;
694 case 0x06: /* ret */
695 proto_tree_add_item (code_tree, hf_code_rval, tvb, offset, 2, ENC_BIG_ENDIAN);
696 break;
697 case 0x07: /* misc */
698 proto_tree_add_item (code_tree, hf_code_misc_op, tvb, offset, 2, ENC_BIG_ENDIAN);
699 break;
700 default:
701 proto_tree_add_item (code_tree, hf_code_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
702 break;
704 offset += 2;
706 proto_tree_add_item (tree, hf_jt, tvb, offset, 1, ENC_BIG_ENDIAN);
707 offset += 1;
709 proto_tree_add_item (tree, hf_jf, tvb, offset, 1, ENC_BIG_ENDIAN);
710 offset += 1;
712 proto_tree_add_item (tree, hf_instr_value, tvb, offset, 4, ENC_BIG_ENDIAN);
713 offset += 4;
715 return offset;
719 static void
720 dissect_rpcap_filter (tvbuff_t *tvb, packet_info *pinfo,
721 proto_tree *parent_tree, int offset)
723 proto_tree *tree;
724 proto_item *ti;
725 uint32_t nitems, i;
727 ti = proto_tree_add_item (parent_tree, hf_filter, tvb, offset, -1, ENC_NA);
728 tree = proto_item_add_subtree (ti, ett_filter);
730 proto_tree_add_item (tree, hf_filtertype, tvb, offset, 2, ENC_BIG_ENDIAN);
731 offset += 2;
733 proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
734 offset += 2;
736 nitems = tvb_get_ntohl (tvb, offset);
737 proto_tree_add_item (tree, hf_nitems, tvb, offset, 4, ENC_BIG_ENDIAN);
738 offset += 4;
740 for (i = 0; i < nitems; i++) {
741 offset = dissect_rpcap_filterbpf_insn (tvb, pinfo, tree, offset);
742 if (tvb_reported_length_remaining (tvb, offset) < 0) {
743 /* No more data in packet */
744 expert_add_info(pinfo, ti, &ei_no_more_data);
745 break;
751 static int
752 dissect_rpcap_auth_request (tvbuff_t *tvb, packet_info *pinfo _U_,
753 proto_tree *parent_tree, int offset)
755 proto_tree *tree;
756 proto_item *ti;
757 uint16_t type, slen1, slen2;
759 ti = proto_tree_add_item (parent_tree, hf_auth_request, tvb, offset, -1, ENC_NA);
760 tree = proto_item_add_subtree (ti, ett_auth_request);
762 type = tvb_get_ntohs (tvb, offset);
763 proto_tree_add_item (tree, hf_auth_type, tvb, offset, 2, ENC_BIG_ENDIAN);
764 offset += 2;
766 proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
767 offset += 2;
769 slen1 = tvb_get_ntohs (tvb, offset);
770 proto_tree_add_item (tree, hf_auth_slen1, tvb, offset, 2, ENC_BIG_ENDIAN);
771 offset += 2;
773 slen2 = tvb_get_ntohs (tvb, offset);
774 proto_tree_add_item (tree, hf_auth_slen2, tvb, offset, 2, ENC_BIG_ENDIAN);
775 offset += 2;
777 if (type == RPCAP_RMTAUTH_NULL) {
778 proto_item_append_text (ti, " (none)");
779 } else if (type == RPCAP_RMTAUTH_PWD) {
780 const uint8_t *username, *password;
782 proto_tree_add_item_ret_string(tree, hf_auth_username, tvb, offset, slen1, ENC_ASCII|ENC_NA, pinfo->pool, &username);
783 offset += slen1;
785 proto_tree_add_item_ret_string(tree, hf_auth_password, tvb, offset, slen2, ENC_ASCII|ENC_NA, pinfo->pool, &password);
786 offset += slen2;
788 proto_item_append_text (ti, " (%s/%s)", username, password);
790 return offset;
794 static void
795 dissect_rpcap_auth_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
796 proto_tree *parent_tree, int offset)
798 proto_tree *tree;
799 proto_item *ti;
800 uint32_t minvers, maxvers;
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.
807 if (tvb_reported_length_remaining(tvb, offset) != 0) {
808 ti = proto_tree_add_item (parent_tree, hf_auth_reply, tvb, offset, -1, ENC_NA);
809 tree = proto_item_add_subtree (ti, ett_auth_reply);
811 proto_tree_add_item_ret_uint (tree, hf_auth_minvers, tvb, offset, 1, ENC_BIG_ENDIAN, &minvers);
812 offset += 1;
814 proto_tree_add_item_ret_uint (tree, hf_auth_maxvers, tvb, offset, 1, ENC_BIG_ENDIAN, &maxvers);
816 proto_item_append_text (ti, ", minimum version %u, maximum version %u", minvers, maxvers);
821 static void
822 dissect_rpcap_open_request (tvbuff_t *tvb, packet_info *pinfo _U_,
823 proto_tree *parent_tree, int offset)
825 int len;
827 len = tvb_reported_length_remaining (tvb, offset);
828 proto_tree_add_item (parent_tree, hf_open_request, tvb, offset, len, ENC_ASCII);
832 static void
833 dissect_rpcap_open_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
834 proto_tree *parent_tree, int offset)
836 proto_tree *tree;
837 proto_item *ti;
839 ti = proto_tree_add_item (parent_tree, hf_open_reply, tvb, offset, -1, ENC_NA);
840 tree = proto_item_add_subtree (ti, ett_open_reply);
842 linktype = tvb_get_ntohl (tvb, offset);
843 proto_tree_add_item (tree, hf_linktype, tvb, offset, 4, ENC_BIG_ENDIAN);
844 offset += 4;
846 proto_tree_add_item (tree, hf_tzoff, tvb, offset, 4, ENC_BIG_ENDIAN);
850 static void
851 dissect_rpcap_startcap_request (tvbuff_t *tvb, packet_info *pinfo,
852 proto_tree *parent_tree, int offset)
854 proto_tree *tree, *field_tree;
855 proto_item *ti, *field_ti;
856 uint16_t flags;
858 ti = proto_tree_add_item (parent_tree, hf_startcap_request, tvb, offset, -1, ENC_NA);
859 tree = proto_item_add_subtree (ti, ett_startcap_request);
861 proto_tree_add_item (tree, hf_snaplen, tvb, offset, 4, ENC_BIG_ENDIAN);
862 offset += 4;
864 proto_tree_add_item (tree, hf_read_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
865 offset += 4;
867 flags = tvb_get_ntohs (tvb, offset);
868 field_ti = proto_tree_add_uint_format (tree, hf_flags, tvb, offset, 2, flags, "Flags");
869 field_tree = proto_item_add_subtree (field_ti, ett_startcap_flags);
870 proto_tree_add_item (field_tree, hf_flags_promisc, tvb, offset, 2, ENC_BIG_ENDIAN);
871 proto_tree_add_item (field_tree, hf_flags_dgram, tvb, offset, 2, ENC_BIG_ENDIAN);
872 proto_tree_add_item (field_tree, hf_flags_serveropen, tvb, offset, 2, ENC_BIG_ENDIAN);
873 proto_tree_add_item (field_tree, hf_flags_inbound, tvb, offset, 2, ENC_BIG_ENDIAN);
874 proto_tree_add_item (field_tree, hf_flags_outbound, tvb, offset, 2, ENC_BIG_ENDIAN);
876 if (flags & 0x1F) {
877 char *flagstr = wmem_strdup_printf (pinfo->pool, "%s%s%s%s%s",
878 (flags & FLAG_PROMISC) ? ", Promiscuous" : "",
879 (flags & FLAG_DGRAM) ? ", Datagram" : "",
880 (flags & FLAG_SERVEROPEN) ? ", ServerOpen" : "",
881 (flags & FLAG_INBOUND) ? ", Inbound" : "",
882 (flags & FLAG_OUTBOUND) ? ", Outbound" : "");
883 proto_item_append_text (field_ti, ":%s", &flagstr[1]);
884 } else {
885 proto_item_append_text (field_ti, " (none)");
887 offset += 2;
889 proto_tree_add_item (tree, hf_client_port, tvb, offset, 2, ENC_BIG_ENDIAN);
890 offset += 2;
892 dissect_rpcap_filter (tvb, pinfo, tree, offset);
896 static void
897 dissect_rpcap_startcap_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
898 proto_tree *parent_tree, int offset)
900 proto_tree *tree;
901 proto_item *ti;
903 ti = proto_tree_add_item (parent_tree, hf_startcap_reply, tvb, offset, -1, ENC_NA);
904 tree = proto_item_add_subtree (ti, ett_startcap_reply);
906 proto_tree_add_item (tree, hf_bufsize, tvb, offset, 4, ENC_BIG_ENDIAN);
907 offset += 4;
909 proto_tree_add_item (tree, hf_server_port, tvb, offset, 2, ENC_BIG_ENDIAN);
910 offset += 2;
912 proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
916 static void
917 dissect_rpcap_stats_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
918 proto_tree *parent_tree, int offset)
920 proto_tree *tree;
921 proto_item *ti;
923 ti = proto_tree_add_item (parent_tree, hf_stats_reply, tvb, offset, 16, ENC_NA);
924 tree = proto_item_add_subtree (ti, ett_stats_reply);
926 proto_tree_add_item (tree, hf_ifrecv, tvb, offset, 4, ENC_BIG_ENDIAN);
927 offset += 4;
929 proto_tree_add_item (tree, hf_ifdrop, tvb, offset, 4, ENC_BIG_ENDIAN);
930 offset += 4;
932 proto_tree_add_item (tree, hf_krnldrop, tvb, offset, 4, ENC_BIG_ENDIAN);
933 offset += 4;
935 proto_tree_add_item (tree, hf_srvcapt, tvb, offset, 4, ENC_BIG_ENDIAN);
939 static int
940 dissect_rpcap_sampling_request (tvbuff_t *tvb, packet_info *pinfo _U_,
941 proto_tree *parent_tree, int offset)
943 proto_tree *tree;
944 proto_item *ti;
945 uint32_t value;
946 uint8_t method;
948 ti = proto_tree_add_item (parent_tree, hf_sampling_request, tvb, offset, -1, ENC_NA);
949 tree = proto_item_add_subtree (ti, ett_sampling_request);
951 method = tvb_get_uint8 (tvb, offset);
952 proto_tree_add_item (tree, hf_sampling_method, tvb, offset, 1, ENC_BIG_ENDIAN);
953 offset += 1;
955 proto_tree_add_item (tree, hf_sampling_dummy1, tvb, offset, 1, ENC_BIG_ENDIAN);
956 offset += 1;
958 proto_tree_add_item (tree, hf_sampling_dummy2, tvb, offset, 2, ENC_BIG_ENDIAN);
959 offset += 2;
961 value = tvb_get_ntohl (tvb, offset);
962 proto_tree_add_item (tree, hf_sampling_value, tvb, offset, 4, ENC_BIG_ENDIAN);
963 offset += 4;
965 switch (method) {
966 case RPCAP_SAMP_NOSAMP:
967 proto_item_append_text (ti, ": None");
968 break;
969 case RPCAP_SAMP_1_EVERY_N:
970 proto_item_append_text (ti, ": 1 every %d", value);
971 break;
972 case RPCAP_SAMP_FIRST_AFTER_N_MS:
973 proto_item_append_text (ti, ": First after %d ms", value);
974 break;
975 default:
976 break;
978 return offset;
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)
986 proto_tree *tree;
987 proto_item *ti;
988 tvbuff_t *new_tvb;
989 unsigned caplen, len, frame_no;
990 int reported_length_remaining;
992 ti = proto_tree_add_item (parent_tree, hf_packet, tvb, offset, 20, ENC_NA);
993 tree = proto_item_add_subtree (ti, ett_packet);
995 proto_tree_add_item(tree, hf_timestamp, tvb, offset, 8, ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN);
996 offset += 8;
998 caplen = tvb_get_ntohl (tvb, offset);
999 ti = proto_tree_add_item (tree, hf_caplen, tvb, offset, 4, ENC_BIG_ENDIAN);
1000 offset += 4;
1002 len = tvb_get_ntohl (tvb, offset);
1003 proto_tree_add_item (tree, hf_len, tvb, offset, 4, ENC_BIG_ENDIAN);
1004 offset += 4;
1006 frame_no = tvb_get_ntohl (tvb, offset);
1007 proto_tree_add_item (tree, hf_npkt, tvb, offset, 4, ENC_BIG_ENDIAN);
1008 offset += 4;
1010 proto_item_append_text (ti, ", Frame %u", frame_no);
1011 proto_item_append_text (top_item, " Frame %u", frame_no);
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.
1017 reported_length_remaining = tvb_reported_length_remaining (tvb, offset);
1018 if (caplen > (unsigned)reported_length_remaining) {
1019 expert_add_info(pinfo, ti, &ei_caplen_too_big);
1020 return;
1023 new_tvb = tvb_new_subset_length_caplen (tvb, offset, caplen, len);
1024 if (decode_content && linktype != -1) {
1025 TRY {
1026 call_dissector_with_data(pcap_pktdata_handle, new_tvb, pinfo, top_tree, &linktype);
1028 CATCH_BOUNDS_ERRORS {
1029 show_exception(tvb, pinfo, top_tree, EXCEPT_CODE, GET_MESSAGE);
1031 ENDTRY;
1033 if (!info_added) {
1034 /* Only indicate when not added before */
1035 /* Indicate RPCAP in the protocol column */
1036 col_prepend_fence_fstr(pinfo->cinfo, COL_PROTOCOL, "R|");
1038 /* Indicate RPCAP in the info column */
1039 col_prepend_fence_fstr (pinfo->cinfo, COL_INFO, "Remote | ");
1040 info_added = true;
1041 register_frame_end_routine(pinfo, rpcap_frame_end);
1043 } else {
1044 if (linktype == -1) {
1045 proto_item_append_text (ti, ", Unknown link-layer type");
1047 call_data_dissector(new_tvb, pinfo, top_tree);
1052 static int
1053 dissect_rpcap (tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, void* data _U_)
1055 proto_tree *tree;
1056 proto_item *ti;
1057 tvbuff_t *new_tvb;
1058 int len, offset = 0;
1059 uint8_t msg_type;
1060 uint16_t msg_value;
1062 col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME);
1064 col_clear(pinfo->cinfo, COL_INFO);
1066 ti = proto_tree_add_item (top_tree, proto_rpcap, tvb, offset, -1, ENC_NA);
1067 tree = proto_item_add_subtree (ti, ett_rpcap);
1069 proto_tree_add_item (tree, hf_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1070 offset++;
1072 msg_type = tvb_get_uint8 (tvb, offset);
1073 proto_tree_add_item (tree, hf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1074 offset++;
1076 col_append_str (pinfo->cinfo, COL_INFO,
1077 val_to_str (msg_type, message_type, "Unknown: 0x%02x"));
1079 proto_item_append_text (ti, ", %s", val_to_str (msg_type, message_type, "Unknown: 0x%02x"));
1081 msg_value = tvb_get_ntohs (tvb, offset);
1082 if (msg_type == RPCAP_MSG_ERROR) {
1083 proto_tree_add_item (tree, hf_error_value, tvb, offset, 2, ENC_BIG_ENDIAN);
1084 } else {
1085 proto_tree_add_item (tree, hf_value, tvb, offset, 2, ENC_BIG_ENDIAN);
1087 offset += 2;
1089 proto_tree_add_item (tree, hf_plen, tvb, offset, 4, ENC_BIG_ENDIAN);
1090 offset += 4;
1093 switch (msg_type) {
1094 case RPCAP_MSG_ERROR:
1095 dissect_rpcap_error (tvb, pinfo, tree, offset);
1096 break;
1097 case RPCAP_MSG_OPEN_REQ:
1098 dissect_rpcap_open_request (tvb, pinfo, tree, offset);
1099 break;
1100 case RPCAP_MSG_STARTCAP_REQ:
1101 dissect_rpcap_startcap_request (tvb, pinfo, tree, offset);
1102 break;
1103 case RPCAP_MSG_UPDATEFILTER_REQ:
1104 dissect_rpcap_filter (tvb, pinfo, tree, offset);
1105 break;
1106 case RPCAP_MSG_PACKET:
1107 proto_item_set_len (ti, 28);
1108 dissect_rpcap_packet (tvb, pinfo, top_tree, tree, offset, ti);
1109 break;
1110 case RPCAP_MSG_AUTH_REQ:
1111 dissect_rpcap_auth_request (tvb, pinfo, tree, offset);
1112 break;
1113 case RPCAP_MSG_SETSAMPLING_REQ:
1114 dissect_rpcap_sampling_request (tvb, pinfo, tree, offset);
1115 break;
1116 case RPCAP_MSG_AUTH_REPLY:
1117 dissect_rpcap_auth_reply (tvb, pinfo, tree, offset);
1118 break;
1119 case RPCAP_MSG_FINDALLIF_REPLY:
1120 dissect_rpcap_findalldevs_reply (tvb, pinfo, tree, offset, msg_value);
1121 break;
1122 case RPCAP_MSG_OPEN_REPLY:
1123 dissect_rpcap_open_reply (tvb, pinfo, tree, offset);
1124 break;
1125 case RPCAP_MSG_STARTCAP_REPLY:
1126 dissect_rpcap_startcap_reply (tvb, pinfo, tree, offset);
1127 break;
1128 case RPCAP_MSG_STATS_REPLY:
1129 dissect_rpcap_stats_reply (tvb, pinfo, tree, offset);
1130 break;
1131 default:
1132 len = tvb_reported_length_remaining (tvb, offset);
1133 if (len) {
1134 /* Yet unknown, dump as data */
1135 proto_item_set_len (ti, 8);
1136 new_tvb = tvb_new_subset_remaining (tvb, offset);
1137 call_data_dissector(new_tvb, pinfo, top_tree);
1139 break;
1142 return tvb_captured_length(tvb);
1146 static bool
1147 check_rpcap_heur (tvbuff_t *tvb, bool tcp)
1149 int offset = 0;
1150 uint8_t version, msg_type;
1151 uint16_t msg_value;
1152 uint32_t plen, len, caplen;
1154 if (tvb_captured_length (tvb) < 8)
1155 /* Too short */
1156 return false;
1158 version = tvb_get_uint8 (tvb, offset);
1159 if (version != 0)
1160 /* Incorrect version */
1161 return false;
1162 offset++;
1164 msg_type = tvb_get_uint8 (tvb, offset);
1165 if (!tcp && msg_type != 7) {
1166 /* UDP is only used for packets */
1167 return false;
1169 if (try_val_to_str(msg_type, message_type) == NULL)
1170 /* Unknown message type */
1171 return false;
1172 offset++;
1174 msg_value = tvb_get_ntohs (tvb, offset);
1175 if (msg_value > 0) {
1176 if (msg_type == RPCAP_MSG_ERROR) {
1177 /* Must have a valid error code */
1178 if (try_val_to_str(msg_value, error_codes) == NULL)
1179 return false;
1180 } else if (msg_type != RPCAP_MSG_FINDALLIF_REPLY) {
1181 return false;
1184 offset += 2;
1186 plen = tvb_get_ntohl (tvb, offset);
1187 offset += 4;
1188 len = (uint32_t) tvb_reported_length_remaining (tvb, offset);
1190 switch (msg_type) {
1192 case RPCAP_MSG_FINDALLIF_REQ:
1193 case RPCAP_MSG_UPDATEFILTER_REPLY:
1194 case RPCAP_MSG_STATS_REQ:
1195 case RPCAP_MSG_CLOSE:
1196 case RPCAP_MSG_SETSAMPLING_REPLY:
1197 case RPCAP_MSG_ENDCAP_REQ:
1198 case RPCAP_MSG_ENDCAP_REPLY:
1199 /* Empty payload */
1200 if (plen != 0 || len != 0)
1201 return false;
1202 break;
1204 case RPCAP_MSG_OPEN_REPLY:
1205 case RPCAP_MSG_STARTCAP_REPLY:
1206 case RPCAP_MSG_SETSAMPLING_REQ:
1207 /* Always 8 bytes */
1208 if (plen != 8 || len != 8)
1209 return false;
1210 break;
1212 case RPCAP_MSG_STATS_REPLY:
1213 /* Always 16 bytes */
1214 if (plen != 16 || len != 16)
1215 return false;
1216 break;
1218 case RPCAP_MSG_PACKET:
1219 /* Must have the frame header */
1220 if (plen < 20)
1221 return false;
1223 /* Check if capture length is valid */
1224 caplen = tvb_get_ntohl (tvb, offset+8);
1225 /* Always 20 bytes less than packet length */
1226 if (caplen != (plen - 20) || caplen > 65535)
1227 return false;
1228 break;
1230 case RPCAP_MSG_FINDALLIF_REPLY:
1231 case RPCAP_MSG_ERROR:
1232 case RPCAP_MSG_OPEN_REQ:
1233 case RPCAP_MSG_STARTCAP_REQ:
1234 case RPCAP_MSG_UPDATEFILTER_REQ:
1235 case RPCAP_MSG_AUTH_REQ:
1236 case RPCAP_MSG_AUTH_REPLY:
1237 /* Variable length */
1238 if (plen != len)
1239 return false;
1240 break;
1241 default:
1242 /* Unknown message type */
1243 return false;
1246 return true;
1250 static unsigned
1251 get_rpcap_pdu_len (packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1253 return tvb_get_ntohl (tvb, offset + 4) + 8;
1257 static int
1258 dissect_rpcap_tcp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1260 tcp_dissect_pdus (tvb, pinfo, tree, rpcap_desegment, 8,
1261 get_rpcap_pdu_len, dissect_rpcap, data);
1262 return tvb_captured_length (tvb);
1265 static bool
1266 dissect_rpcap_heur_tcp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1268 if (check_rpcap_heur (tvb, true)) {
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.
1275 conversation_t *conversation = find_conversation_pinfo (pinfo, 0);
1276 if (conversation)
1277 conversation_set_dissector_from_frame_number (conversation,
1278 pinfo->num,
1279 rpcap_tcp_handle);
1280 tcp_dissect_pdus (tvb, pinfo, tree, rpcap_desegment, 8,
1281 get_rpcap_pdu_len, dissect_rpcap, data);
1283 return true;
1286 return false;
1290 static bool
1291 dissect_rpcap_heur_udp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1293 if (check_rpcap_heur (tvb, false)) {
1294 /* This is probably a rpcap udp package */
1295 dissect_rpcap (tvb, pinfo, tree, data);
1297 return true;
1300 return false;
1304 void
1305 proto_register_rpcap (void)
1307 static hf_register_info hf[] = {
1308 /* Common header for all messages */
1309 { &hf_version,
1310 { "Version", "rpcap.version", FT_UINT8, BASE_DEC,
1311 NULL, 0x0, NULL, HFILL } },
1312 { &hf_type,
1313 { "Message type", "rpcap.type", FT_UINT8, BASE_HEX,
1314 VALS(message_type), 0x0, NULL, HFILL } },
1315 { &hf_value,
1316 { "Message value", "rpcap.value", FT_UINT16, BASE_DEC,
1317 NULL, 0x0, NULL, HFILL } },
1318 { &hf_plen,
1319 { "Payload length", "rpcap.len", FT_UINT32, BASE_DEC,
1320 NULL, 0x0, NULL, HFILL } },
1322 /* Error */
1323 { &hf_error,
1324 { "Error", "rpcap.error", FT_STRING, BASE_STR_WSP,
1325 NULL, 0x0, "Error text", HFILL } },
1326 { &hf_error_value,
1327 { "Error value", "rpcap.error_value", FT_UINT16, BASE_DEC,
1328 VALS(error_codes), 0x0, NULL, HFILL } },
1330 /* Packet header */
1331 { &hf_packet,
1332 { "Packet", "rpcap.packet", FT_NONE, BASE_NONE,
1333 NULL, 0x0, "Packet data", HFILL } },
1334 { &hf_timestamp,
1335 { "Arrival time", "rpcap.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
1336 NULL, 0x0, NULL, HFILL } },
1337 { &hf_caplen,
1338 { "Capture length", "rpcap.cap_len", FT_UINT32, BASE_DEC,
1339 NULL, 0x0, NULL, HFILL } },
1340 { &hf_len,
1341 { "Frame length", "rpcap.len", FT_UINT32, BASE_DEC,
1342 NULL, 0x0, "Frame length (off wire)", HFILL } },
1343 { &hf_npkt,
1344 { "Frame number", "rpcap.number", FT_UINT32, BASE_DEC,
1345 NULL, 0x0, NULL, HFILL } },
1347 /* Authentication request */
1348 { &hf_auth_request,
1349 { "Authentication request", "rpcap.auth_request", FT_NONE, BASE_NONE,
1350 NULL, 0x0, NULL, HFILL } },
1351 { &hf_auth_type,
1352 { "Authentication type", "rpcap.auth_type", FT_UINT16, BASE_DEC,
1353 VALS(auth_type), 0x0, NULL, HFILL } },
1354 { &hf_auth_slen1,
1355 { "Authentication item length 1", "rpcap.auth_len1", FT_UINT16, BASE_DEC,
1356 NULL, 0x0, NULL, HFILL } },
1357 { &hf_auth_slen2,
1358 { "Authentication item length 2", "rpcap.auth_len2", FT_UINT16, BASE_DEC,
1359 NULL, 0x0, NULL, HFILL } },
1360 { &hf_auth_username,
1361 { "Username", "rpcap.username", FT_STRING, BASE_NONE,
1362 NULL, 0x0, NULL, HFILL } },
1363 { &hf_auth_password,
1364 { "Password", "rpcap.password", FT_STRING, BASE_NONE,
1365 NULL, 0x0, NULL, HFILL } },
1367 /* Authentication reply */
1368 { &hf_auth_reply,
1369 { "Authentication reply", "rpcap.auth_reply", FT_NONE, BASE_NONE,
1370 NULL, 0x0, NULL, HFILL } },
1371 { &hf_auth_minvers,
1372 { "Minimum version number supported", "rpcap.auth_minvers", FT_UINT8, BASE_DEC,
1373 NULL, 0x0, NULL, HFILL } },
1374 { &hf_auth_maxvers,
1375 { "Maximum version number supported", "rpcap.auth_maxvers", FT_UINT8, BASE_DEC,
1376 NULL, 0x0, NULL, HFILL } },
1378 /* Open request */
1379 { &hf_open_request,
1380 { "Open request", "rpcap.open_request", FT_STRING, BASE_NONE,
1381 NULL, 0x0, NULL, HFILL } },
1383 /* Open reply */
1384 { &hf_open_reply,
1385 { "Open reply", "rpcap.open_reply", FT_NONE, BASE_NONE,
1386 NULL, 0x0, NULL, HFILL } },
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.
1395 { &hf_linktype,
1396 { "Link type", "rpcap.linktype", FT_UINT32, BASE_DEC,
1397 VALS(link_type_vals), 0x0, NULL, HFILL } },
1398 { &hf_tzoff,
1399 { "Timezone offset", "rpcap.tzoff", FT_UINT32, BASE_DEC,
1400 NULL, 0x0, NULL, HFILL } },
1402 /* Start capture request */
1403 { &hf_startcap_request,
1404 { "Start capture request", "rpcap.startcap_request", FT_NONE, BASE_NONE,
1405 NULL, 0x0, NULL, HFILL } },
1406 { &hf_snaplen,
1407 { "Snap length", "rpcap.snaplen", FT_UINT32, BASE_DEC,
1408 NULL, 0x0, NULL, HFILL } },
1409 { &hf_read_timeout,
1410 { "Read timeout", "rpcap.read_timeout", FT_UINT32, BASE_DEC,
1411 NULL, 0x0, NULL, HFILL } },
1412 { &hf_flags,
1413 { "Flags", "rpcap.flags", FT_UINT16, BASE_DEC,
1414 NULL, 0x0, "Capture flags", HFILL } },
1415 { &hf_flags_promisc,
1416 { "Promiscuous mode", "rpcap.flags.promisc", FT_BOOLEAN, 16,
1417 TFS(&tfs_enabled_disabled), FLAG_PROMISC, NULL, HFILL } },
1418 { &hf_flags_dgram,
1419 { "Use Datagram", "rpcap.flags.dgram", FT_BOOLEAN, 16,
1420 TFS(&tfs_yes_no), FLAG_DGRAM, NULL, HFILL } },
1421 { &hf_flags_serveropen,
1422 { "Server open", "rpcap.flags.serveropen", FT_BOOLEAN, 16,
1423 TFS(&tfs_open_closed), FLAG_SERVEROPEN, NULL, HFILL } },
1424 { &hf_flags_inbound,
1425 { "Inbound", "rpcap.flags.inbound", FT_BOOLEAN, 16,
1426 TFS(&tfs_yes_no), FLAG_INBOUND, NULL, HFILL } },
1427 { &hf_flags_outbound,
1428 { "Outbound", "rpcap.flags.outbound", FT_BOOLEAN, 16,
1429 TFS(&tfs_yes_no), FLAG_OUTBOUND, NULL, HFILL } },
1430 { &hf_client_port,
1431 { "Client Port", "rpcap.client_port", FT_UINT16, BASE_DEC,
1432 NULL, 0x0, NULL, HFILL } },
1434 /* Start capture reply */
1435 { &hf_startcap_reply,
1436 { "Start capture reply", "rpcap.startcap_reply", FT_NONE, BASE_NONE,
1437 NULL, 0x0, NULL, HFILL } },
1438 { &hf_bufsize,
1439 { "Buffer size", "rpcap.bufsize", FT_UINT32, BASE_DEC,
1440 NULL, 0x0, NULL, HFILL } },
1441 { &hf_server_port,
1442 { "Server port", "rpcap.server_port", FT_UINT16, BASE_DEC,
1443 NULL, 0x0, NULL, HFILL } },
1444 { &hf_dummy,
1445 { "Dummy", "rpcap.dummy", FT_UINT16, BASE_DEC,
1446 NULL, 0x0, NULL, HFILL } },
1448 /* Filter */
1449 { &hf_filter,
1450 { "Filter", "rpcap.filter", FT_NONE, BASE_NONE,
1451 NULL, 0x0, NULL, HFILL } },
1452 { &hf_filtertype,
1453 { "Filter type", "rpcap.filtertype", FT_UINT16, BASE_DEC,
1454 NULL, 0x0, "Filter type (BPF)", HFILL } },
1455 { &hf_nitems,
1456 { "Number of items", "rpcap.nitems", FT_UINT32, BASE_DEC,
1457 NULL, 0x0, NULL, HFILL } },
1459 /* Filter BPF instruction */
1460 { &hf_filterbpf_insn,
1461 { "Filter BPF instruction", "rpcap.filterbpf_insn", FT_NONE, BASE_NONE,
1462 NULL, 0x0, NULL, HFILL } },
1463 { &hf_code,
1464 { "Op code", "rpcap.opcode", FT_UINT16, BASE_HEX,
1465 NULL, 0x0, "Operation code", HFILL } },
1466 { &hf_code_class,
1467 { "Class", "rpcap.opcode.class", FT_UINT16, BASE_HEX,
1468 VALS(bpf_class), 0x07, "Instruction Class", HFILL } },
1469 { &hf_code_fields,
1470 { "Fields", "rpcap.opcode.fields", FT_UINT16, BASE_HEX,
1471 NULL, 0xF8, "Class Fields", HFILL } },
1472 { &hf_code_ld_size,
1473 { "Size", "rpcap.opcode.size", FT_UINT16, BASE_HEX,
1474 VALS(bpf_size), 0x18, NULL, HFILL } },
1475 { &hf_code_ld_mode,
1476 { "Mode", "rpcap.opcode.mode", FT_UINT16, BASE_HEX,
1477 VALS(bpf_mode), 0xE0, NULL, HFILL } },
1478 { &hf_code_alu_op,
1479 { "Op", "rpcap.opcode.aluop", FT_UINT16, BASE_HEX,
1480 VALS(bpf_alu_op), 0xF0, NULL, HFILL } },
1481 { &hf_code_jmp_op,
1482 { "Op", "rpcap.opcode.jmpop", FT_UINT16, BASE_HEX,
1483 VALS(bpf_jmp_op), 0xF0, NULL, HFILL } },
1484 { &hf_code_src,
1485 { "Src", "rpcap.opcode.src", FT_UINT16, BASE_HEX,
1486 VALS(bpf_src), 0x08, NULL, HFILL } },
1487 { &hf_code_rval,
1488 { "Rval", "rpcap.opcode.rval", FT_UINT16, BASE_HEX,
1489 VALS(bpf_rval), 0x18, NULL, HFILL } },
1490 { &hf_code_misc_op,
1491 { "Op", "rpcap.opcode.miscop", FT_UINT16, BASE_HEX,
1492 VALS(bpf_misc_op), 0xF8, NULL, HFILL } },
1493 { &hf_jt,
1494 { "JT", "rpcap.jt", FT_UINT8, BASE_DEC,
1495 NULL, 0x0, NULL, HFILL } },
1496 { &hf_jf,
1497 { "JF", "rpcap.jf", FT_UINT8, BASE_DEC,
1498 NULL, 0x0, NULL, HFILL } },
1499 { &hf_instr_value,
1500 { "Instruction value", "rpcap.instr_value", FT_UINT32, BASE_DEC,
1501 NULL, 0x0, "Instruction-Dependent value", HFILL } },
1503 /* Statistics reply */
1504 { &hf_stats_reply,
1505 { "Statistics", "rpcap.stats_reply", FT_NONE, BASE_NONE,
1506 NULL, 0x0, "Statistics reply data", HFILL } },
1507 { &hf_ifrecv,
1508 { "Received by kernel filter", "rpcap.ifrecv", FT_UINT32, BASE_DEC,
1509 NULL, 0x0, NULL, HFILL } },
1510 { &hf_ifdrop,
1511 { "Dropped by network interface", "rpcap.ifdrop", FT_UINT32, BASE_DEC,
1512 NULL, 0x0, NULL, HFILL } },
1513 { &hf_krnldrop,
1514 { "Dropped by kernel filter", "rpcap.krnldrop", FT_UINT32, BASE_DEC,
1515 NULL, 0x0, NULL, HFILL } },
1516 { &hf_srvcapt,
1517 { "Captured by rpcapd", "rpcap.srvcapt", FT_UINT32, BASE_DEC,
1518 NULL, 0x0, "Captured by RPCAP daemon", HFILL } },
1520 /* Find all devices reply */
1521 { &hf_findalldevs_reply,
1522 { "Find all devices", "rpcap.findalldevs_reply", FT_NONE, BASE_NONE,
1523 NULL, 0x0, NULL, HFILL } },
1524 { &hf_findalldevs_if,
1525 { "Interface", "rpcap.if", FT_NONE, BASE_NONE,
1526 NULL, 0x0, NULL, HFILL } },
1527 { &hf_namelen,
1528 { "Name length", "rpcap.namelen", FT_UINT16, BASE_DEC,
1529 NULL, 0x0, NULL, HFILL } },
1530 { &hf_desclen,
1531 { "Description length", "rpcap.desclen", FT_UINT32, BASE_DEC,
1532 NULL, 0x0, NULL, HFILL } },
1533 { &hf_if_flags,
1534 { "Interface flags", "rpcap.if.flags", FT_UINT32, BASE_DEC,
1535 NULL, 0x0, NULL, HFILL } },
1536 { &hf_naddr,
1537 { "Number of addresses", "rpcap.naddr", FT_UINT32, BASE_DEC,
1538 NULL, 0x0, NULL, HFILL } },
1539 { &hf_if_name,
1540 { "Name", "rpcap.ifname", FT_STRING, BASE_NONE,
1541 NULL, 0x0, "Interface name", HFILL } },
1542 { &hf_if_desc,
1543 { "Description", "rpcap.ifdesc", FT_STRING, BASE_NONE,
1544 NULL, 0x0, "Interface description", HFILL } },
1546 /* Find all devices / Interface addresses */
1547 { &hf_findalldevs_ifaddr,
1548 { "Interface address", "rpcap.ifaddr", FT_NONE, BASE_NONE,
1549 NULL, 0x0, NULL, HFILL } },
1550 { &hf_if_addr,
1551 { "Address", "rpcap.addr", FT_NONE, BASE_NONE,
1552 NULL, 0x0, "Network address", HFILL } },
1553 { &hf_if_netmask,
1554 { "Netmask", "rpcap.netmask", FT_NONE, BASE_NONE,
1555 NULL, 0x0, NULL, HFILL } },
1556 { &hf_if_broadaddr,
1557 { "Broadcast", "rpcap.broadaddr", FT_NONE, BASE_NONE,
1558 NULL, 0x0, NULL, HFILL } },
1559 { &hf_if_dstaddr,
1560 { "P2P destination address", "rpcap.dstaddr", FT_NONE, BASE_NONE,
1561 NULL, 0x0, NULL, HFILL } },
1562 { &hf_if_af,
1563 { "Address family", "rpcap.if.af", FT_UINT16, BASE_HEX,
1564 VALS(address_family), 0x0, NULL, HFILL } },
1565 { &hf_if_port,
1566 { "Port", "rpcap.if.port", FT_UINT16, BASE_DEC,
1567 NULL, 0x0, "Port number", HFILL } },
1568 { &hf_if_ipv4,
1569 { "IPv4 address", "rpcap.if.ipv4", FT_IPv4, BASE_NONE,
1570 NULL, 0x0, NULL, HFILL } },
1571 { &hf_if_flowinfo,
1572 { "Flow information", "rpcap.if.flowinfo", FT_UINT32, BASE_HEX,
1573 NULL, 0x0, NULL, HFILL } },
1574 { &hf_if_ipv6,
1575 { "IPv6 address", "rpcap.if.ipv6", FT_IPv6, BASE_NONE,
1576 NULL, 0x0, NULL, HFILL } },
1577 { &hf_if_scopeid,
1578 { "Scope ID", "rpcap.if.scopeid", FT_UINT32, BASE_HEX,
1579 NULL, 0x0, NULL, HFILL } },
1580 { &hf_if_padding,
1581 { "Padding", "rpcap.if.padding", FT_BYTES, BASE_NONE,
1582 NULL, 0x0, NULL, HFILL } },
1583 { &hf_if_unknown,
1584 { "Unknown address", "rpcap.if.unknown", FT_BYTES, BASE_NONE,
1585 NULL, 0x0, NULL, HFILL } },
1587 /* Sampling request */
1588 { &hf_sampling_request,
1589 { "Sampling", "rpcap.sampling_request", FT_NONE, BASE_NONE,
1590 NULL, 0x0, NULL, HFILL } },
1591 { &hf_sampling_method,
1592 { "Method", "rpcap.sampling_method", FT_UINT8, BASE_DEC,
1593 VALS(sampling_method), 0x0, "Sampling method", HFILL } },
1594 { &hf_sampling_dummy1,
1595 { "Dummy1", "rpcap.dummy", FT_UINT8, BASE_DEC,
1596 NULL, 0x0, NULL, HFILL } },
1597 { &hf_sampling_dummy2,
1598 { "Dummy2", "rpcap.dummy", FT_UINT16, BASE_DEC,
1599 NULL, 0x0, NULL, HFILL } },
1600 { &hf_sampling_value,
1601 { "Value", "rpcap.sampling_value", FT_UINT32, BASE_DEC,
1602 NULL, 0x0, NULL, HFILL } },
1605 static int *ett[] = {
1606 &ett_rpcap,
1607 &ett_error,
1608 &ett_packet,
1609 &ett_auth_request,
1610 &ett_auth_reply,
1611 &ett_open_reply,
1612 &ett_startcap_request,
1613 &ett_startcap_reply,
1614 &ett_startcap_flags,
1615 &ett_filter,
1616 &ett_filterbpf_insn,
1617 &ett_filterbpf_insn_code,
1618 &ett_stats_reply,
1619 &ett_findalldevs_reply,
1620 &ett_findalldevs_if,
1621 &ett_findalldevs_ifaddr,
1622 &ett_ifaddr,
1623 &ett_sampling_request
1626 static ei_register_info ei[] = {
1627 { &ei_error, { "rpcap.error.expert", PI_SEQUENCE, PI_NOTE, "Error", EXPFILL }},
1628 { &ei_if_unknown, { "rpcap.if_unknown", PI_SEQUENCE, PI_NOTE, "Unknown address family", EXPFILL }},
1629 { &ei_no_more_data, { "rpcap.no_more_data", PI_MALFORMED, PI_ERROR, "No more data in packet", EXPFILL }},
1630 { &ei_caplen_too_big, { "rpcap.caplen_too_big", PI_MALFORMED, PI_ERROR, "Caplen is bigger than the remaining message length", EXPFILL }},
1633 module_t *rpcap_module;
1634 expert_module_t* expert_rpcap;
1636 proto_rpcap = proto_register_protocol (PNAME, PSNAME, PFNAME);
1637 register_dissector (PFNAME, dissect_rpcap, proto_rpcap);
1638 rpcap_tcp_handle = register_dissector(PFNAME ".tcp", dissect_rpcap_tcp, proto_rpcap);
1639 expert_rpcap = expert_register_protocol(proto_rpcap);
1640 expert_register_field_array(expert_rpcap, ei, array_length(ei));
1642 proto_register_field_array (proto_rpcap, hf, array_length (hf));
1643 proto_register_subtree_array (ett, array_length (ett));
1645 /* Register our configuration options */
1646 rpcap_module = prefs_register_protocol (proto_rpcap, proto_reg_handoff_rpcap);
1648 prefs_register_bool_preference (rpcap_module, "desegment_pdus",
1649 "Reassemble PDUs spanning multiple TCP segments",
1650 "Whether the RPCAP dissector should reassemble PDUs"
1651 " spanning multiple TCP segments."
1652 " To use this option, you must also enable \"Allow subdissectors"
1653 " to reassemble TCP streams\" in the TCP protocol settings.",
1654 &rpcap_desegment);
1655 prefs_register_bool_preference (rpcap_module, "decode_content",
1656 "Decode content according to link-layer type",
1657 "Whether the packets should be decoded according to"
1658 " the link-layer type.",
1659 &decode_content);
1660 prefs_register_uint_preference (rpcap_module, "linktype",
1661 "Default link-layer type",
1662 "Default link-layer type to use if an Open Reply packet"
1663 " has not been captured.",
1664 10, &global_linktype);
1667 void
1668 proto_reg_handoff_rpcap (void)
1670 static bool rpcap_prefs_initialized = false;
1672 if (!rpcap_prefs_initialized) {
1673 pcap_pktdata_handle = find_dissector_add_dependency("pcap_pktdata", proto_rpcap);
1674 rpcap_prefs_initialized = true;
1676 heur_dissector_add ("tcp", dissect_rpcap_heur_tcp, "RPCAP over TCP", "rpcap_tcp", proto_rpcap, HEURISTIC_ENABLE);
1677 heur_dissector_add ("udp", dissect_rpcap_heur_udp, "RPCAP over UDP", "rpcap_udp", proto_rpcap, HEURISTIC_ENABLE);
1680 info_added = false;
1681 linktype = global_linktype;
1685 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1687 * Local Variables:
1688 * c-basic-offset: 2
1689 * tab-width: 8
1690 * indent-tabs-mode: nil
1691 * End:
1693 * ex: set shiftwidth=2 tabstop=8 expandtab:
1694 * :indentSize=2:tabSize=8:noTabs=true: