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>
47 #include <epan/strutil.h>
52 * RFC 1831, "RPC: Remote Procedure Call Protocol Specification
55 * RFC 1832, "XDR: External Data Representation Standard";
57 * RFC 2203, "RPCSEC_GSS Protocol Specification".
61 * RFC 2695, "Authentication Mechanisms for ONC RPC"
63 * although we don't currently dissect AUTH_DES or AUTH_KERB.
66 /* desegmentation of RPC over TCP */
67 static gboolean rpc_desegment = TRUE;
69 /* defragmentation of fragmented RPC over TCP records */
70 static gboolean rpc_defragment = FALSE;
72 /* try to dissect RPC packets for programs that are not known
73 * (proprietary ones) by ethereal.
75 static gboolean rpc_dissect_unknown_programs = FALSE;
77 /* try to find RPC fragment start if normal decode fails
78 * (good when starting decode of mid-stream capture)
80 static gboolean rpc_find_fragment_start = FALSE;
82 static struct true_false_string yesno = { "Yes", "No" };
84 static int rpc_tap = -1;
86 static const value_string rpc_msg_type[] = {
88 { RPC_REPLY, "Reply" },
92 static const value_string rpc_reply_state[] = {
93 { MSG_ACCEPTED, "accepted" },
94 { MSG_DENIED, "denied" },
98 const value_string rpc_auth_flavor[] = {
99 { AUTH_NULL, "AUTH_NULL" },
100 { AUTH_UNIX, "AUTH_UNIX" },
101 { AUTH_SHORT, "AUTH_SHORT" },
102 { AUTH_DES, "AUTH_DES" },
103 { RPCSEC_GSS, "RPCSEC_GSS" },
104 { AUTH_GSSAPI, "AUTH_GSSAPI" },
108 static const value_string rpc_authgss_proc[] = {
109 { RPCSEC_GSS_DATA, "RPCSEC_GSS_DATA" },
110 { RPCSEC_GSS_INIT, "RPCSEC_GSS_INIT" },
111 { RPCSEC_GSS_CONTINUE_INIT, "RPCSEC_GSS_CONTINUE_INIT" },
112 { RPCSEC_GSS_DESTROY, "RPCSEC_GSS_DESTROY" },
116 static const value_string rpc_authgssapi_proc[] = {
117 { AUTH_GSSAPI_EXIT, "AUTH_GSSAPI_EXIT" },
118 { AUTH_GSSAPI_INIT, "AUTH_GSSAPI_INIT" },
119 { AUTH_GSSAPI_CONTINUE_INIT, "AUTH_GSSAPI_CONTINUE_INIT" },
120 { AUTH_GSSAPI_MSG, "AUTH_GSSAPI_MSG" },
121 { AUTH_GSSAPI_DESTROY, "AUTH_GSSAPI_DESTROY" },
125 value_string rpc_authgss_svc[] = {
126 { RPCSEC_GSS_SVC_NONE, "rpcsec_gss_svc_none" },
127 { RPCSEC_GSS_SVC_INTEGRITY, "rpcsec_gss_svc_integrity" },
128 { RPCSEC_GSS_SVC_PRIVACY, "rpcsec_gss_svc_privacy" },
132 static const value_string rpc_accept_state[] = {
133 { SUCCESS, "RPC executed successfully" },
134 { PROG_UNAVAIL, "remote hasn't exported program" },
135 { PROG_MISMATCH, "remote can't support version #" },
136 { PROC_UNAVAIL, "program can't support procedure" },
137 { GARBAGE_ARGS, "procedure can't decode params" },
138 { SYSTEM_ERROR, "system errors like memory allocation failure" },
142 static const value_string rpc_reject_state[] = {
143 { RPC_MISMATCH, "RPC_MISMATCH" },
144 { AUTH_ERROR, "AUTH_ERROR" },
148 static const value_string rpc_auth_state[] = {
149 { AUTH_BADCRED, "bad credential (seal broken)" },
150 { AUTH_REJECTEDCRED, "client must begin new session" },
151 { AUTH_BADVERF, "bad verifier (seal broken)" },
152 { AUTH_REJECTEDVERF, "verifier expired or replayed" },
153 { AUTH_TOOWEAK, "rejected for security reasons" },
154 { RPCSEC_GSSCREDPROB, "GSS credential problem" },
155 { RPCSEC_GSSCTXPROB, "GSS context problem" },
159 static const value_string rpc_authdes_namekind[] = {
160 { AUTHDES_NAMEKIND_FULLNAME, "ADN_FULLNAME" },
161 { AUTHDES_NAMEKIND_NICKNAME, "ADN_NICKNAME" },
165 /* the protocol number */
166 static int proto_rpc = -1;
167 static int hf_rpc_reqframe = -1;
168 static int hf_rpc_repframe = -1;
169 static int hf_rpc_lastfrag = -1;
170 static int hf_rpc_fraglen = -1;
171 static int hf_rpc_xid = -1;
172 static int hf_rpc_msgtype = -1;
173 static int hf_rpc_version = -1;
174 static int hf_rpc_version_min = -1;
175 static int hf_rpc_version_max = -1;
176 static int hf_rpc_program = -1;
177 static int hf_rpc_programversion = -1;
178 static int hf_rpc_programversion_min = -1;
179 static int hf_rpc_programversion_max = -1;
180 static int hf_rpc_procedure = -1;
181 static int hf_rpc_auth_flavor = -1;
182 static int hf_rpc_auth_length = -1;
183 static int hf_rpc_auth_machinename = -1;
184 static int hf_rpc_auth_stamp = -1;
185 static int hf_rpc_auth_uid = -1;
186 static int hf_rpc_auth_gid = -1;
187 static int hf_rpc_authgss_v = -1;
188 static int hf_rpc_authgss_proc = -1;
189 static int hf_rpc_authgss_seq = -1;
190 static int hf_rpc_authgss_svc = -1;
191 static int hf_rpc_authgss_ctx = -1;
192 static int hf_rpc_authgss_major = -1;
193 static int hf_rpc_authgss_minor = -1;
194 static int hf_rpc_authgss_window = -1;
195 static int hf_rpc_authgss_token_length = -1;
196 static int hf_rpc_authgss_data_length = -1;
197 static int hf_rpc_authgss_data = -1;
198 static int hf_rpc_authgss_checksum = -1;
199 static int hf_rpc_authgssapi_v = -1;
200 static int hf_rpc_authgssapi_msg = -1;
201 static int hf_rpc_authgssapi_msgv = -1;
202 static int hf_rpc_authgssapi_handle = -1;
203 static int hf_rpc_authgssapi_isn = -1;
204 static int hf_rpc_authdes_namekind = -1;
205 static int hf_rpc_authdes_netname = -1;
206 static int hf_rpc_authdes_convkey = -1;
207 static int hf_rpc_authdes_window = -1;
208 static int hf_rpc_authdes_nickname = -1;
209 static int hf_rpc_authdes_timestamp = -1;
210 static int hf_rpc_authdes_windowverf = -1;
211 static int hf_rpc_authdes_timeverf = -1;
212 static int hf_rpc_state_accept = -1;
213 static int hf_rpc_state_reply = -1;
214 static int hf_rpc_state_reject = -1;
215 static int hf_rpc_state_auth = -1;
216 static int hf_rpc_dup = -1;
217 static int hf_rpc_call_dup = -1;
218 static int hf_rpc_reply_dup = -1;
219 static int hf_rpc_value_follows = -1;
220 static int hf_rpc_array_len = -1;
221 static int hf_rpc_time = -1;
222 static int hf_rpc_fragments = -1;
223 static int hf_rpc_fragment = -1;
224 static int hf_rpc_fragment_overlap = -1;
225 static int hf_rpc_fragment_overlap_conflict = -1;
226 static int hf_rpc_fragment_multiple_tails = -1;
227 static int hf_rpc_fragment_too_long_fragment = -1;
228 static int hf_rpc_fragment_error = -1;
230 static gint ett_rpc = -1;
231 static gint ett_rpc_unknown_program = -1;
232 static gint ett_rpc_fragments = -1;
233 static gint ett_rpc_fragment = -1;
234 static gint ett_rpc_fraghdr = -1;
235 static gint ett_rpc_string = -1;
236 static gint ett_rpc_cred = -1;
237 static gint ett_rpc_verf = -1;
238 static gint ett_rpc_gids = -1;
239 static gint ett_rpc_gss_token = -1;
240 static gint ett_rpc_gss_data = -1;
241 static gint ett_rpc_array = -1;
242 static gint ett_rpc_authgssapi_msg = -1;
244 static dissector_handle_t rpc_tcp_handle;
245 static dissector_handle_t rpc_handle;
246 static dissector_handle_t gssapi_handle;
247 static dissector_handle_t data_handle;
249 static guint max_rpc_tcp_pdu_size = 262144;
251 static const fragment_items rpc_frag_items = {
256 &hf_rpc_fragment_overlap,
257 &hf_rpc_fragment_overlap_conflict,
258 &hf_rpc_fragment_multiple_tails,
259 &hf_rpc_fragment_too_long_fragment,
260 &hf_rpc_fragment_error,
265 /* Hash table with info on RPC program numbers */
266 GHashTable *rpc_progs;
268 /* Hash table with info on RPC procedure numbers */
269 GHashTable *rpc_procs;
271 static void dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
272 static void dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
274 /***********************************/
275 /* Hash array with procedure names */
276 /***********************************/
280 rpc_proc_equal(gconstpointer k1, gconstpointer k2)
282 const rpc_proc_info_key* key1 = (const rpc_proc_info_key*) k1;
283 const rpc_proc_info_key* key2 = (const rpc_proc_info_key*) k2;
285 return ((key1->prog == key2->prog &&
286 key1->vers == key2->vers &&
287 key1->proc == key2->proc) ?
291 /* calculate a hash key */
293 rpc_proc_hash(gconstpointer k)
295 const rpc_proc_info_key* key = (const rpc_proc_info_key*) k;
297 return (key->prog ^ (key->vers<<16) ^ (key->proc<<24));
301 /* insert some entries */
303 rpc_init_proc_table(guint prog, guint vers, const vsff *proc_table,
306 rpc_prog_info_key rpc_prog_key;
307 rpc_prog_info_value *rpc_prog;
311 * Add the operation number hfinfo value for this version of the
314 rpc_prog_key.prog = prog;
315 rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key);
316 DISSECTOR_ASSERT(rpc_prog != NULL);
317 rpc_prog->procedure_hfs = g_array_set_size(rpc_prog->procedure_hfs,
319 g_array_insert_val(rpc_prog->procedure_hfs, vers, procedure_hf);
321 for (proc = proc_table ; proc->strptr!=NULL; proc++) {
322 rpc_proc_info_key *key;
323 rpc_proc_info_value *value;
325 key = (rpc_proc_info_key *) g_malloc(sizeof(rpc_proc_info_key));
328 key->proc = proc->value;
330 value = (rpc_proc_info_value *) g_malloc(sizeof(rpc_proc_info_value));
331 value->name = proc->strptr;
332 value->dissect_call = proc->dissect_call;
333 value->dissect_reply = proc->dissect_reply;
335 g_hash_table_insert(rpc_procs,key,value);
340 /* return the name associated with a previously registered procedure. */
342 rpc_proc_name(guint32 prog, guint32 vers, guint32 proc)
344 rpc_proc_info_key key;
345 rpc_proc_info_value *value;
348 procname=ep_alloc(20);
353 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL)
354 procname = (char *)value->name;
356 /* happens only with strange program versions or
357 non-existing dissectors */
358 g_snprintf(procname, 20, "proc-%u", key.proc);
363 /*----------------------------------------*/
364 /* end of Hash array with procedure names */
365 /*----------------------------------------*/
368 /*********************************/
369 /* Hash array with program names */
370 /*********************************/
374 rpc_prog_equal(gconstpointer k1, gconstpointer k2)
376 const rpc_prog_info_key* key1 = (const rpc_prog_info_key*) k1;
377 const rpc_prog_info_key* key2 = (const rpc_prog_info_key*) k2;
379 return ((key1->prog == key2->prog) ?
384 /* calculate a hash key */
386 rpc_prog_hash(gconstpointer k)
388 const rpc_prog_info_key* key = (const rpc_prog_info_key*) k;
395 rpc_init_prog(int proto, guint32 prog, int ett)
397 rpc_prog_info_key *key;
398 rpc_prog_info_value *value;
400 key = (rpc_prog_info_key *) g_malloc(sizeof(rpc_prog_info_key));
403 value = (rpc_prog_info_value *) g_malloc(sizeof(rpc_prog_info_value));
404 value->proto = find_protocol_by_id(proto);
405 value->proto_id = proto;
407 value->progname = proto_get_protocol_short_name(value->proto);
408 value->procedure_hfs = g_array_new(FALSE, TRUE, sizeof (int));
410 g_hash_table_insert(rpc_progs,key,value);
415 /* return the hf_field associated with a previously registered program.
417 int rpc_prog_hf(guint32 prog, guint32 vers)
419 rpc_prog_info_key rpc_prog_key;
420 rpc_prog_info_value *rpc_prog;
422 rpc_prog_key.prog = prog;
423 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key))) {
424 return g_array_index(rpc_prog->procedure_hfs, int, vers);
429 /* return the name associated with a previously registered program. This
430 should probably eventually be expanded to use the rpc YP/NIS map
431 so that it can give names for programs not handled by ethereal */
432 const char *rpc_prog_name(guint32 prog)
434 const char *progname = NULL;
435 rpc_prog_info_key rpc_prog_key;
436 rpc_prog_info_value *rpc_prog;
438 rpc_prog_key.prog = prog;
439 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
440 progname = "Unknown";
443 progname = rpc_prog->progname;
449 /*--------------------------------------*/
450 /* end of Hash array with program names */
451 /*--------------------------------------*/
453 typedef struct _rpc_call_info_key {
455 conversation_t *conversation;
458 static GHashTable *rpc_calls;
460 static GHashTable *rpc_indir_calls;
464 rpc_call_equal(gconstpointer k1, gconstpointer k2)
466 const rpc_call_info_key* key1 = (const rpc_call_info_key*) k1;
467 const rpc_call_info_key* key2 = (const rpc_call_info_key*) k2;
469 return (key1->xid == key2->xid &&
470 key1->conversation == key2->conversation);
474 /* calculate a hash key */
476 rpc_call_hash(gconstpointer k)
478 const rpc_call_info_key* key = (const rpc_call_info_key*) k;
480 return key->xid + GPOINTER_TO_UINT(key->conversation);
485 rpc_roundup(unsigned int a)
487 unsigned int mod = a % 4;
488 return a + ((mod)? 4-mod : 0);
493 dissect_rpc_bool(tvbuff_t *tvb, proto_tree *tree,
494 int hfindex, int offset)
497 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
503 dissect_rpc_uint32(tvbuff_t *tvb, proto_tree *tree,
504 int hfindex, int offset)
507 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
513 dissect_rpc_uint64(tvbuff_t *tvb, proto_tree *tree,
514 int hfindex, int offset)
516 header_field_info *hfinfo;
518 hfinfo = proto_registrar_get_nth(hfindex);
519 DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
521 proto_tree_add_item(tree, hfindex, tvb, offset, 8, FALSE);
527 * We want to make this function available outside this file and
528 * allow callers to pass a dissection function for the opaque data
531 dissect_rpc_opaque_data(tvbuff_t *tvb, int offset,
535 gboolean fixed_length, guint32 length,
536 gboolean string_data, char **string_buffer_ret,
537 dissect_function_t *dissect_it)
540 proto_item *string_item = NULL;
541 proto_tree *string_tree = NULL;
543 guint32 string_length;
544 guint32 string_length_full;
545 guint32 string_length_packet;
546 guint32 string_length_captured;
547 guint32 string_length_copy;
551 guint32 fill_length_packet;
552 guint32 fill_length_captured;
553 guint32 fill_length_copy;
557 char *string_buffer = NULL;
558 char *string_buffer_print = NULL;
561 string_length = length;
562 data_offset = offset;
565 string_length = tvb_get_ntohl(tvb,offset+0);
566 data_offset = offset + 4;
568 string_length_captured = tvb_length_remaining(tvb, data_offset);
569 string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
570 string_length_full = rpc_roundup(string_length);
571 if (string_length_captured < string_length) {
572 /* truncated string */
573 string_length_copy = string_length_captured;
576 fill_length_copy = 0;
577 if (string_length_packet < string_length)
578 exception = ReportedBoundsError;
580 exception = BoundsError;
583 /* full string data */
584 string_length_copy = string_length;
585 fill_length = string_length_full - string_length;
586 fill_length_captured = tvb_length_remaining(tvb,
587 data_offset + string_length);
588 fill_length_packet = tvb_reported_length_remaining(tvb,
589 data_offset + string_length);
590 if (fill_length_captured < fill_length) {
591 /* truncated fill bytes */
592 fill_length_copy = fill_length_packet;
594 if (fill_length_packet < fill_length)
595 exception = ReportedBoundsError;
597 exception = BoundsError;
600 /* full fill bytes */
601 fill_length_copy = fill_length;
607 * If we were passed a dissection routine, make a TVB of the data
608 * and call the dissection routine
612 tvbuff_t *opaque_tvb;
614 opaque_tvb = tvb_new_subset(tvb, data_offset, string_length_copy,
617 return (*dissect_it)(opaque_tvb, offset, pinfo, tree);
623 tmpstr = tvb_get_ephemeral_string(tvb, data_offset, string_length_copy);
624 string_buffer = memcpy(ep_alloc(string_length_copy+1), tmpstr, string_length_copy);
626 string_buffer = tvb_memcpy(tvb, ep_alloc(string_length_copy+1), data_offset, string_length_copy);
628 string_buffer[string_length_copy] = '\0';
629 /* calculate a nice printable string */
631 if (string_length != string_length_copy) {
635 formatted = format_text(string_buffer, strlen(string_buffer));
636 /* alloc maximum data area */
637 string_buffer_print = (char*)ep_alloc(strlen(formatted) + 12 + 1);
638 /* copy over the data */
639 strcpy(string_buffer_print,formatted);
640 /* append <TRUNCATED> */
641 /* This way, we get the TRUNCATED even
642 in the case of totally wrong packets,
643 where \0 are inside the string.
644 TRUNCATED will appear at the
645 first \0 or at the end (where we
646 put the securing \0).
648 strcat(string_buffer_print,"<TRUNCATED>");
650 string_buffer_print="<DATA><TRUNCATED>";
654 string_buffer_print =
655 ep_strdup(format_text(string_buffer, strlen(string_buffer)));
657 string_buffer_print="<DATA>";
661 string_buffer_print="<EMPTY>";
665 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
666 "%s: %s", proto_registrar_get_name(hfindex),
667 string_buffer_print);
668 string_tree = proto_item_add_subtree(string_item,
673 proto_tree_add_text(string_tree, tvb,offset+0,4,
674 "length: %u", string_length);
680 proto_tree_add_string_format(string_tree,
681 hfindex, tvb, offset, string_length_copy,
683 "contents: %s", string_buffer_print);
685 proto_tree_add_bytes_format(string_tree,
686 hfindex, tvb, offset, string_length_copy,
688 "contents: %s", string_buffer_print);
692 offset += string_length_copy;
696 if (fill_truncated) {
697 proto_tree_add_text(string_tree, tvb,
698 offset,fill_length_copy,
699 "fill bytes: opaque data<TRUNCATED>");
702 proto_tree_add_text(string_tree, tvb,
703 offset,fill_length_copy,
704 "fill bytes: opaque data");
707 offset += fill_length_copy;
711 proto_item_set_end(string_item, tvb, offset);
713 if (string_buffer_ret != NULL)
714 *string_buffer_ret = string_buffer_print;
717 * If the data was truncated, throw the appropriate exception,
718 * so that dissection stops and the frame is properly marked.
727 dissect_rpc_string(tvbuff_t *tvb, proto_tree *tree,
728 int hfindex, int offset, char **string_buffer_ret)
730 offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL,
731 hfindex, FALSE, 0, TRUE, string_buffer_ret, NULL);
737 dissect_rpc_data(tvbuff_t *tvb, proto_tree *tree,
738 int hfindex, int offset)
740 offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL,
741 hfindex, FALSE, 0, FALSE, NULL, NULL);
747 dissect_rpc_bytes(tvbuff_t *tvb, proto_tree *tree,
748 int hfindex, int offset, guint32 length,
749 gboolean string_data, char **string_buffer_ret)
751 offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL,
752 hfindex, TRUE, length, string_data, string_buffer_ret, NULL);
758 dissect_rpc_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
759 int offset, dissect_function_t *rpc_list_dissector)
761 guint32 value_follows;
764 value_follows = tvb_get_ntohl(tvb, offset+0);
765 proto_tree_add_boolean(tree,hf_rpc_value_follows, tvb,
766 offset+0, 4, value_follows);
768 if (value_follows == 1) {
769 offset = rpc_list_dissector(tvb, offset, pinfo, tree);
780 dissect_rpc_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
781 int offset, dissect_function_t *rpc_array_dissector,
784 proto_item* lock_item;
785 proto_tree* lock_tree;
788 num = tvb_get_ntohl(tvb, offset);
791 proto_tree_add_none_format(tree, hfindex, tvb, offset, 4,
798 lock_item = proto_tree_add_item(tree, hfindex, tvb, offset, -1, FALSE);
800 lock_tree = proto_item_add_subtree(lock_item, ett_rpc_array);
802 offset = dissect_rpc_uint32(tvb, lock_tree,
803 hf_rpc_array_len, offset);
806 offset = rpc_array_dissector(tvb, offset, pinfo, lock_tree);
809 proto_item_set_end(lock_item, tvb, offset);
814 dissect_rpc_authunix_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
823 proto_tree *gtree = NULL;
825 stamp = tvb_get_ntohl(tvb,offset+0);
827 proto_tree_add_uint(tree, hf_rpc_auth_stamp, tvb,
831 offset = dissect_rpc_string(tvb, tree,
832 hf_rpc_auth_machinename, offset, NULL);
834 uid = tvb_get_ntohl(tvb,offset+0);
836 proto_tree_add_uint(tree, hf_rpc_auth_uid, tvb,
840 gid = tvb_get_ntohl(tvb,offset+0);
842 proto_tree_add_uint(tree, hf_rpc_auth_gid, tvb,
846 gids_count = tvb_get_ntohl(tvb,offset+0);
848 gitem = proto_tree_add_text(tree, tvb,
849 offset, 4+gids_count*4, "Auxiliary GIDs");
850 gtree = proto_item_add_subtree(gitem, ett_rpc_gids);
854 for (gids_i = 0 ; gids_i < gids_count ; gids_i++) {
855 gids_entry = tvb_get_ntohl(tvb,offset+0);
857 proto_tree_add_uint(gtree, hf_rpc_auth_gid, tvb,
858 offset, 4, gids_entry);
861 /* how can I NOW change the gitem to print a list with
862 the first 16 gids? */
868 dissect_rpc_authgss_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
875 agc_v = tvb_get_ntohl(tvb, offset+0);
877 proto_tree_add_uint(tree, hf_rpc_authgss_v,
878 tvb, offset+0, 4, agc_v);
881 agc_proc = tvb_get_ntohl(tvb, offset+0);
883 proto_tree_add_uint(tree, hf_rpc_authgss_proc,
884 tvb, offset+0, 4, agc_proc);
887 agc_seq = tvb_get_ntohl(tvb, offset+0);
889 proto_tree_add_uint(tree, hf_rpc_authgss_seq,
890 tvb, offset+0, 4, agc_seq);
893 agc_svc = tvb_get_ntohl(tvb, offset+0);
895 proto_tree_add_uint(tree, hf_rpc_authgss_svc,
896 tvb, offset+0, 4, agc_svc);
899 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
906 dissect_rpc_authdes_desblock(tvbuff_t *tvb, proto_tree *tree,
907 int hfindex, int offset)
912 value_high = tvb_get_ntohl(tvb, offset + 0);
913 value_low = tvb_get_ntohl(tvb, offset + 4);
916 proto_tree_add_text(tree, tvb, offset, 8,
917 "%s: 0x%x%08x", proto_registrar_get_name(hfindex), value_high,
925 dissect_rpc_authdes_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
931 adc_namekind = tvb_get_ntohl(tvb, offset+0);
933 proto_tree_add_uint(tree, hf_rpc_authdes_namekind,
934 tvb, offset+0, 4, adc_namekind);
939 case AUTHDES_NAMEKIND_FULLNAME:
940 offset = dissect_rpc_string(tvb, tree,
941 hf_rpc_authdes_netname, offset, NULL);
942 offset = dissect_rpc_authdes_desblock(tvb, tree,
943 hf_rpc_authdes_convkey, offset);
944 window = tvb_get_ntohl(tvb, offset+0);
945 proto_tree_add_uint(tree, hf_rpc_authdes_window, tvb, offset+0, 4,
950 case AUTHDES_NAMEKIND_NICKNAME:
951 nickname = tvb_get_ntohl(tvb, offset+0);
952 proto_tree_add_uint(tree, hf_rpc_authdes_nickname, tvb, offset+0, 4,
962 dissect_rpc_authgssapi_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
967 agc_v = tvb_get_ntohl(tvb, offset+0);
969 proto_tree_add_uint(tree, hf_rpc_authgssapi_v,
970 tvb, offset+0, 4, agc_v);
973 agc_msg = tvb_get_ntohl(tvb, offset+0);
975 proto_tree_add_boolean(tree, hf_rpc_authgssapi_msg,
976 tvb, offset+0, 4, agc_msg);
979 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgssapi_handle,
986 dissect_rpc_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
994 flavor = tvb_get_ntohl(tvb,offset+0);
995 length = tvb_get_ntohl(tvb,offset+4);
996 length = rpc_roundup(length);
999 citem = proto_tree_add_text(tree, tvb, offset,
1000 8+length, "Credentials");
1001 ctree = proto_item_add_subtree(citem, ett_rpc_cred);
1002 proto_tree_add_uint(ctree, hf_rpc_auth_flavor, tvb,
1003 offset+0, 4, flavor);
1004 proto_tree_add_uint(ctree, hf_rpc_auth_length, tvb,
1005 offset+4, 4, length);
1009 dissect_rpc_authunix_cred(tvb, ctree, offset+8);
1017 dissect_rpc_authdes_cred(tvb, ctree, offset+8);
1021 dissect_rpc_authgss_cred(tvb, ctree, offset+8);
1025 dissect_rpc_authgssapi_cred(tvb, ctree, offset+8);
1030 proto_tree_add_text(ctree, tvb, offset+8,
1031 length,"opaque data");
1035 offset += 8 + length;
1041 * XDR opaque object, the contents of which are interpreted as a GSS-API
1045 dissect_rpc_authgss_token(tvbuff_t* tvb, proto_tree* tree, int offset,
1048 guint32 opaque_length, rounded_length;
1049 gint len_consumed, length, reported_length;
1053 proto_tree *gtree = NULL;
1055 opaque_length = tvb_get_ntohl(tvb, offset+0);
1056 rounded_length = rpc_roundup(opaque_length);
1058 gitem = proto_tree_add_text(tree, tvb, offset,
1059 4+rounded_length, "GSS Token");
1060 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_token);
1061 proto_tree_add_uint(gtree, hf_rpc_authgss_token_length,
1062 tvb, offset+0, 4, opaque_length);
1065 length = tvb_length_remaining(tvb, offset);
1066 reported_length = tvb_reported_length_remaining(tvb, offset);
1067 DISSECTOR_ASSERT(length >= 0);
1068 DISSECTOR_ASSERT(reported_length >= 0);
1069 if (length > reported_length)
1070 length = reported_length;
1071 if ((guint32)length > opaque_length)
1072 length = opaque_length;
1073 if ((guint32)reported_length > opaque_length)
1074 reported_length = opaque_length;
1075 new_tvb = tvb_new_subset(tvb, offset, length, reported_length);
1076 len_consumed = call_dissector(gssapi_handle, new_tvb, pinfo, gtree);
1077 offset += len_consumed;
1078 offset = rpc_roundup(offset);
1082 /* AUTH_DES verifiers are asymmetrical, so we need to know what type of
1083 * verifier we're decoding (CALL or REPLY).
1086 dissect_rpc_verf(tvbuff_t* tvb, proto_tree* tree, int offset, int msg_type,
1095 flavor = tvb_get_ntohl(tvb,offset+0);
1096 length = tvb_get_ntohl(tvb,offset+4);
1097 length = rpc_roundup(length);
1100 vitem = proto_tree_add_text(tree, tvb, offset,
1101 8+length, "Verifier");
1102 vtree = proto_item_add_subtree(vitem, ett_rpc_verf);
1103 proto_tree_add_uint(vtree, hf_rpc_auth_flavor, tvb,
1104 offset+0, 4, flavor);
1108 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1109 offset+4, 4, length);
1110 dissect_rpc_authunix_cred(tvb, vtree, offset+8);
1113 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1114 offset+4, 4, length);
1116 if (msg_type == RPC_CALL)
1120 dissect_rpc_authdes_desblock(tvb, vtree,
1121 hf_rpc_authdes_timestamp, offset+8);
1122 window = tvb_get_ntohl(tvb, offset+16);
1123 proto_tree_add_uint(vtree, hf_rpc_authdes_windowverf, tvb,
1124 offset+16, 4, window);
1128 /* must be an RPC_REPLY */
1131 dissect_rpc_authdes_desblock(tvb, vtree,
1132 hf_rpc_authdes_timeverf, offset+8);
1133 nickname = tvb_get_ntohl(tvb, offset+16);
1134 proto_tree_add_uint(vtree, hf_rpc_authdes_nickname, tvb,
1135 offset+16, 4, nickname);
1139 dissect_rpc_authgss_token(tvb, vtree, offset+4, pinfo);
1142 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1143 offset+4, 4, length);
1145 proto_tree_add_text(vtree, tvb, offset+8,
1146 length, "opaque data");
1150 offset += 8 + length;
1156 dissect_rpc_authgss_initarg(tvbuff_t* tvb, proto_tree* tree, int offset,
1159 return dissect_rpc_authgss_token(tvb, tree, offset, pinfo);
1163 dissect_rpc_authgss_initres(tvbuff_t* tvb, proto_tree* tree, int offset,
1166 int major, minor, window;
1168 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
1171 major = tvb_get_ntohl(tvb,offset+0);
1173 proto_tree_add_uint(tree, hf_rpc_authgss_major, tvb,
1174 offset+0, 4, major);
1177 minor = tvb_get_ntohl(tvb,offset+0);
1179 proto_tree_add_uint(tree, hf_rpc_authgss_minor, tvb,
1180 offset+0, 4, minor);
1183 window = tvb_get_ntohl(tvb,offset+0);
1185 proto_tree_add_uint(tree, hf_rpc_authgss_window, tvb,
1186 offset+0, 4, window);
1189 offset = dissect_rpc_authgss_token(tvb, tree, offset, pinfo);
1195 dissect_rpc_authgssapi_initarg(tvbuff_t* tvb, proto_tree* tree, int offset,
1200 proto_tree *mtree = NULL;
1203 mitem = proto_tree_add_text(tree, tvb, offset, -1,
1205 mtree = proto_item_add_subtree(mitem, ett_rpc_authgssapi_msg);
1207 version = tvb_get_ntohl(tvb, offset+0);
1209 proto_tree_add_uint(mtree, hf_rpc_authgssapi_msgv, tvb,
1210 offset+0, 4, version);
1214 offset = dissect_rpc_authgss_token(tvb, mtree, offset, pinfo);
1220 dissect_rpc_authgssapi_initres(tvbuff_t* tvb, proto_tree* tree, int offset,
1226 proto_tree *mtree = NULL;
1229 mitem = proto_tree_add_text(tree, tvb, offset, -1,
1231 mtree = proto_item_add_subtree(mitem, ett_rpc_authgssapi_msg);
1234 version = tvb_get_ntohl(tvb,offset+0);
1236 proto_tree_add_uint(mtree, hf_rpc_authgssapi_msgv, tvb,
1237 offset+0, 4, version);
1241 offset = dissect_rpc_data(tvb, mtree, hf_rpc_authgssapi_handle,
1244 major = tvb_get_ntohl(tvb,offset+0);
1246 proto_tree_add_uint(mtree, hf_rpc_authgss_major, tvb,
1247 offset+0, 4, major);
1251 minor = tvb_get_ntohl(tvb,offset+0);
1253 proto_tree_add_uint(mtree, hf_rpc_authgss_minor, tvb,
1254 offset+0, 4, minor);
1258 offset = dissect_rpc_authgss_token(tvb, mtree, offset, pinfo);
1260 offset = dissect_rpc_data(tvb, mtree, hf_rpc_authgssapi_isn, offset);
1266 dissect_auth_gssapi_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1268 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1274 call_dissect_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1275 int offset, dissect_function_t* dissect_function, const char *progname)
1277 const char *saved_proto;
1279 if (dissect_function != NULL) {
1280 /* set the current protocol name */
1281 saved_proto = pinfo->current_proto;
1282 if (progname != NULL)
1283 pinfo->current_proto = progname;
1285 /* call the dissector for the next level */
1286 offset = dissect_function(tvb, offset, pinfo, tree);
1288 /* restore the protocol name */
1289 pinfo->current_proto = saved_proto;
1297 dissect_rpc_authgss_integ_data(tvbuff_t *tvb, packet_info *pinfo,
1298 proto_tree *tree, int offset,
1299 dissect_function_t* dissect_function,
1300 const char *progname)
1302 guint32 length, rounded_length, seq;
1305 proto_tree *gtree = NULL;
1307 length = tvb_get_ntohl(tvb, offset+0);
1308 rounded_length = rpc_roundup(length);
1309 seq = tvb_get_ntohl(tvb, offset+4);
1312 gitem = proto_tree_add_text(tree, tvb, offset,
1313 4+rounded_length, "GSS Data");
1314 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_data);
1315 proto_tree_add_uint(gtree, hf_rpc_authgss_data_length,
1316 tvb, offset+0, 4, length);
1317 proto_tree_add_uint(gtree, hf_rpc_authgss_seq,
1318 tvb, offset+4, 4, seq);
1322 if (dissect_function != NULL) {
1324 call_dissect_function(tvb, pinfo, gtree, offset,
1325 dissect_function, progname);
1327 offset += rounded_length - 4;
1328 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_checksum,
1335 dissect_rpc_authgss_priv_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1337 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1343 * Dissect the arguments to an indirect call; used by the portmapper/RPCBIND
1346 * Record this call in a hash table, similar to the hash table for
1347 * direct calls, so we can find it when dissecting an indirect call reply.
1350 dissect_rpc_indir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1351 int offset, int args_id, guint32 prog, guint32 vers, guint32 proc)
1353 conversation_t* conversation;
1354 static address null_address = { AT_NONE, 0, NULL };
1355 rpc_proc_info_key key;
1356 rpc_proc_info_value *value;
1357 rpc_call_info_value *rpc_call;
1358 rpc_call_info_key rpc_call_key;
1359 rpc_call_info_key *new_rpc_call_key;
1360 dissect_function_t *dissect_function = NULL;
1365 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1366 dissect_function = value->dissect_call;
1368 /* Keep track of the address whence the call came, and the
1369 port to which the call is being sent, so that we can
1370 match up calls with replies.
1372 If the transport is connection-oriented (we check, for
1373 now, only for "pinfo->ptype" of PT_TCP), we also take
1374 into account the port from which the call was sent
1375 and the address to which the call was sent, because
1376 the addresses and ports of the two endpoints should be
1377 the same for all calls and replies. (XXX - what if
1378 the connection is broken and re-established?)
1380 If the transport is connectionless, we don't worry
1381 about the address to which the call was sent and from
1382 which the reply was sent, because there's no
1383 guarantee that the reply will come from the address
1384 to which the call was sent. We also don't worry about
1385 the port *from* which the call was sent and *to* which
1386 the reply was sent, because some clients (*cough* OS X
1387 NFS client *cough) might send retransmissions from a
1388 different port from the original request. */
1389 if (pinfo->ptype == PT_TCP) {
1390 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1391 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1392 pinfo->destport, 0);
1395 * XXX - you currently still have to pass a non-null
1396 * pointer for the second address argument even
1397 * if you use NO_ADDR_B.
1399 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1400 &null_address, pinfo->ptype, pinfo->destport,
1401 0, NO_ADDR_B|NO_PORT_B);
1403 if (conversation == NULL) {
1404 /* It's not part of any conversation - create a new
1407 XXX - this should never happen, as we should've
1408 created a conversation for it in the RPC
1410 if (pinfo->ptype == PT_TCP) {
1411 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
1412 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1413 pinfo->destport, 0);
1415 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
1416 &null_address, pinfo->ptype, pinfo->destport,
1417 0, NO_ADDR2|NO_PORT2);
1421 /* Make the dissector for this conversation the non-heuristic
1423 conversation_set_dissector(conversation,
1424 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1426 /* Prepare the key data.
1428 Dissectors for RPC procedure calls and replies shouldn't
1429 create new tvbuffs, and we don't create one ourselves,
1430 so we should have been handed the tvbuff for this RPC call;
1431 as such, the XID is at offset 0 in this tvbuff. */
1432 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1433 rpc_call_key.conversation = conversation;
1435 /* look up the request */
1436 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1437 if (rpc_call == NULL) {
1438 /* We didn't find it; create a new entry.
1439 Prepare the value data.
1440 Not all of it is needed for handling indirect
1441 calls, so we set a bunch of items to 0. */
1442 new_rpc_call_key = se_alloc(sizeof(rpc_call_info_key));
1443 *new_rpc_call_key = rpc_call_key;
1444 rpc_call = se_alloc(sizeof(rpc_call_info_value));
1445 rpc_call->req_num = 0;
1446 rpc_call->rep_num = 0;
1447 rpc_call->prog = prog;
1448 rpc_call->vers = vers;
1449 rpc_call->proc = proc;
1450 rpc_call->private_data = NULL;
1453 * XXX - what about RPCSEC_GSS?
1454 * Do we have to worry about it?
1456 rpc_call->flavor = FLAVOR_NOT_GSSAPI;
1457 rpc_call->gss_proc = 0;
1458 rpc_call->gss_svc = 0;
1459 rpc_call->proc_info = value;
1461 g_hash_table_insert(rpc_indir_calls, new_rpc_call_key,
1466 /* We don't know the procedure.
1467 Happens only with strange program versions or
1468 non-existing dissectors.
1469 Just show the arguments as opaque data. */
1470 offset = dissect_rpc_data(tvb, tree, args_id,
1477 proto_tree_add_text(tree, tvb, offset, 4,
1478 "Argument length: %u",
1479 tvb_get_ntohl(tvb, offset));
1483 /* Dissect the arguments */
1484 offset = call_dissect_function(tvb, pinfo, tree, offset,
1485 dissect_function, NULL);
1490 * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1494 dissect_rpc_indir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1495 int offset, int result_id, int prog_id, int vers_id, int proc_id)
1497 conversation_t* conversation;
1498 static address null_address = { AT_NONE, 0, NULL };
1499 rpc_call_info_key rpc_call_key;
1500 rpc_call_info_value *rpc_call;
1501 char *procname=NULL;
1502 dissect_function_t *dissect_function = NULL;
1504 /* Look for the matching call in the hash table of indirect
1505 calls. A reply must match a call that we've seen, and the
1506 reply must be sent to the same address that the call came
1507 from, and must come from the port to which the call was sent.
1509 If the transport is connection-oriented (we check, for
1510 now, only for "pinfo->ptype" of PT_TCP), we take
1511 into account the port from which the call was sent
1512 and the address to which the call was sent, because
1513 the addresses and ports of the two endpoints should be
1514 the same for all calls and replies.
1516 If the transport is connectionless, we don't worry
1517 about the address to which the call was sent and from
1518 which the reply was sent, because there's no
1519 guarantee that the reply will come from the address
1520 to which the call was sent. We also don't worry about
1521 the port *from* which the call was sent and *to* which
1522 the reply was sent, because some clients (*cough* OS X
1523 NFS client *cough) might send retransmissions from a
1524 different port from the original request. */
1525 if (pinfo->ptype == PT_TCP) {
1526 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1527 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1530 * XXX - you currently still have to pass a non-null
1531 * pointer for the second address argument even
1532 * if you use NO_ADDR_B.
1534 conversation = find_conversation(pinfo->fd->num, &pinfo->dst, &null_address,
1535 pinfo->ptype, pinfo->srcport, 0, NO_ADDR_B|NO_PORT_B);
1537 if (conversation == NULL) {
1538 /* We haven't seen an RPC call for that conversation,
1539 so we can't check for a reply to that call.
1540 Just show the reply stuff as opaque data. */
1541 offset = dissect_rpc_data(tvb, tree, result_id,
1546 /* The XIDs of the call and reply must match. */
1547 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1548 rpc_call_key.conversation = conversation;
1549 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1550 if (rpc_call == NULL) {
1551 /* The XID doesn't match a call from that
1552 conversation, so it's probably not an RPC reply.
1553 Just show the reply stuff as opaque data. */
1554 offset = dissect_rpc_data(tvb, tree, result_id,
1559 if (rpc_call->proc_info != NULL) {
1560 dissect_function = rpc_call->proc_info->dissect_reply;
1561 if (rpc_call->proc_info->name != NULL) {
1562 procname = (char *)rpc_call->proc_info->name;
1565 procname=ep_alloc(20);
1566 g_snprintf(procname, 20, "proc-%u", rpc_call->proc);
1571 dissect_function = NULL;
1573 procname=ep_alloc(20);
1574 g_snprintf(procname, 20, "proc-%u", rpc_call->proc);
1579 /* Put the program, version, and procedure into the tree. */
1580 proto_tree_add_uint_format(tree, prog_id, tvb,
1581 0, 0, rpc_call->prog, "Program: %s (%u)",
1582 rpc_prog_name(rpc_call->prog), rpc_call->prog);
1583 proto_tree_add_uint(tree, vers_id, tvb, 0, 0, rpc_call->vers);
1584 proto_tree_add_uint_format(tree, proc_id, tvb,
1585 0, 0, rpc_call->proc, "Procedure: %s (%u)",
1586 procname, rpc_call->proc);
1589 if (dissect_function == NULL) {
1590 /* We don't know how to dissect the reply procedure.
1591 Just show the reply stuff as opaque data. */
1592 offset = dissect_rpc_data(tvb, tree, result_id,
1598 /* Put the length of the reply value into the tree. */
1599 proto_tree_add_text(tree, tvb, offset, 4,
1600 "Argument length: %u",
1601 tvb_get_ntohl(tvb, offset));
1605 /* Dissect the return value */
1606 offset = call_dissect_function(tvb, pinfo, tree, offset,
1607 dissect_function, NULL);
1612 * Just mark this as a continuation of an earlier packet.
1615 dissect_rpc_continuation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1617 proto_item *rpc_item;
1618 proto_tree *rpc_tree;
1620 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1621 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1622 if (check_col(pinfo->cinfo, COL_INFO))
1623 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1626 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1628 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1629 proto_tree_add_text(rpc_tree, tvb, 0, -1, "Continuation data");
1635 * Produce a dummy RPC program entry for the given RPC program key
1636 * and version values.
1639 static void make_fake_rpc_prog_if_needed (rpc_prog_info_key *prpc_prog_key,
1643 rpc_prog_info_value *rpc_prog = NULL;
1646 /* sanity check: no one uses versions > 10 */
1651 if( (rpc_prog = g_hash_table_lookup(rpc_progs, prpc_prog_key)) == NULL) {
1652 /* ok this is not a known rpc program so we
1653 * will have to fake it.
1655 int proto_rpc_unknown_program;
1656 char *NAME, *Name, *name;
1657 static const vsff unknown_proc[] = {
1658 { 0,"NULL",NULL,NULL },
1659 { 0,NULL,NULL,NULL }
1665 g_snprintf(NAME, 36, "Unknown RPC Program:%d",prpc_prog_key->prog);
1666 g_snprintf(Name, 32, "RPC:%d",prpc_prog_key->prog);
1667 g_snprintf(name, 32, "rpc%d",prpc_prog_key->prog);
1668 proto_rpc_unknown_program = proto_register_protocol(NAME, Name, name);
1670 rpc_init_prog(proto_rpc_unknown_program, prpc_prog_key->prog, ett_rpc_unknown_program);
1671 rpc_init_proc_table(prpc_prog_key->prog, prog_ver, unknown_proc, hf_rpc_procedure);
1678 dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1679 tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
1680 guint32 rpc_rm, gboolean first_pdu)
1683 rpc_call_info_key rpc_call_key;
1684 rpc_call_info_value *rpc_call = NULL;
1685 rpc_prog_info_value *rpc_prog = NULL;
1686 rpc_prog_info_key rpc_prog_key;
1689 unsigned int rpcvers;
1690 unsigned int prog = 0;
1691 unsigned int vers = 0;
1692 unsigned int proc = 0;
1693 flavor_t flavor = FLAVOR_UNKNOWN;
1694 unsigned int gss_proc = 0;
1695 unsigned int gss_svc = 0;
1696 protocol_t *proto = NULL;
1701 unsigned int reply_state;
1702 unsigned int accept_state;
1703 unsigned int reject_state;
1705 const char *msg_type_name = NULL;
1706 const char *progname = NULL;
1707 char *procname = NULL;
1709 unsigned int vers_low;
1710 unsigned int vers_high;
1712 unsigned int auth_state;
1714 proto_item *rpc_item = NULL;
1715 proto_tree *rpc_tree = NULL;
1717 proto_item *pitem = NULL;
1718 proto_tree *ptree = NULL;
1719 int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
1721 rpc_call_info_key *new_rpc_call_key;
1722 rpc_proc_info_key key;
1723 rpc_proc_info_value *value = NULL;
1724 conversation_t* conversation;
1725 static address null_address = { AT_NONE, 0, NULL };
1728 dissect_function_t *dissect_function = NULL;
1729 gboolean dissect_rpc = TRUE;
1733 * Check to see whether this looks like an RPC call or reply.
1735 if (!tvb_bytes_exist(tvb, offset, 8)) {
1736 /* Captured data in packet isn't enough to let us tell. */
1740 /* both directions need at least this */
1741 msg_type = tvb_get_ntohl(tvb, offset + 4);
1746 /* check for RPC call */
1747 if (!tvb_bytes_exist(tvb, offset, 16)) {
1748 /* Captured data in packet isn't enough to let us
1753 /* XID can be anything, so dont check it.
1754 We already have the message type.
1755 Check whether an RPC version number of 2 is in the
1756 location where it would be, and that an RPC program
1757 number we know about is in the location where it would be.
1759 XXX - Sun's snoop appears to recognize as RPC even calls
1760 to stuff it doesn't dissect; does it just look for a 2
1761 at that location, which seems far to weak a heuristic
1762 (too many false positives), or does it have some additional
1765 We could conceivably check for any of the program numbers
1768 ftp://ftp.tau.ac.il/pub/users/eilon/rpc/rpc
1770 and report it as RPC (but not dissect the payload if
1771 we don't have a subdissector) if it matches. */
1772 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1774 /* we only dissect version 2 */
1775 if (tvb_get_ntohl(tvb, offset + 8) != 2 ){
1778 /* let the user be able to weaken the heuristics if he need
1779 * to look at proprietary protocols not known
1782 if(rpc_dissect_unknown_programs){
1785 /* if the user has specified that he wants to try to
1786 * dissect even completely unknown RPC program numbers
1787 * then let him do that.
1788 * In this case we only check that the program number
1789 * is neither 0 nor -1 which is better than nothing.
1791 if(rpc_prog_key.prog==0 || rpc_prog_key.prog==0xffffffff){
1794 version=tvb_get_ntohl(tvb, offset+16);
1795 make_fake_rpc_prog_if_needed (&rpc_prog_key, version);
1797 if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
1798 /* They're not, so it's probably not an RPC call. */
1804 /* Check for RPC reply. A reply must match a call that
1805 we've seen, and the reply must be sent to the same
1806 address that the call came from, and must come from
1807 the port to which the call was sent.
1809 If the transport is connection-oriented (we check, for
1810 now, only for "pinfo->ptype" of PT_TCP), we take
1811 into account the port from which the call was sent
1812 and the address to which the call was sent, because
1813 the addresses and ports of the two endpoints should be
1814 the same for all calls and replies.
1816 If the transport is connectionless, we don't worry
1817 about the address to which the call was sent and from
1818 which the reply was sent, because there's no
1819 guarantee that the reply will come from the address
1820 to which the call was sent. We also don't worry about
1821 the port *from* which the call was sent and *to* which
1822 the reply was sent, because some clients (*cough* OS X
1823 NFS client *cough) might send retransmissions from a
1824 different port from the original request. */
1825 if (pinfo->ptype == PT_TCP) {
1826 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1827 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1828 pinfo->destport, 0);
1831 * XXX - you currently still have to pass a non-null
1832 * pointer for the second address argument even
1833 * if you use NO_ADDR_B.
1835 conversation = find_conversation(pinfo->fd->num, &pinfo->dst,
1836 &null_address, pinfo->ptype, pinfo->srcport,
1837 0, NO_ADDR_B|NO_PORT_B);
1839 if (conversation == NULL) {
1840 /* We haven't seen an RPC call for that conversation,
1841 so we can't check for a reply to that call. */
1845 /* The XIDs of the call and reply must match. */
1846 rpc_call_key.xid = tvb_get_ntohl(tvb, offset + 0);
1847 rpc_call_key.conversation = conversation;
1848 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1849 if (rpc_call == NULL) {
1850 /* The XID doesn't match a call from that
1851 conversation, so it's probably not an RPC reply. */
1853 /* unless we're permitted to scan for embedded records
1854 * and this is a connection-oriented transport, give up */
1855 if ((! rpc_find_fragment_start) || (pinfo->ptype != PT_TCP)) {
1859 /* in parse-partials, so define a dummy conversation for this reply */
1860 new_rpc_call_key = se_alloc(sizeof(rpc_call_info_key));
1861 *new_rpc_call_key = rpc_call_key;
1862 rpc_call = se_alloc(sizeof(rpc_call_info_value));
1863 rpc_call->req_num = 0;
1864 rpc_call->rep_num = pinfo->fd->num;
1868 rpc_call->private_data = NULL;
1869 rpc_call->xid = rpc_call_key.xid;
1870 rpc_call->flavor = FLAVOR_NOT_GSSAPI; /* total punt */
1871 rpc_call->gss_proc = 0;
1872 rpc_call->gss_svc = 0;
1873 rpc_call->proc_info = value;
1874 rpc_call->req_time = pinfo->fd->abs_ts;
1877 g_hash_table_insert(rpc_calls, new_rpc_call_key, rpc_call);
1879 /* and fake up a matching program */
1880 rpc_prog_key.prog = rpc_call->prog;
1883 /* pass rpc_info to subdissectors */
1884 rpc_call->request=FALSE;
1885 pinfo->private_data=rpc_call;
1889 /* The putative message type field contains neither
1890 RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1897 * This is RPC-over-TCP; check if this is the last
1900 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
1902 * This isn't the last fragment.
1903 * If we're doing reassembly, just return
1904 * TRUE to indicate that this looks like
1905 * the beginning of an RPC message,
1906 * and let them do fragment reassembly.
1913 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1914 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1917 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1919 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1922 show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
1927 xid = tvb_get_ntohl(tvb, offset + 0);
1929 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1930 offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1933 msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1935 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1936 offset+4, 4, msg_type);
1937 proto_item_append_text(rpc_item, ", Type:%s XID:0x%08x", msg_type_name, xid);
1945 /* we know already the proto-entry, the ETT-const,
1947 proto = rpc_prog->proto;
1948 proto_id = rpc_prog->proto_id;
1949 ett = rpc_prog->ett;
1950 progname = rpc_prog->progname;
1952 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1954 proto_tree_add_uint(rpc_tree,
1955 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1958 prog = tvb_get_ntohl(tvb, offset + 4);
1961 proto_tree_add_uint_format(rpc_tree,
1962 hf_rpc_program, tvb, offset+4, 4, prog,
1963 "Program: %s (%u)", progname, prog);
1966 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1967 /* Set the protocol name to the underlying
1969 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1972 vers = tvb_get_ntohl(tvb, offset+8);
1974 proto_tree_add_uint(rpc_tree,
1975 hf_rpc_programversion, tvb, offset+8, 4, vers);
1978 proc = tvb_get_ntohl(tvb, offset+12);
1984 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1985 dissect_function = value->dissect_call;
1986 procname = (char *)value->name;
1989 /* happens only with strange program versions or
1990 non-existing dissectors */
1992 dissect_function = NULL;
1994 procname=ep_alloc(20);
1995 g_snprintf(procname, 20, "proc-%u", proc);
1998 /* Check for RPCSEC_GSS and AUTH_GSSAPI */
1999 if (tvb_bytes_exist(tvb, offset+16, 4)) {
2000 switch (tvb_get_ntohl(tvb, offset+16)) {
2004 * It's GSS-API authentication...
2006 if (tvb_bytes_exist(tvb, offset+28, 8)) {
2008 * ...and we have the procedure
2009 * and service information for it.
2011 flavor = FLAVOR_GSSAPI;
2012 gss_proc = tvb_get_ntohl(tvb, offset+28);
2013 gss_svc = tvb_get_ntohl(tvb, offset+36);
2016 * ...but the procedure and service
2017 * information isn't available.
2019 flavor = FLAVOR_GSSAPI_NO_INFO;
2025 * AUTH_GSSAPI flavor. If auth_msg is TRUE,
2026 * then this is an AUTH_GSSAPI message and
2027 * not an application level message.
2029 if (tvb_bytes_exist(tvb, offset+28, 4)) {
2030 if (tvb_get_ntohl(tvb, offset+28)) {
2031 flavor = FLAVOR_AUTHGSSAPI_MSG;
2034 match_strval(gss_proc,
2035 rpc_authgssapi_proc);
2037 flavor = FLAVOR_AUTHGSSAPI;
2044 * It's not GSS-API authentication.
2046 flavor = FLAVOR_NOT_GSSAPI;
2052 proto_tree_add_uint_format(rpc_tree,
2053 hf_rpc_procedure, tvb, offset+12, 4, proc,
2054 "Procedure: %s (%u)", procname, proc);
2057 if (check_col(pinfo->cinfo, COL_INFO)) {
2059 col_clear(pinfo->cinfo, COL_INFO);
2061 col_append_fstr(pinfo->cinfo, COL_INFO, " ; ");
2062 col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2068 /* Keep track of the address whence the call came, and the
2069 port to which the call is being sent, so that we can
2070 match up calls with replies.
2072 If the transport is connection-oriented (we check, for
2073 now, only for "pinfo->ptype" of PT_TCP), we also take
2074 into account the port from which the call was sent
2075 and the address to which the call was sent, because
2076 the addresses and ports of the two endpoints should be
2077 the same for all calls and replies. (XXX - what if
2078 the connection is broken and re-established?)
2080 If the transport is connectionless, we don't worry
2081 about the address to which the call was sent and from
2082 which the reply was sent, because there's no
2083 guarantee that the reply will come from the address
2084 to which the call was sent. We also don't worry about
2085 the port *from* which the call was sent and *to* which
2086 the reply was sent, because some clients (*cough* OS X
2087 NFS client *cough) might send retransmissions from a
2088 different port from the original request. */
2089 if (pinfo->ptype == PT_TCP) {
2090 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
2091 &pinfo->dst, pinfo->ptype, pinfo->srcport,
2092 pinfo->destport, 0);
2095 * XXX - you currently still have to pass a non-null
2096 * pointer for the second address argument even
2097 * if you use NO_ADDR_B.
2099 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
2100 &null_address, pinfo->ptype, pinfo->destport,
2101 0, NO_ADDR_B|NO_PORT_B);
2103 if (conversation == NULL) {
2104 /* It's not part of any conversation - create a new
2106 if (pinfo->ptype == PT_TCP) {
2107 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
2108 &pinfo->dst, pinfo->ptype, pinfo->srcport,
2109 pinfo->destport, 0);
2111 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
2112 &null_address, pinfo->ptype, pinfo->destport,
2113 0, NO_ADDR2|NO_PORT2);
2117 /* Make the dissector for this conversation the non-heuristic
2119 conversation_set_dissector(conversation,
2120 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
2122 /* prepare the key data */
2123 rpc_call_key.xid = xid;
2124 rpc_call_key.conversation = conversation;
2126 /* look up the request */
2127 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
2129 /* We've seen a request with this XID, with the same
2130 source and destination, before - but was it
2132 if (pinfo->fd->num != rpc_call->req_num) {
2133 /* No, so it's a duplicate request.
2135 if (check_col(pinfo->cinfo, COL_INFO)) {
2136 col_prepend_fstr(pinfo->cinfo, COL_INFO,
2137 "[RPC retransmission of #%d]", rpc_call->req_num);
2139 proto_tree_add_item(rpc_tree,
2140 hf_rpc_dup, tvb, 0,0, TRUE);
2141 proto_tree_add_uint(rpc_tree,
2142 hf_rpc_call_dup, tvb, 0,0, rpc_call->req_num);
2144 if(rpc_call->rep_num){
2145 if (check_col(pinfo->cinfo, COL_INFO)) {
2146 col_append_fstr(pinfo->cinfo, COL_INFO," (Reply In %d)", rpc_call->rep_num);
2150 /* Prepare the value data.
2151 "req_num" and "rep_num" are frame numbers;
2152 frame numbers are 1-origin, so we use 0
2153 to mean "we don't yet know in which frame
2154 the reply for this call appears". */
2155 new_rpc_call_key = se_alloc(sizeof(rpc_call_info_key));
2156 *new_rpc_call_key = rpc_call_key;
2157 rpc_call = se_alloc(sizeof(rpc_call_info_value));
2158 rpc_call->req_num = pinfo->fd->num;
2159 rpc_call->rep_num = 0;
2160 rpc_call->prog = prog;
2161 rpc_call->vers = vers;
2162 rpc_call->proc = proc;
2163 rpc_call->private_data = NULL;
2164 rpc_call->xid = xid;
2165 rpc_call->flavor = flavor;
2166 rpc_call->gss_proc = gss_proc;
2167 rpc_call->gss_svc = gss_svc;
2168 rpc_call->proc_info = value;
2169 rpc_call->req_time = pinfo->fd->abs_ts;
2172 g_hash_table_insert(rpc_calls, new_rpc_call_key,
2176 if(rpc_call && rpc_call->rep_num){
2177 proto_tree_add_uint_format(rpc_tree, hf_rpc_repframe,
2178 tvb, 0, 0, rpc_call->rep_num,
2179 "The reply to this request is in frame %u",
2185 offset = dissect_rpc_cred(tvb, rpc_tree, offset);
2186 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2188 /* pass rpc_info to subdissectors */
2189 rpc_call->request=TRUE;
2190 pinfo->private_data=rpc_call;
2192 /* go to the next dissector */
2194 break; /* end of RPC call */
2197 /* we know already the type from the calling routine,
2198 and we already have "rpc_call" set above. */
2199 prog = rpc_call->prog;
2200 vers = rpc_call->vers;
2201 proc = rpc_call->proc;
2202 flavor = rpc_call->flavor;
2203 gss_proc = rpc_call->gss_proc;
2204 gss_svc = rpc_call->gss_svc;
2206 if (rpc_call->proc_info != NULL) {
2207 dissect_function = rpc_call->proc_info->dissect_reply;
2208 if (rpc_call->proc_info->name != NULL) {
2209 procname = (char *)rpc_call->proc_info->name;
2212 procname=ep_alloc(20);
2213 g_snprintf(procname, 20, "proc-%u", proc);
2218 dissect_function = NULL;
2220 procname=ep_alloc(20);
2221 g_snprintf(procname, 20, "proc-%u", proc);
2225 * If this is an AUTH_GSSAPI message, then the RPC procedure
2226 * is not an application procedure, but rather an auth level
2227 * procedure, so it would be misleading to print the RPC
2228 * procname. Replace the RPC procname with the corresponding
2229 * AUTH_GSSAPI procname.
2231 if (flavor == FLAVOR_AUTHGSSAPI_MSG) {
2232 procname = (char *)match_strval(gss_proc, rpc_authgssapi_proc);
2235 rpc_prog_key.prog = prog;
2236 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
2240 progname = "Unknown";
2243 proto = rpc_prog->proto;
2244 proto_id = rpc_prog->proto_id;
2245 ett = rpc_prog->ett;
2246 progname = rpc_prog->progname;
2248 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2249 /* Set the protocol name to the underlying
2251 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
2255 if (check_col(pinfo->cinfo, COL_INFO)) {
2257 col_clear(pinfo->cinfo, COL_INFO);
2259 col_append_fstr(pinfo->cinfo, COL_INFO, " ; ");
2260 col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2267 proto_tree_add_uint_format(rpc_tree,
2268 hf_rpc_program, tvb, 0, 0, prog,
2269 "Program: %s (%u)", progname, prog);
2270 proto_tree_add_uint(rpc_tree,
2271 hf_rpc_programversion, tvb, 0, 0, vers);
2272 proto_tree_add_uint_format(rpc_tree,
2273 hf_rpc_procedure, tvb, 0, 0, proc,
2274 "Procedure: %s (%u)", procname, proc);
2277 reply_state = tvb_get_ntohl(tvb,offset+0);
2279 proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
2280 offset+0, 4, reply_state);
2284 /* Indicate the frame to which this is a reply. */
2285 if(rpc_call && rpc_call->req_num){
2286 proto_tree_add_uint_format(rpc_tree, hf_rpc_reqframe,
2287 tvb, 0, 0, rpc_call->req_num,
2288 "This is a reply to a request in frame %u",
2290 nstime_delta(&ns, &pinfo->fd->abs_ts, &rpc_call->req_time);
2291 proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
2294 if (check_col(pinfo->cinfo, COL_INFO)) {
2295 col_append_fstr(pinfo->cinfo, COL_INFO," (Call In %d)", rpc_call->req_num);
2300 if ((!rpc_call) || (rpc_call->rep_num == 0)) {
2301 /* We have not yet seen a reply to that call, so
2302 this must be the first reply; remember its
2304 rpc_call->rep_num = pinfo->fd->num;
2306 /* We have seen a reply to this call - but was it
2308 if (rpc_call->rep_num != pinfo->fd->num) {
2309 /* No, so it's a duplicate reply.
2311 if (check_col(pinfo->cinfo, COL_INFO)) {
2312 col_prepend_fstr(pinfo->cinfo, COL_INFO,
2313 "[RPC duplicate of #%d]", rpc_call->rep_num);
2315 proto_tree_add_item(rpc_tree,
2316 hf_rpc_dup, tvb, 0,0, TRUE);
2317 proto_tree_add_uint(rpc_tree,
2318 hf_rpc_reply_dup, tvb, 0,0, rpc_call->rep_num);
2322 switch (reply_state) {
2325 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2326 accept_state = tvb_get_ntohl(tvb,offset+0);
2328 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
2329 offset+0, 4, accept_state);
2332 switch (accept_state) {
2335 /* go to the next dissector */
2339 vers_low = tvb_get_ntohl(tvb,offset+0);
2340 vers_high = tvb_get_ntohl(tvb,offset+4);
2342 proto_tree_add_uint(rpc_tree,
2343 hf_rpc_programversion_min,
2344 tvb, offset+0, 4, vers_low);
2345 proto_tree_add_uint(rpc_tree,
2346 hf_rpc_programversion_max,
2347 tvb, offset+4, 4, vers_high);
2352 * There's no protocol reply, so don't
2353 * try to dissect it.
2355 dissect_rpc = FALSE;
2360 * There's no protocol reply, so don't
2361 * try to dissect it.
2363 dissect_rpc = FALSE;
2369 reject_state = tvb_get_ntohl(tvb,offset+0);
2371 proto_tree_add_uint(rpc_tree,
2372 hf_rpc_state_reject, tvb, offset+0, 4,
2377 if (reject_state==RPC_MISMATCH) {
2378 vers_low = tvb_get_ntohl(tvb,offset+0);
2379 vers_high = tvb_get_ntohl(tvb,offset+4);
2381 proto_tree_add_uint(rpc_tree,
2383 tvb, offset+0, 4, vers_low);
2384 proto_tree_add_uint(rpc_tree,
2386 tvb, offset+4, 4, vers_high);
2389 } else if (reject_state==AUTH_ERROR) {
2390 auth_state = tvb_get_ntohl(tvb,offset+0);
2392 proto_tree_add_uint(rpc_tree,
2393 hf_rpc_state_auth, tvb, offset+0, 4,
2400 * There's no protocol reply, so don't
2401 * try to dissect it.
2403 dissect_rpc = FALSE;
2408 * This isn't a valid reply state, so we have
2409 * no clue what's going on; don't try to dissect
2410 * the protocol reply.
2412 dissect_rpc = FALSE;
2415 break; /* end of RPC reply */
2419 * The switch statement at the top returned if
2420 * this was neither an RPC call nor a reply.
2422 DISSECTOR_ASSERT_NOT_REACHED();
2425 /* now we know, that RPC was shorter */
2427 tvb_ensure_bytes_exist(tvb, offset, 0);
2428 proto_item_set_end(rpc_item, tvb, offset);
2433 * There's no RPC call or reply here; just dissect
2434 * whatever's left as data.
2436 call_dissector(data_handle,
2437 tvb_new_subset(tvb, offset, -1, -1), pinfo, rpc_tree);
2441 /* create here the program specific sub-tree */
2442 if (tree && (flavor != FLAVOR_AUTHGSSAPI_MSG)) {
2443 pitem = proto_tree_add_item(tree, proto_id, tvb, offset, -1,
2446 ptree = proto_item_add_subtree(pitem, ett);
2450 proto_tree_add_uint(ptree,
2451 hf_rpc_programversion, tvb, 0, 0, vers);
2452 if (rpc_prog->procedure_hfs->len > vers)
2453 procedure_hf = g_array_index(rpc_prog->procedure_hfs, int, vers);
2456 * No such element in the GArray.
2460 if (procedure_hf != 0 && procedure_hf != -1) {
2461 proto_tree_add_uint(ptree,
2462 procedure_hf, tvb, 0, 0, proc);
2464 proto_tree_add_uint_format(ptree,
2465 hf_rpc_procedure, tvb, 0, 0, proc,
2466 "Procedure: %s (%u)", procname, proc);
2471 /* we must queue this packet to the tap system before we actually
2472 call the subdissectors since short packets (i.e. nfs read reply)
2473 will cause an exception and execution would never reach the call
2474 to tap_queue_packet() in that case
2476 tap_queue_packet(rpc_tap, pinfo, rpc_call);
2478 /* proto==0 if this is an unknown program */
2479 if( (proto==0) || !proto_is_protocol_enabled(proto)){
2480 dissect_function = NULL;
2484 * Handle RPCSEC_GSS and AUTH_GSSAPI specially.
2488 case FLAVOR_UNKNOWN:
2490 * We don't know the authentication flavor, so we can't
2491 * dissect the payload.
2493 proto_tree_add_text(ptree, tvb, offset, -1,
2494 "Unknown authentication flavor - cannot dissect");
2497 case FLAVOR_NOT_GSSAPI:
2499 * It's not GSS-API authentication. Just dissect the
2502 offset = call_dissect_function(tvb, pinfo, ptree, offset,
2503 dissect_function, progname);
2506 case FLAVOR_GSSAPI_NO_INFO:
2508 * It's GSS-API authentication, but we don't have the
2509 * procedure and service information, so we can't dissect
2512 proto_tree_add_text(ptree, tvb, offset, -1,
2513 "GSS-API authentication, but procedure and service unknown - cannot dissect");
2518 * It's GSS-API authentication, and we have the procedure
2519 * and service information; process the GSS-API stuff,
2520 * and process the payload if there is any.
2524 case RPCSEC_GSS_INIT:
2525 case RPCSEC_GSS_CONTINUE_INIT:
2526 if (msg_type == RPC_CALL) {
2527 offset = dissect_rpc_authgss_initarg(tvb,
2528 ptree, offset, pinfo);
2531 offset = dissect_rpc_authgss_initres(tvb,
2532 ptree, offset, pinfo);
2536 case RPCSEC_GSS_DATA:
2537 if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2538 offset = call_dissect_function(tvb,
2539 pinfo, ptree, offset,
2543 else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2544 offset = dissect_rpc_authgss_integ_data(tvb,
2545 pinfo, ptree, offset,
2549 else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2550 offset = dissect_rpc_authgss_priv_data(tvb,
2560 case FLAVOR_AUTHGSSAPI_MSG:
2562 * This is an AUTH_GSSAPI message. It contains data
2563 * only for the authentication procedure and not for the
2564 * application level RPC procedure. Reset the column
2565 * protocol and info fields to indicate that this is
2566 * an RPC auth level message, then process the args.
2568 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2569 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
2571 if (check_col(pinfo->cinfo, COL_INFO)) {
2572 col_clear(pinfo->cinfo, COL_INFO);
2573 col_append_fstr(pinfo->cinfo, COL_INFO,
2575 match_strval(gss_proc, rpc_authgssapi_proc),
2576 msg_type_name, xid);
2581 case AUTH_GSSAPI_INIT:
2582 case AUTH_GSSAPI_CONTINUE_INIT:
2583 case AUTH_GSSAPI_MSG:
2584 if (msg_type == RPC_CALL) {
2585 offset = dissect_rpc_authgssapi_initarg(tvb,
2586 rpc_tree, offset, pinfo);
2588 offset = dissect_rpc_authgssapi_initres(tvb,
2589 rpc_tree, offset, pinfo);
2593 case AUTH_GSSAPI_DESTROY:
2594 offset = dissect_rpc_data(tvb, rpc_tree,
2595 hf_rpc_authgss_data, offset);
2598 case AUTH_GSSAPI_EXIT:
2602 /* Adjust the length to account for the auth message. */
2604 proto_item_set_end(rpc_item, tvb, offset);
2608 case FLAVOR_AUTHGSSAPI:
2610 * An RPC with AUTH_GSSAPI authentication. The data
2611 * portion is always private, so don't call the dissector.
2613 offset = dissect_auth_gssapi_data(tvb, ptree, offset);
2617 if (tvb_length_remaining(tvb, offset) > 0) {
2619 * dissect any remaining bytes (incomplete dissection) as pure
2623 call_dissector(data_handle,
2624 tvb_new_subset(tvb, offset, -1, -1), pinfo, ptree);
2627 /* XXX this should really loop over all fhandles registred for the frame */
2628 if(nfs_fhandle_reqrep_matching){
2629 nfs_fhandle_data_t *fhd;
2632 if(rpc_call && rpc_call->rep_num){
2633 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2634 nfs_fhandle_frame_table,
2635 GINT_TO_POINTER(rpc_call->rep_num));
2637 dissect_fhandle_hidden(pinfo,
2643 if(rpc_call && rpc_call->req_num){
2644 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2645 nfs_fhandle_frame_table,
2646 GINT_TO_POINTER(rpc_call->req_num));
2648 dissect_fhandle_hidden(pinfo,
2660 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2662 return dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2667 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2669 if (!dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2671 if (tvb_length(tvb) != 0)
2672 dissect_rpc_continuation(tvb, pinfo, tree);
2677 /* Defragmentation of RPC-over-TCP records */
2678 /* table to hold defragmented RPC records */
2679 static GHashTable *rpc_fragment_table = NULL;
2681 static GHashTable *rpc_reassembly_table = NULL;
2683 typedef struct _rpc_fragment_key {
2692 rpc_fragment_hash(gconstpointer k)
2694 const rpc_fragment_key *key = (const rpc_fragment_key *)k;
2696 return key->conv_id + key->seq;
2700 rpc_fragment_equal(gconstpointer k1, gconstpointer k2)
2702 const rpc_fragment_key *key1 = (const rpc_fragment_key *)k1;
2703 const rpc_fragment_key *key2 = (const rpc_fragment_key *)k2;
2705 return key1->conv_id == key2->conv_id &&
2706 key1->seq == key2->seq;
2710 show_rpc_fragheader(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2712 proto_item *hdr_item;
2713 proto_tree *hdr_tree;
2717 fraglen = rpc_rm & RPC_RM_FRAGLEN;
2719 hdr_item = proto_tree_add_text(tree, tvb, 0, 4,
2720 "Fragment header: %s%u %s",
2721 (rpc_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
2722 fraglen, plurality(fraglen, "byte", "bytes"));
2723 hdr_tree = proto_item_add_subtree(hdr_item, ett_rpc_fraghdr);
2725 proto_tree_add_boolean(hdr_tree, hf_rpc_lastfrag, tvb, 0, 4,
2727 proto_tree_add_uint(hdr_tree, hf_rpc_fraglen, tvb, 0, 4,
2733 show_rpc_fragment(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2737 * Show the fragment header and the data for the fragment.
2739 show_rpc_fragheader(tvb, tree, rpc_rm);
2740 proto_tree_add_text(tree, tvb, 4, -1, "Fragment Data");
2745 make_frag_tree(tvbuff_t *tvb, proto_tree *tree, int proto, gint ett,
2748 proto_item *frag_item;
2749 proto_tree *frag_tree;
2752 return; /* nothing to do */
2754 frag_item = proto_tree_add_protocol_format(tree, proto, tvb, 0, -1,
2755 "%s Fragment", proto_get_protocol_name(proto));
2756 frag_tree = proto_item_add_subtree(frag_item, ett);
2757 show_rpc_fragment(tvb, frag_tree, rpc_rm);
2761 show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
2762 guint32 rpc_rm, fragment_data *ipfd_head, packet_info *pinfo)
2764 proto_item *frag_tree_item;
2767 return; /* don't do any work */
2769 if (tvb != frag_tvb) {
2771 * This message was not all in one fragment,
2772 * so show the fragment header *and* the data
2773 * for the fragment (which is the last fragment),
2774 * and a tree with information about all fragments.
2776 show_rpc_fragment(frag_tvb, tree, rpc_rm);
2779 * Show a tree with information about all fragments.
2781 show_fragment_tree(ipfd_head, &rpc_frag_items, tree, pinfo, tvb, &frag_tree_item);
2784 * This message was all in one fragment, so just show
2785 * the fragment header.
2787 show_rpc_fragheader(tvb, tree, rpc_rm);
2792 call_message_dissector(tvbuff_t *tvb, tvbuff_t *rec_tvb, packet_info *pinfo,
2793 proto_tree *tree, tvbuff_t *frag_tvb, rec_dissector_t dissector,
2794 fragment_data *ipfd_head, guint32 rpc_rm, gboolean first_pdu)
2796 const char *saved_proto;
2797 volatile gboolean rpc_succeeded;
2800 * Catch the ReportedBoundsError exception; if
2801 * this particular message happens to get a
2802 * ReportedBoundsError exception, that doesn't
2803 * mean that we should stop dissecting RPC
2804 * messages within this frame or chunk of
2807 * If it gets a BoundsError, we can stop, as there's
2808 * nothing more to see, so we just re-throw it.
2810 saved_proto = pinfo->current_proto;
2811 rpc_succeeded = FALSE;
2813 rpc_succeeded = (*dissector)(rec_tvb, pinfo, tree,
2814 frag_tvb, ipfd_head, TRUE, rpc_rm, first_pdu);
2816 CATCH(BoundsError) {
2819 CATCH(ReportedBoundsError) {
2820 show_reported_bounds_error(tvb, pinfo, tree);
2821 pinfo->current_proto = saved_proto;
2824 * We treat this as a "successful" dissection of
2825 * an RPC packet, as "dissect_rpc_message()"
2826 * *did* decide it was an RPC packet, throwing
2827 * an exception while dissecting it as such.
2829 rpc_succeeded = TRUE;
2832 return rpc_succeeded;
2836 dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
2837 proto_tree *tree, rec_dissector_t dissector, gboolean is_heur,
2838 int proto, int ett, gboolean defragment, gboolean first_pdu)
2840 struct tcpinfo *tcpinfo;
2843 volatile guint32 len;
2845 gint tvb_len, tvb_reported_len;
2847 gboolean rpc_succeeded;
2848 gboolean save_fragmented;
2849 rpc_fragment_key old_rfk, *rfk, *new_rfk;
2850 conversation_t *conversation;
2851 fragment_data *ipfd_head;
2854 if (pinfo == NULL || pinfo->private_data == NULL) {
2857 tcpinfo = pinfo->private_data;
2859 if (tcpinfo == NULL) {
2862 seq = tcpinfo->seq + offset;
2865 * Get the record mark.
2867 if (!tvb_bytes_exist(tvb, offset, 4)) {
2869 * XXX - we should somehow arrange to handle
2870 * a record mark split across TCP segments.
2872 return 0; /* not enough to tell if it's valid */
2874 rpc_rm = tvb_get_ntohl(tvb, offset);
2876 len = rpc_rm & RPC_RM_FRAGLEN;
2879 * Do TCP desegmentation, if enabled.
2881 * reject fragments bigger than this preference setting.
2882 * This is arbitrary, but should at least prevent
2883 * some crashes from either packets with really
2884 * large RPC-over-TCP fragments or from stuff that's
2885 * not really valid for this protocol.
2887 if (len > max_rpc_tcp_pdu_size)
2888 return 0; /* pretend it's not valid */
2889 if (rpc_desegment) {
2890 seglen = tvb_length_remaining(tvb, offset + 4);
2892 if ((gint)len > seglen && pinfo->can_desegment) {
2894 * This frame doesn't have all of the
2895 * data for this message, but we can do
2898 * If this is a heuristic dissector, just
2899 * return 0 - we don't want to try to get
2900 * more data, as that's too likely to cause
2901 * us to misidentify this as valid.
2903 * XXX - this means that we won't
2904 * recognize the first fragment of a
2905 * multi-fragment RPC operation unless
2906 * we've already identified this
2907 * conversation as being an RPC
2908 * conversation (and thus aren't running
2909 * heuristically) - that would be a problem
2910 * if, for example, the first segment were
2911 * the beginning of a large NFS WRITE.
2913 * If this isn't a heuristic dissector,
2914 * we've already identified this conversation
2915 * as containing data for this protocol, as we
2916 * saw valid data in previous frames. Try to
2920 return 0; /* not valid */
2922 pinfo->desegment_offset = offset;
2923 pinfo->desegment_len = len - seglen;
2924 return -((gint32) pinfo->desegment_len);
2928 len += 4; /* include record mark */
2929 tvb_len = tvb_length_remaining(tvb, offset);
2930 tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2931 if (tvb_len > (gint)len)
2933 if (tvb_reported_len > (gint)len)
2934 tvb_reported_len = len;
2935 frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2939 * If we're not defragmenting, just hand this to the
2944 * This is the first fragment we've seen, and it's also
2945 * the last fragment; that means the record wasn't
2946 * fragmented. Hand the dissector the tvbuff for the
2947 * fragment as the tvbuff for the record.
2953 * Mark this as fragmented, so if somebody throws an
2954 * exception, we don't report it as a malformed frame.
2956 save_fragmented = pinfo->fragmented;
2957 pinfo->fragmented = TRUE;
2958 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
2959 tree, frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu);
2960 pinfo->fragmented = save_fragmented;
2962 return 0; /* not RPC */
2967 * First, we check to see if this fragment is part of a record
2968 * that we're in the process of defragmenting.
2970 * The key is the conversation ID for the conversation to which
2971 * the packet belongs and the current sequence number.
2972 * We must first find the conversation and, if we don't find
2973 * one, create it. We know this is running over TCP, so the
2974 * conversation should not wildcard either address or port.
2976 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2977 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2978 if (conversation == NULL) {
2980 * It's not part of any conversation - create a new one.
2982 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2983 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2985 old_rfk.conv_id = conversation->index;
2987 rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
2991 * This fragment was not found in our table, so it doesn't
2992 * contain a continuation of a higher-level PDU.
2993 * Is it the last fragment?
2995 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2997 * This isn't the last fragment, so we don't
2998 * have the complete record.
3000 * It's the first fragment we've seen, so if
3001 * it's truly the first fragment of the record,
3002 * and it has enough data, the dissector can at
3003 * least check whether it looks like a valid
3004 * message, as it contains the start of the
3007 * The dissector should not dissect anything
3008 * if the "last fragment" flag isn't set in
3009 * the record marker, so it shouldn't throw
3012 if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
3013 NULL, TRUE, rpc_rm, first_pdu))
3014 return 0; /* not valid */
3017 * OK, now start defragmentation with that
3018 * fragment. Add this fragment, and set up
3019 * next packet/sequence number as well.
3021 * We must remember this fragment.
3024 rfk = se_alloc(sizeof(rpc_fragment_key));
3025 rfk->conv_id = conversation->index;
3028 rfk->start_seq = seq;
3029 g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
3032 * Start defragmentation.
3034 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4,
3035 pinfo, rfk->start_seq, rpc_fragment_table,
3036 rfk->offset, len - 4, TRUE);
3039 * Make sure that defragmentation isn't complete;
3040 * it shouldn't be, as this is the first fragment
3041 * we've seen, and the "last fragment" bit wasn't
3044 if (ipfd_head == NULL) {
3045 new_rfk = se_alloc(sizeof(rpc_fragment_key));
3046 new_rfk->conv_id = rfk->conv_id;
3047 new_rfk->seq = seq + len;
3048 new_rfk->offset = rfk->offset + len - 4;
3049 new_rfk->start_seq = rfk->start_seq;
3050 g_hash_table_insert(rpc_reassembly_table, new_rfk,
3054 * This is part of a fragmented record,
3055 * but it's not the first part.
3056 * Show it as a record marker plus data, under
3057 * a top-level tree for this protocol.
3059 make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
3062 * No more processing need be done, as we don't
3063 * have a complete record.
3067 /* oddly, we have a first fragment, not marked as last,
3068 * but which the defragmenter thinks is complete.
3069 * So rather than creating a fragment reassembly tree,
3070 * we simply throw away the partial fragment structure
3071 * and fall though to our "sole fragment" processing below.
3077 * This is the first fragment we've seen, and it's also
3078 * the last fragment; that means the record wasn't
3079 * fragmented. Hand the dissector the tvbuff for the
3080 * fragment as the tvbuff for the record.
3086 * OK, this fragment was found, which means it continues
3087 * a record. This means we must defragment it.
3088 * Add it to the defragmentation lists.
3090 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4, pinfo,
3091 rfk->start_seq, rpc_fragment_table,
3092 rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
3094 if (ipfd_head == NULL) {
3096 * fragment_add_multiple_ok() returned NULL.
3097 * This means that defragmentation is not
3100 * We must add an entry to the hash table with
3101 * the sequence number following this fragment
3102 * as the starting sequence number, so that when
3103 * we see that fragment we'll find that entry.
3105 * XXX - as TCP stream data is not currently
3106 * guaranteed to be provided in order to dissectors,
3107 * RPC fragments aren't guaranteed to be provided
3110 new_rfk = se_alloc(sizeof(rpc_fragment_key));
3111 new_rfk->conv_id = rfk->conv_id;
3112 new_rfk->seq = seq + len;
3113 new_rfk->offset = rfk->offset + len - 4;
3114 new_rfk->start_seq = rfk->start_seq;
3115 g_hash_table_insert(rpc_reassembly_table, new_rfk,
3119 * This is part of a fragmented record,
3120 * but it's not the first part.
3121 * Show it as a record marker plus data, under
3122 * a top-level tree for this protocol,
3123 * but don't hand it to the dissector
3125 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3128 * No more processing need be done, as we don't
3129 * have a complete record.
3135 * It's completely defragmented.
3137 * We only call subdissector for the last fragment.
3138 * XXX - this assumes in-order delivery of RPC
3139 * fragments, which requires in-order delivery of TCP
3142 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
3144 * Well, it's defragmented, but this isn't
3145 * the last fragment; this probably means
3146 * this isn't the first pass, so we don't
3147 * need to start defragmentation.
3149 * This is part of a fragmented record,
3150 * but it's not the first part.
3151 * Show it as a record marker plus data, under
3152 * a top-level tree for this protocol,
3153 * but don't show it to the dissector.
3155 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3158 * No more processing need be done, as we
3159 * only disssect the data with the last
3166 * OK, this is the last segment.
3167 * Create a tvbuff for the defragmented
3172 * Create a new TVB structure for
3173 * defragmented data.
3175 rec_tvb = tvb_new_real_data(ipfd_head->data,
3176 ipfd_head->datalen, ipfd_head->datalen);
3179 * Add this tvb as a child to the original
3182 tvb_set_child_real_data_tvbuff(tvb, rec_tvb);
3185 * Add defragmented data to the data source list.
3187 add_new_data_source(pinfo, rec_tvb, "Defragmented");
3191 * We have something to hand to the RPC message
3194 if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
3195 frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu))
3196 return 0; /* not RPC */
3198 } /* end of dissect_rpc_fragment() */
3201 * Scans tvb, starting at given offset, to see if we can find
3202 * what looks like a valid RPC-over-TCP reply header.
3204 * @param tvb Buffer to inspect for RPC reply header.
3205 * @param offset Offset to begin search of tvb at.
3207 * @return -1 if no reply header found, else offset to start of header
3208 * (i.e., to the RPC record mark field).
3212 find_rpc_over_tcp_reply_start(tvbuff_t *tvb, int offset)
3216 * Looking for partial header sequence. From beginning of
3217 * stream-style header, including "record mark", full ONC-RPC
3219 * BE int32 record mark (rfc 1831 sec. 10)
3220 * ? int32 XID (rfc 1831 sec. 8)
3221 * BE int32 msg_type (ibid sec. 8, call = 0, reply = 1)
3223 * -------------------------------------------------------------
3224 * Then reply-specific fields are
3225 * BE int32 reply_stat (ibid, accept = 0, deny = 1)
3227 * Then, assuming accepted,
3229 * BE int32 auth_flavor (ibid, none = 0)
3230 * BE int32 ? auth_len (ibid, none = 0)
3232 * BE int32 accept_stat (ibid, success = 0, errs are 1..5 in rpc v2)
3234 * -------------------------------------------------------------
3235 * Or, call-specific fields are
3236 * BE int32 rpc_vers (rfc 1831 sec 8, always == 2)
3237 * BE int32 prog (NFS == 000186A3)
3238 * BE int32 prog_ver (NFS v2/3 == 2 or 3)
3239 * BE int32 proc_id (NFS, <= 256 ???)
3244 /* Initially, we search only for something matching the template
3245 * of a successful reply with no auth verifier.
3246 * Our first qualification test is search for a string of zero bytes,
3247 * corresponding the four guint32 values
3253 * If this string of zeros matches, then we go back and check the
3254 * preceding msg_type and record_mark fields.
3257 const gint cbZeroTail = 4 * 4; /* four guint32s of zeros */
3258 const gint ibPatternStart = 3 * 4; /* offset of zero fill from reply start */
3259 const guint8 * pbWholeBuf; /* all of tvb, from offset onwards */
3260 const int NoMatch = -1;
3262 gint ibSearchStart; /* offset of search start, in case of false hits. */
3264 const guint8 * pbBuf;
3266 gint cbInBuf; /* bytes in tvb, from offset onwards */
3274 cbInBuf = tvb_reported_length_remaining(tvb, offset);
3276 /* start search at first possible location */
3277 ibSearchStart = ibPatternStart;
3279 if (cbInBuf < (cbZeroTail + ibSearchStart)) {
3280 /* nothing to search, so claim no RPC */
3284 pbWholeBuf = tvb_get_ptr(tvb, offset, cbInBuf);
3285 if (pbWholeBuf == NULL) {
3286 /* probably never take this, as get_ptr seems to assert */
3290 while ((cbInBuf - ibSearchStart) > cbZeroTail) {
3291 /* First test for long tail of zeros, starting at the back.
3292 * A failure lets us skip the maximum possible buffer amount.
3294 pbBuf = pbWholeBuf + ibSearchStart + cbZeroTail - 1;
3295 for (i = cbZeroTail; i > 0; i --)
3299 /* match failure. Since we need N contiguous zeros,
3300 * we can increment next match start so zero testing
3301 * begins right after this failure spot.
3311 if (pbBuf == NULL) {
3315 /* got a match in zero-fill region, verify reply ID and
3316 * record mark fields */
3317 ulMsgType = pntohl (pbWholeBuf + ibSearchStart - 4);
3318 ulRecMark = pntohl (pbWholeBuf + ibSearchStart - ibPatternStart);
3320 if ((ulMsgType == RPC_REPLY) &&
3321 ((ulRecMark & ~0x80000000) <= (unsigned) max_rpc_tcp_pdu_size)) {
3322 /* looks ok, try dissect */
3323 return (offset + ibSearchStart - ibPatternStart);
3326 /* no match yet, nor egregious miss either. Inch along to next try */
3332 } /* end of find_rpc_over_tcp_reply_start() */
3335 * Scans tvb for what looks like a valid RPC call / reply header.
3336 * If found, calls standard dissect_rpc_fragment() logic to digest
3337 * the (hopefully valid) fragment.
3339 * With any luck, one invocation of this will be sufficient to get
3340 * us back in alignment with the stream, and no further calls to
3341 * this routine will be needed for a given conversation. As if. :-)
3344 * Same as dissect_rpc_fragment(). Will return zero (no frame)
3345 * if no valid RPC header is found.
3349 find_and_dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
3350 proto_tree *tree, rec_dissector_t dissector,
3352 int proto, int ett, gboolean defragment)
3359 offReply = find_rpc_over_tcp_reply_start(tvb, offset);
3361 /* could search for request, but not needed (or testable) thus far */
3362 return (0); /* claim no RPC */
3365 len = dissect_rpc_fragment(tvb, offReply,
3367 dissector, is_heur, proto, ett,
3369 TRUE /* force first-pdu state */);
3371 /* misses are reported as-is */
3377 /* returning a non-zero length, correct it to reflect the extra offset
3378 * we found necessary
3381 len += offReply - offset;
3384 /* negative length seems to only be used as a flag,
3385 * don't mess it up until found necessary
3387 /* len -= offReply - offset; */
3392 } /* end of find_and_dissect_rpc_fragment */
3398 * NEED_MORE_DATA, if we don't have enough data to dissect anything;
3400 * IS_RPC, if we dissected at least one message in its entirety
3403 * IS_NOT_RPC, if we found no RPC message.
3411 static rpc_tcp_return_t
3412 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3416 gboolean saw_rpc = FALSE;
3417 gboolean first_pdu = TRUE;
3420 while (tvb_reported_length_remaining(tvb, offset) != 0) {
3422 * Process this fragment.
3424 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
3425 dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
3426 rpc_defragment, first_pdu);
3428 if ((len == 0) && first_pdu && rpc_find_fragment_start) {
3430 * Try discarding some leading bytes from tvb, on assumption
3431 * that we are looking at the middle of a stream-based transfer
3433 len = find_and_dissect_rpc_fragment(tvb, offset, pinfo, tree,
3434 dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
3441 * We need more data from the TCP stream for
3444 return NEED_MORE_DATA;
3448 * It's not RPC. Stop processing.
3454 If the length indicates that the PDU continues beyond
3455 the end of this tvb, then tell TCP about it so that it
3456 knows where the next PDU starts.
3457 This is to help TCP detect when PDUs are not aligned to
3458 segment boundaries and allow it to find RPC headers
3459 that starts in the middle of a TCP segment.
3461 if(!pinfo->fd->flags.visited){
3462 if(len>tvb_reported_length_remaining(tvb, offset)){
3463 pinfo->want_pdu_tracking=2;
3464 pinfo->bytes_until_next_pdu=len-tvb_reported_length_remaining(tvb, offset);
3470 return saw_rpc ? IS_RPC : IS_NOT_RPC;
3474 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3476 switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
3485 /* "Can't happen" */
3486 DISSECTOR_ASSERT_NOT_REACHED();
3492 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3494 if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
3495 dissect_rpc_continuation(tvb, pinfo, tree);
3498 /* Discard any state we've saved. */
3500 rpc_init_protocol(void)
3502 if (rpc_calls != NULL) {
3503 g_hash_table_destroy(rpc_calls);
3506 if (rpc_indir_calls != NULL) {
3507 g_hash_table_destroy(rpc_indir_calls);
3508 rpc_indir_calls = NULL;
3510 if (rpc_reassembly_table != NULL) {
3511 g_hash_table_destroy(rpc_reassembly_table);
3512 rpc_reassembly_table = NULL;
3515 rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3516 rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3517 rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
3518 rpc_fragment_equal);
3520 fragment_table_init(&rpc_fragment_table);
3523 /* will be called once from register.c at startup time */
3525 proto_register_rpc(void)
3527 static hf_register_info hf[] = {
3528 { &hf_rpc_reqframe, {
3529 "Request Frame", "rpc.reqframe", FT_FRAMENUM, BASE_NONE,
3530 NULL, 0, "Request Frame", HFILL }},
3531 { &hf_rpc_repframe, {
3532 "Reply Frame", "rpc.repframe", FT_FRAMENUM, BASE_NONE,
3533 NULL, 0, "Reply Frame", HFILL }},
3534 { &hf_rpc_lastfrag, {
3535 "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
3536 &yesno, RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
3537 { &hf_rpc_fraglen, {
3538 "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
3539 NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
3541 "XID", "rpc.xid", FT_UINT32, BASE_HEX,
3542 NULL, 0, "XID", HFILL }},
3543 { &hf_rpc_msgtype, {
3544 "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
3545 VALS(rpc_msg_type), 0, "Message Type", HFILL }},
3546 { &hf_rpc_state_reply, {
3547 "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
3548 VALS(rpc_reply_state), 0, "Reply State", HFILL }},
3549 { &hf_rpc_state_accept, {
3550 "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
3551 VALS(rpc_accept_state), 0, "Accept State", HFILL }},
3552 { &hf_rpc_state_reject, {
3553 "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
3554 VALS(rpc_reject_state), 0, "Reject State", HFILL }},
3555 { &hf_rpc_state_auth, {
3556 "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
3557 VALS(rpc_auth_state), 0, "Auth State", HFILL }},
3558 { &hf_rpc_version, {
3559 "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
3560 NULL, 0, "RPC Version", HFILL }},
3561 { &hf_rpc_version_min, {
3562 "RPC Version (Minimum)", "rpc.version.min", FT_UINT32,
3563 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3564 { &hf_rpc_version_max, {
3565 "RPC Version (Maximum)", "rpc.version.max", FT_UINT32,
3566 BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
3567 { &hf_rpc_program, {
3568 "Program", "rpc.program", FT_UINT32, BASE_DEC,
3569 NULL, 0, "Program", HFILL }},
3570 { &hf_rpc_programversion, {
3571 "Program Version", "rpc.programversion", FT_UINT32,
3572 BASE_DEC, NULL, 0, "Program Version", HFILL }},
3573 { &hf_rpc_programversion_min, {
3574 "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32,
3575 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3576 { &hf_rpc_programversion_max, {
3577 "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32,
3578 BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
3579 { &hf_rpc_procedure, {
3580 "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
3581 NULL, 0, "Procedure", HFILL }},
3582 { &hf_rpc_auth_flavor, {
3583 "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
3584 VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
3585 { &hf_rpc_auth_length, {
3586 "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
3587 NULL, 0, "Length", HFILL }},
3588 { &hf_rpc_auth_stamp, {
3589 "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
3590 NULL, 0, "Stamp", HFILL }},
3591 { &hf_rpc_auth_uid, {
3592 "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
3593 NULL, 0, "UID", HFILL }},
3594 { &hf_rpc_auth_gid, {
3595 "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
3596 NULL, 0, "GID", HFILL }},
3597 { &hf_rpc_authgss_v, {
3598 "GSS Version", "rpc.authgss.version", FT_UINT32,
3599 BASE_DEC, NULL, 0, "GSS Version", HFILL }},
3600 { &hf_rpc_authgss_proc, {
3601 "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
3602 BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
3603 { &hf_rpc_authgss_seq, {
3604 "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
3605 BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
3606 { &hf_rpc_authgss_svc, {
3607 "GSS Service", "rpc.authgss.service", FT_UINT32,
3608 BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
3609 { &hf_rpc_authgss_ctx, {
3610 "GSS Context", "rpc.authgss.context", FT_BYTES,
3611 BASE_HEX, NULL, 0, "GSS Context", HFILL }},
3612 { &hf_rpc_authgss_major, {
3613 "GSS Major Status", "rpc.authgss.major", FT_UINT32,
3614 BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
3615 { &hf_rpc_authgss_minor, {
3616 "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
3617 BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
3618 { &hf_rpc_authgss_window, {
3619 "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
3620 BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
3621 { &hf_rpc_authgss_token_length, {
3622 "GSS Token Length", "rpc.authgss.token_length", FT_UINT32,
3623 BASE_DEC, NULL, 0, "GSS Token Length", HFILL }},
3624 { &hf_rpc_authgss_data_length, {
3625 "Length", "rpc.authgss.data.length", FT_UINT32,
3626 BASE_DEC, NULL, 0, "Length", HFILL }},
3627 { &hf_rpc_authgss_data, {
3628 "GSS Data", "rpc.authgss.data", FT_BYTES,
3629 BASE_HEX, NULL, 0, "GSS Data", HFILL }},
3630 { &hf_rpc_authgss_checksum, {
3631 "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
3632 BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
3633 { &hf_rpc_authgssapi_v, {
3634 "AUTH_GSSAPI Version", "rpc.authgssapi.version",
3635 FT_UINT32, BASE_DEC, NULL, 0, "AUTH_GSSAPI Version",
3637 { &hf_rpc_authgssapi_msg, {
3638 "AUTH_GSSAPI Message", "rpc.authgssapi.message",
3639 FT_BOOLEAN, BASE_NONE, &yesno, 0, "AUTH_GSSAPI Message",
3641 { &hf_rpc_authgssapi_msgv, {
3642 "Msg Version", "rpc.authgssapi.msgversion",
3643 FT_UINT32, BASE_DEC, NULL, 0, "Msg Version",
3645 { &hf_rpc_authgssapi_handle, {
3646 "Client Handle", "rpc.authgssapi.handle",
3647 FT_BYTES, BASE_HEX, NULL, 0, "Client Handle", HFILL }},
3648 { &hf_rpc_authgssapi_isn, {
3649 "Signed ISN", "rpc.authgssapi.isn",
3650 FT_BYTES, BASE_HEX, NULL, 0, "Signed ISN", HFILL }},
3651 { &hf_rpc_authdes_namekind, {
3652 "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
3653 VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
3654 { &hf_rpc_authdes_netname, {
3655 "Netname", "rpc.authdes.netname", FT_STRING,
3656 BASE_DEC, NULL, 0, "Netname", HFILL }},
3657 { &hf_rpc_authdes_convkey, {
3658 "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
3659 BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
3660 { &hf_rpc_authdes_window, {
3661 "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
3662 BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
3663 { &hf_rpc_authdes_nickname, {
3664 "Nickname", "rpc.authdes.nickname", FT_UINT32,
3665 BASE_HEX, NULL, 0, "Nickname", HFILL }},
3666 { &hf_rpc_authdes_timestamp, {
3667 "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
3668 BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
3669 { &hf_rpc_authdes_windowverf, {
3670 "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
3671 BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
3672 { &hf_rpc_authdes_timeverf, {
3673 "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
3674 BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
3675 { &hf_rpc_auth_machinename, {
3676 "Machine Name", "rpc.auth.machinename", FT_STRING,
3677 BASE_DEC, NULL, 0, "Machine Name", HFILL }},
3679 "Duplicate Call/Reply", "rpc.dup", FT_NONE, BASE_NONE,
3680 NULL, 0, "Duplicate Call/Reply", HFILL }},
3681 { &hf_rpc_call_dup, {
3682 "Duplicate to the call in", "rpc.call.dup", FT_FRAMENUM, BASE_DEC,
3683 NULL, 0, "This is a duplicate to the call in frame", HFILL }},
3684 { &hf_rpc_reply_dup, {
3685 "Duplicate to the reply in", "rpc.reply.dup", FT_FRAMENUM, BASE_DEC,
3686 NULL, 0, "This is a duplicate to the reply in frame", HFILL }},
3687 { &hf_rpc_value_follows, {
3688 "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
3689 &yesno, 0, "Value Follows", HFILL }},
3690 { &hf_rpc_array_len, {
3691 "num", "rpc.array.len", FT_UINT32, BASE_DEC,
3692 NULL, 0, "Length of RPC array", HFILL }},
3695 "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
3696 NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
3698 { &hf_rpc_fragment_overlap,
3699 { "Fragment overlap", "rpc.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3700 "Fragment overlaps with other fragments", HFILL }},
3702 { &hf_rpc_fragment_overlap_conflict,
3703 { "Conflicting data in fragment overlap", "rpc.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3704 "Overlapping fragments contained conflicting data", HFILL }},
3706 { &hf_rpc_fragment_multiple_tails,
3707 { "Multiple tail fragments found", "rpc.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3708 "Several tails were found when defragmenting the packet", HFILL }},
3710 { &hf_rpc_fragment_too_long_fragment,
3711 { "Fragment too long", "rpc.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3712 "Fragment contained data past end of packet", HFILL }},
3714 { &hf_rpc_fragment_error,
3715 { "Defragmentation error", "rpc.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3716 "Defragmentation error due to illegal fragments", HFILL }},
3719 { "RPC Fragment", "rpc.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3720 "RPC Fragment", HFILL }},
3722 { &hf_rpc_fragments,
3723 { "RPC Fragments", "rpc.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3724 "RPC Fragments", HFILL }},
3726 static gint *ett[] = {
3738 &ett_rpc_authgssapi_msg,
3739 &ett_rpc_unknown_program,
3741 module_t *rpc_module;
3743 proto_rpc = proto_register_protocol("Remote Procedure Call",
3745 /* this is a dummy dissector for all those unknown rpc programs */
3746 proto_register_field_array(proto_rpc, hf, array_length(hf));
3747 proto_register_subtree_array(ett, array_length(ett));
3748 register_init_routine(&rpc_init_protocol);
3750 rpc_module = prefs_register_protocol(proto_rpc, NULL);
3751 prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
3752 "Reassemble RPC over TCP messages\nspanning multiple TCP segments",
3753 "Whether the RPC dissector should reassemble messages spanning multiple TCP segments."
3754 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3756 prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
3757 "Reassemble fragmented RPC-over-TCP messages",
3758 "Whether the RPC dissector should defragment RPC-over-TCP messages.",
3761 prefs_register_uint_preference(rpc_module, "max_tcp_pdu_size", "Maximum size of a RPC-over-TCP PDU",
3762 "Set the maximum size of RPCoverTCP PDUs. "
3763 " If the size field of the record marker is larger "
3764 "than this value it will not be considered a valid RPC PDU.",
3765 10, &max_rpc_tcp_pdu_size);
3767 prefs_register_bool_preference(rpc_module, "dissect_unknown_programs",
3768 "Dissect unknown RPC program numbers",
3769 "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.",
3770 &rpc_dissect_unknown_programs);
3772 prefs_register_bool_preference(rpc_module, "find_fragment_start",
3773 "Attempt to locate start-of-fragment in partial RPC-over-TCP captures",
3774 "Whether the RPC dissector should attempt to locate RPC PDU boundaries when initial fragment alignment is not known. This may cause false positives, or slow operation.",
3775 &rpc_find_fragment_start);
3777 register_dissector("rpc", dissect_rpc, proto_rpc);
3778 rpc_handle = find_dissector("rpc");
3779 register_dissector("rpc-tcp", dissect_rpc_tcp, proto_rpc);
3780 rpc_tcp_handle = find_dissector("rpc-tcp");
3781 rpc_tap = register_tap("rpc");
3784 * Init the hash tables. Dissectors for RPC protocols must
3785 * have a "handoff registration" routine that registers the
3786 * protocol with RPC; they must not do it in their protocol
3787 * registration routine, as their protocol registration
3788 * routine might be called before this routine is called and
3789 * thus might be called before the hash tables are initialized,
3790 * but it's guaranteed that all protocol registration routines
3791 * will be called before any handoff registration routines
3794 rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
3795 rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
3799 proto_reg_handoff_rpc(void)
3801 dissector_handle_t rpc_tcp_handle;
3802 dissector_handle_t rpc_udp_handle;
3804 /* tcp/udp port 111 is used by portmapper which is an onc-rpc service.
3805 we register onc-rpc on this port so that we can choose RPC in
3806 the list offered by DecodeAs, and so that traffic to or from
3807 port 111 from or to a higher-numbered port is dissected as RPC
3808 even if there's a dissector registered on the other port (it's
3809 probably RPC traffic from some randomly-chosen port that happens
3810 to match some port for which we have a dissector)
3812 rpc_tcp_handle = create_dissector_handle(dissect_rpc_tcp, proto_rpc);
3813 dissector_add("tcp.port", 111, rpc_tcp_handle);
3814 rpc_udp_handle = create_dissector_handle(dissect_rpc, proto_rpc);
3815 dissector_add("udp.port", 111, rpc_udp_handle);
3817 heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
3818 heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
3819 gssapi_handle = find_dissector("gssapi");
3820 data_handle = find_dissector("data");