2 * Routines for rpc dissection
3 * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
5 * $Id: packet-rpc.c,v 1.97 2002/06/07 10:11:39 guy Exp $
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.
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
40 #include <epan/packet.h>
41 #include <epan/conversation.h>
42 #include "packet-rpc.h"
43 #include "packet-frame.h"
44 #include "packet-tcp.h"
46 #include "reassemble.h"
47 #include "rpc_defrag.h"
48 #include "packet-nfs.h"
53 * RFC 1831, "RPC: Remote Procedure Call Protocol Specification
56 * RFC 1832, "XDR: External Data Representation Standard";
58 * RFC 2203, "RPCSEC_GSS Protocol Specification".
62 * RFC 2695, "Authentication Mechanisms for ONC RPC"
64 * although we don't currently dissect AUTH_DES or AUTH_KERB.
67 /* desegmentation of RPC over TCP */
68 static gboolean rpc_desegment = TRUE;
70 /* defragmentation of fragmented RPC over TCP records */
71 static gboolean rpc_defragment = FALSE;
73 static struct true_false_string yesno = { "Yes", "No" };
76 static const value_string rpc_msg_type[] = {
78 { RPC_REPLY, "Reply" },
82 static const value_string rpc_reply_state[] = {
83 { MSG_ACCEPTED, "accepted" },
84 { MSG_DENIED, "denied" },
88 const value_string rpc_auth_flavor[] = {
89 { AUTH_NULL, "AUTH_NULL" },
90 { AUTH_UNIX, "AUTH_UNIX" },
91 { AUTH_SHORT, "AUTH_SHORT" },
92 { AUTH_DES, "AUTH_DES" },
93 { RPCSEC_GSS, "RPCSEC_GSS" },
97 static const value_string rpc_authgss_proc[] = {
98 { RPCSEC_GSS_DATA, "RPCSEC_GSS_DATA" },
99 { RPCSEC_GSS_INIT, "RPCSEC_GSS_INIT" },
100 { RPCSEC_GSS_CONTINUE_INIT, "RPCSEC_GSS_CONTINUE_INIT" },
101 { RPCSEC_GSS_DESTROY, "RPCSEC_GSS_DESTROY" },
105 value_string rpc_authgss_svc[] = {
106 { RPCSEC_GSS_SVC_NONE, "rpcsec_gss_svc_none" },
107 { RPCSEC_GSS_SVC_INTEGRITY, "rpcsec_gss_svc_integrity" },
108 { RPCSEC_GSS_SVC_PRIVACY, "rpcsec_gss_svc_privacy" },
112 static const value_string rpc_accept_state[] = {
113 { SUCCESS, "RPC executed successfully" },
114 { PROG_UNAVAIL, "remote hasn't exported program" },
115 { PROG_MISMATCH, "remote can't support version #" },
116 { PROC_UNAVAIL, "program can't support procedure" },
117 { GARBAGE_ARGS, "procedure can't decode params" },
121 static const value_string rpc_reject_state[] = {
122 { RPC_MISMATCH, "RPC_MISMATCH" },
123 { AUTH_ERROR, "AUTH_ERROR" },
127 static const value_string rpc_auth_state[] = {
128 { AUTH_BADCRED, "bad credential (seal broken)" },
129 { AUTH_REJECTEDCRED, "client must begin new session" },
130 { AUTH_BADVERF, "bad verifier (seal broken)" },
131 { AUTH_REJECTEDVERF, "verifier expired or replayed" },
132 { AUTH_TOOWEAK, "rejected for security reasons" },
133 { RPCSEC_GSSCREDPROB, "GSS credential problem" },
134 { RPCSEC_GSSCTXPROB, "GSS context problem" },
138 static const value_string rpc_authdes_namekind[] = {
139 { AUTHDES_NAMEKIND_FULLNAME, "ADN_FULLNAME" },
140 { AUTHDES_NAMEKIND_NICKNAME, "ADN_NICKNAME" },
144 /* the protocol number */
145 static int proto_rpc = -1;
146 static int hf_rpc_lastfrag = -1;
147 static int hf_rpc_fraglen = -1;
148 static int hf_rpc_xid = -1;
149 static int hf_rpc_msgtype = -1;
150 static int hf_rpc_version = -1;
151 static int hf_rpc_version_min = -1;
152 static int hf_rpc_version_max = -1;
153 static int hf_rpc_program = -1;
154 static int hf_rpc_programversion = -1;
155 static int hf_rpc_programversion_min = -1;
156 static int hf_rpc_programversion_max = -1;
157 static int hf_rpc_procedure = -1;
158 static int hf_rpc_auth_flavor = -1;
159 static int hf_rpc_auth_length = -1;
160 static int hf_rpc_auth_machinename = -1;
161 static int hf_rpc_auth_stamp = -1;
162 static int hf_rpc_auth_uid = -1;
163 static int hf_rpc_auth_gid = -1;
164 static int hf_rpc_authgss_v = -1;
165 static int hf_rpc_authgss_proc = -1;
166 static int hf_rpc_authgss_seq = -1;
167 static int hf_rpc_authgss_svc = -1;
168 static int hf_rpc_authgss_ctx = -1;
169 static int hf_rpc_authgss_major = -1;
170 static int hf_rpc_authgss_minor = -1;
171 static int hf_rpc_authgss_window = -1;
172 static int hf_rpc_authgss_token = -1;
173 static int hf_rpc_authgss_data_length = -1;
174 static int hf_rpc_authgss_data = -1;
175 static int hf_rpc_authgss_checksum = -1;
176 static int hf_rpc_authdes_namekind = -1;
177 static int hf_rpc_authdes_netname = -1;
178 static int hf_rpc_authdes_convkey = -1;
179 static int hf_rpc_authdes_window = -1;
180 static int hf_rpc_authdes_nickname = -1;
181 static int hf_rpc_authdes_timestamp = -1;
182 static int hf_rpc_authdes_windowverf = -1;
183 static int hf_rpc_authdes_timeverf = -1;
184 static int hf_rpc_state_accept = -1;
185 static int hf_rpc_state_reply = -1;
186 static int hf_rpc_state_reject = -1;
187 static int hf_rpc_state_auth = -1;
188 static int hf_rpc_dup = -1;
189 static int hf_rpc_call_dup = -1;
190 static int hf_rpc_reply_dup = -1;
191 static int hf_rpc_value_follows = -1;
192 static int hf_rpc_array_len = -1;
193 static int hf_rpc_time = -1;
194 static int hf_rpc_fragments = -1;
195 static int hf_rpc_fragment = -1;
196 static int hf_rpc_fragment_overlap = -1;
197 static int hf_rpc_fragment_overlap_conflict = -1;
198 static int hf_rpc_fragment_multiple_tails = -1;
199 static int hf_rpc_fragment_too_long_fragment = -1;
200 static int hf_rpc_fragment_error = -1;
202 static gint ett_rpc = -1;
203 static gint ett_rpc_fragments = -1;
204 static gint ett_rpc_fragment = -1;
205 static gint ett_rpc_fraghdr = -1;
206 static gint ett_rpc_string = -1;
207 static gint ett_rpc_cred = -1;
208 static gint ett_rpc_verf = -1;
209 static gint ett_rpc_gids = -1;
210 static gint ett_rpc_gss_data = -1;
211 static gint ett_rpc_array = -1;
213 static dissector_handle_t rpc_tcp_handle;
214 static dissector_handle_t rpc_handle;
215 static dissector_handle_t data_handle;
217 fragment_items rpc_frag_items = {
222 &hf_rpc_fragment_overlap,
223 &hf_rpc_fragment_overlap_conflict,
224 &hf_rpc_fragment_multiple_tails,
225 &hf_rpc_fragment_too_long_fragment,
226 &hf_rpc_fragment_error,
230 /* Hash table with info on RPC program numbers */
231 static GHashTable *rpc_progs;
233 /* Hash table with info on RPC procedure numbers */
234 static GHashTable *rpc_procs;
236 typedef struct _rpc_proc_info_key {
242 typedef struct _rpc_proc_info_value {
244 dissect_function_t *dissect_call;
245 dissect_function_t *dissect_reply;
246 } rpc_proc_info_value;
248 typedef struct _rpc_prog_info_key {
252 typedef struct _rpc_prog_info_value {
256 } rpc_prog_info_value;
258 static void dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
259 static void dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
261 /***********************************/
262 /* Hash array with procedure names */
263 /***********************************/
267 rpc_proc_equal(gconstpointer k1, gconstpointer k2)
269 rpc_proc_info_key* key1 = (rpc_proc_info_key*) k1;
270 rpc_proc_info_key* key2 = (rpc_proc_info_key*) k2;
272 return ((key1->prog == key2->prog &&
273 key1->vers == key2->vers &&
274 key1->proc == key2->proc) ?
278 /* calculate a hash key */
280 rpc_proc_hash(gconstpointer k)
282 rpc_proc_info_key* key = (rpc_proc_info_key*) k;
284 return (key->prog ^ (key->vers<<16) ^ (key->proc<<24));
288 /* insert some entries */
290 rpc_init_proc_table(guint prog, guint vers, const vsff *proc_table)
294 for (proc = proc_table ; proc->strptr!=NULL; proc++) {
295 rpc_proc_info_key *key;
296 rpc_proc_info_value *value;
298 key = (rpc_proc_info_key *) g_malloc(sizeof(rpc_proc_info_key));
301 key->proc = proc->value;
303 value = (rpc_proc_info_value *) g_malloc(sizeof(rpc_proc_info_value));
304 value->name = proc->strptr;
305 value->dissect_call = proc->dissect_call;
306 value->dissect_reply = proc->dissect_reply;
308 g_hash_table_insert(rpc_procs,key,value);
312 /* return the name associated with a previously registered procedure. */
313 char *rpc_proc_name(guint32 prog, guint32 vers, guint32 proc)
315 rpc_proc_info_key key;
316 rpc_proc_info_value *value;
318 static char procname_static[20];
324 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL)
325 procname = value->name;
327 /* happens only with strange program versions or
328 non-existing dissectors */
329 sprintf(procname_static, "proc-%u", key.proc);
330 procname = procname_static;
335 /*----------------------------------------*/
336 /* end of Hash array with procedure names */
337 /*----------------------------------------*/
340 /*********************************/
341 /* Hash array with program names */
342 /*********************************/
346 rpc_prog_equal(gconstpointer k1, gconstpointer k2)
348 rpc_prog_info_key* key1 = (rpc_prog_info_key*) k1;
349 rpc_prog_info_key* key2 = (rpc_prog_info_key*) k2;
351 return ((key1->prog == key2->prog) ?
356 /* calculate a hash key */
358 rpc_prog_hash(gconstpointer k)
360 rpc_prog_info_key* key = (rpc_prog_info_key*) k;
367 rpc_init_prog(int proto, guint32 prog, int ett)
369 rpc_prog_info_key *key;
370 rpc_prog_info_value *value;
372 key = (rpc_prog_info_key *) g_malloc(sizeof(rpc_prog_info_key));
375 value = (rpc_prog_info_value *) g_malloc(sizeof(rpc_prog_info_value));
376 value->proto = proto;
378 value->progname = proto_get_protocol_short_name(proto);
380 g_hash_table_insert(rpc_progs,key,value);
383 /* return the name associated with a previously registered program. This
384 should probably eventually be expanded to use the rpc YP/NIS map
385 so that it can give names for programs not handled by ethereal */
386 char *rpc_prog_name(guint32 prog)
388 char *progname = NULL;
389 rpc_prog_info_key rpc_prog_key;
390 rpc_prog_info_value *rpc_prog;
392 rpc_prog_key.prog = prog;
393 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
394 progname = "Unknown";
397 progname = rpc_prog->progname;
403 /*--------------------------------------*/
404 /* end of Hash array with program names */
405 /*--------------------------------------*/
407 typedef struct _rpc_call_info_key {
409 conversation_t *conversation;
412 static GMemChunk *rpc_call_info_key_chunk;
414 static GMemChunk *rpc_call_info_value_chunk;
416 static GHashTable *rpc_calls;
418 static GHashTable *rpc_indir_calls;
422 rpc_call_equal(gconstpointer k1, gconstpointer k2)
424 rpc_call_info_key* key1 = (rpc_call_info_key*) k1;
425 rpc_call_info_key* key2 = (rpc_call_info_key*) k2;
427 return (key1->xid == key2->xid &&
428 key1->conversation == key2->conversation);
432 /* calculate a hash key */
434 rpc_call_hash(gconstpointer k)
436 rpc_call_info_key* key = (rpc_call_info_key*) k;
438 return key->xid + (guint32)(key->conversation);
443 rpc_roundup(unsigned int a)
445 unsigned int mod = a % 4;
446 return a + ((mod)? 4-mod : 0);
451 dissect_rpc_bool(tvbuff_t *tvb, proto_tree *tree,
452 int hfindex, int offset)
455 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
461 dissect_rpc_uint32(tvbuff_t *tvb, proto_tree *tree,
462 int hfindex, int offset)
465 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
471 dissect_rpc_uint64(tvbuff_t *tvb, proto_tree *tree,
472 int hfindex, int offset)
474 header_field_info *hfinfo;
476 hfinfo = proto_registrar_get_nth(hfindex);
477 g_assert(hfinfo->type == FT_UINT64);
479 proto_tree_add_item(tree, hfindex, tvb, offset, 8, FALSE);
486 dissect_rpc_opaque_data(tvbuff_t *tvb, int offset,
487 proto_tree *tree, int hfindex, gboolean string_data,
488 char **string_buffer_ret)
490 proto_item *string_item = NULL;
491 proto_tree *string_tree = NULL;
492 int old_offset = offset;
494 guint32 string_length;
495 guint32 string_length_full;
496 guint32 string_length_packet;
497 guint32 string_length_captured;
498 guint32 string_length_copy;
502 guint32 fill_length_packet;
503 guint32 fill_length_captured;
504 guint32 fill_length_copy;
508 char *string_buffer = NULL;
509 char *string_buffer_print = NULL;
511 string_length = tvb_get_ntohl(tvb,offset+0);
512 string_length_full = rpc_roundup(string_length);
513 string_length_captured = tvb_length_remaining(tvb, offset + 4);
514 string_length_packet = tvb_reported_length_remaining(tvb, offset + 4);
515 if (string_length_captured < string_length) {
516 /* truncated string */
517 string_length_copy = string_length_captured;
520 fill_length_copy = 0;
521 if (string_length_packet < string_length)
522 exception = ReportedBoundsError;
524 exception = BoundsError;
527 /* full string data */
528 string_length_copy = string_length;
529 fill_length = string_length_full - string_length;
530 fill_length_captured = tvb_length_remaining(tvb,
531 offset + 4 + string_length);
532 fill_length_packet = tvb_reported_length_remaining(tvb,
533 offset + 4 + string_length);
534 if (fill_length_captured < fill_length) {
535 /* truncated fill bytes */
536 fill_length_copy = fill_length_packet;
538 if (fill_length_packet < fill_length)
539 exception = ReportedBoundsError;
541 exception = BoundsError;
544 /* full fill bytes */
545 fill_length_copy = fill_length;
549 string_buffer = (char*)g_malloc(string_length_copy +
550 (string_data ? 1 : 0));
551 tvb_memcpy(tvb,string_buffer,offset+4,string_length_copy);
553 string_buffer[string_length_copy] = '\0';
555 /* calculate a nice printable string */
557 if (string_length != string_length_copy) {
559 /* alloc maximum data area */
560 string_buffer_print = (char*)g_malloc(string_length_copy + 12 + 1);
561 /* copy over the data */
562 memcpy(string_buffer_print,string_buffer,string_length_copy);
563 /* append a 0 byte for sure printing */
564 string_buffer_print[string_length_copy] = '\0';
565 /* append <TRUNCATED> */
566 /* This way, we get the TRUNCATED even
567 in the case of totally wrong packets,
568 where \0 are inside the string.
569 TRUNCATED will appear at the
570 first \0 or at the end (where we
571 put the securing \0).
573 strcat(string_buffer_print,"<TRUNCATED>");
576 string_buffer_print = g_strdup("<DATA><TRUNCATED>");
581 string_buffer_print = g_strdup(string_buffer);
584 string_buffer_print = g_strdup("<DATA>");
589 string_buffer_print = g_strdup("<EMPTY>");
593 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
594 "%s: %s", proto_registrar_get_name(hfindex), string_buffer_print);
596 proto_tree_add_string_hidden(tree, hfindex, tvb, offset+4,
597 string_length_copy, string_buffer);
600 string_tree = proto_item_add_subtree(string_item, ett_rpc_string);
604 proto_tree_add_text(string_tree, tvb,offset+0,4,
605 "length: %u", string_length);
610 proto_tree_add_string_format(string_tree,
611 hfindex, tvb, offset, string_length_copy,
613 "contents: %s", string_buffer_print);
615 proto_tree_add_bytes_format(string_tree,
616 hfindex, tvb, offset, string_length_copy,
618 "contents: %s", string_buffer_print);
621 offset += string_length_copy;
624 if (fill_truncated) {
625 proto_tree_add_text(string_tree, tvb,
626 offset,fill_length_copy,
627 "fill bytes: opaque data<TRUNCATED>");
630 proto_tree_add_text(string_tree, tvb,
631 offset,fill_length_copy,
632 "fill bytes: opaque data");
635 offset += fill_length_copy;
639 proto_item_set_len(string_item, offset - old_offset);
642 if (string_buffer != NULL) g_free (string_buffer );
643 if (string_buffer_print != NULL) {
644 if (string_buffer_ret != NULL)
645 *string_buffer_ret = string_buffer_print;
647 g_free (string_buffer_print);
651 * If the data was truncated, throw the appropriate exception,
652 * so that dissection stops and the frame is properly marked.
661 dissect_rpc_string(tvbuff_t *tvb, proto_tree *tree,
662 int hfindex, int offset, char **string_buffer_ret)
664 offset = dissect_rpc_opaque_data(tvb, offset, tree,
665 hfindex, TRUE, string_buffer_ret);
671 dissect_rpc_data(tvbuff_t *tvb, proto_tree *tree,
672 int hfindex, int offset)
674 offset = dissect_rpc_opaque_data(tvb, offset, tree, hfindex,
682 dissect_rpc_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
683 int offset, dissect_function_t *rpc_list_dissector)
685 guint32 value_follows;
688 value_follows = tvb_get_ntohl(tvb, offset+0);
689 proto_tree_add_boolean(tree,hf_rpc_value_follows, tvb,
690 offset+0, 4, value_follows);
692 if (value_follows == 1) {
693 offset = rpc_list_dissector(tvb, offset, pinfo, tree);
704 dissect_rpc_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
705 int offset, dissect_function_t *rpc_array_dissector,
708 proto_item* lock_item;
709 proto_tree* lock_tree;
711 int old_offset = offset;
713 num = tvb_get_ntohl(tvb, offset);
716 proto_tree_add_none_format(tree, hfindex, tvb, offset, 4,
723 lock_item = proto_tree_add_item(tree, hfindex, tvb, offset, -1, FALSE);
725 lock_tree = proto_item_add_subtree(lock_item, ett_rpc_array);
727 offset = dissect_rpc_uint32(tvb, lock_tree,
728 hf_rpc_array_len, offset);
731 offset = rpc_array_dissector(tvb, offset, pinfo, lock_tree);
734 proto_item_set_len(lock_item, offset-old_offset);
739 dissect_rpc_authunix_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
748 proto_tree *gtree = NULL;
750 stamp = tvb_get_ntohl(tvb,offset+0);
752 proto_tree_add_uint(tree, hf_rpc_auth_stamp, tvb,
756 offset = dissect_rpc_string(tvb, tree,
757 hf_rpc_auth_machinename, offset, NULL);
759 uid = tvb_get_ntohl(tvb,offset+0);
761 proto_tree_add_uint(tree, hf_rpc_auth_uid, tvb,
765 gid = tvb_get_ntohl(tvb,offset+0);
767 proto_tree_add_uint(tree, hf_rpc_auth_gid, tvb,
771 gids_count = tvb_get_ntohl(tvb,offset+0);
773 gitem = proto_tree_add_text(tree, tvb,
774 offset, 4+gids_count*4, "Auxiliary GIDs");
775 gtree = proto_item_add_subtree(gitem, ett_rpc_gids);
779 for (gids_i = 0 ; gids_i < gids_count ; gids_i++) {
780 gids_entry = tvb_get_ntohl(tvb,offset+0);
782 proto_tree_add_uint(gtree, hf_rpc_auth_gid, tvb,
783 offset, 4, gids_entry);
786 /* how can I NOW change the gitem to print a list with
787 the first 16 gids? */
793 dissect_rpc_authgss_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
800 agc_v = tvb_get_ntohl(tvb, offset+0);
802 proto_tree_add_uint(tree, hf_rpc_authgss_v,
803 tvb, offset+0, 4, agc_v);
806 agc_proc = tvb_get_ntohl(tvb, offset+0);
808 proto_tree_add_uint(tree, hf_rpc_authgss_proc,
809 tvb, offset+0, 4, agc_proc);
812 agc_seq = tvb_get_ntohl(tvb, offset+0);
814 proto_tree_add_uint(tree, hf_rpc_authgss_seq,
815 tvb, offset+0, 4, agc_seq);
818 agc_svc = tvb_get_ntohl(tvb, offset+0);
820 proto_tree_add_uint(tree, hf_rpc_authgss_svc,
821 tvb, offset+0, 4, agc_svc);
824 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
831 dissect_rpc_authdes_desblock(tvbuff_t *tvb, proto_tree *tree,
832 int hfindex, int offset)
837 value_high = tvb_get_ntohl(tvb, offset + 0);
838 value_low = tvb_get_ntohl(tvb, offset + 4);
841 proto_tree_add_text(tree, tvb, offset, 8,
842 "%s: 0x%x%08x", proto_registrar_get_name(hfindex), value_high,
850 dissect_rpc_authdes_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
856 adc_namekind = tvb_get_ntohl(tvb, offset+0);
858 proto_tree_add_uint(tree, hf_rpc_authdes_namekind,
859 tvb, offset+0, 4, adc_namekind);
864 case AUTHDES_NAMEKIND_FULLNAME:
865 offset = dissect_rpc_string(tvb, tree,
866 hf_rpc_authdes_netname, offset, NULL);
867 offset = dissect_rpc_authdes_desblock(tvb, tree,
868 hf_rpc_authdes_convkey, offset);
869 window = tvb_get_ntohl(tvb, offset+0);
870 proto_tree_add_uint(tree, hf_rpc_authdes_window, tvb, offset+0, 4,
875 case AUTHDES_NAMEKIND_NICKNAME:
876 nickname = tvb_get_ntohl(tvb, offset+0);
877 proto_tree_add_uint(tree, hf_rpc_authdes_nickname, tvb, offset+0, 4,
887 dissect_rpc_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
895 flavor = tvb_get_ntohl(tvb,offset+0);
896 length = tvb_get_ntohl(tvb,offset+4);
897 length = rpc_roundup(length);
900 citem = proto_tree_add_text(tree, tvb, offset,
901 8+length, "Credentials");
902 ctree = proto_item_add_subtree(citem, ett_rpc_cred);
903 proto_tree_add_uint(ctree, hf_rpc_auth_flavor, tvb,
904 offset+0, 4, flavor);
905 proto_tree_add_uint(ctree, hf_rpc_auth_length, tvb,
906 offset+4, 4, length);
910 dissect_rpc_authunix_cred(tvb, ctree, offset+8);
918 dissect_rpc_authdes_cred(tvb, ctree, offset+8);
922 dissect_rpc_authgss_cred(tvb, ctree, offset+8);
926 proto_tree_add_text(ctree, tvb, offset+8,
927 length,"opaque data");
931 offset += 8 + length;
936 /* AUTH_DES verifiers are asymmetrical, so we need to know what type of
937 * verifier we're decoding (CALL or REPLY).
940 dissect_rpc_verf(tvbuff_t* tvb, proto_tree* tree, int offset, int msg_type)
948 flavor = tvb_get_ntohl(tvb,offset+0);
949 length = tvb_get_ntohl(tvb,offset+4);
950 length = rpc_roundup(length);
953 vitem = proto_tree_add_text(tree, tvb, offset,
954 8+length, "Verifier");
955 vtree = proto_item_add_subtree(vitem, ett_rpc_verf);
956 proto_tree_add_uint(vtree, hf_rpc_auth_flavor, tvb,
957 offset+0, 4, flavor);
961 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
962 offset+4, 4, length);
963 dissect_rpc_authunix_cred(tvb, vtree, offset+8);
966 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
967 offset+4, 4, length);
969 if (msg_type == RPC_CALL)
973 dissect_rpc_authdes_desblock(tvb, vtree,
974 hf_rpc_authdes_timestamp, offset+8);
975 window = tvb_get_ntohl(tvb, offset+16);
976 proto_tree_add_uint(vtree, hf_rpc_authdes_windowverf, tvb,
977 offset+16, 4, window);
981 /* must be an RPC_REPLY */
984 dissect_rpc_authdes_desblock(tvb, vtree,
985 hf_rpc_authdes_timeverf, offset+8);
986 nickname = tvb_get_ntohl(tvb, offset+16);
987 proto_tree_add_uint(vtree, hf_rpc_authdes_nickname, tvb,
988 offset+16, 4, nickname);
992 dissect_rpc_data(tvb, vtree,
993 hf_rpc_authgss_checksum, offset+4);
996 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
997 offset+4, 4, length);
999 proto_tree_add_text(vtree, tvb, offset+8,
1000 length, "opaque data");
1004 offset += 8 + length;
1010 dissect_rpc_authgss_initarg(tvbuff_t* tvb, proto_tree* tree, int offset)
1012 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_token,
1018 dissect_rpc_authgss_initres(tvbuff_t* tvb, proto_tree* tree, int offset)
1020 int major, minor, window;
1022 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
1025 major = tvb_get_ntohl(tvb,offset+0);
1027 proto_tree_add_uint(tree, hf_rpc_authgss_major, tvb,
1028 offset+0, 4, major);
1031 minor = tvb_get_ntohl(tvb,offset+0);
1033 proto_tree_add_uint(tree, hf_rpc_authgss_minor, tvb,
1034 offset+0, 4, minor);
1037 window = tvb_get_ntohl(tvb,offset+0);
1039 proto_tree_add_uint(tree, hf_rpc_authgss_window, tvb,
1040 offset+0, 4, window);
1043 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_token,
1051 call_dissect_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1052 int offset, dissect_function_t* dissect_function, const char *progname)
1054 const char *saved_proto;
1056 if (dissect_function != NULL) {
1057 /* set the current protocol name */
1058 saved_proto = pinfo->current_proto;
1059 if (progname != NULL)
1060 pinfo->current_proto = progname;
1062 /* call the dissector for the next level */
1063 offset = dissect_function(tvb, offset, pinfo, tree);
1065 /* restore the protocol name */
1066 pinfo->current_proto = saved_proto;
1074 dissect_rpc_authgss_integ_data(tvbuff_t *tvb, packet_info *pinfo,
1075 proto_tree *tree, int offset,
1076 dissect_function_t* dissect_function,
1077 const char *progname)
1079 guint32 length, seq;
1082 proto_tree *gtree = NULL;
1084 length = tvb_get_ntohl(tvb, offset+0);
1085 length = rpc_roundup(length);
1086 seq = tvb_get_ntohl(tvb, offset+4);
1089 gitem = proto_tree_add_text(tree, tvb, offset,
1090 4+length, "GSS Data");
1091 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_data);
1092 proto_tree_add_uint(gtree, hf_rpc_authgss_data_length,
1093 tvb, offset+0, 4, length);
1094 proto_tree_add_uint(gtree, hf_rpc_authgss_seq,
1095 tvb, offset+4, 4, seq);
1099 if (dissect_function != NULL) {
1101 call_dissect_function(tvb, pinfo, gtree, offset,
1102 dissect_function, progname);
1104 offset += length - 4;
1105 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_checksum,
1112 dissect_rpc_authgss_priv_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1114 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1120 * Dissect the arguments to an indirect call; used by the portmapper/RPCBIND
1123 * Record this call in a hash table, similar to the hash table for
1124 * direct calls, so we can find it when dissecting an indirect call reply.
1127 dissect_rpc_indir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1128 int offset, int args_id, guint32 prog, guint32 vers, guint32 proc)
1130 conversation_t* conversation;
1131 static address null_address = { AT_NONE, 0, NULL };
1132 rpc_proc_info_key key;
1133 rpc_proc_info_value *value;
1134 rpc_call_info_value *rpc_call;
1135 rpc_call_info_key rpc_call_key;
1136 rpc_call_info_key *new_rpc_call_key;
1137 dissect_function_t *dissect_function = NULL;
1142 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1143 dissect_function = value->dissect_call;
1145 /* Keep track of the address and port whence the call came,
1146 and the port to which the call is being sent, so that
1147 we can match up calls with replies.
1149 If the transport is connection-oriented (we check, for
1150 now, only for "pinfo->ptype" of PT_TCP), we take
1151 into account the address from which the call was sent
1152 and the address to which the call was sent, because
1153 the addresses of the two endpoints should be the same
1154 for all calls and replies.
1156 If the transport is connectionless, we don't worry
1157 about the address to which the call was sent and from
1158 which the reply was sent, because there's no
1159 guarantee that the reply will come from the address
1160 to which the call was sent. */
1161 if (pinfo->ptype == PT_TCP) {
1162 conversation = find_conversation(&pinfo->src,
1163 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1164 pinfo->destport, 0);
1167 * XXX - can we just use NO_ADDR_B? Unfortunately,
1168 * you currently still have to pass a non-null
1169 * pointer for the second address argument even
1172 conversation = find_conversation(&pinfo->src,
1173 &null_address, pinfo->ptype, pinfo->srcport,
1174 pinfo->destport, 0);
1176 if (conversation == NULL) {
1177 /* It's not part of any conversation - create a new
1180 XXX - this should never happen, as we should've
1181 created a conversation for it in the RPC
1183 if (pinfo->ptype == PT_TCP) {
1184 conversation = conversation_new(&pinfo->src,
1185 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1186 pinfo->destport, 0);
1188 conversation = conversation_new(&pinfo->src,
1189 &null_address, pinfo->ptype, pinfo->srcport,
1190 pinfo->destport, 0);
1194 /* Make the dissector for this conversation the non-heuristic
1196 conversation_set_dissector(conversation,
1197 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1199 /* Prepare the key data.
1201 Dissectors for RPC procedure calls and replies shouldn't
1202 create new tvbuffs, and we don't create one ourselves,
1203 so we should have been handed the tvbuff for this RPC call;
1204 as such, the XID is at offset 0 in this tvbuff. */
1205 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1206 rpc_call_key.conversation = conversation;
1208 /* look up the request */
1209 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1210 if (rpc_call == NULL) {
1211 /* We didn't find it; create a new entry.
1212 Prepare the value data.
1213 Not all of it is needed for handling indirect
1214 calls, so we set a bunch of items to 0. */
1215 new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1216 *new_rpc_call_key = rpc_call_key;
1217 rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1218 rpc_call->req_num = 0;
1219 rpc_call->rep_num = 0;
1220 rpc_call->prog = prog;
1221 rpc_call->vers = vers;
1222 rpc_call->proc = proc;
1223 rpc_call->private_data = NULL;
1226 * XXX - what about RPCSEC_GSS?
1227 * Do we have to worry about it?
1229 rpc_call->flavor = FLAVOR_NOT_GSSAPI;
1230 rpc_call->gss_proc = 0;
1231 rpc_call->gss_svc = 0;
1232 rpc_call->proc_info = value;
1234 g_hash_table_insert(rpc_indir_calls, new_rpc_call_key,
1239 /* We don't know the procedure.
1240 Happens only with strange program versions or
1241 non-existing dissectors.
1242 Just show the arguments as opaque data. */
1243 offset = dissect_rpc_data(tvb, tree, args_id,
1250 proto_tree_add_text(tree, tvb, offset, 4,
1251 "Argument length: %u",
1252 tvb_get_ntohl(tvb, offset));
1256 /* Dissect the arguments */
1257 offset = call_dissect_function(tvb, pinfo, tree, offset,
1258 dissect_function, NULL);
1263 * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1267 dissect_rpc_indir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1268 int offset, int result_id, int prog_id, int vers_id, int proc_id)
1270 conversation_t* conversation;
1271 static address null_address = { AT_NONE, 0, NULL };
1272 rpc_call_info_key rpc_call_key;
1273 rpc_call_info_value *rpc_call;
1274 char *procname = NULL;
1275 char procname_static[20];
1276 dissect_function_t *dissect_function = NULL;
1278 /* Look for the matching call in the hash table of indirect
1279 calls. A reply must match a call that we've seen, and the
1280 reply must be sent to the same port and address that the
1281 call came from, and must come from the port to which the
1284 If the transport is connection-oriented (we check, for
1285 now, only for "pinfo->ptype" of PT_TCP), we take
1286 into account the address from which the call was sent
1287 and the address to which the call was sent, because
1288 the addresses of the two endpoints should be the same
1289 for all calls and replies.
1291 If the transport is connectionless, we don't worry
1292 about the address to which the call was sent and from
1293 which the reply was sent, because there's no
1294 guarantee that the reply will come from the address
1295 to which the call was sent. */
1296 if (pinfo->ptype == PT_TCP) {
1297 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1298 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1301 * XXX - can we just use NO_ADDR_B? Unfortunately,
1302 * you currently still have to pass a non-null
1303 * pointer for the second address argument even
1306 conversation = find_conversation(&null_address, &pinfo->dst,
1307 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1309 if (conversation == NULL) {
1310 /* We haven't seen an RPC call for that conversation,
1311 so we can't check for a reply to that call.
1312 Just show the reply stuff as opaque data. */
1313 offset = dissect_rpc_data(tvb, tree, result_id,
1318 /* The XIDs of the call and reply must match. */
1319 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1320 rpc_call_key.conversation = conversation;
1321 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1322 if (rpc_call == NULL) {
1323 /* The XID doesn't match a call from that
1324 conversation, so it's probably not an RPC reply.
1325 Just show the reply stuff as opaque data. */
1326 offset = dissect_rpc_data(tvb, tree, result_id,
1331 if (rpc_call->proc_info != NULL) {
1332 dissect_function = rpc_call->proc_info->dissect_reply;
1333 if (rpc_call->proc_info->name != NULL) {
1334 procname = rpc_call->proc_info->name;
1337 sprintf(procname_static, "proc-%u", rpc_call->proc);
1338 procname = procname_static;
1343 dissect_function = NULL;
1345 sprintf(procname_static, "proc-%u", rpc_call->proc);
1346 procname = procname_static;
1351 /* Put the program, version, and procedure into the tree. */
1352 proto_tree_add_uint_format(tree, prog_id, tvb,
1353 0, 0, rpc_call->prog, "Program: %s (%u)",
1354 rpc_prog_name(rpc_call->prog), rpc_call->prog);
1355 proto_tree_add_uint(tree, vers_id, tvb, 0, 0, rpc_call->vers);
1356 proto_tree_add_uint_format(tree, proc_id, tvb,
1357 0, 0, rpc_call->proc, "Procedure: %s (%u)",
1358 procname, rpc_call->proc);
1361 if (dissect_function == NULL) {
1362 /* We don't know how to dissect the reply procedure.
1363 Just show the reply stuff as opaque data. */
1364 offset = dissect_rpc_data(tvb, tree, result_id,
1370 /* Put the length of the reply value into the tree. */
1371 proto_tree_add_text(tree, tvb, offset, 4,
1372 "Argument length: %u",
1373 tvb_get_ntohl(tvb, offset));
1377 /* Dissect the return value */
1378 offset = call_dissect_function(tvb, pinfo, tree, offset,
1379 dissect_function, NULL);
1384 * Just mark this as a continuation of an earlier packet.
1387 dissect_rpc_continuation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1389 proto_item *rpc_item;
1390 proto_tree *rpc_tree;
1392 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1393 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1394 if (check_col(pinfo->cinfo, COL_INFO))
1395 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1398 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1400 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1401 proto_tree_add_text(rpc_tree, tvb, 0, -1, "Continuation data");
1406 dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1407 tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
1411 rpc_call_info_key rpc_call_key;
1412 rpc_call_info_value *rpc_call = NULL;
1413 rpc_prog_info_value *rpc_prog = NULL;
1414 rpc_prog_info_key rpc_prog_key;
1417 unsigned int rpcvers;
1418 unsigned int prog = 0;
1419 unsigned int vers = 0;
1420 unsigned int proc = 0;
1421 flavor_t flavor = FLAVOR_UNKNOWN;
1422 unsigned int gss_proc = 0;
1423 unsigned int gss_svc = 0;
1427 unsigned int reply_state;
1428 unsigned int accept_state;
1429 unsigned int reject_state;
1431 char *msg_type_name = NULL;
1432 char *progname = NULL;
1433 char *procname = NULL;
1434 static char procname_static[20];
1436 unsigned int vers_low;
1437 unsigned int vers_high;
1439 unsigned int auth_state;
1441 proto_item *rpc_item = NULL;
1442 proto_tree *rpc_tree = NULL;
1444 proto_item *pitem = NULL;
1445 proto_tree *ptree = NULL;
1446 int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
1447 int offset_old = offset;
1449 rpc_call_info_key *new_rpc_call_key;
1450 rpc_proc_info_key key;
1451 rpc_proc_info_value *value = NULL;
1452 conversation_t* conversation;
1453 static address null_address = { AT_NONE, 0, NULL };
1456 dissect_function_t *dissect_function = NULL;
1457 gboolean dissect_rpc = TRUE;
1460 * Check to see whether this looks like an RPC call or reply.
1462 if (!tvb_bytes_exist(tvb, offset, 8)) {
1463 /* Captured data in packet isn't enough to let us tell. */
1467 /* both directions need at least this */
1468 msg_type = tvb_get_ntohl(tvb, offset + 4);
1473 /* check for RPC call */
1474 if (!tvb_bytes_exist(tvb, offset, 16)) {
1475 /* Captured data in packet isn't enough to let us
1480 /* XID can be anything, we don't check it.
1481 We already have the message type.
1482 Check whether an RPC version number of 2 is in the
1483 location where it would be, and that an RPC program
1484 number we know about is in the location where it would be. */
1485 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1486 if (tvb_get_ntohl(tvb, offset + 8) != 2 ||
1487 ((rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key))
1489 /* They're not, so it's probably not an RPC call. */
1495 /* Check for RPC reply. A reply must match a call that
1496 we've seen, and the reply must be sent to the same
1497 port and address that the call came from, and must
1498 come from the port to which the call was sent.
1500 If the transport is connection-oriented (we check, for
1501 now, only for "pinfo->ptype" of PT_TCP), we take
1502 into account the address from which the call was sent
1503 and the address to which the call was sent, because
1504 the addresses of the two endpoints should be the same
1505 for all calls and replies.
1507 If the transport is connectionless, we don't worry
1508 about the address to which the call was sent and from
1509 which the reply was sent, because there's no
1510 guarantee that the reply will come from the address
1511 to which the call was sent. */
1512 if (pinfo->ptype == PT_TCP) {
1513 conversation = find_conversation(&pinfo->src,
1514 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1515 pinfo->destport, 0);
1518 * XXX - can we just use NO_ADDR_B? Unfortunately,
1519 * you currently still have to pass a non-null
1520 * pointer for the second address argument even
1523 conversation = find_conversation(&null_address,
1524 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1525 pinfo->destport, 0);
1527 if (conversation == NULL) {
1528 /* We haven't seen an RPC call for that conversation,
1529 so we can't check for a reply to that call. */
1533 /* The XIDs of the call and reply must match. */
1534 rpc_call_key.xid = tvb_get_ntohl(tvb, offset + 0);
1535 rpc_call_key.conversation = conversation;
1536 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1537 if (rpc_call == NULL) {
1538 /* The XID doesn't match a call from that
1539 conversation, so it's probably not an RPC reply. */
1542 /* pass rpc_info to subdissectors */
1543 rpc_call->request=FALSE;
1544 pinfo->private_data=rpc_call;
1548 /* The putative message type field contains neither
1549 RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1556 * This is RPC-over-TCP; check if this is the last
1559 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
1561 * This isn't the last fragment.
1562 * If we're doing reassembly, just return
1563 * TRUE to indicate that this looks like
1564 * the beginning of an RPC message,
1565 * and let them do fragment reassembly.
1572 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1573 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1574 if (check_col(pinfo->cinfo, COL_INFO))
1575 col_clear(pinfo->cinfo, COL_INFO);
1578 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1580 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1583 show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
1588 xid = tvb_get_ntohl(tvb, offset + 0);
1590 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1591 offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1594 msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1596 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1597 offset+4, 4, msg_type);
1605 /* we know already the proto-entry, the ETT-const,
1607 proto = rpc_prog->proto;
1608 ett = rpc_prog->ett;
1609 progname = rpc_prog->progname;
1611 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1613 proto_tree_add_uint(rpc_tree,
1614 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1617 prog = tvb_get_ntohl(tvb, offset + 4);
1620 proto_tree_add_uint_format(rpc_tree,
1621 hf_rpc_program, tvb, offset+4, 4, prog,
1622 "Program: %s (%u)", progname, prog);
1625 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1626 /* Set the protocol name to the underlying
1628 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1631 vers = tvb_get_ntohl(tvb, offset+8);
1633 proto_tree_add_uint(rpc_tree,
1634 hf_rpc_programversion, tvb, offset+8, 4, vers);
1637 proc = tvb_get_ntohl(tvb, offset+12);
1643 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1644 dissect_function = value->dissect_call;
1645 procname = value->name;
1648 /* happens only with strange program versions or
1649 non-existing dissectors */
1651 dissect_function = NULL;
1653 sprintf(procname_static, "proc-%u", proc);
1654 procname = procname_static;
1658 proto_tree_add_uint_format(rpc_tree,
1659 hf_rpc_procedure, tvb, offset+12, 4, proc,
1660 "Procedure: %s (%u)", procname, proc);
1663 if (check_col(pinfo->cinfo, COL_INFO)) {
1664 col_add_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s XID 0x%x",
1671 /* Check for RPCSEC_GSS */
1672 if (tvb_bytes_exist(tvb, offset+16, 4)) {
1673 switch (tvb_get_ntohl(tvb, offset+16)) {
1677 * It's GSS-API authentication...
1679 if (tvb_bytes_exist(tvb, offset+28, 8)) {
1681 * ...and we have the procedure
1682 * and service information for it.
1684 flavor = FLAVOR_GSSAPI;
1685 gss_proc = tvb_get_ntohl(tvb, offset+28);
1686 gss_svc = tvb_get_ntohl(tvb, offset+36);
1689 * ...but the procedure and service
1690 * information isn't available.
1692 flavor = FLAVOR_GSSAPI_NO_INFO;
1698 * It's not GSS-API authentication.
1700 flavor = FLAVOR_NOT_GSSAPI;
1705 /* Keep track of the address and port whence the call came,
1706 and the port to which the call is being sent, so that
1707 we can match up calls with replies.
1709 If the transport is connection-oriented (we check, for
1710 now, only for "pinfo->ptype" of PT_TCP), we take
1711 into account the address from which the call was sent
1712 and the address to which the call was sent, because
1713 the addresses of the two endpoints should be the same
1714 for all calls and replies.
1716 If the transport is connectionless, we don't worry
1717 about the address to which the call was sent and from
1718 which the reply was sent, because there's no
1719 guarantee that the reply will come from the address
1720 to which the call was sent. */
1721 if (pinfo->ptype == PT_TCP) {
1722 conversation = find_conversation(&pinfo->src,
1723 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1724 pinfo->destport, 0);
1727 * XXX - can we just use NO_ADDR_B? Unfortunately,
1728 * you currently still have to pass a non-null
1729 * pointer for the second address argument even
1732 conversation = find_conversation(&pinfo->src,
1733 &null_address, pinfo->ptype, pinfo->srcport,
1734 pinfo->destport, 0);
1736 if (conversation == NULL) {
1737 /* It's not part of any conversation - create a new
1739 if (pinfo->ptype == PT_TCP) {
1740 conversation = conversation_new(&pinfo->src,
1741 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1742 pinfo->destport, 0);
1744 conversation = conversation_new(&pinfo->src,
1745 &null_address, pinfo->ptype, pinfo->srcport,
1746 pinfo->destport, 0);
1750 /* Make the dissector for this conversation the non-heuristic
1752 conversation_set_dissector(conversation,
1753 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1755 /* prepare the key data */
1756 rpc_call_key.xid = xid;
1757 rpc_call_key.conversation = conversation;
1759 /* look up the request */
1760 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1761 if (rpc_call != NULL) {
1762 /* We've seen a request with this XID, with the same
1763 source and destination, before - but was it
1765 if (pinfo->fd->num != rpc_call->req_num) {
1766 /* No, so it's a duplicate request.
1768 if (check_col(pinfo->cinfo, COL_INFO)) {
1769 col_append_fstr(pinfo->cinfo, COL_INFO,
1770 " dup XID 0x%x", xid);
1772 proto_tree_add_uint_hidden(rpc_tree,
1773 hf_rpc_dup, tvb, 0,0, xid);
1774 proto_tree_add_uint_hidden(rpc_tree,
1775 hf_rpc_call_dup, tvb, 0,0, xid);
1781 /* Prepare the value data.
1782 "req_num" and "rep_num" are frame numbers;
1783 frame numbers are 1-origin, so we use 0
1784 to mean "we don't yet know in which frame
1785 the reply for this call appears". */
1786 new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1787 *new_rpc_call_key = rpc_call_key;
1788 rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1789 rpc_call->req_num = pinfo->fd->num;
1790 rpc_call->rep_num = 0;
1791 rpc_call->prog = prog;
1792 rpc_call->vers = vers;
1793 rpc_call->proc = proc;
1794 rpc_call->private_data = NULL;
1795 rpc_call->xid = xid;
1796 rpc_call->flavor = flavor;
1797 rpc_call->gss_proc = gss_proc;
1798 rpc_call->gss_svc = gss_svc;
1799 rpc_call->proc_info = value;
1800 rpc_call->req_time.secs=pinfo->fd->abs_secs;
1801 rpc_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
1804 g_hash_table_insert(rpc_calls, new_rpc_call_key,
1808 if(rpc_call && rpc_call->rep_num){
1809 proto_tree_add_text(rpc_tree, tvb, 0, 0,
1810 "The reply to this request is in frame %u",
1816 offset = dissect_rpc_cred(tvb, rpc_tree, offset);
1817 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type);
1819 /* pass rpc_info to subdissectors */
1820 rpc_call->request=TRUE;
1821 pinfo->private_data=rpc_call;
1823 /* go to the next dissector */
1825 break; /* end of RPC call */
1828 /* we know already the type from the calling routine,
1829 and we already have "rpc_call" set above. */
1830 prog = rpc_call->prog;
1831 vers = rpc_call->vers;
1832 proc = rpc_call->proc;
1833 flavor = rpc_call->flavor;
1834 gss_proc = rpc_call->gss_proc;
1835 gss_svc = rpc_call->gss_svc;
1837 if (rpc_call->proc_info != NULL) {
1838 dissect_function = rpc_call->proc_info->dissect_reply;
1839 if (rpc_call->proc_info->name != NULL) {
1840 procname = rpc_call->proc_info->name;
1843 sprintf(procname_static, "proc-%u", proc);
1844 procname = procname_static;
1849 dissect_function = NULL;
1851 sprintf(procname_static, "proc-%u", proc);
1852 procname = procname_static;
1855 rpc_prog_key.prog = prog;
1856 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
1859 progname = "Unknown";
1862 proto = rpc_prog->proto;
1863 ett = rpc_prog->ett;
1864 progname = rpc_prog->progname;
1866 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1867 /* Set the protocol name to the underlying
1869 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1873 if (check_col(pinfo->cinfo, COL_INFO)) {
1874 col_add_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s XID 0x%x",
1882 proto_tree_add_uint_format(rpc_tree,
1883 hf_rpc_program, tvb, 0, 0, prog,
1884 "Program: %s (%u)", progname, prog);
1885 proto_tree_add_uint(rpc_tree,
1886 hf_rpc_programversion, tvb, 0, 0, vers);
1887 proto_tree_add_uint_format(rpc_tree,
1888 hf_rpc_procedure, tvb, 0, 0, proc,
1889 "Procedure: %s (%u)", procname, proc);
1892 reply_state = tvb_get_ntohl(tvb,offset+0);
1894 proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
1895 offset+0, 4, reply_state);
1899 /* Indicate the frame to which this is a reply. */
1900 if(rpc_call && rpc_call->req_num){
1901 proto_tree_add_text(rpc_tree, tvb, 0, 0,
1902 "This is a reply to a request in frame %u",
1904 ns.secs= pinfo->fd->abs_secs-rpc_call->req_time.secs;
1905 ns.nsecs=pinfo->fd->abs_usecs*1000-rpc_call->req_time.nsecs;
1907 ns.nsecs+=1000000000;
1910 proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
1915 if (rpc_call->rep_num == 0) {
1916 /* We have not yet seen a reply to that call, so
1917 this must be the first reply; remember its
1919 rpc_call->rep_num = pinfo->fd->num;
1921 /* We have seen a reply to this call - but was it
1923 if (rpc_call->rep_num != pinfo->fd->num) {
1924 /* No, so it's a duplicate reply.
1926 if (check_col(pinfo->cinfo, COL_INFO)) {
1927 col_append_fstr(pinfo->cinfo, COL_INFO,
1928 " dup XID 0x%x", xid);
1930 proto_tree_add_uint_hidden(rpc_tree,
1931 hf_rpc_dup, tvb, 0,0, xid);
1932 proto_tree_add_uint_hidden(rpc_tree,
1933 hf_rpc_reply_dup, tvb, 0,0, xid);
1939 switch (reply_state) {
1942 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type);
1943 accept_state = tvb_get_ntohl(tvb,offset+0);
1945 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
1946 offset+0, 4, accept_state);
1949 switch (accept_state) {
1952 /* go to the next dissector */
1956 vers_low = tvb_get_ntohl(tvb,offset+0);
1957 vers_high = tvb_get_ntohl(tvb,offset+4);
1959 proto_tree_add_uint(rpc_tree,
1960 hf_rpc_programversion_min,
1961 tvb, offset+0, 4, vers_low);
1962 proto_tree_add_uint(rpc_tree,
1963 hf_rpc_programversion_max,
1964 tvb, offset+4, 4, vers_high);
1969 * There's no protocol reply, so don't
1970 * try to dissect it.
1972 dissect_rpc = FALSE;
1977 * There's no protocol reply, so don't
1978 * try to dissect it.
1980 dissect_rpc = FALSE;
1986 reject_state = tvb_get_ntohl(tvb,offset+0);
1988 proto_tree_add_uint(rpc_tree,
1989 hf_rpc_state_reject, tvb, offset+0, 4,
1994 if (reject_state==RPC_MISMATCH) {
1995 vers_low = tvb_get_ntohl(tvb,offset+0);
1996 vers_high = tvb_get_ntohl(tvb,offset+4);
1998 proto_tree_add_uint(rpc_tree,
2000 tvb, offset+0, 4, vers_low);
2001 proto_tree_add_uint(rpc_tree,
2003 tvb, offset+4, 4, vers_high);
2006 } else if (reject_state==AUTH_ERROR) {
2007 auth_state = tvb_get_ntohl(tvb,offset+0);
2009 proto_tree_add_uint(rpc_tree,
2010 hf_rpc_state_auth, tvb, offset+0, 4,
2017 * There's no protocol reply, so don't
2018 * try to dissect it.
2020 dissect_rpc = FALSE;
2025 * This isn't a valid reply state, so we have
2026 * no clue what's going on; don't try to dissect
2027 * the protocol reply.
2029 dissect_rpc = FALSE;
2032 break; /* end of RPC reply */
2036 * The switch statement at the top returned if
2037 * this was neither an RPC call nor a reply.
2039 g_assert_not_reached();
2042 /* now we know, that RPC was shorter */
2044 proto_item_set_len(rpc_item, offset - offset_old);
2049 * There's no RPC call or reply here; just dissect
2050 * whatever's left as data.
2052 call_dissector(data_handle,
2053 tvb_new_subset(tvb, offset, -1, -1), pinfo, rpc_tree);
2057 /* create here the program specific sub-tree */
2059 pitem = proto_tree_add_item(tree, proto, tvb, offset, -1,
2062 ptree = proto_item_add_subtree(pitem, ett);
2066 proto_tree_add_uint(ptree,
2067 hf_rpc_programversion, tvb, 0, 0, vers);
2068 proto_tree_add_uint_format(ptree,
2069 hf_rpc_procedure, tvb, 0, 0, proc,
2070 "Procedure: %s (%u)", procname, proc);
2074 if (!proto_is_protocol_enabled(proto))
2075 dissect_function = NULL;
2078 * Handle RPCSEC_GSS specially.
2082 case FLAVOR_UNKNOWN:
2084 * We don't know the authentication flavor, so we can't
2085 * dissect the payload.
2087 proto_tree_add_text(ptree, tvb, offset, -1,
2088 "Unknown authentication flavor - cannot dissect");
2091 case FLAVOR_NOT_GSSAPI:
2093 * It's not GSS-API authentication. Just dissect the
2096 offset = call_dissect_function(tvb, pinfo, ptree, offset,
2097 dissect_function, progname);
2100 case FLAVOR_GSSAPI_NO_INFO:
2102 * It's GSS-API authentication, but we don't have the
2103 * procedure and service information, so we can't dissect
2106 proto_tree_add_text(ptree, tvb, offset, -1,
2107 "GSS-API authentication, but procedure and service unknown - cannot dissect");
2112 * It's GSS-API authentication, and we have the procedure
2113 * and service information; process the GSS-API stuff,
2114 * and process the payload if there is any.
2118 case RPCSEC_GSS_INIT:
2119 case RPCSEC_GSS_CONTINUE_INIT:
2120 if (msg_type == RPC_CALL) {
2121 offset = dissect_rpc_authgss_initarg(tvb,
2125 offset = dissect_rpc_authgss_initres(tvb,
2130 case RPCSEC_GSS_DATA:
2131 if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2132 offset = call_dissect_function(tvb,
2133 pinfo, ptree, offset,
2137 else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2138 offset = dissect_rpc_authgss_integ_data(tvb,
2139 pinfo, ptree, offset,
2143 else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2144 offset = dissect_rpc_authgss_priv_data(tvb,
2154 /* dissect any remaining bytes (incomplete dissection) as pure data in
2156 call_dissector(data_handle,
2157 tvb_new_subset(tvb, offset, -1, -1), pinfo, ptree);
2160 /* XXX this should really loop over all fhandles registred for the frame */
2161 if(nfs_fhandle_reqrep_matching){
2162 nfs_fhandle_data_t *fhd;
2165 if(rpc_call && rpc_call->rep_num){
2166 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2167 nfs_fhandle_frame_table,
2168 (gconstpointer)rpc_call->rep_num);
2170 dissect_fhandle_hidden(pinfo,
2176 if(rpc_call && rpc_call->req_num){
2177 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2178 nfs_fhandle_frame_table,
2179 (gconstpointer)rpc_call->req_num);
2181 dissect_fhandle_hidden(pinfo,
2193 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2195 return dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0);
2199 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2201 if (!dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0))
2202 dissect_rpc_continuation(tvb, pinfo, tree);
2205 /* Defragmentation of RPC-over-TCP records */
2206 /* table to hold defragmented RPC records */
2207 static GHashTable *rpc_fragment_table = NULL;
2209 static GHashTable *rpc_reassembly_table = NULL;
2210 static GMemChunk *rpc_fragment_key_chunk = NULL;
2211 static int rpc_fragment_init_count = 200;
2213 typedef struct _rpc_fragment_key {
2222 rpc_fragment_hash(gconstpointer k)
2224 rpc_fragment_key *key = (rpc_fragment_key *)k;
2226 return key->conv_id + key->seq;
2230 rpc_fragment_equal(gconstpointer k1, gconstpointer k2)
2232 rpc_fragment_key *key1 = (rpc_fragment_key *)k1;
2233 rpc_fragment_key *key2 = (rpc_fragment_key *)k2;
2235 return key1->conv_id == key2->conv_id &&
2236 key1->seq == key2->seq;
2240 show_rpc_fragheader(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2242 proto_item *hdr_item;
2243 proto_tree *hdr_tree;
2247 fraglen = rpc_rm & RPC_RM_FRAGLEN;
2249 hdr_item = proto_tree_add_text(tree, tvb, 0, 4,
2250 "Fragment header: %s%u %s",
2251 (rpc_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
2252 fraglen, plurality(fraglen, "byte", "bytes"));
2253 hdr_tree = proto_item_add_subtree(hdr_item, ett_rpc_fraghdr);
2255 proto_tree_add_boolean(hdr_tree, hf_rpc_lastfrag, tvb, 0, 4,
2257 proto_tree_add_uint(hdr_tree, hf_rpc_fraglen, tvb, 0, 4,
2263 show_rpc_fragment(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2267 * Show the fragment header and the data for the fragment.
2269 show_rpc_fragheader(tvb, tree, rpc_rm);
2270 proto_tree_add_text(tree, tvb, 4, -1, "Fragment Data");
2275 make_frag_tree(tvbuff_t *tvb, proto_tree *tree, int proto, gint ett,
2278 proto_item *frag_item;
2279 proto_tree *frag_tree;
2282 return; /* nothing to do */
2284 frag_item = proto_tree_add_protocol_format(tree, proto, tvb, 0, -1,
2285 "%s Fragment", proto_get_protocol_name(proto));
2286 frag_tree = proto_item_add_subtree(frag_item, ett);
2287 show_rpc_fragment(tvb, frag_tree, rpc_rm);
2291 show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
2292 guint32 rpc_rm, fragment_data *ipfd_head, packet_info *pinfo)
2295 return; /* don't do any work */
2297 if (tvb != frag_tvb) {
2299 * This message was not all in one fragment,
2300 * so show the fragment header *and* the data
2301 * for the fragment (which is the last fragment),
2302 * and a tree with information about all fragments.
2304 show_rpc_fragment(frag_tvb, tree, rpc_rm);
2307 * Show a tree with information about all fragments.
2309 show_fragment_tree(ipfd_head, &rpc_frag_items, tree, pinfo, tvb);
2312 * This message was all in one fragment, so just show
2313 * the fragment header.
2315 show_rpc_fragheader(tvb, tree, rpc_rm);
2320 call_message_dissector(tvbuff_t *tvb, tvbuff_t *rec_tvb, packet_info *pinfo,
2321 proto_tree *tree, tvbuff_t *frag_tvb, rec_dissector_t dissector,
2322 fragment_data *ipfd_head, guint32 rpc_rm)
2324 const char *saved_proto;
2325 volatile gboolean rpc_succeeded;
2328 * Catch the ReportedBoundsError exception; if
2329 * this particular message happens to get a
2330 * ReportedBoundsError exception, that doesn't
2331 * mean that we should stop dissecting RPC
2332 * messages within this frame or chunk of
2335 * If it gets a BoundsError, we can stop, as there's
2336 * nothing more to see, so we just re-throw it.
2338 saved_proto = pinfo->current_proto;
2339 rpc_succeeded = FALSE;
2341 rpc_succeeded = (*dissector)(rec_tvb, pinfo, tree,
2342 frag_tvb, ipfd_head, TRUE, rpc_rm);
2344 CATCH(BoundsError) {
2347 CATCH(ReportedBoundsError) {
2348 show_reported_bounds_error(tvb, pinfo, tree);
2349 pinfo->current_proto = saved_proto;
2352 * We treat this as a "successful" dissection of
2353 * an RPC packet, as "dissect_rpc_message()"
2354 * *did* decide it was an RPC packet, throwing
2355 * an exception while dissecting it as such.
2357 rpc_succeeded = TRUE;
2360 return rpc_succeeded;
2364 dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
2365 proto_tree *tree, rec_dissector_t dissector, gboolean is_heur,
2366 int proto, int ett, gboolean defragment)
2368 struct tcpinfo *tcpinfo = pinfo->private_data;
2369 guint32 seq = tcpinfo->seq + offset;
2371 volatile gint32 len;
2373 gint tvb_len, tvb_reported_len;
2375 gboolean rpc_succeeded;
2376 gboolean save_fragmented;
2377 rpc_fragment_key old_rfk, *rfk, *new_rfk;
2378 conversation_t *conversation;
2379 fragment_data *ipfd_head;
2383 * Get the record mark.
2385 if (!tvb_bytes_exist(tvb, offset, 4)) {
2387 * XXX - we should somehow arrange to handle
2388 * a record mark split across TCP segments.
2390 return 0; /* not enough to tell if it's valid */
2392 rpc_rm = tvb_get_ntohl(tvb, offset);
2394 len = rpc_rm & RPC_RM_FRAGLEN;
2397 * Do TCP desegmentation, if enabled.
2399 * XXX - reject fragments bigger than 2 megabytes.
2400 * This is arbitrary, but should at least prevent
2401 * some crashes from either packets with really
2402 * large RPC-over-TCP fragments or from stuff that's
2403 * not really valid for this protocol.
2405 if (len > 2*1024*1024)
2406 return 0; /* pretend it's not valid */
2407 if (rpc_desegment) {
2408 seglen = tvb_length_remaining(tvb, offset + 4);
2410 if (len > seglen && pinfo->can_desegment) {
2412 * This frame doesn't have all of the
2413 * data for this message, but we can do
2416 * If this is a heuristic dissector, just
2417 * return 0 - we don't want to try to get
2418 * more data, as that's too likely to cause
2419 * us to misidentify this as valid.
2421 * If this isn't a heuristic dissector,
2422 * we've already identified this conversation
2423 * as containing data for this protocol, as we
2424 * saw valid data in previous frames. Try to
2428 return 0; /* not valid */
2430 pinfo->desegment_offset = offset;
2431 pinfo->desegment_len = len - seglen;
2432 return -pinfo->desegment_len;
2436 len += 4; /* include record mark */
2437 tvb_len = tvb_length_remaining(tvb, offset);
2438 tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2441 if (tvb_reported_len > len)
2442 tvb_reported_len = len;
2443 frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2447 * If we're not defragmenting, just hand this to the
2452 * This is the first fragment we've seen, and it's also
2453 * the last fragment; that means the record wasn't
2454 * fragmented. Hand the dissector the tvbuff for the
2455 * fragment as the tvbuff for the record.
2461 * Mark this as fragmented, so if somebody throws an
2462 * exception, we don't report it as a malformed frame.
2464 save_fragmented = pinfo->fragmented;
2465 pinfo->fragmented = TRUE;
2466 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
2467 tree, frag_tvb, dissector, ipfd_head, rpc_rm);
2468 pinfo->fragmented = save_fragmented;
2470 return 0; /* not RPC */
2475 * First, we check to see if this fragment is part of a record
2476 * that we're in the process of defragmenting.
2478 * The key is the conversation ID for the conversation to which
2479 * the packet belongs and the current sequence number.
2480 * We must first find the conversation and, if we don't find
2481 * one, create it. We know this is running over TCP, so the
2482 * conversation should not wildcard either address or port.
2484 conversation = find_conversation(&pinfo->src, &pinfo->dst,
2485 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2486 if (conversation == NULL) {
2488 * It's not part of any conversation - create a new one.
2490 conversation = conversation_new(&pinfo->src, &pinfo->dst,
2491 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2493 old_rfk.conv_id = conversation->index;
2495 rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
2499 * This fragment was not found in our table, so it doesn't
2500 * contain a continuation of a higher-level PDU.
2501 * Is it the last fragment?
2503 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2505 * This isn't the last fragment, so we don't
2506 * have the complete record.
2508 * It's the first fragment we've seen, so if
2509 * it's truly the first fragment of the record,
2510 * and it has enough data, the dissector can at
2511 * least check whether it looks like a valid
2512 * message, as it contains the start of the
2515 * The dissector should not dissect anything
2516 * if the "last fragment" flag isn't set in
2517 * the record marker, so it shouldn't throw
2520 if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
2521 NULL, TRUE, rpc_rm))
2522 return 0; /* not valid */
2525 * OK, now start defragmentation with that
2526 * fragment. Add this fragment, and set up
2527 * next packet/sequence number as well.
2529 * We must remember this fragment.
2532 rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2533 rfk->conv_id = conversation->index;
2536 rfk->start_seq = seq;
2537 g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
2540 * Start defragmentation.
2542 ipfd_head = fragment_add(tvb, offset + 4, pinfo,
2543 rfk->start_seq, rpc_fragment_table,
2544 rfk->offset, len - 4, TRUE);
2547 * Make sure that defragmentation isn't complete;
2548 * it shouldn't be, as this is the first fragment
2549 * we've seen, and the "last fragment" bit wasn't
2552 g_assert(ipfd_head == NULL);
2554 new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2555 new_rfk->conv_id = rfk->conv_id;
2556 new_rfk->seq = seq + len;
2557 new_rfk->offset = rfk->offset + len - 4;
2558 new_rfk->start_seq = rfk->start_seq;
2559 g_hash_table_insert(rpc_reassembly_table, new_rfk,
2563 * This is part of a fragmented record,
2564 * but it's not the first part.
2565 * Show it as a record marker plus data, under
2566 * a top-level tree for this protocol.
2568 make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
2571 * No more processing need be done, as we don't
2572 * have a complete record.
2578 * This is the first fragment we've seen, and it's also
2579 * the last fragment; that means the record wasn't
2580 * fragmented. Hand the dissector the tvbuff for the
2581 * fragment as the tvbuff for the record.
2587 * OK, this fragment was found, which means it continues
2588 * a record. This means we must defragment it.
2589 * Add it to the defragmentation lists.
2591 ipfd_head = fragment_add(tvb, offset + 4, pinfo,
2592 rfk->start_seq, rpc_fragment_table,
2593 rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
2595 if (ipfd_head == NULL) {
2597 * fragment_add() returned NULL, This means that
2598 * defragmentation is not completed yet.
2600 * We must add an entry to the hash table with
2601 * the sequence number following this fragment
2602 * as the starting sequence number, so that when
2603 * we see that fragment we'll find that entry.
2605 * XXX - as TCP stream data is not currently
2606 * guaranteed to be provided in order to dissectors,
2607 * RPC fragments aren't guaranteed to be provided
2610 new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2611 new_rfk->conv_id = rfk->conv_id;
2612 new_rfk->seq = seq + len;
2613 new_rfk->offset = rfk->offset + len - 4;
2614 new_rfk->start_seq = rfk->start_seq;
2615 g_hash_table_insert(rpc_reassembly_table, new_rfk,
2619 * This is part of a fragmented record,
2620 * but it's not the first part.
2621 * Show it as a record marker plus data, under
2622 * a top-level tree for this protocol,
2623 * but don't hand it to the dissector
2625 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
2628 * No more processing need be done, as we don't
2629 * have a complete record.
2635 * It's completely defragmented.
2637 * We only call subdissector for the last fragment.
2638 * XXX - this assumes in-order delivery of RPC
2639 * fragments, which requires in-order delivery of TCP
2642 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2644 * Well, it's defragmented, but this isn't
2645 * the last fragment; this probably means
2646 * this isn't the first pass, so we don't
2647 * need to start defragmentation.
2649 * This is part of a fragmented record,
2650 * but it's not the first part.
2651 * Show it as a record marker plus data, under
2652 * a top-level tree for this protocol,
2653 * but don't show it to the dissector.
2655 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
2658 * No more processing need be done, as we
2659 * only disssect the data with the last
2666 * OK, this is the last segment.
2667 * Create a tvbuff for the defragmented
2672 * Create a new TVB structure for
2673 * defragmented data.
2675 rec_tvb = tvb_new_real_data(ipfd_head->data,
2676 ipfd_head->datalen, ipfd_head->datalen);
2679 * Add this tvb as a child to the original
2682 tvb_set_child_real_data_tvbuff(tvb, rec_tvb);
2685 * Add defragmented data to the data source list.
2687 add_new_data_source(pinfo, rec_tvb, "Defragmented");
2691 * We have something to hand to the RPC message
2694 if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
2695 frag_tvb, dissector, ipfd_head, rpc_rm))
2696 return 0; /* not RPC */
2703 * NEED_MORE_DATA, if we don't have enough data to dissect anything;
2705 * IS_RPC, if we dissected at least one message in its entirety
2708 * IS_NOT_RPC, if we found no RPC message.
2716 static rpc_tcp_return_t
2717 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2721 gboolean saw_rpc = FALSE;
2724 while (tvb_reported_length_remaining(tvb, offset) != 0) {
2726 * Process this fragment.
2728 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
2729 dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
2733 * We need more data from the TCP stream for
2736 return NEED_MORE_DATA;
2740 * It's not RPC. Stop processing.
2748 return saw_rpc ? IS_RPC : IS_NOT_RPC;
2752 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2754 switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
2763 /* "Can't happen" */
2764 g_assert_not_reached();
2770 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2772 if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
2773 dissect_rpc_continuation(tvb, pinfo, tree);
2776 /* Discard any state we've saved. */
2778 rpc_init_protocol(void)
2780 if (rpc_calls != NULL) {
2781 g_hash_table_destroy(rpc_calls);
2784 if (rpc_indir_calls != NULL) {
2785 g_hash_table_destroy(rpc_indir_calls);
2786 rpc_indir_calls = NULL;
2788 if (rpc_call_info_key_chunk != NULL) {
2789 g_mem_chunk_destroy(rpc_call_info_key_chunk);
2790 rpc_call_info_key_chunk = NULL;
2792 if (rpc_call_info_value_chunk != NULL) {
2793 g_mem_chunk_destroy(rpc_call_info_value_chunk);
2794 rpc_call_info_value_chunk = NULL;
2796 if (rpc_fragment_key_chunk != NULL) {
2797 g_mem_chunk_destroy(rpc_fragment_key_chunk);
2798 rpc_fragment_key_chunk = NULL;
2800 if (rpc_reassembly_table != NULL) {
2801 g_hash_table_destroy(rpc_reassembly_table);
2802 rpc_reassembly_table = NULL;
2805 rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
2806 rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
2807 rpc_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
2808 sizeof(rpc_call_info_key),
2809 200 * sizeof(rpc_call_info_key),
2811 rpc_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
2812 sizeof(rpc_call_info_value),
2813 200 * sizeof(rpc_call_info_value),
2815 rpc_fragment_key_chunk = g_mem_chunk_new("rpc_fragment_key_chunk",
2816 sizeof(rpc_fragment_key),
2817 rpc_fragment_init_count*sizeof(rpc_fragment_key),
2819 rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
2820 rpc_fragment_equal);
2822 fragment_table_init(&rpc_fragment_table);
2825 /* will be called once from register.c at startup time */
2827 proto_register_rpc(void)
2829 static hf_register_info hf[] = {
2830 { &hf_rpc_lastfrag, {
2831 "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
2832 &yesno, RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
2833 { &hf_rpc_fraglen, {
2834 "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
2835 NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
2837 "XID", "rpc.xid", FT_UINT32, BASE_HEX,
2838 NULL, 0, "XID", HFILL }},
2839 { &hf_rpc_msgtype, {
2840 "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
2841 VALS(rpc_msg_type), 0, "Message Type", HFILL }},
2842 { &hf_rpc_state_reply, {
2843 "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
2844 VALS(rpc_reply_state), 0, "Reply State", HFILL }},
2845 { &hf_rpc_state_accept, {
2846 "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
2847 VALS(rpc_accept_state), 0, "Accept State", HFILL }},
2848 { &hf_rpc_state_reject, {
2849 "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
2850 VALS(rpc_reject_state), 0, "Reject State", HFILL }},
2851 { &hf_rpc_state_auth, {
2852 "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
2853 VALS(rpc_auth_state), 0, "Auth State", HFILL }},
2854 { &hf_rpc_version, {
2855 "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
2856 NULL, 0, "RPC Version", HFILL }},
2857 { &hf_rpc_version_min, {
2858 "RPC Version (Minimum)", "rpc.version.min", FT_UINT32,
2859 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
2860 { &hf_rpc_version_max, {
2861 "RPC Version (Maximum)", "rpc.version.max", FT_UINT32,
2862 BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
2863 { &hf_rpc_program, {
2864 "Program", "rpc.program", FT_UINT32, BASE_DEC,
2865 NULL, 0, "Program", HFILL }},
2866 { &hf_rpc_programversion, {
2867 "Program Version", "rpc.programversion", FT_UINT32,
2868 BASE_DEC, NULL, 0, "Program Version", HFILL }},
2869 { &hf_rpc_programversion_min, {
2870 "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32,
2871 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
2872 { &hf_rpc_programversion_max, {
2873 "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32,
2874 BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
2875 { &hf_rpc_procedure, {
2876 "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
2877 NULL, 0, "Procedure", HFILL }},
2878 { &hf_rpc_auth_flavor, {
2879 "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
2880 VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
2881 { &hf_rpc_auth_length, {
2882 "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
2883 NULL, 0, "Length", HFILL }},
2884 { &hf_rpc_auth_stamp, {
2885 "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
2886 NULL, 0, "Stamp", HFILL }},
2887 { &hf_rpc_auth_uid, {
2888 "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
2889 NULL, 0, "UID", HFILL }},
2890 { &hf_rpc_auth_gid, {
2891 "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
2892 NULL, 0, "GID", HFILL }},
2893 { &hf_rpc_authgss_v, {
2894 "GSS Version", "rpc.authgss.version", FT_UINT32,
2895 BASE_DEC, NULL, 0, "GSS Version", HFILL }},
2896 { &hf_rpc_authgss_proc, {
2897 "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
2898 BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
2899 { &hf_rpc_authgss_seq, {
2900 "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
2901 BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
2902 { &hf_rpc_authgss_svc, {
2903 "GSS Service", "rpc.authgss.service", FT_UINT32,
2904 BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
2905 { &hf_rpc_authgss_ctx, {
2906 "GSS Context", "rpc.authgss.context", FT_BYTES,
2907 BASE_HEX, NULL, 0, "GSS Context", HFILL }},
2908 { &hf_rpc_authgss_major, {
2909 "GSS Major Status", "rpc.authgss.major", FT_UINT32,
2910 BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
2911 { &hf_rpc_authgss_minor, {
2912 "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
2913 BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
2914 { &hf_rpc_authgss_window, {
2915 "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
2916 BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
2917 { &hf_rpc_authgss_token, {
2918 "GSS Token", "rpc.authgss.token", FT_BYTES,
2919 BASE_HEX, NULL, 0, "GSS Token", HFILL }},
2920 { &hf_rpc_authgss_data_length, {
2921 "Length", "rpc.authgss.data.length", FT_UINT32,
2922 BASE_DEC, NULL, 0, "Length", HFILL }},
2923 { &hf_rpc_authgss_data, {
2924 "GSS Data", "rpc.authgss.data", FT_BYTES,
2925 BASE_HEX, NULL, 0, "GSS Data", HFILL }},
2926 { &hf_rpc_authgss_checksum, {
2927 "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
2928 BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
2929 { &hf_rpc_authdes_namekind, {
2930 "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
2931 VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
2932 { &hf_rpc_authdes_netname, {
2933 "Netname", "rpc.authdes.netname", FT_STRING,
2934 BASE_DEC, NULL, 0, "Netname", HFILL }},
2935 { &hf_rpc_authdes_convkey, {
2936 "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
2937 BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
2938 { &hf_rpc_authdes_window, {
2939 "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
2940 BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
2941 { &hf_rpc_authdes_nickname, {
2942 "Nickname", "rpc.authdes.nickname", FT_UINT32,
2943 BASE_HEX, NULL, 0, "Nickname", HFILL }},
2944 { &hf_rpc_authdes_timestamp, {
2945 "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
2946 BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
2947 { &hf_rpc_authdes_windowverf, {
2948 "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
2949 BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
2950 { &hf_rpc_authdes_timeverf, {
2951 "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
2952 BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
2953 { &hf_rpc_auth_machinename, {
2954 "Machine Name", "rpc.auth.machinename", FT_STRING,
2955 BASE_DEC, NULL, 0, "Machine Name", HFILL }},
2957 "Duplicate Transaction", "rpc.dup", FT_UINT32, BASE_DEC,
2958 NULL, 0, "Duplicate Transaction", HFILL }},
2959 { &hf_rpc_call_dup, {
2960 "Duplicate Call", "rpc.call.dup", FT_UINT32, BASE_DEC,
2961 NULL, 0, "Duplicate Call", HFILL }},
2962 { &hf_rpc_reply_dup, {
2963 "Duplicate Reply", "rpc.reply.dup", FT_UINT32, BASE_DEC,
2964 NULL, 0, "Duplicate Reply", HFILL }},
2965 { &hf_rpc_value_follows, {
2966 "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
2967 &yesno, 0, "Value Follows", HFILL }},
2968 { &hf_rpc_array_len, {
2969 "num", "rpc.array.len", FT_UINT32, BASE_DEC,
2970 NULL, 0, "Length of RPC array", HFILL }},
2973 "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
2974 NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
2976 { &hf_rpc_fragment_overlap,
2977 { "Fragment overlap", "rpc.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2978 "Fragment overlaps with other fragments", HFILL }},
2980 { &hf_rpc_fragment_overlap_conflict,
2981 { "Conflicting data in fragment overlap", "rpc.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2982 "Overlapping fragments contained conflicting data", HFILL }},
2984 { &hf_rpc_fragment_multiple_tails,
2985 { "Multiple tail fragments found", "rpc.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2986 "Several tails were found when defragmenting the packet", HFILL }},
2988 { &hf_rpc_fragment_too_long_fragment,
2989 { "Fragment too long", "rpc.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2990 "Fragment contained data past end of packet", HFILL }},
2992 { &hf_rpc_fragment_error,
2993 { "Defragmentation error", "rpc.fragment.error", FT_NONE, BASE_NONE, NULL, 0x0,
2994 "Defragmentation error due to illegal fragments", HFILL }},
2997 { "RPC Fragment", "rpc.fragment", FT_NONE, BASE_NONE, NULL, 0x0,
2998 "RPC Fragment", HFILL }},
3000 { &hf_rpc_fragments,
3001 { "RPC Fragments", "rpc.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3002 "RPC Fragments", HFILL }},
3004 static gint *ett[] = {
3016 module_t *rpc_module;
3018 proto_rpc = proto_register_protocol("Remote Procedure Call",
3020 proto_register_field_array(proto_rpc, hf, array_length(hf));
3021 proto_register_subtree_array(ett, array_length(ett));
3022 register_init_routine(&rpc_init_protocol);
3024 rpc_module = prefs_register_protocol(proto_rpc, NULL);
3025 prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
3026 "Desegment all RPC-over-TCP messages",
3027 "Whether the RPC dissector should desegment all RPC-over-TCP messages",
3029 prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
3030 "Defragment all RPC-over-TCP messages",
3031 "Whether the RPC dissector should defragment multi-fragment RPC-over-TCP messages",
3034 register_dissector("rpc", dissect_rpc, proto_rpc);
3035 rpc_handle = find_dissector("rpc");
3036 register_dissector("rpc-tcp", dissect_rpc_tcp, proto_rpc);
3037 rpc_tcp_handle = find_dissector("rpc-tcp");
3040 * Init the hash tables. Dissectors for RPC protocols must
3041 * have a "handoff registration" routine that registers the
3042 * protocol with RPC; they must not do it in their protocol
3043 * registration routine, as their protocol registration
3044 * routine might be called before this routine is called and
3045 * thus might be called before the hash tables are initialized,
3046 * but it's guaranteed that all protocol registration routines
3047 * will be called before any handoff registration routines
3050 rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
3051 rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
3055 proto_reg_handoff_rpc(void)
3057 heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
3058 heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
3059 data_handle = find_dissector("data");