2 * Routines for rpc dissection
3 * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-smb.c
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #include <epan/packet.h>
37 #include <epan/conversation.h>
38 #include "packet-rpc.h"
39 #include "packet-frame.h"
40 #include "packet-tcp.h"
41 #include <epan/prefs.h>
42 #include <epan/reassemble.h>
43 #include "rpc_defrag.h"
44 #include "packet-nfs.h"
46 #include <epan/emem.h>
51 * RFC 1831, "RPC: Remote Procedure Call Protocol Specification
54 * RFC 1832, "XDR: External Data Representation Standard";
56 * RFC 2203, "RPCSEC_GSS Protocol Specification".
60 * RFC 2695, "Authentication Mechanisms for ONC RPC"
62 * although we don't currently dissect AUTH_DES or AUTH_KERB.
65 /* desegmentation of RPC over TCP */
66 static gboolean rpc_desegment = TRUE;
68 /* defragmentation of fragmented RPC over TCP records */
69 static gboolean rpc_defragment = FALSE;
71 /* try to dissect RPC packets for programs that are not known
72 * (proprietary ones) by ethereal.
74 static gboolean rpc_dissect_unknown_programs = FALSE;
77 static struct true_false_string yesno = { "Yes", "No" };
79 static int rpc_tap = -1;
81 static const value_string rpc_msg_type[] = {
83 { RPC_REPLY, "Reply" },
87 static const value_string rpc_reply_state[] = {
88 { MSG_ACCEPTED, "accepted" },
89 { MSG_DENIED, "denied" },
93 const value_string rpc_auth_flavor[] = {
94 { AUTH_NULL, "AUTH_NULL" },
95 { AUTH_UNIX, "AUTH_UNIX" },
96 { AUTH_SHORT, "AUTH_SHORT" },
97 { AUTH_DES, "AUTH_DES" },
98 { RPCSEC_GSS, "RPCSEC_GSS" },
99 { AUTH_GSSAPI, "AUTH_GSSAPI" },
103 static const value_string rpc_authgss_proc[] = {
104 { RPCSEC_GSS_DATA, "RPCSEC_GSS_DATA" },
105 { RPCSEC_GSS_INIT, "RPCSEC_GSS_INIT" },
106 { RPCSEC_GSS_CONTINUE_INIT, "RPCSEC_GSS_CONTINUE_INIT" },
107 { RPCSEC_GSS_DESTROY, "RPCSEC_GSS_DESTROY" },
111 static const value_string rpc_authgssapi_proc[] = {
112 { AUTH_GSSAPI_EXIT, "AUTH_GSSAPI_EXIT" },
113 { AUTH_GSSAPI_INIT, "AUTH_GSSAPI_INIT" },
114 { AUTH_GSSAPI_CONTINUE_INIT, "AUTH_GSSAPI_CONTINUE_INIT" },
115 { AUTH_GSSAPI_MSG, "AUTH_GSSAPI_MSG" },
116 { AUTH_GSSAPI_DESTROY, "AUTH_GSSAPI_DESTROY" },
120 value_string rpc_authgss_svc[] = {
121 { RPCSEC_GSS_SVC_NONE, "rpcsec_gss_svc_none" },
122 { RPCSEC_GSS_SVC_INTEGRITY, "rpcsec_gss_svc_integrity" },
123 { RPCSEC_GSS_SVC_PRIVACY, "rpcsec_gss_svc_privacy" },
127 static const value_string rpc_accept_state[] = {
128 { SUCCESS, "RPC executed successfully" },
129 { PROG_UNAVAIL, "remote hasn't exported program" },
130 { PROG_MISMATCH, "remote can't support version #" },
131 { PROC_UNAVAIL, "program can't support procedure" },
132 { GARBAGE_ARGS, "procedure can't decode params" },
133 { SYSTEM_ERROR, "system errors like memory allocation failure" },
137 static const value_string rpc_reject_state[] = {
138 { RPC_MISMATCH, "RPC_MISMATCH" },
139 { AUTH_ERROR, "AUTH_ERROR" },
143 static const value_string rpc_auth_state[] = {
144 { AUTH_BADCRED, "bad credential (seal broken)" },
145 { AUTH_REJECTEDCRED, "client must begin new session" },
146 { AUTH_BADVERF, "bad verifier (seal broken)" },
147 { AUTH_REJECTEDVERF, "verifier expired or replayed" },
148 { AUTH_TOOWEAK, "rejected for security reasons" },
149 { RPCSEC_GSSCREDPROB, "GSS credential problem" },
150 { RPCSEC_GSSCTXPROB, "GSS context problem" },
154 static const value_string rpc_authdes_namekind[] = {
155 { AUTHDES_NAMEKIND_FULLNAME, "ADN_FULLNAME" },
156 { AUTHDES_NAMEKIND_NICKNAME, "ADN_NICKNAME" },
160 /* the protocol number */
161 static int proto_rpc = -1;
162 static int hf_rpc_reqframe = -1;
163 static int hf_rpc_repframe = -1;
164 static int hf_rpc_lastfrag = -1;
165 static int hf_rpc_fraglen = -1;
166 static int hf_rpc_xid = -1;
167 static int hf_rpc_msgtype = -1;
168 static int hf_rpc_version = -1;
169 static int hf_rpc_version_min = -1;
170 static int hf_rpc_version_max = -1;
171 static int hf_rpc_program = -1;
172 static int hf_rpc_programversion = -1;
173 static int hf_rpc_programversion_min = -1;
174 static int hf_rpc_programversion_max = -1;
175 static int hf_rpc_procedure = -1;
176 static int hf_rpc_auth_flavor = -1;
177 static int hf_rpc_auth_length = -1;
178 static int hf_rpc_auth_machinename = -1;
179 static int hf_rpc_auth_stamp = -1;
180 static int hf_rpc_auth_uid = -1;
181 static int hf_rpc_auth_gid = -1;
182 static int hf_rpc_authgss_v = -1;
183 static int hf_rpc_authgss_proc = -1;
184 static int hf_rpc_authgss_seq = -1;
185 static int hf_rpc_authgss_svc = -1;
186 static int hf_rpc_authgss_ctx = -1;
187 static int hf_rpc_authgss_major = -1;
188 static int hf_rpc_authgss_minor = -1;
189 static int hf_rpc_authgss_window = -1;
190 static int hf_rpc_authgss_token_length = -1;
191 static int hf_rpc_authgss_data_length = -1;
192 static int hf_rpc_authgss_data = -1;
193 static int hf_rpc_authgss_checksum = -1;
194 static int hf_rpc_authgssapi_v = -1;
195 static int hf_rpc_authgssapi_msg = -1;
196 static int hf_rpc_authgssapi_msgv = -1;
197 static int hf_rpc_authgssapi_handle = -1;
198 static int hf_rpc_authgssapi_isn = -1;
199 static int hf_rpc_authdes_namekind = -1;
200 static int hf_rpc_authdes_netname = -1;
201 static int hf_rpc_authdes_convkey = -1;
202 static int hf_rpc_authdes_window = -1;
203 static int hf_rpc_authdes_nickname = -1;
204 static int hf_rpc_authdes_timestamp = -1;
205 static int hf_rpc_authdes_windowverf = -1;
206 static int hf_rpc_authdes_timeverf = -1;
207 static int hf_rpc_state_accept = -1;
208 static int hf_rpc_state_reply = -1;
209 static int hf_rpc_state_reject = -1;
210 static int hf_rpc_state_auth = -1;
211 static int hf_rpc_dup = -1;
212 static int hf_rpc_call_dup = -1;
213 static int hf_rpc_reply_dup = -1;
214 static int hf_rpc_value_follows = -1;
215 static int hf_rpc_array_len = -1;
216 static int hf_rpc_time = -1;
217 static int hf_rpc_fragments = -1;
218 static int hf_rpc_fragment = -1;
219 static int hf_rpc_fragment_overlap = -1;
220 static int hf_rpc_fragment_overlap_conflict = -1;
221 static int hf_rpc_fragment_multiple_tails = -1;
222 static int hf_rpc_fragment_too_long_fragment = -1;
223 static int hf_rpc_fragment_error = -1;
225 static gint ett_rpc = -1;
226 static gint ett_rpc_unknown_program = -1;
227 static gint ett_rpc_fragments = -1;
228 static gint ett_rpc_fragment = -1;
229 static gint ett_rpc_fraghdr = -1;
230 static gint ett_rpc_string = -1;
231 static gint ett_rpc_cred = -1;
232 static gint ett_rpc_verf = -1;
233 static gint ett_rpc_gids = -1;
234 static gint ett_rpc_gss_token = -1;
235 static gint ett_rpc_gss_data = -1;
236 static gint ett_rpc_array = -1;
237 static gint ett_rpc_authgssapi_msg = -1;
239 static dissector_handle_t rpc_tcp_handle;
240 static dissector_handle_t rpc_handle;
241 static dissector_handle_t gssapi_handle;
242 static dissector_handle_t data_handle;
244 static guint max_rpc_tcp_pdu_size = 262144;
246 static const fragment_items rpc_frag_items = {
251 &hf_rpc_fragment_overlap,
252 &hf_rpc_fragment_overlap_conflict,
253 &hf_rpc_fragment_multiple_tails,
254 &hf_rpc_fragment_too_long_fragment,
255 &hf_rpc_fragment_error,
260 /* Hash table with info on RPC program numbers */
261 GHashTable *rpc_progs;
263 /* Hash table with info on RPC procedure numbers */
264 GHashTable *rpc_procs;
266 static void dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
267 static void dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
269 /***********************************/
270 /* Hash array with procedure names */
271 /***********************************/
275 rpc_proc_equal(gconstpointer k1, gconstpointer k2)
277 const rpc_proc_info_key* key1 = (const rpc_proc_info_key*) k1;
278 const rpc_proc_info_key* key2 = (const rpc_proc_info_key*) k2;
280 return ((key1->prog == key2->prog &&
281 key1->vers == key2->vers &&
282 key1->proc == key2->proc) ?
286 /* calculate a hash key */
288 rpc_proc_hash(gconstpointer k)
290 const rpc_proc_info_key* key = (const rpc_proc_info_key*) k;
292 return (key->prog ^ (key->vers<<16) ^ (key->proc<<24));
296 /* insert some entries */
298 rpc_init_proc_table(guint prog, guint vers, const vsff *proc_table,
301 rpc_prog_info_key rpc_prog_key;
302 rpc_prog_info_value *rpc_prog;
306 * Add the operation number hfinfo value for this version of the
309 rpc_prog_key.prog = prog;
310 rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key);
311 DISSECTOR_ASSERT(rpc_prog != NULL);
312 rpc_prog->procedure_hfs = g_array_set_size(rpc_prog->procedure_hfs,
314 g_array_insert_val(rpc_prog->procedure_hfs, vers, procedure_hf);
316 for (proc = proc_table ; proc->strptr!=NULL; proc++) {
317 rpc_proc_info_key *key;
318 rpc_proc_info_value *value;
320 key = (rpc_proc_info_key *) g_malloc(sizeof(rpc_proc_info_key));
323 key->proc = proc->value;
325 value = (rpc_proc_info_value *) g_malloc(sizeof(rpc_proc_info_value));
326 value->name = proc->strptr;
327 value->dissect_call = proc->dissect_call;
328 value->dissect_reply = proc->dissect_reply;
330 g_hash_table_insert(rpc_procs,key,value);
335 /* return the name associated with a previously registered procedure. */
336 char *rpc_proc_name(guint32 prog, guint32 vers, guint32 proc)
338 rpc_proc_info_key key;
339 rpc_proc_info_value *value;
341 static char procname_static[20];
347 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL)
348 procname = value->name;
350 /* happens only with strange program versions or
351 non-existing dissectors */
352 sprintf(procname_static, "proc-%u", key.proc);
353 procname = procname_static;
358 /*----------------------------------------*/
359 /* end of Hash array with procedure names */
360 /*----------------------------------------*/
363 /*********************************/
364 /* Hash array with program names */
365 /*********************************/
369 rpc_prog_equal(gconstpointer k1, gconstpointer k2)
371 const rpc_prog_info_key* key1 = (const rpc_prog_info_key*) k1;
372 const rpc_prog_info_key* key2 = (const rpc_prog_info_key*) k2;
374 return ((key1->prog == key2->prog) ?
379 /* calculate a hash key */
381 rpc_prog_hash(gconstpointer k)
383 const rpc_prog_info_key* key = (const rpc_prog_info_key*) k;
390 rpc_init_prog(int proto, guint32 prog, int ett)
392 rpc_prog_info_key *key;
393 rpc_prog_info_value *value;
395 key = (rpc_prog_info_key *) g_malloc(sizeof(rpc_prog_info_key));
398 value = (rpc_prog_info_value *) g_malloc(sizeof(rpc_prog_info_value));
399 value->proto = find_protocol_by_id(proto);
400 value->proto_id = proto;
402 value->progname = proto_get_protocol_short_name(value->proto);
403 value->procedure_hfs = g_array_new(FALSE, TRUE, sizeof (int));
405 g_hash_table_insert(rpc_progs,key,value);
410 /* return the hf_field associated with a previously registered program.
412 int rpc_prog_hf(guint32 prog, guint32 vers)
414 rpc_prog_info_key rpc_prog_key;
415 rpc_prog_info_value *rpc_prog;
417 rpc_prog_key.prog = prog;
418 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key))) {
419 return g_array_index(rpc_prog->procedure_hfs, int, vers);
424 /* return the name associated with a previously registered program. This
425 should probably eventually be expanded to use the rpc YP/NIS map
426 so that it can give names for programs not handled by ethereal */
427 const char *rpc_prog_name(guint32 prog)
429 const char *progname = NULL;
430 rpc_prog_info_key rpc_prog_key;
431 rpc_prog_info_value *rpc_prog;
433 rpc_prog_key.prog = prog;
434 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
435 progname = "Unknown";
438 progname = rpc_prog->progname;
444 /*--------------------------------------*/
445 /* end of Hash array with program names */
446 /*--------------------------------------*/
448 typedef struct _rpc_call_info_key {
450 conversation_t *conversation;
453 static GMemChunk *rpc_call_info_key_chunk;
455 static GMemChunk *rpc_call_info_value_chunk;
457 static GHashTable *rpc_calls;
459 static GHashTable *rpc_indir_calls;
463 rpc_call_equal(gconstpointer k1, gconstpointer k2)
465 const rpc_call_info_key* key1 = (const rpc_call_info_key*) k1;
466 const rpc_call_info_key* key2 = (const rpc_call_info_key*) k2;
468 return (key1->xid == key2->xid &&
469 key1->conversation == key2->conversation);
473 /* calculate a hash key */
475 rpc_call_hash(gconstpointer k)
477 const rpc_call_info_key* key = (const rpc_call_info_key*) k;
479 return key->xid + GPOINTER_TO_UINT(key->conversation);
484 rpc_roundup(unsigned int a)
486 unsigned int mod = a % 4;
487 return a + ((mod)? 4-mod : 0);
492 dissect_rpc_bool(tvbuff_t *tvb, proto_tree *tree,
493 int hfindex, int offset)
496 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
502 dissect_rpc_uint32(tvbuff_t *tvb, proto_tree *tree,
503 int hfindex, int offset)
506 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
512 dissect_rpc_uint64(tvbuff_t *tvb, proto_tree *tree,
513 int hfindex, int offset)
515 header_field_info *hfinfo;
517 hfinfo = proto_registrar_get_nth(hfindex);
518 DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
520 proto_tree_add_item(tree, hfindex, tvb, offset, 8, FALSE);
526 * We want to make this function available outside this file and
527 * allow callers to pass a dissection function for the opaque data
530 dissect_rpc_opaque_data(tvbuff_t *tvb, int offset,
534 gboolean fixed_length, guint32 length,
535 gboolean string_data, char **string_buffer_ret,
536 dissect_function_t *dissect_it)
539 proto_item *string_item = NULL;
540 proto_tree *string_tree = NULL;
542 guint32 string_length;
543 guint32 string_length_full;
544 guint32 string_length_packet;
545 guint32 string_length_captured;
546 guint32 string_length_copy;
550 guint32 fill_length_packet;
551 guint32 fill_length_captured;
552 guint32 fill_length_copy;
556 char *string_buffer = NULL;
557 char *string_buffer_print = NULL;
560 string_length = length;
561 data_offset = offset;
564 string_length = tvb_get_ntohl(tvb,offset+0);
565 data_offset = offset + 4;
567 string_length_captured = tvb_length_remaining(tvb, data_offset);
568 string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
569 string_length_full = rpc_roundup(string_length);
570 if (string_length_captured < string_length) {
571 /* truncated string */
572 string_length_copy = string_length_captured;
575 fill_length_copy = 0;
576 if (string_length_packet < string_length)
577 exception = ReportedBoundsError;
579 exception = BoundsError;
582 /* full string data */
583 string_length_copy = string_length;
584 fill_length = string_length_full - string_length;
585 fill_length_captured = tvb_length_remaining(tvb,
586 data_offset + string_length);
587 fill_length_packet = tvb_reported_length_remaining(tvb,
588 data_offset + string_length);
589 if (fill_length_captured < fill_length) {
590 /* truncated fill bytes */
591 fill_length_copy = fill_length_packet;
593 if (fill_length_packet < fill_length)
594 exception = ReportedBoundsError;
596 exception = BoundsError;
599 /* full fill bytes */
600 fill_length_copy = fill_length;
606 * If we were passed a dissection routine, make a TVB of the data
607 * and call the dissection routine
611 tvbuff_t *opaque_tvb;
613 opaque_tvb = tvb_new_subset(tvb, data_offset, string_length_copy,
616 return (*dissect_it)(opaque_tvb, offset, pinfo, tree);
622 tmpstr = tvb_get_string(tvb, data_offset, string_length_copy);
623 string_buffer = memcpy(ep_alloc(string_length_copy), tmpstr, string_length_copy);
626 string_buffer = tvb_memcpy(tvb, ep_alloc(string_length_copy), data_offset, string_length_copy);
628 /* calculate a nice printable string */
630 if (string_length != string_length_copy) {
632 /* alloc maximum data area */
633 string_buffer_print = (char*)ep_alloc(string_length_copy + 12 + 1);
634 /* copy over the data */
635 memcpy(string_buffer_print,string_buffer,string_length_copy);
636 /* append a 0 byte for sure printing */
637 string_buffer_print[string_length_copy] = '\0';
638 /* append <TRUNCATED> */
639 /* This way, we get the TRUNCATED even
640 in the case of totally wrong packets,
641 where \0 are inside the string.
642 TRUNCATED will appear at the
643 first \0 or at the end (where we
644 put the securing \0).
646 strcat(string_buffer_print,"<TRUNCATED>");
648 string_buffer_print="<DATA><TRUNCATED>";
652 string_buffer_print = string_buffer;
654 string_buffer_print="<DATA>";
658 string_buffer_print="<EMPTY>";
662 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
663 "%s: %s", proto_registrar_get_name(hfindex),
664 string_buffer_print);
665 string_tree = proto_item_add_subtree(string_item,
670 proto_tree_add_text(string_tree, tvb,offset+0,4,
671 "length: %u", string_length);
677 proto_tree_add_string_format(string_tree,
678 hfindex, tvb, offset, string_length_copy,
680 "contents: %s", string_buffer_print);
682 proto_tree_add_bytes_format(string_tree,
683 hfindex, tvb, offset, string_length_copy,
685 "contents: %s", string_buffer_print);
689 offset += string_length_copy;
693 if (fill_truncated) {
694 proto_tree_add_text(string_tree, tvb,
695 offset,fill_length_copy,
696 "fill bytes: opaque data<TRUNCATED>");
699 proto_tree_add_text(string_tree, tvb,
700 offset,fill_length_copy,
701 "fill bytes: opaque data");
704 offset += fill_length_copy;
708 proto_item_set_end(string_item, tvb, offset);
710 if (string_buffer_ret != NULL)
711 *string_buffer_ret = string_buffer_print;
714 * If the data was truncated, throw the appropriate exception,
715 * so that dissection stops and the frame is properly marked.
724 dissect_rpc_string(tvbuff_t *tvb, proto_tree *tree,
725 int hfindex, int offset, char **string_buffer_ret)
727 offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL,
728 hfindex, FALSE, 0, TRUE, string_buffer_ret, NULL);
734 dissect_rpc_data(tvbuff_t *tvb, proto_tree *tree,
735 int hfindex, int offset)
737 offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL,
738 hfindex, FALSE, 0, FALSE, NULL, NULL);
744 dissect_rpc_bytes(tvbuff_t *tvb, proto_tree *tree,
745 int hfindex, int offset, guint32 length,
746 gboolean string_data, char **string_buffer_ret)
748 offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL,
749 hfindex, TRUE, length, string_data, string_buffer_ret, NULL);
755 dissect_rpc_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
756 int offset, dissect_function_t *rpc_list_dissector)
758 guint32 value_follows;
761 value_follows = tvb_get_ntohl(tvb, offset+0);
762 proto_tree_add_boolean(tree,hf_rpc_value_follows, tvb,
763 offset+0, 4, value_follows);
765 if (value_follows == 1) {
766 offset = rpc_list_dissector(tvb, offset, pinfo, tree);
777 dissect_rpc_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
778 int offset, dissect_function_t *rpc_array_dissector,
781 proto_item* lock_item;
782 proto_tree* lock_tree;
785 num = tvb_get_ntohl(tvb, offset);
788 proto_tree_add_none_format(tree, hfindex, tvb, offset, 4,
795 lock_item = proto_tree_add_item(tree, hfindex, tvb, offset, -1, FALSE);
797 lock_tree = proto_item_add_subtree(lock_item, ett_rpc_array);
799 offset = dissect_rpc_uint32(tvb, lock_tree,
800 hf_rpc_array_len, offset);
803 offset = rpc_array_dissector(tvb, offset, pinfo, lock_tree);
806 proto_item_set_end(lock_item, tvb, offset);
811 dissect_rpc_authunix_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
820 proto_tree *gtree = NULL;
822 stamp = tvb_get_ntohl(tvb,offset+0);
824 proto_tree_add_uint(tree, hf_rpc_auth_stamp, tvb,
828 offset = dissect_rpc_string(tvb, tree,
829 hf_rpc_auth_machinename, offset, NULL);
831 uid = tvb_get_ntohl(tvb,offset+0);
833 proto_tree_add_uint(tree, hf_rpc_auth_uid, tvb,
837 gid = tvb_get_ntohl(tvb,offset+0);
839 proto_tree_add_uint(tree, hf_rpc_auth_gid, tvb,
843 gids_count = tvb_get_ntohl(tvb,offset+0);
845 gitem = proto_tree_add_text(tree, tvb,
846 offset, 4+gids_count*4, "Auxiliary GIDs");
847 gtree = proto_item_add_subtree(gitem, ett_rpc_gids);
851 for (gids_i = 0 ; gids_i < gids_count ; gids_i++) {
852 gids_entry = tvb_get_ntohl(tvb,offset+0);
854 proto_tree_add_uint(gtree, hf_rpc_auth_gid, tvb,
855 offset, 4, gids_entry);
858 /* how can I NOW change the gitem to print a list with
859 the first 16 gids? */
865 dissect_rpc_authgss_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
872 agc_v = tvb_get_ntohl(tvb, offset+0);
874 proto_tree_add_uint(tree, hf_rpc_authgss_v,
875 tvb, offset+0, 4, agc_v);
878 agc_proc = tvb_get_ntohl(tvb, offset+0);
880 proto_tree_add_uint(tree, hf_rpc_authgss_proc,
881 tvb, offset+0, 4, agc_proc);
884 agc_seq = tvb_get_ntohl(tvb, offset+0);
886 proto_tree_add_uint(tree, hf_rpc_authgss_seq,
887 tvb, offset+0, 4, agc_seq);
890 agc_svc = tvb_get_ntohl(tvb, offset+0);
892 proto_tree_add_uint(tree, hf_rpc_authgss_svc,
893 tvb, offset+0, 4, agc_svc);
896 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
903 dissect_rpc_authdes_desblock(tvbuff_t *tvb, proto_tree *tree,
904 int hfindex, int offset)
909 value_high = tvb_get_ntohl(tvb, offset + 0);
910 value_low = tvb_get_ntohl(tvb, offset + 4);
913 proto_tree_add_text(tree, tvb, offset, 8,
914 "%s: 0x%x%08x", proto_registrar_get_name(hfindex), value_high,
922 dissect_rpc_authdes_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
928 adc_namekind = tvb_get_ntohl(tvb, offset+0);
930 proto_tree_add_uint(tree, hf_rpc_authdes_namekind,
931 tvb, offset+0, 4, adc_namekind);
936 case AUTHDES_NAMEKIND_FULLNAME:
937 offset = dissect_rpc_string(tvb, tree,
938 hf_rpc_authdes_netname, offset, NULL);
939 offset = dissect_rpc_authdes_desblock(tvb, tree,
940 hf_rpc_authdes_convkey, offset);
941 window = tvb_get_ntohl(tvb, offset+0);
942 proto_tree_add_uint(tree, hf_rpc_authdes_window, tvb, offset+0, 4,
947 case AUTHDES_NAMEKIND_NICKNAME:
948 nickname = tvb_get_ntohl(tvb, offset+0);
949 proto_tree_add_uint(tree, hf_rpc_authdes_nickname, tvb, offset+0, 4,
959 dissect_rpc_authgssapi_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
964 agc_v = tvb_get_ntohl(tvb, offset+0);
966 proto_tree_add_uint(tree, hf_rpc_authgssapi_v,
967 tvb, offset+0, 4, agc_v);
970 agc_msg = tvb_get_ntohl(tvb, offset+0);
972 proto_tree_add_boolean(tree, hf_rpc_authgssapi_msg,
973 tvb, offset+0, 4, agc_msg);
976 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgssapi_handle,
983 dissect_rpc_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
991 flavor = tvb_get_ntohl(tvb,offset+0);
992 length = tvb_get_ntohl(tvb,offset+4);
993 length = rpc_roundup(length);
996 citem = proto_tree_add_text(tree, tvb, offset,
997 8+length, "Credentials");
998 ctree = proto_item_add_subtree(citem, ett_rpc_cred);
999 proto_tree_add_uint(ctree, hf_rpc_auth_flavor, tvb,
1000 offset+0, 4, flavor);
1001 proto_tree_add_uint(ctree, hf_rpc_auth_length, tvb,
1002 offset+4, 4, length);
1006 dissect_rpc_authunix_cred(tvb, ctree, offset+8);
1014 dissect_rpc_authdes_cred(tvb, ctree, offset+8);
1018 dissect_rpc_authgss_cred(tvb, ctree, offset+8);
1022 dissect_rpc_authgssapi_cred(tvb, ctree, offset+8);
1027 proto_tree_add_text(ctree, tvb, offset+8,
1028 length,"opaque data");
1032 offset += 8 + length;
1038 * XDR opaque object, the contents of which are interpreted as a GSS-API
1042 dissect_rpc_authgss_token(tvbuff_t* tvb, proto_tree* tree, int offset,
1045 guint32 opaque_length, rounded_length;
1046 gint len_consumed, length, reported_length;
1050 proto_tree *gtree = NULL;
1052 opaque_length = tvb_get_ntohl(tvb, offset+0);
1053 rounded_length = rpc_roundup(opaque_length);
1055 gitem = proto_tree_add_text(tree, tvb, offset,
1056 4+rounded_length, "GSS Token");
1057 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_token);
1058 proto_tree_add_uint(gtree, hf_rpc_authgss_token_length,
1059 tvb, offset+0, 4, opaque_length);
1062 length = tvb_length_remaining(tvb, offset);
1063 reported_length = tvb_reported_length_remaining(tvb, offset);
1064 DISSECTOR_ASSERT(length >= 0);
1065 DISSECTOR_ASSERT(reported_length >= 0);
1066 if (length > reported_length)
1067 length = reported_length;
1068 if ((guint32)length > opaque_length)
1069 length = opaque_length;
1070 if ((guint32)reported_length > opaque_length)
1071 reported_length = opaque_length;
1072 new_tvb = tvb_new_subset(tvb, offset, length, reported_length);
1073 len_consumed = call_dissector(gssapi_handle, new_tvb, pinfo, gtree);
1074 offset += len_consumed;
1075 offset = rpc_roundup(offset);
1079 /* AUTH_DES verifiers are asymmetrical, so we need to know what type of
1080 * verifier we're decoding (CALL or REPLY).
1083 dissect_rpc_verf(tvbuff_t* tvb, proto_tree* tree, int offset, int msg_type,
1092 flavor = tvb_get_ntohl(tvb,offset+0);
1093 length = tvb_get_ntohl(tvb,offset+4);
1094 length = rpc_roundup(length);
1097 vitem = proto_tree_add_text(tree, tvb, offset,
1098 8+length, "Verifier");
1099 vtree = proto_item_add_subtree(vitem, ett_rpc_verf);
1100 proto_tree_add_uint(vtree, hf_rpc_auth_flavor, tvb,
1101 offset+0, 4, flavor);
1105 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1106 offset+4, 4, length);
1107 dissect_rpc_authunix_cred(tvb, vtree, offset+8);
1110 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1111 offset+4, 4, length);
1113 if (msg_type == RPC_CALL)
1117 dissect_rpc_authdes_desblock(tvb, vtree,
1118 hf_rpc_authdes_timestamp, offset+8);
1119 window = tvb_get_ntohl(tvb, offset+16);
1120 proto_tree_add_uint(vtree, hf_rpc_authdes_windowverf, tvb,
1121 offset+16, 4, window);
1125 /* must be an RPC_REPLY */
1128 dissect_rpc_authdes_desblock(tvb, vtree,
1129 hf_rpc_authdes_timeverf, offset+8);
1130 nickname = tvb_get_ntohl(tvb, offset+16);
1131 proto_tree_add_uint(vtree, hf_rpc_authdes_nickname, tvb,
1132 offset+16, 4, nickname);
1136 dissect_rpc_authgss_token(tvb, vtree, offset+4, pinfo);
1139 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1140 offset+4, 4, length);
1142 proto_tree_add_text(vtree, tvb, offset+8,
1143 length, "opaque data");
1147 offset += 8 + length;
1153 dissect_rpc_authgss_initarg(tvbuff_t* tvb, proto_tree* tree, int offset,
1156 return dissect_rpc_authgss_token(tvb, tree, offset, pinfo);
1160 dissect_rpc_authgss_initres(tvbuff_t* tvb, proto_tree* tree, int offset,
1163 int major, minor, window;
1165 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
1168 major = tvb_get_ntohl(tvb,offset+0);
1170 proto_tree_add_uint(tree, hf_rpc_authgss_major, tvb,
1171 offset+0, 4, major);
1174 minor = tvb_get_ntohl(tvb,offset+0);
1176 proto_tree_add_uint(tree, hf_rpc_authgss_minor, tvb,
1177 offset+0, 4, minor);
1180 window = tvb_get_ntohl(tvb,offset+0);
1182 proto_tree_add_uint(tree, hf_rpc_authgss_window, tvb,
1183 offset+0, 4, window);
1186 offset = dissect_rpc_authgss_token(tvb, tree, offset, pinfo);
1192 dissect_rpc_authgssapi_initarg(tvbuff_t* tvb, proto_tree* tree, int offset,
1197 proto_tree *mtree = NULL;
1200 mitem = proto_tree_add_text(tree, tvb, offset, -1,
1202 mtree = proto_item_add_subtree(mitem, ett_rpc_authgssapi_msg);
1204 version = tvb_get_ntohl(tvb, offset+0);
1206 proto_tree_add_uint(mtree, hf_rpc_authgssapi_msgv, tvb,
1207 offset+0, 4, version);
1211 offset = dissect_rpc_authgss_token(tvb, mtree, offset, pinfo);
1217 dissect_rpc_authgssapi_initres(tvbuff_t* tvb, proto_tree* tree, int offset,
1223 proto_tree *mtree = NULL;
1226 mitem = proto_tree_add_text(tree, tvb, offset, -1,
1228 mtree = proto_item_add_subtree(mitem, ett_rpc_authgssapi_msg);
1231 version = tvb_get_ntohl(tvb,offset+0);
1233 proto_tree_add_uint(mtree, hf_rpc_authgssapi_msgv, tvb,
1234 offset+0, 4, version);
1238 offset = dissect_rpc_data(tvb, mtree, hf_rpc_authgssapi_handle,
1241 major = tvb_get_ntohl(tvb,offset+0);
1243 proto_tree_add_uint(mtree, hf_rpc_authgss_major, tvb,
1244 offset+0, 4, major);
1248 minor = tvb_get_ntohl(tvb,offset+0);
1250 proto_tree_add_uint(mtree, hf_rpc_authgss_minor, tvb,
1251 offset+0, 4, minor);
1255 offset = dissect_rpc_authgss_token(tvb, mtree, offset, pinfo);
1257 offset = dissect_rpc_data(tvb, mtree, hf_rpc_authgssapi_isn, offset);
1263 dissect_auth_gssapi_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1265 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1271 call_dissect_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1272 int offset, dissect_function_t* dissect_function, const char *progname)
1274 const char *saved_proto;
1276 if (dissect_function != NULL) {
1277 /* set the current protocol name */
1278 saved_proto = pinfo->current_proto;
1279 if (progname != NULL)
1280 pinfo->current_proto = progname;
1282 /* call the dissector for the next level */
1283 offset = dissect_function(tvb, offset, pinfo, tree);
1285 /* restore the protocol name */
1286 pinfo->current_proto = saved_proto;
1294 dissect_rpc_authgss_integ_data(tvbuff_t *tvb, packet_info *pinfo,
1295 proto_tree *tree, int offset,
1296 dissect_function_t* dissect_function,
1297 const char *progname)
1299 guint32 length, rounded_length, seq;
1302 proto_tree *gtree = NULL;
1304 length = tvb_get_ntohl(tvb, offset+0);
1305 rounded_length = rpc_roundup(length);
1306 seq = tvb_get_ntohl(tvb, offset+4);
1309 gitem = proto_tree_add_text(tree, tvb, offset,
1310 4+rounded_length, "GSS Data");
1311 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_data);
1312 proto_tree_add_uint(gtree, hf_rpc_authgss_data_length,
1313 tvb, offset+0, 4, length);
1314 proto_tree_add_uint(gtree, hf_rpc_authgss_seq,
1315 tvb, offset+4, 4, seq);
1319 if (dissect_function != NULL) {
1321 call_dissect_function(tvb, pinfo, gtree, offset,
1322 dissect_function, progname);
1324 offset += rounded_length - 4;
1325 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_checksum,
1332 dissect_rpc_authgss_priv_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1334 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1340 * Dissect the arguments to an indirect call; used by the portmapper/RPCBIND
1343 * Record this call in a hash table, similar to the hash table for
1344 * direct calls, so we can find it when dissecting an indirect call reply.
1347 dissect_rpc_indir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1348 int offset, int args_id, guint32 prog, guint32 vers, guint32 proc)
1350 conversation_t* conversation;
1351 static address null_address = { AT_NONE, 0, NULL };
1352 rpc_proc_info_key key;
1353 rpc_proc_info_value *value;
1354 rpc_call_info_value *rpc_call;
1355 rpc_call_info_key rpc_call_key;
1356 rpc_call_info_key *new_rpc_call_key;
1357 dissect_function_t *dissect_function = NULL;
1362 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1363 dissect_function = value->dissect_call;
1365 /* Keep track of the address whence the call came, and the
1366 port to which the call is being sent, so that we can
1367 match up calls with replies.
1369 If the transport is connection-oriented (we check, for
1370 now, only for "pinfo->ptype" of PT_TCP), we also take
1371 into account the port from which the call was sent
1372 and the address to which the call was sent, because
1373 the addresses and ports of the two endpoints should be
1374 the same for all calls and replies. (XXX - what if
1375 the connection is broken and re-established?)
1377 If the transport is connectionless, we don't worry
1378 about the address to which the call was sent and from
1379 which the reply was sent, because there's no
1380 guarantee that the reply will come from the address
1381 to which the call was sent. We also don't worry about
1382 the port *from* which the call was sent and *to* which
1383 the reply was sent, because some clients (*cough* OS X
1384 NFS client *cough) might send retransmissions from a
1385 different port from the original request. */
1386 if (pinfo->ptype == PT_TCP) {
1387 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1388 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1389 pinfo->destport, 0);
1392 * XXX - you currently still have to pass a non-null
1393 * pointer for the second address argument even
1394 * if you use NO_ADDR_B.
1396 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1397 &null_address, pinfo->ptype, pinfo->destport,
1398 0, NO_ADDR_B|NO_PORT_B);
1400 if (conversation == NULL) {
1401 /* It's not part of any conversation - create a new
1404 XXX - this should never happen, as we should've
1405 created a conversation for it in the RPC
1407 if (pinfo->ptype == PT_TCP) {
1408 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
1409 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1410 pinfo->destport, 0);
1412 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
1413 &null_address, pinfo->ptype, pinfo->destport,
1414 0, NO_ADDR2|NO_PORT2);
1418 /* Make the dissector for this conversation the non-heuristic
1420 conversation_set_dissector(conversation,
1421 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1423 /* Prepare the key data.
1425 Dissectors for RPC procedure calls and replies shouldn't
1426 create new tvbuffs, and we don't create one ourselves,
1427 so we should have been handed the tvbuff for this RPC call;
1428 as such, the XID is at offset 0 in this tvbuff. */
1429 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1430 rpc_call_key.conversation = conversation;
1432 /* look up the request */
1433 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1434 if (rpc_call == NULL) {
1435 /* We didn't find it; create a new entry.
1436 Prepare the value data.
1437 Not all of it is needed for handling indirect
1438 calls, so we set a bunch of items to 0. */
1439 new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1440 *new_rpc_call_key = rpc_call_key;
1441 rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1442 rpc_call->req_num = 0;
1443 rpc_call->rep_num = 0;
1444 rpc_call->prog = prog;
1445 rpc_call->vers = vers;
1446 rpc_call->proc = proc;
1447 rpc_call->private_data = NULL;
1450 * XXX - what about RPCSEC_GSS?
1451 * Do we have to worry about it?
1453 rpc_call->flavor = FLAVOR_NOT_GSSAPI;
1454 rpc_call->gss_proc = 0;
1455 rpc_call->gss_svc = 0;
1456 rpc_call->proc_info = value;
1458 g_hash_table_insert(rpc_indir_calls, new_rpc_call_key,
1463 /* We don't know the procedure.
1464 Happens only with strange program versions or
1465 non-existing dissectors.
1466 Just show the arguments as opaque data. */
1467 offset = dissect_rpc_data(tvb, tree, args_id,
1474 proto_tree_add_text(tree, tvb, offset, 4,
1475 "Argument length: %u",
1476 tvb_get_ntohl(tvb, offset));
1480 /* Dissect the arguments */
1481 offset = call_dissect_function(tvb, pinfo, tree, offset,
1482 dissect_function, NULL);
1487 * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1491 dissect_rpc_indir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1492 int offset, int result_id, int prog_id, int vers_id, int proc_id)
1494 conversation_t* conversation;
1495 static address null_address = { AT_NONE, 0, NULL };
1496 rpc_call_info_key rpc_call_key;
1497 rpc_call_info_value *rpc_call;
1498 char *procname = NULL;
1499 char procname_static[20];
1500 dissect_function_t *dissect_function = NULL;
1502 /* Look for the matching call in the hash table of indirect
1503 calls. A reply must match a call that we've seen, and the
1504 reply must be sent to the same address that the call came
1505 from, and must come from the port to which the call was sent.
1507 If the transport is connection-oriented (we check, for
1508 now, only for "pinfo->ptype" of PT_TCP), we take
1509 into account the port from which the call was sent
1510 and the address to which the call was sent, because
1511 the addresses and ports of the two endpoints should be
1512 the same for all calls and replies.
1514 If the transport is connectionless, we don't worry
1515 about the address to which the call was sent and from
1516 which the reply was sent, because there's no
1517 guarantee that the reply will come from the address
1518 to which the call was sent. We also don't worry about
1519 the port *from* which the call was sent and *to* which
1520 the reply was sent, because some clients (*cough* OS X
1521 NFS client *cough) might send retransmissions from a
1522 different port from the original request. */
1523 if (pinfo->ptype == PT_TCP) {
1524 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1525 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1528 * XXX - you currently still have to pass a non-null
1529 * pointer for the second address argument even
1530 * if you use NO_ADDR_B.
1532 conversation = find_conversation(pinfo->fd->num, &pinfo->dst, &null_address,
1533 pinfo->ptype, pinfo->srcport, 0, NO_ADDR_B|NO_PORT_B);
1535 if (conversation == NULL) {
1536 /* We haven't seen an RPC call for that conversation,
1537 so we can't check for a reply to that call.
1538 Just show the reply stuff as opaque data. */
1539 offset = dissect_rpc_data(tvb, tree, result_id,
1544 /* The XIDs of the call and reply must match. */
1545 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1546 rpc_call_key.conversation = conversation;
1547 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1548 if (rpc_call == NULL) {
1549 /* The XID doesn't match a call from that
1550 conversation, so it's probably not an RPC reply.
1551 Just show the reply stuff as opaque data. */
1552 offset = dissect_rpc_data(tvb, tree, result_id,
1557 if (rpc_call->proc_info != NULL) {
1558 dissect_function = rpc_call->proc_info->dissect_reply;
1559 if (rpc_call->proc_info->name != NULL) {
1560 procname = rpc_call->proc_info->name;
1563 sprintf(procname_static, "proc-%u", rpc_call->proc);
1564 procname = procname_static;
1569 dissect_function = NULL;
1571 sprintf(procname_static, "proc-%u", rpc_call->proc);
1572 procname = procname_static;
1577 /* Put the program, version, and procedure into the tree. */
1578 proto_tree_add_uint_format(tree, prog_id, tvb,
1579 0, 0, rpc_call->prog, "Program: %s (%u)",
1580 rpc_prog_name(rpc_call->prog), rpc_call->prog);
1581 proto_tree_add_uint(tree, vers_id, tvb, 0, 0, rpc_call->vers);
1582 proto_tree_add_uint_format(tree, proc_id, tvb,
1583 0, 0, rpc_call->proc, "Procedure: %s (%u)",
1584 procname, rpc_call->proc);
1587 if (dissect_function == NULL) {
1588 /* We don't know how to dissect the reply procedure.
1589 Just show the reply stuff as opaque data. */
1590 offset = dissect_rpc_data(tvb, tree, result_id,
1596 /* Put the length of the reply value into the tree. */
1597 proto_tree_add_text(tree, tvb, offset, 4,
1598 "Argument length: %u",
1599 tvb_get_ntohl(tvb, offset));
1603 /* Dissect the return value */
1604 offset = call_dissect_function(tvb, pinfo, tree, offset,
1605 dissect_function, NULL);
1610 * Just mark this as a continuation of an earlier packet.
1613 dissect_rpc_continuation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1615 proto_item *rpc_item;
1616 proto_tree *rpc_tree;
1618 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1619 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1620 if (check_col(pinfo->cinfo, COL_INFO))
1621 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1624 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1626 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1627 proto_tree_add_text(rpc_tree, tvb, 0, -1, "Continuation data");
1632 dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1633 tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
1634 guint32 rpc_rm, gboolean first_pdu)
1637 rpc_call_info_key rpc_call_key;
1638 rpc_call_info_value *rpc_call = NULL;
1639 rpc_prog_info_value *rpc_prog = NULL;
1640 rpc_prog_info_key rpc_prog_key;
1643 unsigned int rpcvers;
1644 unsigned int prog = 0;
1645 unsigned int vers = 0;
1646 unsigned int proc = 0;
1647 flavor_t flavor = FLAVOR_UNKNOWN;
1648 unsigned int gss_proc = 0;
1649 unsigned int gss_svc = 0;
1650 protocol_t *proto = NULL;
1655 unsigned int reply_state;
1656 unsigned int accept_state;
1657 unsigned int reject_state;
1659 const char *msg_type_name = NULL;
1660 const char *progname = NULL;
1661 const char *procname = NULL;
1662 static char procname_static[20];
1664 unsigned int vers_low;
1665 unsigned int vers_high;
1667 unsigned int auth_state;
1669 proto_item *rpc_item = NULL;
1670 proto_tree *rpc_tree = NULL;
1672 proto_item *pitem = NULL;
1673 proto_tree *ptree = NULL;
1674 int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
1676 rpc_call_info_key *new_rpc_call_key;
1677 rpc_proc_info_key key;
1678 rpc_proc_info_value *value = NULL;
1679 conversation_t* conversation;
1680 static address null_address = { AT_NONE, 0, NULL };
1683 dissect_function_t *dissect_function = NULL;
1684 gboolean dissect_rpc = TRUE;
1688 * Check to see whether this looks like an RPC call or reply.
1690 if (!tvb_bytes_exist(tvb, offset, 8)) {
1691 /* Captured data in packet isn't enough to let us tell. */
1695 /* both directions need at least this */
1696 msg_type = tvb_get_ntohl(tvb, offset + 4);
1701 /* check for RPC call */
1702 if (!tvb_bytes_exist(tvb, offset, 16)) {
1703 /* Captured data in packet isn't enough to let us
1708 /* XID can be anything, so dont check it.
1709 We already have the message type.
1710 Check whether an RPC version number of 2 is in the
1711 location where it would be, and that an RPC program
1712 number we know about is in the location where it would be.
1714 XXX - Sun's snoop appears to recognize as RPC even calls
1715 to stuff it doesn't dissect; does it just look for a 2
1716 at that location, which seems far to weak a heuristic
1717 (too many false positives), or does it have some additional
1720 We could conceivably check for any of the program numbers
1723 ftp://ftp.tau.ac.il/pub/users/eilon/rpc/rpc
1725 and report it as RPC (but not dissect the payload if
1726 we don't have a subdissector) if it matches. */
1727 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1729 /* we only dissect version 2 */
1730 if (tvb_get_ntohl(tvb, offset + 8) != 2 ){
1733 /* let the user be able to weaken the heuristics if he need
1734 * to look at proprietary protocols not known
1737 if(rpc_dissect_unknown_programs){
1738 /* if the user has specified that he wants to try to
1739 * dissect even completely unknown RPC program numbers
1740 * then let him do that.
1741 * In this case we only check that the program number
1742 * is neither 0 nor -1 which is better than nothing.
1744 if(rpc_prog_key.prog==0 || rpc_prog_key.prog==0xffffffff){
1747 if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
1748 /* ok this is not a known rpc program so we
1749 * will have to fake it.
1751 int proto_rpc_unknown_program;
1752 char *NAME, *Name, *name;
1753 static const vsff unknown_proc[] = {
1754 { 0,"NULL",NULL,NULL },
1755 { 0,NULL,NULL,NULL }
1761 sprintf(NAME, "Unknown RPC Program:%d",rpc_prog_key.prog);
1762 sprintf(Name, "RPC:%d",rpc_prog_key.prog);
1763 sprintf(name, "rpc%d",rpc_prog_key.prog);
1764 proto_rpc_unknown_program = proto_register_protocol(NAME, Name, name);
1766 rpc_init_prog(proto_rpc_unknown_program, rpc_prog_key.prog, ett_rpc_unknown_program);
1767 rpc_init_proc_table(rpc_prog_key.prog, tvb_get_ntohl(tvb, offset + 16), unknown_proc, hf_rpc_procedure);
1771 if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
1772 /* They're not, so it's probably not an RPC call. */
1778 /* Check for RPC reply. A reply must match a call that
1779 we've seen, and the reply must be sent to the same
1780 address that the call came from, and must come from
1781 the port to which the call was sent.
1783 If the transport is connection-oriented (we check, for
1784 now, only for "pinfo->ptype" of PT_TCP), we take
1785 into account the port from which the call was sent
1786 and the address to which the call was sent, because
1787 the addresses and ports of the two endpoints should be
1788 the same for all calls and replies.
1790 If the transport is connectionless, we don't worry
1791 about the address to which the call was sent and from
1792 which the reply was sent, because there's no
1793 guarantee that the reply will come from the address
1794 to which the call was sent. We also don't worry about
1795 the port *from* which the call was sent and *to* which
1796 the reply was sent, because some clients (*cough* OS X
1797 NFS client *cough) might send retransmissions from a
1798 different port from the original request. */
1799 if (pinfo->ptype == PT_TCP) {
1800 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1801 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1802 pinfo->destport, 0);
1805 * XXX - you currently still have to pass a non-null
1806 * pointer for the second address argument even
1807 * if you use NO_ADDR_B.
1809 conversation = find_conversation(pinfo->fd->num, &pinfo->dst,
1810 &null_address, pinfo->ptype, pinfo->srcport,
1811 0, NO_ADDR_B|NO_PORT_B);
1813 if (conversation == NULL) {
1814 /* We haven't seen an RPC call for that conversation,
1815 so we can't check for a reply to that call. */
1819 /* The XIDs of the call and reply must match. */
1820 rpc_call_key.xid = tvb_get_ntohl(tvb, offset + 0);
1821 rpc_call_key.conversation = conversation;
1822 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1823 if (rpc_call == NULL) {
1824 /* The XID doesn't match a call from that
1825 conversation, so it's probably not an RPC reply. */
1828 /* pass rpc_info to subdissectors */
1829 rpc_call->request=FALSE;
1830 pinfo->private_data=rpc_call;
1834 /* The putative message type field contains neither
1835 RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1842 * This is RPC-over-TCP; check if this is the last
1845 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
1847 * This isn't the last fragment.
1848 * If we're doing reassembly, just return
1849 * TRUE to indicate that this looks like
1850 * the beginning of an RPC message,
1851 * and let them do fragment reassembly.
1858 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1859 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1862 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1864 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1867 show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
1872 xid = tvb_get_ntohl(tvb, offset + 0);
1874 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1875 offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1878 msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1880 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1881 offset+4, 4, msg_type);
1882 proto_item_append_text(rpc_item, ", Type:%s XID:0x%08x", msg_type_name, xid);
1890 /* we know already the proto-entry, the ETT-const,
1892 proto = rpc_prog->proto;
1893 proto_id = rpc_prog->proto_id;
1894 ett = rpc_prog->ett;
1895 progname = rpc_prog->progname;
1897 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1899 proto_tree_add_uint(rpc_tree,
1900 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1903 prog = tvb_get_ntohl(tvb, offset + 4);
1906 proto_tree_add_uint_format(rpc_tree,
1907 hf_rpc_program, tvb, offset+4, 4, prog,
1908 "Program: %s (%u)", progname, prog);
1911 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1912 /* Set the protocol name to the underlying
1914 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1917 vers = tvb_get_ntohl(tvb, offset+8);
1919 proto_tree_add_uint(rpc_tree,
1920 hf_rpc_programversion, tvb, offset+8, 4, vers);
1923 proc = tvb_get_ntohl(tvb, offset+12);
1929 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1930 dissect_function = value->dissect_call;
1931 procname = value->name;
1934 /* happens only with strange program versions or
1935 non-existing dissectors */
1937 dissect_function = NULL;
1939 sprintf(procname_static, "proc-%u", proc);
1940 procname = procname_static;
1943 /* Check for RPCSEC_GSS and AUTH_GSSAPI */
1944 if (tvb_bytes_exist(tvb, offset+16, 4)) {
1945 switch (tvb_get_ntohl(tvb, offset+16)) {
1949 * It's GSS-API authentication...
1951 if (tvb_bytes_exist(tvb, offset+28, 8)) {
1953 * ...and we have the procedure
1954 * and service information for it.
1956 flavor = FLAVOR_GSSAPI;
1957 gss_proc = tvb_get_ntohl(tvb, offset+28);
1958 gss_svc = tvb_get_ntohl(tvb, offset+36);
1961 * ...but the procedure and service
1962 * information isn't available.
1964 flavor = FLAVOR_GSSAPI_NO_INFO;
1970 * AUTH_GSSAPI flavor. If auth_msg is TRUE,
1971 * then this is an AUTH_GSSAPI message and
1972 * not an application level message.
1974 if (tvb_bytes_exist(tvb, offset+28, 4)) {
1975 if (tvb_get_ntohl(tvb, offset+28)) {
1976 flavor = FLAVOR_AUTHGSSAPI_MSG;
1979 match_strval(gss_proc,
1980 rpc_authgssapi_proc);
1982 flavor = FLAVOR_AUTHGSSAPI;
1989 * It's not GSS-API authentication.
1991 flavor = FLAVOR_NOT_GSSAPI;
1997 proto_tree_add_uint_format(rpc_tree,
1998 hf_rpc_procedure, tvb, offset+12, 4, proc,
1999 "Procedure: %s (%u)", procname, proc);
2002 if (check_col(pinfo->cinfo, COL_INFO)) {
2004 col_clear(pinfo->cinfo, COL_INFO);
2006 col_append_fstr(pinfo->cinfo, COL_INFO, " ; ");
2007 col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2013 /* Keep track of the address whence the call came, and the
2014 port to which the call is being sent, so that we can
2015 match up calls with replies.
2017 If the transport is connection-oriented (we check, for
2018 now, only for "pinfo->ptype" of PT_TCP), we also take
2019 into account the port from which the call was sent
2020 and the address to which the call was sent, because
2021 the addresses and ports of the two endpoints should be
2022 the same for all calls and replies. (XXX - what if
2023 the connection is broken and re-established?)
2025 If the transport is connectionless, we don't worry
2026 about the address to which the call was sent and from
2027 which the reply was sent, because there's no
2028 guarantee that the reply will come from the address
2029 to which the call was sent. We also don't worry about
2030 the port *from* which the call was sent and *to* which
2031 the reply was sent, because some clients (*cough* OS X
2032 NFS client *cough) might send retransmissions from a
2033 different port from the original request. */
2034 if (pinfo->ptype == PT_TCP) {
2035 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
2036 &pinfo->dst, pinfo->ptype, pinfo->srcport,
2037 pinfo->destport, 0);
2040 * XXX - you currently still have to pass a non-null
2041 * pointer for the second address argument even
2042 * if you use NO_ADDR_B.
2044 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
2045 &null_address, pinfo->ptype, pinfo->destport,
2046 0, NO_ADDR_B|NO_PORT_B);
2048 if (conversation == NULL) {
2049 /* It's not part of any conversation - create a new
2051 if (pinfo->ptype == PT_TCP) {
2052 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
2053 &pinfo->dst, pinfo->ptype, pinfo->srcport,
2054 pinfo->destport, 0);
2056 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
2057 &null_address, pinfo->ptype, pinfo->destport,
2058 0, NO_ADDR2|NO_PORT2);
2062 /* Make the dissector for this conversation the non-heuristic
2064 conversation_set_dissector(conversation,
2065 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
2067 /* prepare the key data */
2068 rpc_call_key.xid = xid;
2069 rpc_call_key.conversation = conversation;
2071 /* look up the request */
2072 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
2074 /* We've seen a request with this XID, with the same
2075 source and destination, before - but was it
2077 if (pinfo->fd->num != rpc_call->req_num) {
2078 /* No, so it's a duplicate request.
2080 if (check_col(pinfo->cinfo, COL_INFO)) {
2081 col_prepend_fstr(pinfo->cinfo, COL_INFO,
2082 "[RPC retransmission of #%d]", rpc_call->req_num);
2084 proto_tree_add_item(rpc_tree,
2085 hf_rpc_dup, tvb, 0,0, TRUE);
2086 proto_tree_add_uint(rpc_tree,
2087 hf_rpc_call_dup, tvb, 0,0, rpc_call->req_num);
2089 if(rpc_call->rep_num){
2090 if (check_col(pinfo->cinfo, COL_INFO)) {
2091 col_append_fstr(pinfo->cinfo, COL_INFO," (Reply In %d)", rpc_call->rep_num);
2095 /* Prepare the value data.
2096 "req_num" and "rep_num" are frame numbers;
2097 frame numbers are 1-origin, so we use 0
2098 to mean "we don't yet know in which frame
2099 the reply for this call appears". */
2100 new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
2101 *new_rpc_call_key = rpc_call_key;
2102 rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
2103 rpc_call->req_num = pinfo->fd->num;
2104 rpc_call->rep_num = 0;
2105 rpc_call->prog = prog;
2106 rpc_call->vers = vers;
2107 rpc_call->proc = proc;
2108 rpc_call->private_data = NULL;
2109 rpc_call->xid = xid;
2110 rpc_call->flavor = flavor;
2111 rpc_call->gss_proc = gss_proc;
2112 rpc_call->gss_svc = gss_svc;
2113 rpc_call->proc_info = value;
2114 rpc_call->req_time.secs=pinfo->fd->abs_secs;
2115 rpc_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
2118 g_hash_table_insert(rpc_calls, new_rpc_call_key,
2122 if(rpc_call && rpc_call->rep_num){
2123 proto_tree_add_uint_format(rpc_tree, hf_rpc_repframe,
2124 tvb, 0, 0, rpc_call->rep_num,
2125 "The reply to this request is in frame %u",
2131 offset = dissect_rpc_cred(tvb, rpc_tree, offset);
2132 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2134 /* pass rpc_info to subdissectors */
2135 rpc_call->request=TRUE;
2136 pinfo->private_data=rpc_call;
2138 /* go to the next dissector */
2140 break; /* end of RPC call */
2143 /* we know already the type from the calling routine,
2144 and we already have "rpc_call" set above. */
2145 prog = rpc_call->prog;
2146 vers = rpc_call->vers;
2147 proc = rpc_call->proc;
2148 flavor = rpc_call->flavor;
2149 gss_proc = rpc_call->gss_proc;
2150 gss_svc = rpc_call->gss_svc;
2152 if (rpc_call->proc_info != NULL) {
2153 dissect_function = rpc_call->proc_info->dissect_reply;
2154 if (rpc_call->proc_info->name != NULL) {
2155 procname = rpc_call->proc_info->name;
2158 sprintf(procname_static, "proc-%u", proc);
2159 procname = procname_static;
2164 dissect_function = NULL;
2166 sprintf(procname_static, "proc-%u", proc);
2167 procname = procname_static;
2171 * If this is an AUTH_GSSAPI message, then the RPC procedure
2172 * is not an application procedure, but rather an auth level
2173 * procedure, so it would be misleading to print the RPC
2174 * procname. Replace the RPC procname with the corresponding
2175 * AUTH_GSSAPI procname.
2177 if (flavor == FLAVOR_AUTHGSSAPI_MSG) {
2178 procname = match_strval(gss_proc, rpc_authgssapi_proc);
2181 rpc_prog_key.prog = prog;
2182 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
2186 progname = "Unknown";
2189 proto = rpc_prog->proto;
2190 proto_id = rpc_prog->proto_id;
2191 ett = rpc_prog->ett;
2192 progname = rpc_prog->progname;
2194 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2195 /* Set the protocol name to the underlying
2197 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
2201 if (check_col(pinfo->cinfo, COL_INFO)) {
2203 col_clear(pinfo->cinfo, COL_INFO);
2205 col_append_fstr(pinfo->cinfo, COL_INFO, " ; ");
2206 col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2213 proto_tree_add_uint_format(rpc_tree,
2214 hf_rpc_program, tvb, 0, 0, prog,
2215 "Program: %s (%u)", progname, prog);
2216 proto_tree_add_uint(rpc_tree,
2217 hf_rpc_programversion, tvb, 0, 0, vers);
2218 proto_tree_add_uint_format(rpc_tree,
2219 hf_rpc_procedure, tvb, 0, 0, proc,
2220 "Procedure: %s (%u)", procname, proc);
2223 reply_state = tvb_get_ntohl(tvb,offset+0);
2225 proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
2226 offset+0, 4, reply_state);
2230 /* Indicate the frame to which this is a reply. */
2231 if(rpc_call && rpc_call->req_num){
2232 proto_tree_add_uint_format(rpc_tree, hf_rpc_reqframe,
2233 tvb, 0, 0, rpc_call->req_num,
2234 "This is a reply to a request in frame %u",
2236 ns.secs= pinfo->fd->abs_secs-rpc_call->req_time.secs;
2237 ns.nsecs=pinfo->fd->abs_usecs*1000-rpc_call->req_time.nsecs;
2239 ns.nsecs+=1000000000;
2242 proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
2245 if (check_col(pinfo->cinfo, COL_INFO)) {
2246 col_append_fstr(pinfo->cinfo, COL_INFO," (Call In %d)", rpc_call->req_num);
2251 if ((!rpc_call) || (rpc_call->rep_num == 0)) {
2252 /* We have not yet seen a reply to that call, so
2253 this must be the first reply; remember its
2255 rpc_call->rep_num = pinfo->fd->num;
2257 /* We have seen a reply to this call - but was it
2259 if (rpc_call->rep_num != pinfo->fd->num) {
2260 /* No, so it's a duplicate reply.
2262 if (check_col(pinfo->cinfo, COL_INFO)) {
2263 col_prepend_fstr(pinfo->cinfo, COL_INFO,
2264 "[RPC duplicate of #%d]", rpc_call->rep_num);
2266 proto_tree_add_item(rpc_tree,
2267 hf_rpc_dup, tvb, 0,0, TRUE);
2268 proto_tree_add_uint(rpc_tree,
2269 hf_rpc_reply_dup, tvb, 0,0, rpc_call->rep_num);
2273 switch (reply_state) {
2276 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2277 accept_state = tvb_get_ntohl(tvb,offset+0);
2279 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
2280 offset+0, 4, accept_state);
2283 switch (accept_state) {
2286 /* go to the next dissector */
2290 vers_low = tvb_get_ntohl(tvb,offset+0);
2291 vers_high = tvb_get_ntohl(tvb,offset+4);
2293 proto_tree_add_uint(rpc_tree,
2294 hf_rpc_programversion_min,
2295 tvb, offset+0, 4, vers_low);
2296 proto_tree_add_uint(rpc_tree,
2297 hf_rpc_programversion_max,
2298 tvb, offset+4, 4, vers_high);
2303 * There's no protocol reply, so don't
2304 * try to dissect it.
2306 dissect_rpc = FALSE;
2311 * There's no protocol reply, so don't
2312 * try to dissect it.
2314 dissect_rpc = FALSE;
2320 reject_state = tvb_get_ntohl(tvb,offset+0);
2322 proto_tree_add_uint(rpc_tree,
2323 hf_rpc_state_reject, tvb, offset+0, 4,
2328 if (reject_state==RPC_MISMATCH) {
2329 vers_low = tvb_get_ntohl(tvb,offset+0);
2330 vers_high = tvb_get_ntohl(tvb,offset+4);
2332 proto_tree_add_uint(rpc_tree,
2334 tvb, offset+0, 4, vers_low);
2335 proto_tree_add_uint(rpc_tree,
2337 tvb, offset+4, 4, vers_high);
2340 } else if (reject_state==AUTH_ERROR) {
2341 auth_state = tvb_get_ntohl(tvb,offset+0);
2343 proto_tree_add_uint(rpc_tree,
2344 hf_rpc_state_auth, tvb, offset+0, 4,
2351 * There's no protocol reply, so don't
2352 * try to dissect it.
2354 dissect_rpc = FALSE;
2359 * This isn't a valid reply state, so we have
2360 * no clue what's going on; don't try to dissect
2361 * the protocol reply.
2363 dissect_rpc = FALSE;
2366 break; /* end of RPC reply */
2370 * The switch statement at the top returned if
2371 * this was neither an RPC call nor a reply.
2373 DISSECTOR_ASSERT_NOT_REACHED();
2376 /* now we know, that RPC was shorter */
2378 tvb_ensure_bytes_exist(tvb, offset, 0);
2379 proto_item_set_end(rpc_item, tvb, offset);
2384 * There's no RPC call or reply here; just dissect
2385 * whatever's left as data.
2387 call_dissector(data_handle,
2388 tvb_new_subset(tvb, offset, -1, -1), pinfo, rpc_tree);
2392 /* create here the program specific sub-tree */
2393 if (tree && (flavor != FLAVOR_AUTHGSSAPI_MSG)) {
2394 pitem = proto_tree_add_item(tree, proto_id, tvb, offset, -1,
2397 ptree = proto_item_add_subtree(pitem, ett);
2401 proto_tree_add_uint(ptree,
2402 hf_rpc_programversion, tvb, 0, 0, vers);
2403 if (rpc_prog->procedure_hfs->len > vers)
2404 procedure_hf = g_array_index(rpc_prog->procedure_hfs, int, vers);
2407 * No such element in the GArray.
2411 if (procedure_hf != 0 && procedure_hf != -1) {
2412 proto_tree_add_uint(ptree,
2413 procedure_hf, tvb, 0, 0, proc);
2415 proto_tree_add_uint_format(ptree,
2416 hf_rpc_procedure, tvb, 0, 0, proc,
2417 "Procedure: %s (%u)", procname, proc);
2422 /* we must queue this packet to the tap system before we actually
2423 call the subdissectors since short packets (i.e. nfs read reply)
2424 will cause an exception and execution would never reach the call
2425 to tap_queue_packet() in that case
2427 tap_queue_packet(rpc_tap, pinfo, rpc_call);
2429 /* proto==0 if this is an unknown program */
2430 if( (proto==0) || !proto_is_protocol_enabled(proto)){
2431 dissect_function = NULL;
2435 * Handle RPCSEC_GSS and AUTH_GSSAPI specially.
2439 case FLAVOR_UNKNOWN:
2441 * We don't know the authentication flavor, so we can't
2442 * dissect the payload.
2444 proto_tree_add_text(ptree, tvb, offset, -1,
2445 "Unknown authentication flavor - cannot dissect");
2448 case FLAVOR_NOT_GSSAPI:
2450 * It's not GSS-API authentication. Just dissect the
2453 offset = call_dissect_function(tvb, pinfo, ptree, offset,
2454 dissect_function, progname);
2457 case FLAVOR_GSSAPI_NO_INFO:
2459 * It's GSS-API authentication, but we don't have the
2460 * procedure and service information, so we can't dissect
2463 proto_tree_add_text(ptree, tvb, offset, -1,
2464 "GSS-API authentication, but procedure and service unknown - cannot dissect");
2469 * It's GSS-API authentication, and we have the procedure
2470 * and service information; process the GSS-API stuff,
2471 * and process the payload if there is any.
2475 case RPCSEC_GSS_INIT:
2476 case RPCSEC_GSS_CONTINUE_INIT:
2477 if (msg_type == RPC_CALL) {
2478 offset = dissect_rpc_authgss_initarg(tvb,
2479 ptree, offset, pinfo);
2482 offset = dissect_rpc_authgss_initres(tvb,
2483 ptree, offset, pinfo);
2487 case RPCSEC_GSS_DATA:
2488 if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2489 offset = call_dissect_function(tvb,
2490 pinfo, ptree, offset,
2494 else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2495 offset = dissect_rpc_authgss_integ_data(tvb,
2496 pinfo, ptree, offset,
2500 else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2501 offset = dissect_rpc_authgss_priv_data(tvb,
2511 case FLAVOR_AUTHGSSAPI_MSG:
2513 * This is an AUTH_GSSAPI message. It contains data
2514 * only for the authentication procedure and not for the
2515 * application level RPC procedure. Reset the column
2516 * protocol and info fields to indicate that this is
2517 * an RPC auth level message, then process the args.
2519 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2520 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
2522 if (check_col(pinfo->cinfo, COL_INFO)) {
2523 col_clear(pinfo->cinfo, COL_INFO);
2524 col_append_fstr(pinfo->cinfo, COL_INFO,
2526 match_strval(gss_proc, rpc_authgssapi_proc),
2527 msg_type_name, xid);
2532 case AUTH_GSSAPI_INIT:
2533 case AUTH_GSSAPI_CONTINUE_INIT:
2534 case AUTH_GSSAPI_MSG:
2535 if (msg_type == RPC_CALL) {
2536 offset = dissect_rpc_authgssapi_initarg(tvb,
2537 rpc_tree, offset, pinfo);
2539 offset = dissect_rpc_authgssapi_initres(tvb,
2540 rpc_tree, offset, pinfo);
2544 case AUTH_GSSAPI_DESTROY:
2545 offset = dissect_rpc_data(tvb, rpc_tree,
2546 hf_rpc_authgss_data, offset);
2549 case AUTH_GSSAPI_EXIT:
2553 /* Adjust the length to account for the auth message. */
2555 proto_item_set_end(rpc_item, tvb, offset);
2559 case FLAVOR_AUTHGSSAPI:
2561 * An RPC with AUTH_GSSAPI authentication. The data
2562 * portion is always private, so don't call the dissector.
2564 offset = dissect_auth_gssapi_data(tvb, ptree, offset);
2568 if (tvb_length_remaining(tvb, offset) > 0) {
2570 * dissect any remaining bytes (incomplete dissection) as pure
2574 call_dissector(data_handle,
2575 tvb_new_subset(tvb, offset, -1, -1), pinfo, ptree);
2578 /* XXX this should really loop over all fhandles registred for the frame */
2579 if(nfs_fhandle_reqrep_matching){
2580 nfs_fhandle_data_t *fhd;
2583 if(rpc_call && rpc_call->rep_num){
2584 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2585 nfs_fhandle_frame_table,
2586 GINT_TO_POINTER(rpc_call->rep_num));
2588 dissect_fhandle_hidden(pinfo,
2594 if(rpc_call && rpc_call->req_num){
2595 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2596 nfs_fhandle_frame_table,
2597 GINT_TO_POINTER(rpc_call->req_num));
2599 dissect_fhandle_hidden(pinfo,
2611 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2613 return dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2618 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2620 if (!dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2622 if (tvb_length(tvb) != 0)
2623 dissect_rpc_continuation(tvb, pinfo, tree);
2628 /* Defragmentation of RPC-over-TCP records */
2629 /* table to hold defragmented RPC records */
2630 static GHashTable *rpc_fragment_table = NULL;
2632 static GHashTable *rpc_reassembly_table = NULL;
2633 static GMemChunk *rpc_fragment_key_chunk = NULL;
2634 static int rpc_fragment_init_count = 200;
2636 typedef struct _rpc_fragment_key {
2645 rpc_fragment_hash(gconstpointer k)
2647 const rpc_fragment_key *key = (const rpc_fragment_key *)k;
2649 return key->conv_id + key->seq;
2653 rpc_fragment_equal(gconstpointer k1, gconstpointer k2)
2655 const rpc_fragment_key *key1 = (const rpc_fragment_key *)k1;
2656 const rpc_fragment_key *key2 = (const rpc_fragment_key *)k2;
2658 return key1->conv_id == key2->conv_id &&
2659 key1->seq == key2->seq;
2663 show_rpc_fragheader(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2665 proto_item *hdr_item;
2666 proto_tree *hdr_tree;
2670 fraglen = rpc_rm & RPC_RM_FRAGLEN;
2672 hdr_item = proto_tree_add_text(tree, tvb, 0, 4,
2673 "Fragment header: %s%u %s",
2674 (rpc_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
2675 fraglen, plurality(fraglen, "byte", "bytes"));
2676 hdr_tree = proto_item_add_subtree(hdr_item, ett_rpc_fraghdr);
2678 proto_tree_add_boolean(hdr_tree, hf_rpc_lastfrag, tvb, 0, 4,
2680 proto_tree_add_uint(hdr_tree, hf_rpc_fraglen, tvb, 0, 4,
2686 show_rpc_fragment(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2690 * Show the fragment header and the data for the fragment.
2692 show_rpc_fragheader(tvb, tree, rpc_rm);
2693 proto_tree_add_text(tree, tvb, 4, -1, "Fragment Data");
2698 make_frag_tree(tvbuff_t *tvb, proto_tree *tree, int proto, gint ett,
2701 proto_item *frag_item;
2702 proto_tree *frag_tree;
2705 return; /* nothing to do */
2707 frag_item = proto_tree_add_protocol_format(tree, proto, tvb, 0, -1,
2708 "%s Fragment", proto_get_protocol_name(proto));
2709 frag_tree = proto_item_add_subtree(frag_item, ett);
2710 show_rpc_fragment(tvb, frag_tree, rpc_rm);
2714 show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
2715 guint32 rpc_rm, fragment_data *ipfd_head, packet_info *pinfo)
2717 proto_item *frag_tree_item;
2720 return; /* don't do any work */
2722 if (tvb != frag_tvb) {
2724 * This message was not all in one fragment,
2725 * so show the fragment header *and* the data
2726 * for the fragment (which is the last fragment),
2727 * and a tree with information about all fragments.
2729 show_rpc_fragment(frag_tvb, tree, rpc_rm);
2732 * Show a tree with information about all fragments.
2734 show_fragment_tree(ipfd_head, &rpc_frag_items, tree, pinfo, tvb, &frag_tree_item);
2737 * This message was all in one fragment, so just show
2738 * the fragment header.
2740 show_rpc_fragheader(tvb, tree, rpc_rm);
2745 call_message_dissector(tvbuff_t *tvb, tvbuff_t *rec_tvb, packet_info *pinfo,
2746 proto_tree *tree, tvbuff_t *frag_tvb, rec_dissector_t dissector,
2747 fragment_data *ipfd_head, guint32 rpc_rm, gboolean first_pdu)
2749 const char *saved_proto;
2750 volatile gboolean rpc_succeeded;
2753 * Catch the ReportedBoundsError exception; if
2754 * this particular message happens to get a
2755 * ReportedBoundsError exception, that doesn't
2756 * mean that we should stop dissecting RPC
2757 * messages within this frame or chunk of
2760 * If it gets a BoundsError, we can stop, as there's
2761 * nothing more to see, so we just re-throw it.
2763 saved_proto = pinfo->current_proto;
2764 rpc_succeeded = FALSE;
2766 rpc_succeeded = (*dissector)(rec_tvb, pinfo, tree,
2767 frag_tvb, ipfd_head, TRUE, rpc_rm, first_pdu);
2769 CATCH(BoundsError) {
2772 CATCH(ReportedBoundsError) {
2773 show_reported_bounds_error(tvb, pinfo, tree);
2774 pinfo->current_proto = saved_proto;
2777 * We treat this as a "successful" dissection of
2778 * an RPC packet, as "dissect_rpc_message()"
2779 * *did* decide it was an RPC packet, throwing
2780 * an exception while dissecting it as such.
2782 rpc_succeeded = TRUE;
2785 return rpc_succeeded;
2789 dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
2790 proto_tree *tree, rec_dissector_t dissector, gboolean is_heur,
2791 int proto, int ett, gboolean defragment, gboolean first_pdu)
2793 struct tcpinfo *tcpinfo;
2796 volatile guint32 len;
2798 gint tvb_len, tvb_reported_len;
2800 gboolean rpc_succeeded;
2801 gboolean save_fragmented;
2802 rpc_fragment_key old_rfk, *rfk, *new_rfk;
2803 conversation_t *conversation;
2804 fragment_data *ipfd_head;
2807 if (pinfo == NULL || pinfo->private_data == NULL) {
2810 tcpinfo = pinfo->private_data;
2812 if (tcpinfo == NULL) {
2815 seq = tcpinfo->seq + offset;
2818 * Get the record mark.
2820 if (!tvb_bytes_exist(tvb, offset, 4)) {
2822 * XXX - we should somehow arrange to handle
2823 * a record mark split across TCP segments.
2825 return 0; /* not enough to tell if it's valid */
2827 rpc_rm = tvb_get_ntohl(tvb, offset);
2829 len = rpc_rm & RPC_RM_FRAGLEN;
2832 * Do TCP desegmentation, if enabled.
2834 * reject fragments bigger than this preference setting.
2835 * This is arbitrary, but should at least prevent
2836 * some crashes from either packets with really
2837 * large RPC-over-TCP fragments or from stuff that's
2838 * not really valid for this protocol.
2840 if (len > max_rpc_tcp_pdu_size)
2841 return 0; /* pretend it's not valid */
2842 if (rpc_desegment) {
2843 seglen = tvb_length_remaining(tvb, offset + 4);
2845 if ((gint)len > seglen && pinfo->can_desegment) {
2847 * This frame doesn't have all of the
2848 * data for this message, but we can do
2851 * If this is a heuristic dissector, just
2852 * return 0 - we don't want to try to get
2853 * more data, as that's too likely to cause
2854 * us to misidentify this as valid.
2856 * XXX - this means that we won't
2857 * recognize the first fragment of a
2858 * multi-fragment RPC operation unless
2859 * we've already identified this
2860 * conversation as being an RPC
2861 * conversation (and thus aren't running
2862 * heuristically) - that would be a problem
2863 * if, for example, the first segment were
2864 * the beginning of a large NFS WRITE.
2866 * If this isn't a heuristic dissector,
2867 * we've already identified this conversation
2868 * as containing data for this protocol, as we
2869 * saw valid data in previous frames. Try to
2873 return 0; /* not valid */
2875 pinfo->desegment_offset = offset;
2876 pinfo->desegment_len = len - seglen;
2877 return -((gint32) pinfo->desegment_len);
2881 len += 4; /* include record mark */
2882 tvb_len = tvb_length_remaining(tvb, offset);
2883 tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2884 if (tvb_len > (gint)len)
2886 if (tvb_reported_len > (gint)len)
2887 tvb_reported_len = len;
2888 frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2892 * If we're not defragmenting, just hand this to the
2897 * This is the first fragment we've seen, and it's also
2898 * the last fragment; that means the record wasn't
2899 * fragmented. Hand the dissector the tvbuff for the
2900 * fragment as the tvbuff for the record.
2906 * Mark this as fragmented, so if somebody throws an
2907 * exception, we don't report it as a malformed frame.
2909 save_fragmented = pinfo->fragmented;
2910 pinfo->fragmented = TRUE;
2911 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
2912 tree, frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu);
2913 pinfo->fragmented = save_fragmented;
2915 return 0; /* not RPC */
2920 * First, we check to see if this fragment is part of a record
2921 * that we're in the process of defragmenting.
2923 * The key is the conversation ID for the conversation to which
2924 * the packet belongs and the current sequence number.
2925 * We must first find the conversation and, if we don't find
2926 * one, create it. We know this is running over TCP, so the
2927 * conversation should not wildcard either address or port.
2929 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2930 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2931 if (conversation == NULL) {
2933 * It's not part of any conversation - create a new one.
2935 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2936 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2938 old_rfk.conv_id = conversation->index;
2940 rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
2944 * This fragment was not found in our table, so it doesn't
2945 * contain a continuation of a higher-level PDU.
2946 * Is it the last fragment?
2948 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2950 * This isn't the last fragment, so we don't
2951 * have the complete record.
2953 * It's the first fragment we've seen, so if
2954 * it's truly the first fragment of the record,
2955 * and it has enough data, the dissector can at
2956 * least check whether it looks like a valid
2957 * message, as it contains the start of the
2960 * The dissector should not dissect anything
2961 * if the "last fragment" flag isn't set in
2962 * the record marker, so it shouldn't throw
2965 if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
2966 NULL, TRUE, rpc_rm, first_pdu))
2967 return 0; /* not valid */
2970 * OK, now start defragmentation with that
2971 * fragment. Add this fragment, and set up
2972 * next packet/sequence number as well.
2974 * We must remember this fragment.
2977 rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2978 rfk->conv_id = conversation->index;
2981 rfk->start_seq = seq;
2982 g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
2985 * Start defragmentation.
2987 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4,
2988 pinfo, rfk->start_seq, rpc_fragment_table,
2989 rfk->offset, len - 4, TRUE);
2992 * Make sure that defragmentation isn't complete;
2993 * it shouldn't be, as this is the first fragment
2994 * we've seen, and the "last fragment" bit wasn't
2997 DISSECTOR_ASSERT(ipfd_head == NULL);
2999 new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
3000 new_rfk->conv_id = rfk->conv_id;
3001 new_rfk->seq = seq + len;
3002 new_rfk->offset = rfk->offset + len - 4;
3003 new_rfk->start_seq = rfk->start_seq;
3004 g_hash_table_insert(rpc_reassembly_table, new_rfk,
3008 * This is part of a fragmented record,
3009 * but it's not the first part.
3010 * Show it as a record marker plus data, under
3011 * a top-level tree for this protocol.
3013 make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
3016 * No more processing need be done, as we don't
3017 * have a complete record.
3023 * This is the first fragment we've seen, and it's also
3024 * the last fragment; that means the record wasn't
3025 * fragmented. Hand the dissector the tvbuff for the
3026 * fragment as the tvbuff for the record.
3032 * OK, this fragment was found, which means it continues
3033 * a record. This means we must defragment it.
3034 * Add it to the defragmentation lists.
3036 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4, pinfo,
3037 rfk->start_seq, rpc_fragment_table,
3038 rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
3040 if (ipfd_head == NULL) {
3042 * fragment_add_multiple_ok() returned NULL.
3043 * This means that defragmentation is not
3046 * We must add an entry to the hash table with
3047 * the sequence number following this fragment
3048 * as the starting sequence number, so that when
3049 * we see that fragment we'll find that entry.
3051 * XXX - as TCP stream data is not currently
3052 * guaranteed to be provided in order to dissectors,
3053 * RPC fragments aren't guaranteed to be provided
3056 new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
3057 new_rfk->conv_id = rfk->conv_id;
3058 new_rfk->seq = seq + len;
3059 new_rfk->offset = rfk->offset + len - 4;
3060 new_rfk->start_seq = rfk->start_seq;
3061 g_hash_table_insert(rpc_reassembly_table, new_rfk,
3065 * This is part of a fragmented record,
3066 * but it's not the first part.
3067 * Show it as a record marker plus data, under
3068 * a top-level tree for this protocol,
3069 * but don't hand it to the dissector
3071 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3074 * No more processing need be done, as we don't
3075 * have a complete record.
3081 * It's completely defragmented.
3083 * We only call subdissector for the last fragment.
3084 * XXX - this assumes in-order delivery of RPC
3085 * fragments, which requires in-order delivery of TCP
3088 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
3090 * Well, it's defragmented, but this isn't
3091 * the last fragment; this probably means
3092 * this isn't the first pass, so we don't
3093 * need to start defragmentation.
3095 * This is part of a fragmented record,
3096 * but it's not the first part.
3097 * Show it as a record marker plus data, under
3098 * a top-level tree for this protocol,
3099 * but don't show it to the dissector.
3101 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3104 * No more processing need be done, as we
3105 * only disssect the data with the last
3112 * OK, this is the last segment.
3113 * Create a tvbuff for the defragmented
3118 * Create a new TVB structure for
3119 * defragmented data.
3121 rec_tvb = tvb_new_real_data(ipfd_head->data,
3122 ipfd_head->datalen, ipfd_head->datalen);
3125 * Add this tvb as a child to the original
3128 tvb_set_child_real_data_tvbuff(tvb, rec_tvb);
3131 * Add defragmented data to the data source list.
3133 add_new_data_source(pinfo, rec_tvb, "Defragmented");
3137 * We have something to hand to the RPC message
3140 if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
3141 frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu))
3142 return 0; /* not RPC */
3149 * NEED_MORE_DATA, if we don't have enough data to dissect anything;
3151 * IS_RPC, if we dissected at least one message in its entirety
3154 * IS_NOT_RPC, if we found no RPC message.
3162 static rpc_tcp_return_t
3163 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3167 gboolean saw_rpc = FALSE;
3168 gboolean first_pdu = TRUE;
3171 while (tvb_reported_length_remaining(tvb, offset) != 0) {
3173 * Process this fragment.
3175 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
3176 dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
3177 rpc_defragment, first_pdu);
3181 * We need more data from the TCP stream for
3184 return NEED_MORE_DATA;
3188 * It's not RPC. Stop processing.
3194 If the length indicates that the PDU continues beyond
3195 the end of this tvb, then tell TCP about it so that it
3196 knows where the next PDU starts.
3197 This is to help TCP detect when PDUs are not aligned to
3198 segment boundaries and allow it to find RPC headers
3199 that starts in the middle of a TCP segment.
3201 if(!pinfo->fd->flags.visited){
3202 if(len>tvb_reported_length_remaining(tvb, offset)){
3203 pinfo->want_pdu_tracking=2;
3204 pinfo->bytes_until_next_pdu=len-tvb_reported_length_remaining(tvb, offset);
3210 return saw_rpc ? IS_RPC : IS_NOT_RPC;
3214 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3216 switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
3225 /* "Can't happen" */
3226 DISSECTOR_ASSERT_NOT_REACHED();
3232 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3234 if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
3235 dissect_rpc_continuation(tvb, pinfo, tree);
3238 /* Discard any state we've saved. */
3240 rpc_init_protocol(void)
3242 if (rpc_calls != NULL) {
3243 g_hash_table_destroy(rpc_calls);
3246 if (rpc_indir_calls != NULL) {
3247 g_hash_table_destroy(rpc_indir_calls);
3248 rpc_indir_calls = NULL;
3250 if (rpc_call_info_key_chunk != NULL) {
3251 g_mem_chunk_destroy(rpc_call_info_key_chunk);
3252 rpc_call_info_key_chunk = NULL;
3254 if (rpc_call_info_value_chunk != NULL) {
3255 g_mem_chunk_destroy(rpc_call_info_value_chunk);
3256 rpc_call_info_value_chunk = NULL;
3258 if (rpc_fragment_key_chunk != NULL) {
3259 g_mem_chunk_destroy(rpc_fragment_key_chunk);
3260 rpc_fragment_key_chunk = NULL;
3262 if (rpc_reassembly_table != NULL) {
3263 g_hash_table_destroy(rpc_reassembly_table);
3264 rpc_reassembly_table = NULL;
3267 rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3268 rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3269 rpc_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
3270 sizeof(rpc_call_info_key),
3271 200 * sizeof(rpc_call_info_key),
3273 rpc_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
3274 sizeof(rpc_call_info_value),
3275 200 * sizeof(rpc_call_info_value),
3277 rpc_fragment_key_chunk = g_mem_chunk_new("rpc_fragment_key_chunk",
3278 sizeof(rpc_fragment_key),
3279 rpc_fragment_init_count*sizeof(rpc_fragment_key),
3281 rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
3282 rpc_fragment_equal);
3284 fragment_table_init(&rpc_fragment_table);
3287 /* will be called once from register.c at startup time */
3289 proto_register_rpc(void)
3291 static hf_register_info hf[] = {
3292 { &hf_rpc_reqframe, {
3293 "Request Frame", "rpc.reqframe", FT_FRAMENUM, BASE_NONE,
3294 NULL, 0, "Request Frame", HFILL }},
3295 { &hf_rpc_repframe, {
3296 "Reply Frame", "rpc.repframe", FT_FRAMENUM, BASE_NONE,
3297 NULL, 0, "Reply Frame", HFILL }},
3298 { &hf_rpc_lastfrag, {
3299 "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
3300 &yesno, RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
3301 { &hf_rpc_fraglen, {
3302 "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
3303 NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
3305 "XID", "rpc.xid", FT_UINT32, BASE_HEX,
3306 NULL, 0, "XID", HFILL }},
3307 { &hf_rpc_msgtype, {
3308 "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
3309 VALS(rpc_msg_type), 0, "Message Type", HFILL }},
3310 { &hf_rpc_state_reply, {
3311 "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
3312 VALS(rpc_reply_state), 0, "Reply State", HFILL }},
3313 { &hf_rpc_state_accept, {
3314 "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
3315 VALS(rpc_accept_state), 0, "Accept State", HFILL }},
3316 { &hf_rpc_state_reject, {
3317 "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
3318 VALS(rpc_reject_state), 0, "Reject State", HFILL }},
3319 { &hf_rpc_state_auth, {
3320 "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
3321 VALS(rpc_auth_state), 0, "Auth State", HFILL }},
3322 { &hf_rpc_version, {
3323 "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
3324 NULL, 0, "RPC Version", HFILL }},
3325 { &hf_rpc_version_min, {
3326 "RPC Version (Minimum)", "rpc.version.min", FT_UINT32,
3327 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3328 { &hf_rpc_version_max, {
3329 "RPC Version (Maximum)", "rpc.version.max", FT_UINT32,
3330 BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
3331 { &hf_rpc_program, {
3332 "Program", "rpc.program", FT_UINT32, BASE_DEC,
3333 NULL, 0, "Program", HFILL }},
3334 { &hf_rpc_programversion, {
3335 "Program Version", "rpc.programversion", FT_UINT32,
3336 BASE_DEC, NULL, 0, "Program Version", HFILL }},
3337 { &hf_rpc_programversion_min, {
3338 "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32,
3339 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3340 { &hf_rpc_programversion_max, {
3341 "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32,
3342 BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
3343 { &hf_rpc_procedure, {
3344 "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
3345 NULL, 0, "Procedure", HFILL }},
3346 { &hf_rpc_auth_flavor, {
3347 "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
3348 VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
3349 { &hf_rpc_auth_length, {
3350 "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
3351 NULL, 0, "Length", HFILL }},
3352 { &hf_rpc_auth_stamp, {
3353 "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
3354 NULL, 0, "Stamp", HFILL }},
3355 { &hf_rpc_auth_uid, {
3356 "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
3357 NULL, 0, "UID", HFILL }},
3358 { &hf_rpc_auth_gid, {
3359 "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
3360 NULL, 0, "GID", HFILL }},
3361 { &hf_rpc_authgss_v, {
3362 "GSS Version", "rpc.authgss.version", FT_UINT32,
3363 BASE_DEC, NULL, 0, "GSS Version", HFILL }},
3364 { &hf_rpc_authgss_proc, {
3365 "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
3366 BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
3367 { &hf_rpc_authgss_seq, {
3368 "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
3369 BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
3370 { &hf_rpc_authgss_svc, {
3371 "GSS Service", "rpc.authgss.service", FT_UINT32,
3372 BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
3373 { &hf_rpc_authgss_ctx, {
3374 "GSS Context", "rpc.authgss.context", FT_BYTES,
3375 BASE_HEX, NULL, 0, "GSS Context", HFILL }},
3376 { &hf_rpc_authgss_major, {
3377 "GSS Major Status", "rpc.authgss.major", FT_UINT32,
3378 BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
3379 { &hf_rpc_authgss_minor, {
3380 "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
3381 BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
3382 { &hf_rpc_authgss_window, {
3383 "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
3384 BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
3385 { &hf_rpc_authgss_token_length, {
3386 "GSS Token Length", "rpc.authgss.token_length", FT_UINT32,
3387 BASE_DEC, NULL, 0, "GSS Token Length", HFILL }},
3388 { &hf_rpc_authgss_data_length, {
3389 "Length", "rpc.authgss.data.length", FT_UINT32,
3390 BASE_DEC, NULL, 0, "Length", HFILL }},
3391 { &hf_rpc_authgss_data, {
3392 "GSS Data", "rpc.authgss.data", FT_BYTES,
3393 BASE_HEX, NULL, 0, "GSS Data", HFILL }},
3394 { &hf_rpc_authgss_checksum, {
3395 "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
3396 BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
3397 { &hf_rpc_authgssapi_v, {
3398 "AUTH_GSSAPI Version", "rpc.authgssapi.version",
3399 FT_UINT32, BASE_DEC, NULL, 0, "AUTH_GSSAPI Version",
3401 { &hf_rpc_authgssapi_msg, {
3402 "AUTH_GSSAPI Message", "rpc.authgssapi.message",
3403 FT_BOOLEAN, BASE_NONE, &yesno, 0, "AUTH_GSSAPI Message",
3405 { &hf_rpc_authgssapi_msgv, {
3406 "Msg Version", "rpc.authgssapi.msgversion",
3407 FT_UINT32, BASE_DEC, NULL, 0, "Msg Version",
3409 { &hf_rpc_authgssapi_handle, {
3410 "Client Handle", "rpc.authgssapi.handle",
3411 FT_BYTES, BASE_HEX, NULL, 0, "Client Handle", HFILL }},
3412 { &hf_rpc_authgssapi_isn, {
3413 "Signed ISN", "rpc.authgssapi.isn",
3414 FT_BYTES, BASE_HEX, NULL, 0, "Signed ISN", HFILL }},
3415 { &hf_rpc_authdes_namekind, {
3416 "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
3417 VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
3418 { &hf_rpc_authdes_netname, {
3419 "Netname", "rpc.authdes.netname", FT_STRING,
3420 BASE_DEC, NULL, 0, "Netname", HFILL }},
3421 { &hf_rpc_authdes_convkey, {
3422 "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
3423 BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
3424 { &hf_rpc_authdes_window, {
3425 "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
3426 BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
3427 { &hf_rpc_authdes_nickname, {
3428 "Nickname", "rpc.authdes.nickname", FT_UINT32,
3429 BASE_HEX, NULL, 0, "Nickname", HFILL }},
3430 { &hf_rpc_authdes_timestamp, {
3431 "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
3432 BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
3433 { &hf_rpc_authdes_windowverf, {
3434 "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
3435 BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
3436 { &hf_rpc_authdes_timeverf, {
3437 "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
3438 BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
3439 { &hf_rpc_auth_machinename, {
3440 "Machine Name", "rpc.auth.machinename", FT_STRING,
3441 BASE_DEC, NULL, 0, "Machine Name", HFILL }},
3443 "Duplicate Call/Reply", "rpc.dup", FT_NONE, BASE_NONE,
3444 NULL, 0, "Duplicate Call/Reply", HFILL }},
3445 { &hf_rpc_call_dup, {
3446 "Duplicate to the call in", "rpc.call.dup", FT_FRAMENUM, BASE_DEC,
3447 NULL, 0, "This is a duplicate to the call in frame", HFILL }},
3448 { &hf_rpc_reply_dup, {
3449 "Duplicate to the reply in", "rpc.reply.dup", FT_FRAMENUM, BASE_DEC,
3450 NULL, 0, "This is a duplicate to the reply in frame", HFILL }},
3451 { &hf_rpc_value_follows, {
3452 "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
3453 &yesno, 0, "Value Follows", HFILL }},
3454 { &hf_rpc_array_len, {
3455 "num", "rpc.array.len", FT_UINT32, BASE_DEC,
3456 NULL, 0, "Length of RPC array", HFILL }},
3459 "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
3460 NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
3462 { &hf_rpc_fragment_overlap,
3463 { "Fragment overlap", "rpc.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3464 "Fragment overlaps with other fragments", HFILL }},
3466 { &hf_rpc_fragment_overlap_conflict,
3467 { "Conflicting data in fragment overlap", "rpc.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3468 "Overlapping fragments contained conflicting data", HFILL }},
3470 { &hf_rpc_fragment_multiple_tails,
3471 { "Multiple tail fragments found", "rpc.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3472 "Several tails were found when defragmenting the packet", HFILL }},
3474 { &hf_rpc_fragment_too_long_fragment,
3475 { "Fragment too long", "rpc.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3476 "Fragment contained data past end of packet", HFILL }},
3478 { &hf_rpc_fragment_error,
3479 { "Defragmentation error", "rpc.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3480 "Defragmentation error due to illegal fragments", HFILL }},
3483 { "RPC Fragment", "rpc.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3484 "RPC Fragment", HFILL }},
3486 { &hf_rpc_fragments,
3487 { "RPC Fragments", "rpc.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3488 "RPC Fragments", HFILL }},
3490 static gint *ett[] = {
3502 &ett_rpc_authgssapi_msg,
3503 &ett_rpc_unknown_program,
3505 module_t *rpc_module;
3507 proto_rpc = proto_register_protocol("Remote Procedure Call",
3509 /* this is a dummy dissector for all those unknown rpc programs */
3510 proto_register_field_array(proto_rpc, hf, array_length(hf));
3511 proto_register_subtree_array(ett, array_length(ett));
3512 register_init_routine(&rpc_init_protocol);
3514 rpc_module = prefs_register_protocol(proto_rpc, NULL);
3515 prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
3516 "Reassemble RPC over TCP messages\nspanning multiple TCP segments",
3517 "Whether the RPC dissector should reassemble messages spanning multiple TCP segments."
3518 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3520 prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
3521 "Reassemble fragmented RPC-over-TCP messages",
3522 "Whether the RPC dissector should defragment RPC-over-TCP messages.",
3525 prefs_register_uint_preference(rpc_module, "max_tcp_pdu_size", "Maximum size of a RPC-over-TCP PDU",
3526 "Set the maximum size of RPCoverTCP PDUs. "
3527 " If the size field of the record marker is larger "
3528 "than this value it will not be considered a valid RPC PDU.",
3529 10, &max_rpc_tcp_pdu_size);
3531 prefs_register_bool_preference(rpc_module, "dissect_unknown_programs",
3532 "Dissect unknown RPC program numbers",
3533 "Whether the RPC dissector should attempt to dissect RPC PDUs containing programs that are not known to Ethereal. This will make the heuristics significantly weaker and elevate the risk for falsely identifying and misdissecting packets significantly.",
3534 &rpc_dissect_unknown_programs);
3536 register_dissector("rpc", dissect_rpc, proto_rpc);
3537 rpc_handle = find_dissector("rpc");
3538 register_dissector("rpc-tcp", dissect_rpc_tcp, proto_rpc);
3539 rpc_tcp_handle = find_dissector("rpc-tcp");
3540 rpc_tap = register_tap("rpc");
3543 * Init the hash tables. Dissectors for RPC protocols must
3544 * have a "handoff registration" routine that registers the
3545 * protocol with RPC; they must not do it in their protocol
3546 * registration routine, as their protocol registration
3547 * routine might be called before this routine is called and
3548 * thus might be called before the hash tables are initialized,
3549 * but it's guaranteed that all protocol registration routines
3550 * will be called before any handoff registration routines
3553 rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
3554 rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
3558 proto_reg_handoff_rpc(void)
3560 dissector_handle_t rpc_tcp_handle;
3561 dissector_handle_t rpc_udp_handle;
3563 /* tcp/udp port 111 is used by portmapper which is an onc-rpc service.
3564 we register onc-rpc on this port so that we can choose RPC in
3565 the list offered by DecodeAs, and so that traffic to or from
3566 port 111 from or to a higher-numbered port is dissected as RPC
3567 even if there's a dissector registered on the other port (it's
3568 probably RPC traffic from some randomly-chosen port that happens
3569 to match some port for which we have a dissector)
3571 rpc_tcp_handle = create_dissector_handle(dissect_rpc_tcp, proto_rpc);
3572 dissector_add("tcp.port", 111, rpc_tcp_handle);
3573 rpc_udp_handle = create_dissector_handle(dissect_rpc, proto_rpc);
3574 dissector_add("udp.port", 111, rpc_udp_handle);
3576 heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
3577 heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
3578 gssapi_handle = find_dissector("gssapi");
3579 data_handle = find_dissector("data");