HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-rpcap.c
blob98e977234cc6030eff3bf335685799d4f4b34123
1 /* packet-rpcap.c
3 * Routines for RPCAP message formats.
5 * Copyright 2008, Stig Bjorlykke <stig@bjorlykke.org>, Thales Norway AS
7 * $Id$
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "config.h"
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
32 #endif
34 #ifdef HAVE_SYS_SOCKET_H
35 #include <sys/socket.h>
36 #endif
38 #ifdef HAVE_WINSOCK2_H
39 #include <winsock2.h>
40 #endif
42 #include <epan/packet.h>
43 #include <epan/prefs.h>
44 #include <epan/to_str.h>
45 #include <epan/expert.h>
46 #include <epan/wmem/wmem.h>
48 #include <wiretap/wtap.h>
50 #include "packet-frame.h"
51 #include "packet-tcp.h"
53 #define PNAME "Remote Packet Capture"
54 #define PSNAME "RPCAP"
55 #define PFNAME "rpcap"
57 #define RPCAP_MSG_ERROR 1
58 #define RPCAP_MSG_FINDALLIF_REQ 2
59 #define RPCAP_MSG_OPEN_REQ 3
60 #define RPCAP_MSG_STARTCAP_REQ 4
61 #define RPCAP_MSG_UPDATEFILTER_REQ 5
62 #define RPCAP_MSG_CLOSE 6
63 #define RPCAP_MSG_PACKET 7
64 #define RPCAP_MSG_AUTH_REQ 8
65 #define RPCAP_MSG_STATS_REQ 9
66 #define RPCAP_MSG_ENDCAP_REQ 10
67 #define RPCAP_MSG_SETSAMPLING_REQ 11
69 #define RPCAP_MSG_FINDALLIF_REPLY (128+RPCAP_MSG_FINDALLIF_REQ)
70 #define RPCAP_MSG_OPEN_REPLY (128+RPCAP_MSG_OPEN_REQ)
71 #define RPCAP_MSG_STARTCAP_REPLY (128+RPCAP_MSG_STARTCAP_REQ)
72 #define RPCAP_MSG_UPDATEFILTER_REPLY (128+RPCAP_MSG_UPDATEFILTER_REQ)
73 #define RPCAP_MSG_AUTH_REPLY (128+RPCAP_MSG_AUTH_REQ)
74 #define RPCAP_MSG_STATS_REPLY (128+RPCAP_MSG_STATS_REQ)
75 #define RPCAP_MSG_ENDCAP_REPLY (128+RPCAP_MSG_ENDCAP_REQ)
76 #define RPCAP_MSG_SETSAMPLING_REPLY (128+RPCAP_MSG_SETSAMPLING_REQ)
78 #define RPCAP_ERR_NETW 1
79 #define RPCAP_ERR_INITTIMEOUT 2
80 #define RPCAP_ERR_AUTH 3
81 #define RPCAP_ERR_FINDALLIF 4
82 #define RPCAP_ERR_NOREMOTEIF 5
83 #define RPCAP_ERR_OPEN 6
84 #define RPCAP_ERR_UPDATEFILTER 7
85 #define RPCAP_ERR_GETSTATS 8
86 #define RPCAP_ERR_READEX 9
87 #define RPCAP_ERR_HOSTNOAUTH 10
88 #define RPCAP_ERR_REMOTEACCEPT 11
89 #define RPCAP_ERR_STARTCAPTURE 12
90 #define RPCAP_ERR_ENDCAPTURE 13
91 #define RPCAP_ERR_RUNTIMETIMEOUT 14
92 #define RPCAP_ERR_SETSAMPLING 15
93 #define RPCAP_ERR_WRONGMSG 16
94 #define RPCAP_ERR_WRONGVER 17
96 #define RPCAP_SAMP_NOSAMP 0
97 #define RPCAP_SAMP_1_EVERY_N 1
98 #define RPCAP_SAMP_FIRST_AFTER_N_MS 2
100 #define RPCAP_RMTAUTH_NULL 0
101 #define RPCAP_RMTAUTH_PWD 1
103 #define FLAG_PROMISC 0x0001
104 #define FLAG_DGRAM 0x0002
105 #define FLAG_SERVEROPEN 0x0004
106 #define FLAG_INBOUND 0x0008
107 #define FLAG_OUTBOUND 0x0010
109 void proto_reg_handoff_rpcap (void);
111 static int proto_rpcap = -1;
113 static int hf_version = -1;
114 static int hf_type = -1;
115 static int hf_value = -1;
116 static int hf_plen = -1;
118 static int hf_error = -1;
119 static int hf_error_value = -1;
121 static int hf_packet = -1;
122 static int hf_timestamp = -1;
123 static int hf_caplen = -1;
124 static int hf_len = -1;
125 static int hf_npkt = -1;
127 static int hf_auth_request = -1;
128 static int hf_auth_type = -1;
129 static int hf_auth_slen1 = -1;
130 static int hf_auth_slen2 = -1;
131 static int hf_auth_username = -1;
132 static int hf_auth_password = -1;
134 static int hf_open_request = -1;
136 static int hf_open_reply = -1;
137 static int hf_linktype = -1;
138 static int hf_tzoff = -1;
140 static int hf_startcap_request = -1;
141 static int hf_snaplen = -1;
142 static int hf_read_timeout = -1;
143 static int hf_flags = -1;
144 static int hf_flags_promisc = -1;
145 static int hf_flags_dgram = -1;
146 static int hf_flags_serveropen = -1;
147 static int hf_flags_inbound = -1;
148 static int hf_flags_outbound = -1;
149 static int hf_client_port = -1;
150 static int hf_startcap_reply = -1;
151 static int hf_bufsize = -1;
152 static int hf_server_port = -1;
153 static int hf_dummy = -1;
155 static int hf_filter = -1;
156 static int hf_filtertype = -1;
157 static int hf_nitems = -1;
159 static int hf_filterbpf_insn = -1;
160 static int hf_code = -1;
161 static int hf_code_class = -1;
162 static int hf_code_fields = -1;
163 static int hf_code_ld_size = -1;
164 static int hf_code_ld_mode = -1;
165 static int hf_code_alu_op = -1;
166 static int hf_code_jmp_op = -1;
167 static int hf_code_src = -1;
168 static int hf_code_rval = -1;
169 static int hf_code_misc_op = -1;
170 static int hf_jt = -1;
171 static int hf_jf = -1;
172 static int hf_instr_value = -1;
174 static int hf_stats_reply = -1;
175 static int hf_ifrecv = -1;
176 static int hf_ifdrop = -1;
177 static int hf_krnldrop = -1;
178 static int hf_srvcapt = -1;
180 static int hf_findalldevs_reply = -1;
181 static int hf_findalldevs_if = -1;
182 static int hf_namelen = -1;
183 static int hf_desclen = -1;
184 static int hf_if_flags = -1;
185 static int hf_naddr = -1;
186 static int hf_if_name = -1;
187 static int hf_if_desc = -1;
189 static int hf_findalldevs_ifaddr = -1;
190 static int hf_if_addr = -1;
191 static int hf_if_netmask = -1;
192 static int hf_if_broadaddr = -1;
193 static int hf_if_dstaddr = -1;
194 static int hf_if_af = -1;
195 static int hf_if_port = -1;
196 static int hf_if_ip = -1;
197 static int hf_if_padding = -1;
198 static int hf_if_unknown = -1;
200 static int hf_sampling_request = -1;
201 static int hf_sampling_method = -1;
202 static int hf_sampling_dummy1 = -1;
203 static int hf_sampling_dummy2 = -1;
204 static int hf_sampling_value = -1;
206 static gint ett_rpcap = -1;
207 static gint ett_error = -1;
208 static gint ett_packet = -1;
209 static gint ett_auth_request = -1;
210 static gint ett_open_reply = -1;
211 static gint ett_startcap_request = -1;
212 static gint ett_startcap_reply = -1;
213 static gint ett_startcap_flags = -1;
214 static gint ett_filter = -1;
215 static gint ett_filterbpf_insn = -1;
216 static gint ett_filterbpf_insn_code = -1;
217 static gint ett_stats_reply = -1;
218 static gint ett_findalldevs_reply = -1;
219 static gint ett_findalldevs_if = -1;
220 static gint ett_findalldevs_ifaddr = -1;
221 static gint ett_ifaddr = -1;
222 static gint ett_sampling_request = -1;
224 static expert_field ei_error = EI_INIT;
225 static expert_field ei_if_unknown = EI_INIT;
226 static expert_field ei_no_more_data = EI_INIT;
227 static expert_field ei_caplen_too_big = EI_INIT;
229 static dissector_handle_t data_handle;
231 /* User definable values */
232 static gboolean rpcap_desegment = TRUE;
233 static gboolean decode_content = TRUE;
234 static guint32 global_linktype = WTAP_ENCAP_UNKNOWN;
236 /* Global variables */
237 static guint32 linktype = WTAP_ENCAP_UNKNOWN;
238 static gboolean info_added = FALSE;
240 static const true_false_string open_closed = {
241 "Open", "Closed"
244 static const value_string message_type[] = {
245 { RPCAP_MSG_ERROR, "Error" },
246 { RPCAP_MSG_FINDALLIF_REQ, "Find all interfaces request" },
247 { RPCAP_MSG_OPEN_REQ, "Open request" },
248 { RPCAP_MSG_STARTCAP_REQ, "Start capture request" },
249 { RPCAP_MSG_UPDATEFILTER_REQ, "Update filter request" },
250 { RPCAP_MSG_CLOSE, "Close" },
251 { RPCAP_MSG_PACKET, "Packet" },
252 { RPCAP_MSG_AUTH_REQ, "Authentication request" },
253 { RPCAP_MSG_STATS_REQ, "Statistics request" },
254 { RPCAP_MSG_ENDCAP_REQ, "End capture request" },
255 { RPCAP_MSG_SETSAMPLING_REQ, "Set sampling request" },
256 { RPCAP_MSG_FINDALLIF_REPLY, "Find all interfaces reply" },
257 { RPCAP_MSG_OPEN_REPLY, "Open reply" },
258 { RPCAP_MSG_STARTCAP_REPLY, "Start capture reply" },
259 { RPCAP_MSG_UPDATEFILTER_REPLY, "Update filter reply" },
260 { RPCAP_MSG_AUTH_REPLY, "Authentication reply" },
261 { RPCAP_MSG_STATS_REPLY, "Statistics reply" },
262 { RPCAP_MSG_ENDCAP_REPLY, "End capture reply" },
263 { RPCAP_MSG_SETSAMPLING_REPLY, "Set sampling reply" },
264 { 0, NULL }
267 static const value_string error_codes[] = {
268 { RPCAP_ERR_NETW, "Network error" },
269 { RPCAP_ERR_INITTIMEOUT, "Initial timeout has expired" },
270 { RPCAP_ERR_AUTH, "Authentication error" },
271 { RPCAP_ERR_FINDALLIF, "Generic findalldevs error" },
272 { RPCAP_ERR_NOREMOTEIF, "No remote interfaces" },
273 { RPCAP_ERR_OPEN, "Generic pcap_open error" },
274 { RPCAP_ERR_UPDATEFILTER, "Generic updatefilter error" },
275 { RPCAP_ERR_GETSTATS, "Generic pcap_stats error" },
276 { RPCAP_ERR_READEX, "Generic pcap_next_ex error" },
277 { RPCAP_ERR_HOSTNOAUTH, "The host is not authorized" },
278 { RPCAP_ERR_REMOTEACCEPT, "Generic pcap_remoteaccept error" },
279 { RPCAP_ERR_STARTCAPTURE, "Generic pcap_startcapture error" },
280 { RPCAP_ERR_ENDCAPTURE, "Generic pcap_endcapture error" },
281 { RPCAP_ERR_RUNTIMETIMEOUT, "Runtime timeout has expired" },
282 { RPCAP_ERR_SETSAMPLING, "Error in setting sampling parameters" },
283 { RPCAP_ERR_WRONGMSG, "Unrecognized message" },
284 { RPCAP_ERR_WRONGVER, "Incompatible version" },
285 { 0, NULL }
288 static const value_string sampling_method[] = {
289 { RPCAP_SAMP_NOSAMP, "No sampling" },
290 { RPCAP_SAMP_1_EVERY_N, "1 every N" },
291 { RPCAP_SAMP_FIRST_AFTER_N_MS, "First after N ms" },
292 { 0, NULL }
295 static const value_string auth_type[] = {
296 { RPCAP_RMTAUTH_NULL, "None" },
297 { RPCAP_RMTAUTH_PWD, "Password" },
298 { 0, NULL }
301 static const value_string address_family[] = {
302 { AF_UNSPEC, "AF_UNSPEC" },
303 { AF_INET, "AF_INET" },
304 { 0, NULL }
307 static const value_string bpf_class[] = {
308 { 0x00, "ld" },
309 { 0x01, "ldx" },
310 { 0x02, "st" },
311 { 0x03, "stx" },
312 { 0x04, "alu" },
313 { 0x05, "jmp" },
314 { 0x06, "ret" },
315 { 0x07, "misc" },
316 { 0, NULL }
319 static const value_string bpf_size[] = {
320 { 0x00, "w" },
321 { 0x01, "h" },
322 { 0x02, "b" },
323 { 0, NULL }
326 static const value_string bpf_mode[] = {
327 { 0x00, "imm" },
328 { 0x01, "abs" },
329 { 0x02, "ind" },
330 { 0x03, "mem" },
331 { 0x04, "len" },
332 { 0x05, "msh" },
333 { 0, NULL }
336 static const value_string bpf_alu_op[] = {
337 { 0x00, "add" },
338 { 0x01, "sub" },
339 { 0x02, "mul" },
340 { 0x03, "div" },
341 { 0x04, "or" },
342 { 0x05, "and" },
343 { 0x06, "lsh" },
344 { 0x07, "rsh" },
345 { 0x08, "neg" },
346 { 0, NULL }
349 static const value_string bpf_jmp_op[] = {
350 { 0x00, "ja" },
351 { 0x01, "jeq" },
352 { 0x02, "jgt" },
353 { 0x03, "jge" },
354 { 0x04, "jset" },
355 { 0, NULL }
358 static const value_string bpf_src[] = {
359 { 0x00, "k" },
360 { 0x01, "x" },
361 { 0, NULL }
364 static const value_string bpf_rval[] = {
365 { 0x00, "k" },
366 { 0x01, "x" },
367 { 0x02, "a" },
368 { 0, NULL }
371 static const value_string bpf_misc_op[] = {
372 { 0x00, "tax" },
373 { 0x10, "txa" },
374 { 0, NULL }
378 static void rpcap_frame_end (void)
380 info_added = FALSE;
384 static void
385 dissect_rpcap_error (tvbuff_t *tvb, packet_info *pinfo,
386 proto_tree *parent_tree, gint offset)
388 proto_item *ti;
389 gint len;
391 len = tvb_length_remaining (tvb, offset);
392 if (len <= 0)
393 return;
395 col_append_fstr (pinfo->cinfo, COL_INFO, ": %s",
396 tvb_format_text_wsp (tvb, offset, len));
398 ti = proto_tree_add_item (parent_tree, hf_error, tvb, offset, len, ENC_ASCII|ENC_NA);
399 expert_add_info_format(pinfo, ti, &ei_error,
400 "Error: %s", tvb_format_text_wsp (tvb, offset, len));
404 static gint
405 dissect_rpcap_ifaddr (tvbuff_t *tvb, packet_info *pinfo,
406 proto_tree *parent_tree, gint offset, int hf_id,
407 proto_item *parent_item)
409 proto_tree *tree;
410 proto_item *ti;
411 gchar ipaddr[MAX_ADDR_STR_LEN];
412 guint32 ipv4;
413 guint16 af;
415 ti = proto_tree_add_item (parent_tree, hf_id, tvb, offset, 128, ENC_BIG_ENDIAN);
416 tree = proto_item_add_subtree (ti, ett_ifaddr);
418 af = tvb_get_ntohs (tvb, offset);
419 proto_tree_add_item (tree, hf_if_af, tvb, offset, 2, ENC_BIG_ENDIAN);
420 offset += 2;
422 if (af == AF_INET) {
423 proto_tree_add_item (tree, hf_if_port, tvb, offset, 2, ENC_BIG_ENDIAN);
424 offset += 2;
426 ipv4 = tvb_get_ipv4 (tvb, offset);
427 ip_to_str_buf((guint8 *)&ipv4, ipaddr, MAX_ADDR_STR_LEN);
428 proto_item_append_text (ti, ": %s", ipaddr);
429 if (parent_item) {
430 proto_item_append_text (parent_item, ": %s", ipaddr);
432 proto_tree_add_item (tree, hf_if_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
433 offset += 4;
435 proto_tree_add_item (tree, hf_if_padding, tvb, offset, 120, ENC_NA);
436 offset += 120;
437 } else {
438 ti = proto_tree_add_item (tree, hf_if_unknown, tvb, offset, 126, ENC_NA);
439 if (af != AF_UNSPEC) {
440 expert_add_info_format(pinfo, ti, &ei_if_unknown,
441 "Unknown address family: %d", af);
443 offset += 126;
446 return offset;
450 static gint
451 dissect_rpcap_findalldevs_ifaddr (tvbuff_t *tvb, packet_info *pinfo _U_,
452 proto_tree *parent_tree, gint offset)
454 proto_tree *tree;
455 proto_item *ti;
456 gint boffset = offset;
458 ti = proto_tree_add_item (parent_tree, hf_findalldevs_ifaddr, tvb, offset, -1, ENC_NA);
459 tree = proto_item_add_subtree (ti, ett_findalldevs_ifaddr);
461 offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_addr, ti);
462 offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_netmask, NULL);
463 offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_broadaddr, NULL);
464 offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_dstaddr, NULL);
466 proto_item_set_len (ti, offset - boffset);
468 return offset;
472 static gint
473 dissect_rpcap_findalldevs_if (tvbuff_t *tvb, packet_info *pinfo _U_,
474 proto_tree *parent_tree, gint offset)
476 proto_tree *tree;
477 proto_item *ti;
478 guint16 namelen, desclen, naddr, i;
479 gint boffset = offset;
481 ti = proto_tree_add_item (parent_tree, hf_findalldevs_if, tvb, offset, -1, ENC_NA);
482 tree = proto_item_add_subtree (ti, ett_findalldevs_if);
484 namelen = tvb_get_ntohs (tvb, offset);
485 proto_tree_add_item (tree, hf_namelen, tvb, offset, 2, ENC_BIG_ENDIAN);
486 offset += 2;
488 desclen = tvb_get_ntohs (tvb, offset);
489 proto_tree_add_item (tree, hf_desclen, tvb, offset, 2, ENC_BIG_ENDIAN);
490 offset += 2;
492 proto_tree_add_item (tree, hf_if_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
493 offset += 4;
495 naddr = tvb_get_ntohs (tvb, offset);
496 proto_tree_add_item (tree, hf_naddr, tvb, offset, 2, ENC_BIG_ENDIAN);
497 offset += 2;
499 proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
500 offset += 2;
502 if (namelen) {
503 proto_item_append_text (ti, ": %s", tvb_get_string (wmem_packet_scope(), tvb, offset, namelen));
504 proto_tree_add_item (tree, hf_if_name, tvb, offset, namelen, ENC_ASCII|ENC_NA);
505 offset += namelen;
508 if (desclen) {
509 proto_tree_add_item (tree, hf_if_desc, tvb, offset, desclen, ENC_ASCII|ENC_NA);
510 offset += desclen;
513 for (i = 0; i < naddr; i++) {
514 offset = dissect_rpcap_findalldevs_ifaddr (tvb, pinfo, tree, offset);
515 if (tvb_length_remaining (tvb, offset) < 0) {
516 /* No more data in packet */
517 expert_add_info(pinfo, ti, &ei_no_more_data);
518 break;
522 proto_item_set_len (ti, offset - boffset);
524 return offset;
528 static void
529 dissect_rpcap_findalldevs_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
530 proto_tree *parent_tree, gint offset, guint16 no_devs)
532 proto_tree *tree;
533 proto_item *ti;
534 guint16 i;
536 ti = proto_tree_add_item (parent_tree, hf_findalldevs_reply, tvb, offset, -1, ENC_NA);
537 tree = proto_item_add_subtree (ti, ett_findalldevs_reply);
539 for (i = 0; i < no_devs; i++) {
540 offset = dissect_rpcap_findalldevs_if (tvb, pinfo, tree, offset);
541 if (tvb_length_remaining (tvb, offset) < 0) {
542 /* No more data in packet */
543 expert_add_info(pinfo, ti, &ei_no_more_data);
544 break;
548 proto_item_append_text (ti, ", %d item%s", no_devs, plurality (no_devs, "", "s"));
552 static gint
553 dissect_rpcap_filterbpf_insn (tvbuff_t *tvb, packet_info *pinfo _U_,
554 proto_tree *parent_tree, gint offset)
556 proto_tree *tree, *code_tree;
557 proto_item *ti, *code_ti;
558 guint8 inst_class;
560 ti = proto_tree_add_item (parent_tree, hf_filterbpf_insn, tvb, offset, 8, ENC_NA);
561 tree = proto_item_add_subtree (ti, ett_filterbpf_insn);
563 code_ti = proto_tree_add_item (tree, hf_code, tvb, offset, 2, ENC_BIG_ENDIAN);
564 code_tree = proto_item_add_subtree (code_ti, ett_filterbpf_insn_code);
565 proto_tree_add_item (code_tree, hf_code_class, tvb, offset, 2, ENC_BIG_ENDIAN);
566 inst_class = tvb_get_guint8 (tvb, offset + 1) & 0x07;
567 proto_item_append_text (ti, ": %s", val_to_str_const (inst_class, bpf_class, ""));
568 switch (inst_class) {
569 case 0x00: /* ld */
570 case 0x01: /* ldx */
571 proto_tree_add_item (code_tree, hf_code_ld_size, tvb, offset, 2, ENC_BIG_ENDIAN);
572 proto_tree_add_item (code_tree, hf_code_ld_mode, tvb, offset, 2, ENC_BIG_ENDIAN);
573 break;
574 case 0x04: /* alu */
575 proto_tree_add_item (code_tree, hf_code_src, tvb, offset, 2, ENC_BIG_ENDIAN);
576 proto_tree_add_item (code_tree, hf_code_alu_op, tvb, offset, 2, ENC_BIG_ENDIAN);
577 break;
578 case 0x05: /* jmp */
579 proto_tree_add_item (code_tree, hf_code_src, tvb, offset, 2, ENC_BIG_ENDIAN);
580 proto_tree_add_item (code_tree, hf_code_jmp_op, tvb, offset, 2, ENC_BIG_ENDIAN);
581 break;
582 case 0x06: /* ret */
583 proto_tree_add_item (code_tree, hf_code_rval, tvb, offset, 2, ENC_BIG_ENDIAN);
584 break;
585 case 0x07: /* misc */
586 proto_tree_add_item (code_tree, hf_code_misc_op, tvb, offset, 2, ENC_BIG_ENDIAN);
587 break;
588 default:
589 proto_tree_add_item (code_tree, hf_code_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
590 break;
592 offset += 2;
594 proto_tree_add_item (tree, hf_jt, tvb, offset, 1, ENC_BIG_ENDIAN);
595 offset += 1;
597 proto_tree_add_item (tree, hf_jf, tvb, offset, 1, ENC_BIG_ENDIAN);
598 offset += 1;
600 proto_tree_add_item (tree, hf_instr_value, tvb, offset, 4, ENC_BIG_ENDIAN);
601 offset += 4;
603 return offset;
607 static void
608 dissect_rpcap_filter (tvbuff_t *tvb, packet_info *pinfo,
609 proto_tree *parent_tree, gint offset)
611 proto_tree *tree;
612 proto_item *ti;
613 guint32 nitems, i;
615 ti = proto_tree_add_item (parent_tree, hf_filter, tvb, offset, -1, ENC_NA);
616 tree = proto_item_add_subtree (ti, ett_filter);
618 proto_tree_add_item (tree, hf_filtertype, tvb, offset, 2, ENC_BIG_ENDIAN);
619 offset += 2;
621 proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
622 offset += 2;
624 nitems = tvb_get_ntohl (tvb, offset);
625 proto_tree_add_item (tree, hf_nitems, tvb, offset, 4, ENC_BIG_ENDIAN);
626 offset += 4;
628 for (i = 0; i < nitems; i++) {
629 offset = dissect_rpcap_filterbpf_insn (tvb, pinfo, tree, offset);
630 if (tvb_length_remaining (tvb, offset) < 0) {
631 /* No more data in packet */
632 expert_add_info(pinfo, ti, &ei_no_more_data);
633 break;
639 static int
640 dissect_rpcap_auth_request (tvbuff_t *tvb, packet_info *pinfo _U_,
641 proto_tree *parent_tree, gint offset)
643 proto_tree *tree;
644 proto_item *ti;
645 guint16 type, slen1, slen2;
647 ti = proto_tree_add_item (parent_tree, hf_auth_request, tvb, offset, -1, ENC_NA);
648 tree = proto_item_add_subtree (ti, ett_auth_request);
650 type = tvb_get_ntohs (tvb, offset);
651 proto_tree_add_item (tree, hf_auth_type, tvb, offset, 2, ENC_BIG_ENDIAN);
652 offset += 2;
654 proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
655 offset += 2;
657 slen1 = tvb_get_ntohs (tvb, offset);
658 proto_tree_add_item (tree, hf_auth_slen1, tvb, offset, 2, ENC_BIG_ENDIAN);
659 offset += 2;
661 slen2 = tvb_get_ntohs (tvb, offset);
662 proto_tree_add_item (tree, hf_auth_slen2, tvb, offset, 2, ENC_BIG_ENDIAN);
663 offset += 2;
665 if (type == RPCAP_RMTAUTH_NULL) {
666 proto_item_append_text (ti, " (none)");
667 } else if (type == RPCAP_RMTAUTH_PWD) {
668 guint8 *username, *password;
670 username = tvb_get_string (wmem_packet_scope(), tvb, offset, slen1);
671 proto_tree_add_item (tree, hf_auth_username, tvb, offset, slen1, ENC_ASCII|ENC_NA);
672 offset += slen1;
674 password = tvb_get_string (wmem_packet_scope(), tvb, offset, slen2);
675 proto_tree_add_item (tree, hf_auth_password, tvb, offset, slen2, ENC_ASCII|ENC_NA);
676 offset += slen2;
678 proto_item_append_text (ti, " (%s/%s)", username, password);
680 return offset;
684 static void
685 dissect_rpcap_open_request (tvbuff_t *tvb, packet_info *pinfo _U_,
686 proto_tree *parent_tree, gint offset)
688 gint len;
690 len = tvb_length_remaining (tvb, offset);
691 proto_tree_add_item (parent_tree, hf_open_request, tvb, offset, len, ENC_ASCII|ENC_NA);
695 static void
696 dissect_rpcap_open_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
697 proto_tree *parent_tree, gint offset)
699 proto_tree *tree;
700 proto_item *ti;
702 ti = proto_tree_add_item (parent_tree, hf_open_reply, tvb, offset, -1, ENC_NA);
703 tree = proto_item_add_subtree (ti, ett_open_reply);
705 linktype = tvb_get_ntohl (tvb, offset);
706 proto_tree_add_item (tree, hf_linktype, tvb, offset, 4, ENC_BIG_ENDIAN);
707 offset += 4;
709 proto_tree_add_item (tree, hf_tzoff, tvb, offset, 4, ENC_BIG_ENDIAN);
713 static void
714 dissect_rpcap_startcap_request (tvbuff_t *tvb, packet_info *pinfo,
715 proto_tree *parent_tree, gint offset)
717 proto_tree *tree, *field_tree;
718 proto_item *ti, *field_ti;
719 guint16 flags;
721 ti = proto_tree_add_item (parent_tree, hf_startcap_request, tvb, offset, -1, ENC_NA);
722 tree = proto_item_add_subtree (ti, ett_startcap_request);
724 proto_tree_add_item (tree, hf_snaplen, tvb, offset, 4, ENC_BIG_ENDIAN);
725 offset += 4;
727 proto_tree_add_item (tree, hf_read_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
728 offset += 4;
730 flags = tvb_get_ntohs (tvb, offset);
731 field_ti = proto_tree_add_uint_format (tree, hf_flags, tvb, offset, 2, flags, "Flags");
732 field_tree = proto_item_add_subtree (field_ti, ett_startcap_flags);
733 proto_tree_add_item (field_tree, hf_flags_promisc, tvb, offset, 2, ENC_BIG_ENDIAN);
734 proto_tree_add_item (field_tree, hf_flags_dgram, tvb, offset, 2, ENC_BIG_ENDIAN);
735 proto_tree_add_item (field_tree, hf_flags_serveropen, tvb, offset, 2, ENC_BIG_ENDIAN);
736 proto_tree_add_item (field_tree, hf_flags_inbound, tvb, offset, 2, ENC_BIG_ENDIAN);
737 proto_tree_add_item (field_tree, hf_flags_outbound, tvb, offset, 2, ENC_BIG_ENDIAN);
739 if (flags & 0x1F) {
740 gchar *flagstr = wmem_strdup_printf (wmem_packet_scope(), "%s%s%s%s%s",
741 (flags & FLAG_PROMISC) ? ", Promiscuous" : "",
742 (flags & FLAG_DGRAM) ? ", Datagram" : "",
743 (flags & FLAG_SERVEROPEN) ? ", ServerOpen" : "",
744 (flags & FLAG_INBOUND) ? ", Inbound" : "",
745 (flags & FLAG_OUTBOUND) ? ", Outbound" : "");
746 proto_item_append_text (field_ti, ":%s", &flagstr[1]);
747 } else {
748 proto_item_append_text (field_ti, " (none)");
750 offset += 2;
752 proto_tree_add_item (tree, hf_client_port, tvb, offset, 2, ENC_BIG_ENDIAN);
753 offset += 2;
755 dissect_rpcap_filter (tvb, pinfo, tree, offset);
759 static void
760 dissect_rpcap_startcap_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
761 proto_tree *parent_tree, gint offset)
763 proto_tree *tree;
764 proto_item *ti;
766 ti = proto_tree_add_item (parent_tree, hf_startcap_reply, tvb, offset, -1, ENC_NA);
767 tree = proto_item_add_subtree (ti, ett_startcap_reply);
769 proto_tree_add_item (tree, hf_bufsize, tvb, offset, 4, ENC_BIG_ENDIAN);
770 offset += 4;
772 proto_tree_add_item (tree, hf_server_port, tvb, offset, 2, ENC_BIG_ENDIAN);
773 offset += 2;
775 proto_tree_add_item (tree, hf_dummy, tvb, offset, 2, ENC_BIG_ENDIAN);
779 static void
780 dissect_rpcap_stats_reply (tvbuff_t *tvb, packet_info *pinfo _U_,
781 proto_tree *parent_tree, gint offset)
783 proto_tree *tree;
784 proto_item *ti;
786 ti = proto_tree_add_item (parent_tree, hf_stats_reply, tvb, offset, 16, ENC_NA);
787 tree = proto_item_add_subtree (ti, ett_stats_reply);
789 proto_tree_add_item (tree, hf_ifrecv, tvb, offset, 4, ENC_BIG_ENDIAN);
790 offset += 4;
792 proto_tree_add_item (tree, hf_ifdrop, tvb, offset, 4, ENC_BIG_ENDIAN);
793 offset += 4;
795 proto_tree_add_item (tree, hf_krnldrop, tvb, offset, 4, ENC_BIG_ENDIAN);
796 offset += 4;
798 proto_tree_add_item (tree, hf_srvcapt, tvb, offset, 4, ENC_BIG_ENDIAN);
802 static int
803 dissect_rpcap_sampling_request (tvbuff_t *tvb, packet_info *pinfo _U_,
804 proto_tree *parent_tree, gint offset)
806 proto_tree *tree;
807 proto_item *ti;
808 guint32 value;
809 guint8 method;
811 ti = proto_tree_add_item (parent_tree, hf_sampling_request, tvb, offset, -1, ENC_NA);
812 tree = proto_item_add_subtree (ti, ett_sampling_request);
814 method = tvb_get_guint8 (tvb, offset);
815 proto_tree_add_item (tree, hf_sampling_method, tvb, offset, 1, ENC_BIG_ENDIAN);
816 offset += 1;
818 proto_tree_add_item (tree, hf_sampling_dummy1, tvb, offset, 1, ENC_BIG_ENDIAN);
819 offset += 1;
821 proto_tree_add_item (tree, hf_sampling_dummy2, tvb, offset, 2, ENC_BIG_ENDIAN);
822 offset += 2;
824 value = tvb_get_ntohl (tvb, offset);
825 proto_tree_add_item (tree, hf_sampling_value, tvb, offset, 4, ENC_BIG_ENDIAN);
826 offset += 4;
828 switch (method) {
829 case RPCAP_SAMP_NOSAMP:
830 proto_item_append_text (ti, ": None");
831 break;
832 case RPCAP_SAMP_1_EVERY_N:
833 proto_item_append_text (ti, ": 1 every %d", value);
834 break;
835 case RPCAP_SAMP_FIRST_AFTER_N_MS:
836 proto_item_append_text (ti, ": First after %d ms", value);
837 break;
838 default:
839 break;
841 return offset;
845 static void
846 dissect_rpcap_packet (tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree,
847 proto_tree *parent_tree, gint offset, proto_item *top_item)
849 proto_tree *tree;
850 proto_item *ti;
851 nstime_t ts;
852 tvbuff_t *new_tvb;
853 guint caplen, len, frame_no;
854 gint reported_length_remaining;
856 ti = proto_tree_add_item (parent_tree, hf_packet, tvb, offset, 20, ENC_NA);
857 tree = proto_item_add_subtree (ti, ett_packet);
859 ts.secs = tvb_get_ntohl (tvb, offset);
860 ts.nsecs = tvb_get_ntohl (tvb, offset + 4) * 1000;
861 proto_tree_add_time(tree, hf_timestamp, tvb, offset, 8, &ts);
862 offset += 8;
864 caplen = tvb_get_ntohl (tvb, offset);
865 ti = proto_tree_add_item (tree, hf_caplen, tvb, offset, 4, ENC_BIG_ENDIAN);
866 offset += 4;
868 len = tvb_get_ntohl (tvb, offset);
869 proto_tree_add_item (tree, hf_len, tvb, offset, 4, ENC_BIG_ENDIAN);
870 offset += 4;
872 frame_no = tvb_get_ntohl (tvb, offset);
873 proto_tree_add_item (tree, hf_npkt, tvb, offset, 4, ENC_BIG_ENDIAN);
874 offset += 4;
876 proto_item_append_text (ti, ", Frame %u", frame_no);
877 proto_item_append_text (top_item, " Frame %u", frame_no);
880 * reported_length_remaining should not be -1, as offset is at
881 * most right past the end of the available data in the packet.
883 reported_length_remaining = tvb_length_remaining (tvb, offset);
884 if (caplen > (guint)reported_length_remaining) {
885 expert_add_info(pinfo, ti, &ei_caplen_too_big);
886 return;
889 new_tvb = tvb_new_subset (tvb, offset, caplen, len);
890 if (decode_content && linktype != WTAP_ENCAP_UNKNOWN) {
891 dissector_try_uint(wtap_encap_dissector_table, linktype, new_tvb, pinfo, top_tree);
893 if (!info_added) {
894 /* Only indicate when not added before */
895 /* Indicate RPCAP in the protocol column */
896 col_prepend_fence_fstr(pinfo->cinfo, COL_PROTOCOL, "R|");
898 /* Indicate RPCAP in the info column */
899 col_prepend_fence_fstr (pinfo->cinfo, COL_INFO, "Remote | ");
900 info_added = TRUE;
901 register_frame_end_routine(pinfo, rpcap_frame_end);
903 } else {
904 if (linktype == WTAP_ENCAP_UNKNOWN) {
905 proto_item_append_text (ti, ", Unknown link-layer type");
907 call_dissector (data_handle, new_tvb, pinfo, top_tree);
912 static int
913 dissect_rpcap (tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, void* data _U_)
915 proto_tree *tree;
916 proto_item *ti;
917 tvbuff_t *new_tvb;
918 gint len, offset = 0;
919 guint8 msg_type;
920 guint16 msg_value;
922 col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME);
924 col_clear(pinfo->cinfo, COL_INFO);
926 ti = proto_tree_add_item (top_tree, proto_rpcap, tvb, offset, -1, ENC_NA);
927 tree = proto_item_add_subtree (ti, ett_rpcap);
929 proto_tree_add_item (tree, hf_version, tvb, offset, 1, ENC_BIG_ENDIAN);
930 offset++;
932 msg_type = tvb_get_guint8 (tvb, offset);
933 proto_tree_add_item (tree, hf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
934 offset++;
936 col_append_fstr (pinfo->cinfo, COL_INFO, "%s",
937 val_to_str (msg_type, message_type, "Unknown: %d"));
939 proto_item_append_text (ti, ", %s", val_to_str (msg_type, message_type, "Unknown: %d"));
941 msg_value = tvb_get_ntohs (tvb, offset);
942 if (msg_type == RPCAP_MSG_ERROR) {
943 proto_tree_add_item (tree, hf_error_value, tvb, offset, 2, ENC_BIG_ENDIAN);
944 } else {
945 proto_tree_add_item (tree, hf_value, tvb, offset, 2, ENC_BIG_ENDIAN);
947 offset += 2;
949 proto_tree_add_item (tree, hf_plen, tvb, offset, 4, ENC_BIG_ENDIAN);
950 offset += 4;
953 switch (msg_type) {
954 case RPCAP_MSG_ERROR:
955 dissect_rpcap_error (tvb, pinfo, tree, offset);
956 break;
957 case RPCAP_MSG_OPEN_REQ:
958 dissect_rpcap_open_request (tvb, pinfo, tree, offset);
959 break;
960 case RPCAP_MSG_STARTCAP_REQ:
961 dissect_rpcap_startcap_request (tvb, pinfo, tree, offset);
962 break;
963 case RPCAP_MSG_UPDATEFILTER_REQ:
964 dissect_rpcap_filter (tvb, pinfo, tree, offset);
965 break;
966 case RPCAP_MSG_PACKET:
967 proto_item_set_len (ti, 28);
968 dissect_rpcap_packet (tvb, pinfo, top_tree, tree, offset, ti);
969 break;
970 case RPCAP_MSG_AUTH_REQ:
971 dissect_rpcap_auth_request (tvb, pinfo, tree, offset);
972 break;
973 case RPCAP_MSG_SETSAMPLING_REQ:
974 dissect_rpcap_sampling_request (tvb, pinfo, tree, offset);
975 break;
976 case RPCAP_MSG_FINDALLIF_REPLY:
977 dissect_rpcap_findalldevs_reply (tvb, pinfo, tree, offset, msg_value);
978 break;
979 case RPCAP_MSG_OPEN_REPLY:
980 dissect_rpcap_open_reply (tvb, pinfo, tree, offset);
981 break;
982 case RPCAP_MSG_STARTCAP_REPLY:
983 dissect_rpcap_startcap_reply (tvb, pinfo, tree, offset);
984 break;
985 case RPCAP_MSG_STATS_REPLY:
986 dissect_rpcap_stats_reply (tvb, pinfo, tree, offset);
987 break;
988 default:
989 len = tvb_length_remaining (tvb, offset);
990 if (len) {
991 /* Yet unknown, dump as data */
992 proto_item_set_len (ti, 8);
993 new_tvb = tvb_new_subset (tvb, offset, len, len);
994 call_dissector (data_handle, new_tvb, pinfo, top_tree);
996 break;
999 return tvb_length(tvb);
1003 static gboolean
1004 check_rpcap_heur (tvbuff_t *tvb, gboolean tcp)
1006 gint offset = 0;
1007 guint8 version, msg_type;
1008 guint16 msg_value;
1009 guint32 plen, len, caplen;
1011 if (tvb_length (tvb) < 8)
1012 /* Too short */
1013 return FALSE;
1015 version = tvb_get_guint8 (tvb, offset);
1016 if (version != 0)
1017 /* Incorrect version */
1018 return FALSE;
1019 offset++;
1021 msg_type = tvb_get_guint8 (tvb, offset);
1022 if (!tcp && msg_type != 7) {
1023 /* UDP is only used for packets */
1024 return FALSE;
1026 if (try_val_to_str(msg_type, message_type) == NULL)
1027 /* Unknown message type */
1028 return FALSE;
1029 offset++;
1031 msg_value = tvb_get_ntohs (tvb, offset);
1032 if (msg_value > 0) {
1033 if (msg_type == RPCAP_MSG_ERROR) {
1034 /* Must have a valid error code */
1035 if (try_val_to_str(msg_value, error_codes) == NULL)
1036 return FALSE;
1037 } else if (msg_type != RPCAP_MSG_FINDALLIF_REPLY) {
1038 return FALSE;
1041 offset += 2;
1043 plen = tvb_get_ntohl (tvb, offset);
1044 offset += 4;
1045 len = (guint32) tvb_length_remaining (tvb, offset);
1047 switch (msg_type) {
1049 case RPCAP_MSG_FINDALLIF_REQ:
1050 case RPCAP_MSG_UPDATEFILTER_REPLY:
1051 case RPCAP_MSG_AUTH_REPLY:
1052 case RPCAP_MSG_STATS_REQ:
1053 case RPCAP_MSG_CLOSE:
1054 case RPCAP_MSG_SETSAMPLING_REPLY:
1055 case RPCAP_MSG_ENDCAP_REQ:
1056 case RPCAP_MSG_ENDCAP_REPLY:
1057 /* Empty payload */
1058 if (plen != 0 || len != 0)
1059 return FALSE;
1060 break;
1062 case RPCAP_MSG_OPEN_REPLY:
1063 case RPCAP_MSG_STARTCAP_REPLY:
1064 case RPCAP_MSG_SETSAMPLING_REQ:
1065 /* Always 8 bytes */
1066 if (plen != 8 || len != 8)
1067 return FALSE;
1068 break;
1070 case RPCAP_MSG_STATS_REPLY:
1071 /* Always 16 bytes */
1072 if (plen != 16 || len != 16)
1073 return FALSE;
1074 break;
1076 case RPCAP_MSG_PACKET:
1077 /* Must have the frame header */
1078 if (plen < 20)
1079 return FALSE;
1081 /* Check if capture length is valid */
1082 caplen = tvb_get_ntohl (tvb, offset+8);
1083 /* Always 20 bytes less than packet length */
1084 if (caplen != (plen - 20) || caplen > 65535)
1085 return FALSE;
1086 break;
1088 case RPCAP_MSG_FINDALLIF_REPLY:
1089 case RPCAP_MSG_ERROR:
1090 case RPCAP_MSG_OPEN_REQ:
1091 case RPCAP_MSG_STARTCAP_REQ:
1092 case RPCAP_MSG_UPDATEFILTER_REQ:
1093 case RPCAP_MSG_AUTH_REQ:
1094 /* Variable length */
1095 if (plen != len)
1096 return FALSE;
1097 break;
1098 default:
1099 /* Unknown message type */
1100 return FALSE;
1103 return TRUE;
1107 static guint
1108 get_rpcap_pdu_len (packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1110 return tvb_get_ntohl (tvb, offset + 4) + 8;
1114 static gboolean
1115 dissect_rpcap_heur_tcp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1117 if (check_rpcap_heur (tvb, TRUE)) {
1118 /* This is probably a rpcap tcp package */
1119 tcp_dissect_pdus (tvb, pinfo, tree, rpcap_desegment, 8,
1120 get_rpcap_pdu_len, dissect_rpcap, data);
1122 return TRUE;
1125 return FALSE;
1129 static gboolean
1130 dissect_rpcap_heur_udp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1132 if (check_rpcap_heur (tvb, FALSE)) {
1133 /* This is probably a rpcap udp package */
1134 dissect_rpcap (tvb, pinfo, tree, data);
1136 return TRUE;
1139 return FALSE;
1143 void
1144 proto_register_rpcap (void)
1146 static hf_register_info hf[] = {
1147 /* Common header for all messages */
1148 { &hf_version,
1149 { "Version", "rpcap.version", FT_UINT8, BASE_DEC,
1150 NULL, 0x0, NULL, HFILL } },
1151 { &hf_type,
1152 { "Message type", "rpcap.type", FT_UINT8, BASE_DEC,
1153 VALS(message_type), 0x0, NULL, HFILL } },
1154 { &hf_value,
1155 { "Message value", "rpcap.value", FT_UINT16, BASE_DEC,
1156 NULL, 0x0, NULL, HFILL } },
1157 { &hf_plen,
1158 { "Payload length", "rpcap.len", FT_UINT32, BASE_DEC,
1159 NULL, 0x0, NULL, HFILL } },
1161 /* Error */
1162 { &hf_error,
1163 { "Error", "rpcap.error", FT_STRING, BASE_NONE,
1164 NULL, 0x0, "Error text", HFILL } },
1165 { &hf_error_value,
1166 { "Error value", "rpcap.error_value", FT_UINT16, BASE_DEC,
1167 VALS(error_codes), 0x0, NULL, HFILL } },
1169 /* Packet header */
1170 { &hf_packet,
1171 { "Packet", "rpcap.packet", FT_NONE, BASE_NONE,
1172 NULL, 0x0, "Packet data", HFILL } },
1173 { &hf_timestamp,
1174 { "Arrival time", "rpcap.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
1175 NULL, 0x0, NULL, HFILL } },
1176 { &hf_caplen,
1177 { "Capture length", "rpcap.cap_len", FT_UINT32, BASE_DEC,
1178 NULL, 0x0, NULL, HFILL } },
1179 { &hf_len,
1180 { "Frame length", "rpcap.len", FT_UINT32, BASE_DEC,
1181 NULL, 0x0, "Frame length (off wire)", HFILL } },
1182 { &hf_npkt,
1183 { "Frame number", "rpcap.number", FT_UINT32, BASE_DEC,
1184 NULL, 0x0, NULL, HFILL } },
1186 /* Authentication request */
1187 { &hf_auth_request,
1188 { "Authentication", "rpcap.auth", FT_NONE, BASE_NONE,
1189 NULL, 0x0, NULL, HFILL } },
1190 { &hf_auth_type,
1191 { "Authentication type", "rpcap.auth_type", FT_UINT16, BASE_DEC,
1192 VALS(auth_type), 0x0, NULL, HFILL } },
1193 { &hf_auth_slen1,
1194 { "Authentication item length 1", "rpcap.auth_len1", FT_UINT16, BASE_DEC,
1195 NULL, 0x0, NULL, HFILL } },
1196 { &hf_auth_slen2,
1197 { "Authentication item length 2", "rpcap.auth_len2", FT_UINT16, BASE_DEC,
1198 NULL, 0x0, NULL, HFILL } },
1199 { &hf_auth_username,
1200 { "Username", "rpcap.username", FT_STRING, BASE_NONE,
1201 NULL, 0x0, NULL, HFILL } },
1202 { &hf_auth_password,
1203 { "Password", "rpcap.password", FT_STRING, BASE_NONE,
1204 NULL, 0x0, NULL, HFILL } },
1206 /* Open request */
1207 { &hf_open_request,
1208 { "Open request", "rpcap.open_request", FT_STRING, BASE_NONE,
1209 NULL, 0x0, NULL, HFILL } },
1211 /* Open reply */
1212 { &hf_open_reply,
1213 { "Open reply", "rpcap.open_reply", FT_NONE, BASE_NONE,
1214 NULL, 0x0, NULL, HFILL } },
1215 { &hf_linktype,
1216 { "Link type", "rpcap.linktype", FT_UINT32, BASE_DEC,
1217 NULL, 0x0, NULL, HFILL } },
1218 { &hf_tzoff,
1219 { "Timezone offset", "rpcap.tzoff", FT_UINT32, BASE_DEC,
1220 NULL, 0x0, NULL, HFILL } },
1222 /* Start capture request */
1223 { &hf_startcap_request,
1224 { "Start capture request", "rpcap.startcap_request", FT_NONE, BASE_NONE,
1225 NULL, 0x0, NULL, HFILL } },
1226 { &hf_snaplen,
1227 { "Snap length", "rpcap.snaplen", FT_UINT32, BASE_DEC,
1228 NULL, 0x0, NULL, HFILL } },
1229 { &hf_read_timeout,
1230 { "Read timeout", "rpcap.read_timeout", FT_UINT32, BASE_DEC,
1231 NULL, 0x0, NULL, HFILL } },
1232 { &hf_flags,
1233 { "Flags", "rpcap.flags", FT_UINT16, BASE_DEC,
1234 NULL, 0x0, "Capture flags", HFILL } },
1235 { &hf_flags_promisc,
1236 { "Promiscuous mode", "rpcap.flags.promisc", FT_BOOLEAN, 16,
1237 TFS(&tfs_enabled_disabled), FLAG_PROMISC, NULL, HFILL } },
1238 { &hf_flags_dgram,
1239 { "Use Datagram", "rpcap.flags.dgram", FT_BOOLEAN, 16,
1240 TFS(&tfs_yes_no), FLAG_DGRAM, NULL, HFILL } },
1241 { &hf_flags_serveropen,
1242 { "Server open", "rpcap.flags.serveropen", FT_BOOLEAN, 16,
1243 TFS(&open_closed), FLAG_SERVEROPEN, NULL, HFILL } },
1244 { &hf_flags_inbound,
1245 { "Inbound", "rpcap.flags.inbound", FT_BOOLEAN, 16,
1246 TFS(&tfs_yes_no), FLAG_INBOUND, NULL, HFILL } },
1247 { &hf_flags_outbound,
1248 { "Outbound", "rpcap.flags.outbound", FT_BOOLEAN, 16,
1249 TFS(&tfs_yes_no), FLAG_OUTBOUND, NULL, HFILL } },
1250 { &hf_client_port,
1251 { "Client Port", "rpcap.client_port", FT_UINT16, BASE_DEC,
1252 NULL, 0x0, NULL, HFILL } },
1254 /* Start capture reply */
1255 { &hf_startcap_reply,
1256 { "Start capture reply", "rpcap.startcap_reply", FT_NONE, BASE_NONE,
1257 NULL, 0x0, NULL, HFILL } },
1258 { &hf_bufsize,
1259 { "Buffer size", "rpcap.bufsize", FT_UINT32, BASE_DEC,
1260 NULL, 0x0, NULL, HFILL } },
1261 { &hf_server_port,
1262 { "Server port", "rpcap.server_port", FT_UINT16, BASE_DEC,
1263 NULL, 0x0, NULL, HFILL } },
1264 { &hf_dummy,
1265 { "Dummy", "rpcap.dummy", FT_UINT16, BASE_DEC,
1266 NULL, 0x0, NULL, HFILL } },
1268 /* Filter */
1269 { &hf_filter,
1270 { "Filter", "rpcap.filter", FT_NONE, BASE_NONE,
1271 NULL, 0x0, NULL, HFILL } },
1272 { &hf_filtertype,
1273 { "Filter type", "rpcap.filtertype", FT_UINT16, BASE_DEC,
1274 NULL, 0x0, "Filter type (BPF)", HFILL } },
1275 { &hf_nitems,
1276 { "Number of items", "rpcap.nitems", FT_UINT32, BASE_DEC,
1277 NULL, 0x0, NULL, HFILL } },
1279 /* Filter BPF instruction */
1280 { &hf_filterbpf_insn,
1281 { "Filter BPF instruction", "rpcap.filterbpf_insn", FT_NONE, BASE_NONE,
1282 NULL, 0x0, NULL, HFILL } },
1283 { &hf_code,
1284 { "Op code", "rpcap.opcode", FT_UINT16, BASE_HEX,
1285 NULL, 0x0, "Operation code", HFILL } },
1286 { &hf_code_class,
1287 { "Class", "rpcap.opcode.class", FT_UINT16, BASE_HEX,
1288 VALS(bpf_class), 0x07, "Instruction Class", HFILL } },
1289 { &hf_code_fields,
1290 { "Fields", "rpcap.opcode.fields", FT_UINT16, BASE_HEX,
1291 NULL, 0xF8, "Class Fields", HFILL } },
1292 { &hf_code_ld_size,
1293 { "Size", "rpcap.opcode.size", FT_UINT16, BASE_HEX,
1294 VALS(bpf_size), 0x18, NULL, HFILL } },
1295 { &hf_code_ld_mode,
1296 { "Mode", "rpcap.opcode.mode", FT_UINT16, BASE_HEX,
1297 VALS(bpf_mode), 0xE0, NULL, HFILL } },
1298 { &hf_code_alu_op,
1299 { "Op", "rpcap.opcode.aluop", FT_UINT16, BASE_HEX,
1300 VALS(bpf_alu_op), 0xF0, NULL, HFILL } },
1301 { &hf_code_jmp_op,
1302 { "Op", "rpcap.opcode.jmpop", FT_UINT16, BASE_HEX,
1303 VALS(bpf_jmp_op), 0xF0, NULL, HFILL } },
1304 { &hf_code_src,
1305 { "Src", "rpcap.opcode.src", FT_UINT16, BASE_HEX,
1306 VALS(bpf_src), 0x08, NULL, HFILL } },
1307 { &hf_code_rval,
1308 { "Rval", "rpcap.opcode.rval", FT_UINT16, BASE_HEX,
1309 VALS(bpf_rval), 0x18, NULL, HFILL } },
1310 { &hf_code_misc_op,
1311 { "Op", "rpcap.opcode.miscop", FT_UINT16, BASE_HEX,
1312 VALS(bpf_misc_op), 0xF8, NULL, HFILL } },
1313 { &hf_jt,
1314 { "JT", "rpcap.jt", FT_UINT8, BASE_DEC,
1315 NULL, 0x0, NULL, HFILL } },
1316 { &hf_jf,
1317 { "JF", "rpcap.jf", FT_UINT8, BASE_DEC,
1318 NULL, 0x0, NULL, HFILL } },
1319 { &hf_instr_value,
1320 { "Instruction value", "rpcap.instr_value", FT_UINT32, BASE_DEC,
1321 NULL, 0x0, "Instruction-Dependent value", HFILL } },
1323 /* Statistics reply */
1324 { &hf_stats_reply,
1325 { "Statistics", "rpcap.stats_reply", FT_NONE, BASE_NONE,
1326 NULL, 0x0, "Statistics reply data", HFILL } },
1327 { &hf_ifrecv,
1328 { "Received by kernel filter", "rpcap.ifrecv", FT_UINT32, BASE_DEC,
1329 NULL, 0x0, "Received by kernel", HFILL } },
1330 { &hf_ifdrop,
1331 { "Dropped by network interface", "rpcap.ifdrop", FT_UINT32, BASE_DEC,
1332 NULL, 0x0, NULL, HFILL } },
1333 { &hf_krnldrop,
1334 { "Dropped by kernel filter", "rpcap.krnldrop", FT_UINT32, BASE_DEC,
1335 NULL, 0x0, NULL, HFILL } },
1336 { &hf_srvcapt,
1337 { "Captured by rpcapd", "rpcap.srvcapt", FT_UINT32, BASE_DEC,
1338 NULL, 0x0, "Captured by RPCAP daemon", HFILL } },
1340 /* Find all devices reply */
1341 { &hf_findalldevs_reply,
1342 { "Find all devices", "rpcap.findalldevs_reply", FT_NONE, BASE_NONE,
1343 NULL, 0x0, NULL, HFILL } },
1344 { &hf_findalldevs_if,
1345 { "Interface", "rpcap.if", FT_NONE, BASE_NONE,
1346 NULL, 0x0, NULL, HFILL } },
1347 { &hf_namelen,
1348 { "Name length", "rpcap.namelen", FT_UINT16, BASE_DEC,
1349 NULL, 0x0, NULL, HFILL } },
1350 { &hf_desclen,
1351 { "Description length", "rpcap.desclen", FT_UINT32, BASE_DEC,
1352 NULL, 0x0, NULL, HFILL } },
1353 { &hf_if_flags,
1354 { "Interface flags", "rpcap.if.flags", FT_UINT32, BASE_DEC,
1355 NULL, 0x0, NULL, HFILL } },
1356 { &hf_naddr,
1357 { "Number of addresses", "rpcap.naddr", FT_UINT32, BASE_DEC,
1358 NULL, 0x0, NULL, HFILL } },
1359 { &hf_if_name,
1360 { "Name", "rpcap.ifname", FT_STRING, BASE_NONE,
1361 NULL, 0x0, "Interface name", HFILL } },
1362 { &hf_if_desc,
1363 { "Description", "rpcap.ifdesc", FT_STRING, BASE_NONE,
1364 NULL, 0x0, "Interface description", HFILL } },
1366 /* Find all devices / Interface addresses */
1367 { &hf_findalldevs_ifaddr,
1368 { "Interface address", "rpcap.ifaddr", FT_NONE, BASE_NONE,
1369 NULL, 0x0, NULL, HFILL } },
1370 { &hf_if_addr,
1371 { "Address", "rpcap.addr", FT_NONE, BASE_NONE,
1372 NULL, 0x0, "Network address", HFILL } },
1373 { &hf_if_netmask,
1374 { "Netmask", "rpcap.netmask", FT_NONE, BASE_NONE,
1375 NULL, 0x0, NULL, HFILL } },
1376 { &hf_if_broadaddr,
1377 { "Broadcast", "rpcap.broadaddr", FT_NONE, BASE_NONE,
1378 NULL, 0x0, NULL, HFILL } },
1379 { &hf_if_dstaddr,
1380 { "P2P destination address", "rpcap.dstaddr", FT_NONE, BASE_NONE,
1381 NULL, 0x0, NULL, HFILL } },
1382 { &hf_if_af,
1383 { "Address family", "rpcap.if.af", FT_UINT16, BASE_HEX,
1384 VALS(address_family), 0x0, NULL, HFILL } },
1385 { &hf_if_port,
1386 { "Port", "rpcap.if.port", FT_UINT16, BASE_DEC,
1387 NULL, 0x0, "Port number", HFILL } },
1388 { &hf_if_ip,
1389 { "IP address", "rpcap.if.ip", FT_IPv4, BASE_NONE,
1390 NULL, 0x0, NULL, HFILL } },
1391 { &hf_if_padding,
1392 { "Padding", "rpcap.if.padding", FT_BYTES, BASE_NONE,
1393 NULL, 0x0, NULL, HFILL } },
1394 { &hf_if_unknown,
1395 { "Unknown address", "rpcap.if.unknown", FT_BYTES, BASE_NONE,
1396 NULL, 0x0, NULL, HFILL } },
1398 /* Sampling request */
1399 { &hf_sampling_request,
1400 { "Sampling", "rpcap.sampling_request", FT_NONE, BASE_NONE,
1401 NULL, 0x0, NULL, HFILL } },
1402 { &hf_sampling_method,
1403 { "Method", "rpcap.sampling_method", FT_UINT8, BASE_DEC,
1404 VALS(sampling_method), 0x0, "Sampling method", HFILL } },
1405 { &hf_sampling_dummy1,
1406 { "Dummy1", "rpcap.dummy", FT_UINT8, BASE_DEC,
1407 NULL, 0x0, NULL, HFILL } },
1408 { &hf_sampling_dummy2,
1409 { "Dummy2", "rpcap.dummy", FT_UINT16, BASE_DEC,
1410 NULL, 0x0, NULL, HFILL } },
1411 { &hf_sampling_value,
1412 { "Value", "rpcap.sampling_value", FT_UINT32, BASE_DEC,
1413 NULL, 0x0, NULL, HFILL } },
1416 static gint *ett[] = {
1417 &ett_rpcap,
1418 &ett_error,
1419 &ett_packet,
1420 &ett_auth_request,
1421 &ett_open_reply,
1422 &ett_startcap_request,
1423 &ett_startcap_reply,
1424 &ett_startcap_flags,
1425 &ett_filter,
1426 &ett_filterbpf_insn,
1427 &ett_filterbpf_insn_code,
1428 &ett_stats_reply,
1429 &ett_findalldevs_reply,
1430 &ett_findalldevs_if,
1431 &ett_findalldevs_ifaddr,
1432 &ett_ifaddr,
1433 &ett_sampling_request
1436 static ei_register_info ei[] = {
1437 { &ei_error, { "rpcap.error.expert", PI_SEQUENCE, PI_NOTE, "Error", EXPFILL }},
1438 { &ei_if_unknown, { "rpcap.if_unknown", PI_SEQUENCE, PI_NOTE, "Unknown address family", EXPFILL }},
1439 { &ei_no_more_data, { "rpcap.no_more_data", PI_MALFORMED, PI_ERROR, "No more data in packet", EXPFILL }},
1440 { &ei_caplen_too_big, { "rpcap.caplen_too_big", PI_MALFORMED, PI_ERROR, "Caplen is bigger than the remaining message length", EXPFILL }},
1443 module_t *rpcap_module;
1444 expert_module_t* expert_rpcap;
1446 proto_rpcap = proto_register_protocol (PNAME, PSNAME, PFNAME);
1447 new_register_dissector (PFNAME, dissect_rpcap, proto_rpcap);
1448 expert_rpcap = expert_register_protocol(proto_rpcap);
1449 expert_register_field_array(expert_rpcap, ei, array_length(ei));
1451 proto_register_field_array (proto_rpcap, hf, array_length (hf));
1452 proto_register_subtree_array (ett, array_length (ett));
1454 /* Register our configuration options */
1455 rpcap_module = prefs_register_protocol (proto_rpcap, proto_reg_handoff_rpcap);
1457 prefs_register_bool_preference (rpcap_module, "desegment_pdus",
1458 "Reassemble PDUs spanning multiple TCP segments",
1459 "Whether the RPCAP dissector should reassemble PDUs"
1460 " spanning multiple TCP segments."
1461 " To use this option, you must also enable \"Allow subdissectors"
1462 " to reassemble TCP streams\" in the TCP protocol settings.",
1463 &rpcap_desegment);
1464 prefs_register_bool_preference (rpcap_module, "decode_content",
1465 "Decode content according to link-layer type",
1466 "Whether the packets should be decoded according to"
1467 " the link-layer type.",
1468 &decode_content);
1469 prefs_register_uint_preference (rpcap_module, "linktype",
1470 "Default link-layer type",
1471 "Default link-layer type to use if an Open Reply packet"
1472 " has not been received.",
1473 10, &global_linktype);
1476 void
1477 proto_reg_handoff_rpcap (void)
1479 static gboolean rpcap_prefs_initialized = FALSE;
1481 if (!rpcap_prefs_initialized) {
1482 data_handle = find_dissector ("data");
1483 rpcap_prefs_initialized = TRUE;
1485 heur_dissector_add ("tcp", dissect_rpcap_heur_tcp, proto_rpcap);
1486 heur_dissector_add ("udp", dissect_rpcap_heur_udp, proto_rpcap);
1489 info_added = FALSE;
1490 linktype = global_linktype;
1494 * Editor modelines
1496 * Local Variables:
1497 * c-basic-offset: 2
1498 * tab-width: 8
1499 * indent-tabs-mode: t
1500 * End:
1502 * ex: set shiftwidth=2 tabstop=8 noexpandtab:
1503 * :indentSize=2:tabSize=8:noTabs=false: