2 * Routines for rpc dissection
3 * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
5 * $Id: packet-rpc.c,v 1.122 2003/05/02 21:58:23 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.
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"
42 #include "reassemble.h"
43 #include "rpc_defrag.h"
44 #include "packet-nfs.h"
50 * RFC 1831, "RPC: Remote Procedure Call Protocol Specification
53 * RFC 1832, "XDR: External Data Representation Standard";
55 * RFC 2203, "RPCSEC_GSS Protocol Specification".
59 * RFC 2695, "Authentication Mechanisms for ONC RPC"
61 * although we don't currently dissect AUTH_DES or AUTH_KERB.
64 /* desegmentation of RPC over TCP */
65 static gboolean rpc_desegment = TRUE;
67 /* defragmentation of fragmented RPC over TCP records */
68 static gboolean rpc_defragment = FALSE;
70 static struct true_false_string yesno = { "Yes", "No" };
72 static int rpc_tap = -1;
74 static const value_string rpc_msg_type[] = {
76 { RPC_REPLY, "Reply" },
80 static const value_string rpc_reply_state[] = {
81 { MSG_ACCEPTED, "accepted" },
82 { MSG_DENIED, "denied" },
86 const value_string rpc_auth_flavor[] = {
87 { AUTH_NULL, "AUTH_NULL" },
88 { AUTH_UNIX, "AUTH_UNIX" },
89 { AUTH_SHORT, "AUTH_SHORT" },
90 { AUTH_DES, "AUTH_DES" },
91 { RPCSEC_GSS, "RPCSEC_GSS" },
92 { AUTH_GSSAPI, "AUTH_GSSAPI" },
96 static const value_string rpc_authgss_proc[] = {
97 { RPCSEC_GSS_DATA, "RPCSEC_GSS_DATA" },
98 { RPCSEC_GSS_INIT, "RPCSEC_GSS_INIT" },
99 { RPCSEC_GSS_CONTINUE_INIT, "RPCSEC_GSS_CONTINUE_INIT" },
100 { RPCSEC_GSS_DESTROY, "RPCSEC_GSS_DESTROY" },
104 static const value_string rpc_authgssapi_proc[] = {
105 { AUTH_GSSAPI_EXIT, "AUTH_GSSAPI_EXIT" },
106 { AUTH_GSSAPI_INIT, "AUTH_GSSAPI_INIT" },
107 { AUTH_GSSAPI_CONTINUE_INIT, "AUTH_GSSAPI_CONTINUE_INIT" },
108 { AUTH_GSSAPI_MSG, "AUTH_GSSAPI_MSG" },
109 { AUTH_GSSAPI_DESTROY, "AUTH_GSSAPI_DESTROY" },
113 value_string rpc_authgss_svc[] = {
114 { RPCSEC_GSS_SVC_NONE, "rpcsec_gss_svc_none" },
115 { RPCSEC_GSS_SVC_INTEGRITY, "rpcsec_gss_svc_integrity" },
116 { RPCSEC_GSS_SVC_PRIVACY, "rpcsec_gss_svc_privacy" },
120 static const value_string rpc_accept_state[] = {
121 { SUCCESS, "RPC executed successfully" },
122 { PROG_UNAVAIL, "remote hasn't exported program" },
123 { PROG_MISMATCH, "remote can't support version #" },
124 { PROC_UNAVAIL, "program can't support procedure" },
125 { GARBAGE_ARGS, "procedure can't decode params" },
129 static const value_string rpc_reject_state[] = {
130 { RPC_MISMATCH, "RPC_MISMATCH" },
131 { AUTH_ERROR, "AUTH_ERROR" },
135 static const value_string rpc_auth_state[] = {
136 { AUTH_BADCRED, "bad credential (seal broken)" },
137 { AUTH_REJECTEDCRED, "client must begin new session" },
138 { AUTH_BADVERF, "bad verifier (seal broken)" },
139 { AUTH_REJECTEDVERF, "verifier expired or replayed" },
140 { AUTH_TOOWEAK, "rejected for security reasons" },
141 { RPCSEC_GSSCREDPROB, "GSS credential problem" },
142 { RPCSEC_GSSCTXPROB, "GSS context problem" },
146 static const value_string rpc_authdes_namekind[] = {
147 { AUTHDES_NAMEKIND_FULLNAME, "ADN_FULLNAME" },
148 { AUTHDES_NAMEKIND_NICKNAME, "ADN_NICKNAME" },
152 /* the protocol number */
153 static int proto_rpc = -1;
154 static int hf_rpc_reqframe = -1;
155 static int hf_rpc_repframe = -1;
156 static int hf_rpc_lastfrag = -1;
157 static int hf_rpc_fraglen = -1;
158 static int hf_rpc_xid = -1;
159 static int hf_rpc_msgtype = -1;
160 static int hf_rpc_version = -1;
161 static int hf_rpc_version_min = -1;
162 static int hf_rpc_version_max = -1;
163 static int hf_rpc_program = -1;
164 static int hf_rpc_programversion = -1;
165 static int hf_rpc_programversion_min = -1;
166 static int hf_rpc_programversion_max = -1;
167 static int hf_rpc_procedure = -1;
168 static int hf_rpc_auth_flavor = -1;
169 static int hf_rpc_auth_length = -1;
170 static int hf_rpc_auth_machinename = -1;
171 static int hf_rpc_auth_stamp = -1;
172 static int hf_rpc_auth_uid = -1;
173 static int hf_rpc_auth_gid = -1;
174 static int hf_rpc_authgss_v = -1;
175 static int hf_rpc_authgss_proc = -1;
176 static int hf_rpc_authgss_seq = -1;
177 static int hf_rpc_authgss_svc = -1;
178 static int hf_rpc_authgss_ctx = -1;
179 static int hf_rpc_authgss_major = -1;
180 static int hf_rpc_authgss_minor = -1;
181 static int hf_rpc_authgss_window = -1;
182 static int hf_rpc_authgss_token_length = -1;
183 static int hf_rpc_authgss_data_length = -1;
184 static int hf_rpc_authgss_data = -1;
185 static int hf_rpc_authgss_checksum = -1;
186 static int hf_rpc_authgssapi_v = -1;
187 static int hf_rpc_authgssapi_msg = -1;
188 static int hf_rpc_authgssapi_msgv = -1;
189 static int hf_rpc_authgssapi_handle = -1;
190 static int hf_rpc_authgssapi_isn = -1;
191 static int hf_rpc_authdes_namekind = -1;
192 static int hf_rpc_authdes_netname = -1;
193 static int hf_rpc_authdes_convkey = -1;
194 static int hf_rpc_authdes_window = -1;
195 static int hf_rpc_authdes_nickname = -1;
196 static int hf_rpc_authdes_timestamp = -1;
197 static int hf_rpc_authdes_windowverf = -1;
198 static int hf_rpc_authdes_timeverf = -1;
199 static int hf_rpc_state_accept = -1;
200 static int hf_rpc_state_reply = -1;
201 static int hf_rpc_state_reject = -1;
202 static int hf_rpc_state_auth = -1;
203 static int hf_rpc_dup = -1;
204 static int hf_rpc_call_dup = -1;
205 static int hf_rpc_reply_dup = -1;
206 static int hf_rpc_value_follows = -1;
207 static int hf_rpc_array_len = -1;
208 static int hf_rpc_time = -1;
209 static int hf_rpc_fragments = -1;
210 static int hf_rpc_fragment = -1;
211 static int hf_rpc_fragment_overlap = -1;
212 static int hf_rpc_fragment_overlap_conflict = -1;
213 static int hf_rpc_fragment_multiple_tails = -1;
214 static int hf_rpc_fragment_too_long_fragment = -1;
215 static int hf_rpc_fragment_error = -1;
217 static gint ett_rpc = -1;
218 static gint ett_rpc_fragments = -1;
219 static gint ett_rpc_fragment = -1;
220 static gint ett_rpc_fraghdr = -1;
221 static gint ett_rpc_string = -1;
222 static gint ett_rpc_cred = -1;
223 static gint ett_rpc_verf = -1;
224 static gint ett_rpc_gids = -1;
225 static gint ett_rpc_gss_token = -1;
226 static gint ett_rpc_gss_data = -1;
227 static gint ett_rpc_array = -1;
228 static gint ett_rpc_authgssapi_msg = -1;
230 static dissector_handle_t rpc_tcp_handle;
231 static dissector_handle_t rpc_handle;
232 static dissector_handle_t gssapi_handle;
233 static dissector_handle_t data_handle;
235 static const fragment_items rpc_frag_items = {
240 &hf_rpc_fragment_overlap,
241 &hf_rpc_fragment_overlap_conflict,
242 &hf_rpc_fragment_multiple_tails,
243 &hf_rpc_fragment_too_long_fragment,
244 &hf_rpc_fragment_error,
249 /* Hash table with info on RPC program numbers */
250 GHashTable *rpc_progs;
252 /* Hash table with info on RPC procedure numbers */
253 GHashTable *rpc_procs;
255 static void dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
256 static void dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
258 /***********************************/
259 /* Hash array with procedure names */
260 /***********************************/
264 rpc_proc_equal(gconstpointer k1, gconstpointer k2)
266 const rpc_proc_info_key* key1 = (const rpc_proc_info_key*) k1;
267 const rpc_proc_info_key* key2 = (const rpc_proc_info_key*) k2;
269 return ((key1->prog == key2->prog &&
270 key1->vers == key2->vers &&
271 key1->proc == key2->proc) ?
275 /* calculate a hash key */
277 rpc_proc_hash(gconstpointer k)
279 const rpc_proc_info_key* key = (const rpc_proc_info_key*) k;
281 return (key->prog ^ (key->vers<<16) ^ (key->proc<<24));
285 /* insert some entries */
287 rpc_init_proc_table(guint prog, guint vers, const vsff *proc_table,
290 rpc_prog_info_key rpc_prog_key;
291 rpc_prog_info_value *rpc_prog;
295 * Add the operation number hfinfo value for this version of the
298 rpc_prog_key.prog = prog;
299 rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key);
300 g_assert(rpc_prog != NULL);
301 rpc_prog->procedure_hfs = g_array_set_size(rpc_prog->procedure_hfs,
303 g_array_insert_val(rpc_prog->procedure_hfs, vers, procedure_hf);
305 for (proc = proc_table ; proc->strptr!=NULL; proc++) {
306 rpc_proc_info_key *key;
307 rpc_proc_info_value *value;
309 key = (rpc_proc_info_key *) g_malloc(sizeof(rpc_proc_info_key));
312 key->proc = proc->value;
314 value = (rpc_proc_info_value *) g_malloc(sizeof(rpc_proc_info_value));
315 value->name = proc->strptr;
316 value->dissect_call = proc->dissect_call;
317 value->dissect_reply = proc->dissect_reply;
319 g_hash_table_insert(rpc_procs,key,value);
323 /* return the name associated with a previously registered procedure. */
324 char *rpc_proc_name(guint32 prog, guint32 vers, guint32 proc)
326 rpc_proc_info_key key;
327 rpc_proc_info_value *value;
329 static char procname_static[20];
335 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL)
336 procname = value->name;
338 /* happens only with strange program versions or
339 non-existing dissectors */
340 sprintf(procname_static, "proc-%u", key.proc);
341 procname = procname_static;
346 /*----------------------------------------*/
347 /* end of Hash array with procedure names */
348 /*----------------------------------------*/
351 /*********************************/
352 /* Hash array with program names */
353 /*********************************/
357 rpc_prog_equal(gconstpointer k1, gconstpointer k2)
359 const rpc_prog_info_key* key1 = (const rpc_prog_info_key*) k1;
360 const rpc_prog_info_key* key2 = (const rpc_prog_info_key*) k2;
362 return ((key1->prog == key2->prog) ?
367 /* calculate a hash key */
369 rpc_prog_hash(gconstpointer k)
371 const rpc_prog_info_key* key = (const rpc_prog_info_key*) k;
378 rpc_init_prog(int proto, guint32 prog, int ett)
380 rpc_prog_info_key *key;
381 rpc_prog_info_value *value;
383 key = (rpc_prog_info_key *) g_malloc(sizeof(rpc_prog_info_key));
386 value = (rpc_prog_info_value *) g_malloc(sizeof(rpc_prog_info_value));
387 value->proto = proto;
389 value->progname = proto_get_protocol_short_name(proto);
390 value->procedure_hfs = g_array_new(FALSE, TRUE, sizeof (int));
392 g_hash_table_insert(rpc_progs,key,value);
395 /* return the name associated with a previously registered program. This
396 should probably eventually be expanded to use the rpc YP/NIS map
397 so that it can give names for programs not handled by ethereal */
398 char *rpc_prog_name(guint32 prog)
400 char *progname = NULL;
401 rpc_prog_info_key rpc_prog_key;
402 rpc_prog_info_value *rpc_prog;
404 rpc_prog_key.prog = prog;
405 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
406 progname = "Unknown";
409 progname = rpc_prog->progname;
415 /*--------------------------------------*/
416 /* end of Hash array with program names */
417 /*--------------------------------------*/
419 typedef struct _rpc_call_info_key {
421 conversation_t *conversation;
424 static GMemChunk *rpc_call_info_key_chunk;
426 static GMemChunk *rpc_call_info_value_chunk;
428 static GHashTable *rpc_calls;
430 static GHashTable *rpc_indir_calls;
434 rpc_call_equal(gconstpointer k1, gconstpointer k2)
436 const rpc_call_info_key* key1 = (const rpc_call_info_key*) k1;
437 const rpc_call_info_key* key2 = (const rpc_call_info_key*) k2;
439 return (key1->xid == key2->xid &&
440 key1->conversation == key2->conversation);
444 /* calculate a hash key */
446 rpc_call_hash(gconstpointer k)
448 const rpc_call_info_key* key = (const rpc_call_info_key*) k;
450 return key->xid + GPOINTER_TO_UINT(key->conversation);
455 rpc_roundup(unsigned int a)
457 unsigned int mod = a % 4;
458 return a + ((mod)? 4-mod : 0);
463 dissect_rpc_bool(tvbuff_t *tvb, proto_tree *tree,
464 int hfindex, int offset)
467 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
473 dissect_rpc_uint32(tvbuff_t *tvb, proto_tree *tree,
474 int hfindex, int offset)
477 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
483 dissect_rpc_uint64(tvbuff_t *tvb, proto_tree *tree,
484 int hfindex, int offset)
486 header_field_info *hfinfo;
488 hfinfo = proto_registrar_get_nth(hfindex);
489 g_assert(hfinfo->type == FT_UINT64);
491 proto_tree_add_item(tree, hfindex, tvb, offset, 8, FALSE);
498 dissect_rpc_opaque_data(tvbuff_t *tvb, int offset,
499 proto_tree *tree, int hfindex,
500 gboolean fixed_length, guint32 length,
501 gboolean string_data, char **string_buffer_ret)
503 proto_item *string_item = NULL;
504 proto_tree *string_tree = NULL;
506 guint32 string_length;
507 guint32 string_length_full;
508 guint32 string_length_packet;
509 guint32 string_length_captured;
510 guint32 string_length_copy;
514 guint32 fill_length_packet;
515 guint32 fill_length_captured;
516 guint32 fill_length_copy;
520 char *string_buffer = NULL;
521 char *string_buffer_print = NULL;
524 string_length = length;
525 string_length_captured = tvb_length_remaining(tvb, offset);
526 string_length_packet = tvb_reported_length_remaining(tvb, offset);
529 string_length = tvb_get_ntohl(tvb,offset+0);
530 string_length_captured = tvb_length_remaining(tvb, offset + 4);
531 string_length_packet = tvb_reported_length_remaining(tvb, offset + 4);
533 string_length_full = rpc_roundup(string_length);
534 if (string_length_captured < string_length) {
535 /* truncated string */
536 string_length_copy = string_length_captured;
539 fill_length_copy = 0;
540 if (string_length_packet < string_length)
541 exception = ReportedBoundsError;
543 exception = BoundsError;
546 /* full string data */
547 string_length_copy = string_length;
548 fill_length = string_length_full - string_length;
550 fill_length_captured = tvb_length_remaining(tvb,
551 offset + string_length);
552 fill_length_packet = tvb_reported_length_remaining(tvb,
553 offset + string_length);
556 fill_length_captured = tvb_length_remaining(tvb,
557 offset + 4 + string_length);
558 fill_length_packet = tvb_reported_length_remaining(tvb,
559 offset + 4 + string_length);
561 if (fill_length_captured < fill_length) {
562 /* truncated fill bytes */
563 fill_length_copy = fill_length_packet;
565 if (fill_length_packet < fill_length)
566 exception = ReportedBoundsError;
568 exception = BoundsError;
571 /* full fill bytes */
572 fill_length_copy = fill_length;
576 string_buffer = (char*)g_malloc(string_length_copy +
577 (string_data ? 1 : 0));
579 tvb_memcpy(tvb,string_buffer, offset, string_length_copy);
581 tvb_memcpy(tvb,string_buffer,offset+4,string_length_copy);
583 string_buffer[string_length_copy] = '\0';
585 /* calculate a nice printable string */
587 if (string_length != string_length_copy) {
589 /* alloc maximum data area */
590 string_buffer_print = (char*)g_malloc(string_length_copy + 12 + 1);
591 /* copy over the data */
592 memcpy(string_buffer_print,string_buffer,string_length_copy);
593 /* append a 0 byte for sure printing */
594 string_buffer_print[string_length_copy] = '\0';
595 /* append <TRUNCATED> */
596 /* This way, we get the TRUNCATED even
597 in the case of totally wrong packets,
598 where \0 are inside the string.
599 TRUNCATED will appear at the
600 first \0 or at the end (where we
601 put the securing \0).
603 strcat(string_buffer_print,"<TRUNCATED>");
606 string_buffer_print = g_strdup("<DATA><TRUNCATED>");
611 string_buffer_print = g_strdup(string_buffer);
614 string_buffer_print = g_strdup("<DATA>");
619 string_buffer_print = g_strdup("<EMPTY>");
623 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
624 "%s: %s", proto_registrar_get_name(hfindex), string_buffer_print);
626 proto_tree_add_string_hidden(tree, hfindex, tvb,
627 (fixed_length)? offset : offset + 4,
628 string_length_copy, string_buffer);
631 string_tree = proto_item_add_subtree(string_item, ett_rpc_string);
636 proto_tree_add_text(string_tree, tvb,offset+0,4,
637 "length: %u", string_length);
643 proto_tree_add_string_format(string_tree,
644 hfindex, tvb, offset, string_length_copy,
646 "contents: %s", string_buffer_print);
648 proto_tree_add_bytes_format(string_tree,
649 hfindex, tvb, offset, string_length_copy,
651 "contents: %s", string_buffer_print);
654 offset += string_length_copy;
657 if (fill_truncated) {
658 proto_tree_add_text(string_tree, tvb,
659 offset,fill_length_copy,
660 "fill bytes: opaque data<TRUNCATED>");
663 proto_tree_add_text(string_tree, tvb,
664 offset,fill_length_copy,
665 "fill bytes: opaque data");
668 offset += fill_length_copy;
672 proto_item_set_end(string_item, tvb, offset);
675 if (string_buffer != NULL) g_free (string_buffer );
676 if (string_buffer_print != NULL) {
677 if (string_buffer_ret != NULL)
678 *string_buffer_ret = string_buffer_print;
680 g_free (string_buffer_print);
684 * If the data was truncated, throw the appropriate exception,
685 * so that dissection stops and the frame is properly marked.
694 dissect_rpc_string(tvbuff_t *tvb, proto_tree *tree,
695 int hfindex, int offset, char **string_buffer_ret)
697 offset = dissect_rpc_opaque_data(tvb, offset, tree,
698 hfindex, FALSE, 0, TRUE, string_buffer_ret);
704 dissect_rpc_data(tvbuff_t *tvb, proto_tree *tree,
705 int hfindex, int offset)
707 offset = dissect_rpc_opaque_data(tvb, offset, tree,
708 hfindex, FALSE, 0, FALSE, NULL);
714 dissect_rpc_bytes(tvbuff_t *tvb, proto_tree *tree,
715 int hfindex, int offset, guint32 length,
716 gboolean string_data, char **string_buffer_ret)
718 offset = dissect_rpc_opaque_data(tvb, offset, tree,
719 hfindex, TRUE, length, string_data, string_buffer_ret);
725 dissect_rpc_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
726 int offset, dissect_function_t *rpc_list_dissector)
728 guint32 value_follows;
731 value_follows = tvb_get_ntohl(tvb, offset+0);
732 proto_tree_add_boolean(tree,hf_rpc_value_follows, tvb,
733 offset+0, 4, value_follows);
735 if (value_follows == 1) {
736 offset = rpc_list_dissector(tvb, offset, pinfo, tree);
747 dissect_rpc_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
748 int offset, dissect_function_t *rpc_array_dissector,
751 proto_item* lock_item;
752 proto_tree* lock_tree;
755 num = tvb_get_ntohl(tvb, offset);
758 proto_tree_add_none_format(tree, hfindex, tvb, offset, 4,
765 lock_item = proto_tree_add_item(tree, hfindex, tvb, offset, -1, FALSE);
767 lock_tree = proto_item_add_subtree(lock_item, ett_rpc_array);
769 offset = dissect_rpc_uint32(tvb, lock_tree,
770 hf_rpc_array_len, offset);
773 offset = rpc_array_dissector(tvb, offset, pinfo, lock_tree);
776 proto_item_set_end(lock_item, tvb, offset);
781 dissect_rpc_authunix_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
790 proto_tree *gtree = NULL;
792 stamp = tvb_get_ntohl(tvb,offset+0);
794 proto_tree_add_uint(tree, hf_rpc_auth_stamp, tvb,
798 offset = dissect_rpc_string(tvb, tree,
799 hf_rpc_auth_machinename, offset, NULL);
801 uid = tvb_get_ntohl(tvb,offset+0);
803 proto_tree_add_uint(tree, hf_rpc_auth_uid, tvb,
807 gid = tvb_get_ntohl(tvb,offset+0);
809 proto_tree_add_uint(tree, hf_rpc_auth_gid, tvb,
813 gids_count = tvb_get_ntohl(tvb,offset+0);
815 gitem = proto_tree_add_text(tree, tvb,
816 offset, 4+gids_count*4, "Auxiliary GIDs");
817 gtree = proto_item_add_subtree(gitem, ett_rpc_gids);
821 for (gids_i = 0 ; gids_i < gids_count ; gids_i++) {
822 gids_entry = tvb_get_ntohl(tvb,offset+0);
824 proto_tree_add_uint(gtree, hf_rpc_auth_gid, tvb,
825 offset, 4, gids_entry);
828 /* how can I NOW change the gitem to print a list with
829 the first 16 gids? */
835 dissect_rpc_authgss_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
842 agc_v = tvb_get_ntohl(tvb, offset+0);
844 proto_tree_add_uint(tree, hf_rpc_authgss_v,
845 tvb, offset+0, 4, agc_v);
848 agc_proc = tvb_get_ntohl(tvb, offset+0);
850 proto_tree_add_uint(tree, hf_rpc_authgss_proc,
851 tvb, offset+0, 4, agc_proc);
854 agc_seq = tvb_get_ntohl(tvb, offset+0);
856 proto_tree_add_uint(tree, hf_rpc_authgss_seq,
857 tvb, offset+0, 4, agc_seq);
860 agc_svc = tvb_get_ntohl(tvb, offset+0);
862 proto_tree_add_uint(tree, hf_rpc_authgss_svc,
863 tvb, offset+0, 4, agc_svc);
866 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
873 dissect_rpc_authdes_desblock(tvbuff_t *tvb, proto_tree *tree,
874 int hfindex, int offset)
879 value_high = tvb_get_ntohl(tvb, offset + 0);
880 value_low = tvb_get_ntohl(tvb, offset + 4);
883 proto_tree_add_text(tree, tvb, offset, 8,
884 "%s: 0x%x%08x", proto_registrar_get_name(hfindex), value_high,
892 dissect_rpc_authdes_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
898 adc_namekind = tvb_get_ntohl(tvb, offset+0);
900 proto_tree_add_uint(tree, hf_rpc_authdes_namekind,
901 tvb, offset+0, 4, adc_namekind);
906 case AUTHDES_NAMEKIND_FULLNAME:
907 offset = dissect_rpc_string(tvb, tree,
908 hf_rpc_authdes_netname, offset, NULL);
909 offset = dissect_rpc_authdes_desblock(tvb, tree,
910 hf_rpc_authdes_convkey, offset);
911 window = tvb_get_ntohl(tvb, offset+0);
912 proto_tree_add_uint(tree, hf_rpc_authdes_window, tvb, offset+0, 4,
917 case AUTHDES_NAMEKIND_NICKNAME:
918 nickname = tvb_get_ntohl(tvb, offset+0);
919 proto_tree_add_uint(tree, hf_rpc_authdes_nickname, tvb, offset+0, 4,
929 dissect_rpc_authgssapi_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
934 agc_v = tvb_get_ntohl(tvb, offset+0);
936 proto_tree_add_uint(tree, hf_rpc_authgssapi_v,
937 tvb, offset+0, 4, agc_v);
940 agc_msg = tvb_get_ntohl(tvb, offset+0);
942 proto_tree_add_boolean(tree, hf_rpc_authgssapi_msg,
943 tvb, offset+0, 4, agc_msg);
946 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgssapi_handle,
953 dissect_rpc_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
961 flavor = tvb_get_ntohl(tvb,offset+0);
962 length = tvb_get_ntohl(tvb,offset+4);
963 length = rpc_roundup(length);
966 citem = proto_tree_add_text(tree, tvb, offset,
967 8+length, "Credentials");
968 ctree = proto_item_add_subtree(citem, ett_rpc_cred);
969 proto_tree_add_uint(ctree, hf_rpc_auth_flavor, tvb,
970 offset+0, 4, flavor);
971 proto_tree_add_uint(ctree, hf_rpc_auth_length, tvb,
972 offset+4, 4, length);
976 dissect_rpc_authunix_cred(tvb, ctree, offset+8);
984 dissect_rpc_authdes_cred(tvb, ctree, offset+8);
988 dissect_rpc_authgss_cred(tvb, ctree, offset+8);
992 dissect_rpc_authgssapi_cred(tvb, ctree, offset+8);
997 proto_tree_add_text(ctree, tvb, offset+8,
998 length,"opaque data");
1002 offset += 8 + length;
1007 /* AUTH_DES verifiers are asymmetrical, so we need to know what type of
1008 * verifier we're decoding (CALL or REPLY).
1011 dissect_rpc_verf(tvbuff_t* tvb, proto_tree* tree, int offset, int msg_type)
1019 flavor = tvb_get_ntohl(tvb,offset+0);
1020 length = tvb_get_ntohl(tvb,offset+4);
1021 length = rpc_roundup(length);
1024 vitem = proto_tree_add_text(tree, tvb, offset,
1025 8+length, "Verifier");
1026 vtree = proto_item_add_subtree(vitem, ett_rpc_verf);
1027 proto_tree_add_uint(vtree, hf_rpc_auth_flavor, tvb,
1028 offset+0, 4, flavor);
1032 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1033 offset+4, 4, length);
1034 dissect_rpc_authunix_cred(tvb, vtree, offset+8);
1037 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1038 offset+4, 4, length);
1040 if (msg_type == RPC_CALL)
1044 dissect_rpc_authdes_desblock(tvb, vtree,
1045 hf_rpc_authdes_timestamp, offset+8);
1046 window = tvb_get_ntohl(tvb, offset+16);
1047 proto_tree_add_uint(vtree, hf_rpc_authdes_windowverf, tvb,
1048 offset+16, 4, window);
1052 /* must be an RPC_REPLY */
1055 dissect_rpc_authdes_desblock(tvb, vtree,
1056 hf_rpc_authdes_timeverf, offset+8);
1057 nickname = tvb_get_ntohl(tvb, offset+16);
1058 proto_tree_add_uint(vtree, hf_rpc_authdes_nickname, tvb,
1059 offset+16, 4, nickname);
1063 dissect_rpc_data(tvb, vtree,
1064 hf_rpc_authgss_checksum, offset+4);
1067 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1068 offset+4, 4, length);
1070 proto_tree_add_text(vtree, tvb, offset+8,
1071 length, "opaque data");
1075 offset += 8 + length;
1081 * XDR opaque object, the contents of which are interpreted as a GSS-API
1085 dissect_rpc_authgss_token(tvbuff_t* tvb, proto_tree* tree, int offset,
1088 guint32 opaque_length, rounded_length;
1089 gint length, reported_length;
1093 proto_tree *gtree = NULL;
1095 opaque_length = tvb_get_ntohl(tvb, offset+0);
1096 rounded_length = rpc_roundup(opaque_length);
1098 gitem = proto_tree_add_text(tree, tvb, offset,
1099 4+rounded_length, "GSS Token");
1100 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_token);
1101 proto_tree_add_uint(gtree, hf_rpc_authgss_token_length,
1102 tvb, offset+0, 4, opaque_length);
1105 length = tvb_length_remaining(tvb, offset);
1106 reported_length = tvb_reported_length_remaining(tvb, offset);
1107 g_assert(length >= 0);
1108 g_assert(reported_length >= 0);
1109 if (length > reported_length)
1110 length = reported_length;
1111 if ((guint32)length > opaque_length)
1112 length = opaque_length;
1113 if ((guint32)reported_length > opaque_length)
1114 reported_length = opaque_length;
1115 new_tvb = tvb_new_subset(tvb, offset, length, reported_length);
1116 call_dissector(gssapi_handle, new_tvb, pinfo, gtree);
1117 offset += rounded_length;
1123 dissect_rpc_authgss_initarg(tvbuff_t* tvb, proto_tree* tree, int offset,
1126 return dissect_rpc_authgss_token(tvb, tree, offset, pinfo);
1130 dissect_rpc_authgss_initres(tvbuff_t* tvb, proto_tree* tree, int offset,
1133 int major, minor, window;
1135 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
1138 major = tvb_get_ntohl(tvb,offset+0);
1140 proto_tree_add_uint(tree, hf_rpc_authgss_major, tvb,
1141 offset+0, 4, major);
1144 minor = tvb_get_ntohl(tvb,offset+0);
1146 proto_tree_add_uint(tree, hf_rpc_authgss_minor, tvb,
1147 offset+0, 4, minor);
1150 window = tvb_get_ntohl(tvb,offset+0);
1152 proto_tree_add_uint(tree, hf_rpc_authgss_window, tvb,
1153 offset+0, 4, window);
1156 offset = dissect_rpc_authgss_token(tvb, tree, offset, pinfo);
1162 dissect_rpc_authgssapi_initarg(tvbuff_t* tvb, proto_tree* tree, int offset,
1167 proto_tree *mtree = NULL;
1170 mitem = proto_tree_add_text(tree, tvb, offset, -1,
1172 mtree = proto_item_add_subtree(mitem, ett_rpc_authgssapi_msg);
1174 version = tvb_get_ntohl(tvb, offset+0);
1176 proto_tree_add_uint(mtree, hf_rpc_authgssapi_msgv, tvb,
1177 offset+0, 4, version);
1181 offset = dissect_rpc_authgss_token(tvb, mtree, offset, pinfo);
1187 dissect_rpc_authgssapi_initres(tvbuff_t* tvb, proto_tree* tree, int offset,
1193 proto_tree *mtree = NULL;
1196 mitem = proto_tree_add_text(tree, tvb, offset, -1,
1198 mtree = proto_item_add_subtree(mitem, ett_rpc_authgssapi_msg);
1201 version = tvb_get_ntohl(tvb,offset+0);
1203 proto_tree_add_uint(mtree, hf_rpc_authgssapi_msgv, tvb,
1204 offset+0, 4, version);
1208 offset = dissect_rpc_data(tvb, mtree, hf_rpc_authgssapi_handle,
1211 major = tvb_get_ntohl(tvb,offset+0);
1213 proto_tree_add_uint(mtree, hf_rpc_authgss_major, tvb,
1214 offset+0, 4, major);
1218 minor = tvb_get_ntohl(tvb,offset+0);
1220 proto_tree_add_uint(mtree, hf_rpc_authgss_minor, tvb,
1221 offset+0, 4, minor);
1225 offset = dissect_rpc_authgss_token(tvb, mtree, offset, pinfo);
1227 offset = dissect_rpc_data(tvb, mtree, hf_rpc_authgssapi_isn, offset);
1233 dissect_auth_gssapi_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1235 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1241 call_dissect_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1242 int offset, dissect_function_t* dissect_function, const char *progname)
1244 const char *saved_proto;
1246 if (dissect_function != NULL) {
1247 /* set the current protocol name */
1248 saved_proto = pinfo->current_proto;
1249 if (progname != NULL)
1250 pinfo->current_proto = progname;
1252 /* call the dissector for the next level */
1253 offset = dissect_function(tvb, offset, pinfo, tree);
1255 /* restore the protocol name */
1256 pinfo->current_proto = saved_proto;
1264 dissect_rpc_authgss_integ_data(tvbuff_t *tvb, packet_info *pinfo,
1265 proto_tree *tree, int offset,
1266 dissect_function_t* dissect_function,
1267 const char *progname)
1269 guint32 length, rounded_length, seq;
1272 proto_tree *gtree = NULL;
1274 length = tvb_get_ntohl(tvb, offset+0);
1275 rounded_length = rpc_roundup(length);
1276 seq = tvb_get_ntohl(tvb, offset+4);
1279 gitem = proto_tree_add_text(tree, tvb, offset,
1280 4+rounded_length, "GSS Data");
1281 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_data);
1282 proto_tree_add_uint(gtree, hf_rpc_authgss_data_length,
1283 tvb, offset+0, 4, length);
1284 proto_tree_add_uint(gtree, hf_rpc_authgss_seq,
1285 tvb, offset+4, 4, seq);
1289 if (dissect_function != NULL) {
1291 call_dissect_function(tvb, pinfo, gtree, offset,
1292 dissect_function, progname);
1294 offset += rounded_length - 4;
1295 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_checksum,
1302 dissect_rpc_authgss_priv_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1304 offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1310 * Dissect the arguments to an indirect call; used by the portmapper/RPCBIND
1313 * Record this call in a hash table, similar to the hash table for
1314 * direct calls, so we can find it when dissecting an indirect call reply.
1317 dissect_rpc_indir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1318 int offset, int args_id, guint32 prog, guint32 vers, guint32 proc)
1320 conversation_t* conversation;
1321 static address null_address = { AT_NONE, 0, NULL };
1322 rpc_proc_info_key key;
1323 rpc_proc_info_value *value;
1324 rpc_call_info_value *rpc_call;
1325 rpc_call_info_key rpc_call_key;
1326 rpc_call_info_key *new_rpc_call_key;
1327 dissect_function_t *dissect_function = NULL;
1332 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1333 dissect_function = value->dissect_call;
1335 /* Keep track of the address and port whence the call came,
1336 and the port to which the call is being sent, so that
1337 we can match up calls with replies.
1339 If the transport is connection-oriented (we check, for
1340 now, only for "pinfo->ptype" of PT_TCP), we take
1341 into account the address from which the call was sent
1342 and the address to which the call was sent, because
1343 the addresses of the two endpoints should be the same
1344 for all calls and replies.
1346 If the transport is connectionless, we don't worry
1347 about the address to which the call was sent and from
1348 which the reply was sent, because there's no
1349 guarantee that the reply will come from the address
1350 to which the call was sent. */
1351 if (pinfo->ptype == PT_TCP) {
1352 conversation = find_conversation(&pinfo->src,
1353 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1354 pinfo->destport, 0);
1357 * XXX - can we just use NO_ADDR_B? Unfortunately,
1358 * you currently still have to pass a non-null
1359 * pointer for the second address argument even
1362 conversation = find_conversation(&pinfo->src,
1363 &null_address, pinfo->ptype, pinfo->srcport,
1364 pinfo->destport, 0);
1366 if (conversation == NULL) {
1367 /* It's not part of any conversation - create a new
1370 XXX - this should never happen, as we should've
1371 created a conversation for it in the RPC
1373 if (pinfo->ptype == PT_TCP) {
1374 conversation = conversation_new(&pinfo->src,
1375 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1376 pinfo->destport, 0);
1378 conversation = conversation_new(&pinfo->src,
1379 &null_address, pinfo->ptype, pinfo->srcport,
1380 pinfo->destport, 0);
1384 /* Make the dissector for this conversation the non-heuristic
1386 conversation_set_dissector(conversation,
1387 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1389 /* Prepare the key data.
1391 Dissectors for RPC procedure calls and replies shouldn't
1392 create new tvbuffs, and we don't create one ourselves,
1393 so we should have been handed the tvbuff for this RPC call;
1394 as such, the XID is at offset 0 in this tvbuff. */
1395 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1396 rpc_call_key.conversation = conversation;
1398 /* look up the request */
1399 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1400 if (rpc_call == NULL) {
1401 /* We didn't find it; create a new entry.
1402 Prepare the value data.
1403 Not all of it is needed for handling indirect
1404 calls, so we set a bunch of items to 0. */
1405 new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1406 *new_rpc_call_key = rpc_call_key;
1407 rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1408 rpc_call->req_num = 0;
1409 rpc_call->rep_num = 0;
1410 rpc_call->prog = prog;
1411 rpc_call->vers = vers;
1412 rpc_call->proc = proc;
1413 rpc_call->private_data = NULL;
1416 * XXX - what about RPCSEC_GSS?
1417 * Do we have to worry about it?
1419 rpc_call->flavor = FLAVOR_NOT_GSSAPI;
1420 rpc_call->gss_proc = 0;
1421 rpc_call->gss_svc = 0;
1422 rpc_call->proc_info = value;
1424 g_hash_table_insert(rpc_indir_calls, new_rpc_call_key,
1429 /* We don't know the procedure.
1430 Happens only with strange program versions or
1431 non-existing dissectors.
1432 Just show the arguments as opaque data. */
1433 offset = dissect_rpc_data(tvb, tree, args_id,
1440 proto_tree_add_text(tree, tvb, offset, 4,
1441 "Argument length: %u",
1442 tvb_get_ntohl(tvb, offset));
1446 /* Dissect the arguments */
1447 offset = call_dissect_function(tvb, pinfo, tree, offset,
1448 dissect_function, NULL);
1453 * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1457 dissect_rpc_indir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1458 int offset, int result_id, int prog_id, int vers_id, int proc_id)
1460 conversation_t* conversation;
1461 static address null_address = { AT_NONE, 0, NULL };
1462 rpc_call_info_key rpc_call_key;
1463 rpc_call_info_value *rpc_call;
1464 char *procname = NULL;
1465 char procname_static[20];
1466 dissect_function_t *dissect_function = NULL;
1468 /* Look for the matching call in the hash table of indirect
1469 calls. A reply must match a call that we've seen, and the
1470 reply must be sent to the same port and address that the
1471 call came from, and must come from the port to which the
1474 If the transport is connection-oriented (we check, for
1475 now, only for "pinfo->ptype" of PT_TCP), we take
1476 into account the address from which the call was sent
1477 and the address to which the call was sent, because
1478 the addresses of the two endpoints should be the same
1479 for all calls and replies.
1481 If the transport is connectionless, we don't worry
1482 about the address to which the call was sent and from
1483 which the reply was sent, because there's no
1484 guarantee that the reply will come from the address
1485 to which the call was sent. */
1486 if (pinfo->ptype == PT_TCP) {
1487 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1488 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1491 * XXX - can we just use NO_ADDR_B? Unfortunately,
1492 * you currently still have to pass a non-null
1493 * pointer for the second address argument even
1496 conversation = find_conversation(&null_address, &pinfo->dst,
1497 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1499 if (conversation == NULL) {
1500 /* We haven't seen an RPC call for that conversation,
1501 so we can't check for a reply to that call.
1502 Just show the reply stuff as opaque data. */
1503 offset = dissect_rpc_data(tvb, tree, result_id,
1508 /* The XIDs of the call and reply must match. */
1509 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1510 rpc_call_key.conversation = conversation;
1511 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1512 if (rpc_call == NULL) {
1513 /* The XID doesn't match a call from that
1514 conversation, so it's probably not an RPC reply.
1515 Just show the reply stuff as opaque data. */
1516 offset = dissect_rpc_data(tvb, tree, result_id,
1521 if (rpc_call->proc_info != NULL) {
1522 dissect_function = rpc_call->proc_info->dissect_reply;
1523 if (rpc_call->proc_info->name != NULL) {
1524 procname = rpc_call->proc_info->name;
1527 sprintf(procname_static, "proc-%u", rpc_call->proc);
1528 procname = procname_static;
1533 dissect_function = NULL;
1535 sprintf(procname_static, "proc-%u", rpc_call->proc);
1536 procname = procname_static;
1541 /* Put the program, version, and procedure into the tree. */
1542 proto_tree_add_uint_format(tree, prog_id, tvb,
1543 0, 0, rpc_call->prog, "Program: %s (%u)",
1544 rpc_prog_name(rpc_call->prog), rpc_call->prog);
1545 proto_tree_add_uint(tree, vers_id, tvb, 0, 0, rpc_call->vers);
1546 proto_tree_add_uint_format(tree, proc_id, tvb,
1547 0, 0, rpc_call->proc, "Procedure: %s (%u)",
1548 procname, rpc_call->proc);
1551 if (dissect_function == NULL) {
1552 /* We don't know how to dissect the reply procedure.
1553 Just show the reply stuff as opaque data. */
1554 offset = dissect_rpc_data(tvb, tree, result_id,
1560 /* Put the length of the reply value into the tree. */
1561 proto_tree_add_text(tree, tvb, offset, 4,
1562 "Argument length: %u",
1563 tvb_get_ntohl(tvb, offset));
1567 /* Dissect the return value */
1568 offset = call_dissect_function(tvb, pinfo, tree, offset,
1569 dissect_function, NULL);
1574 * Just mark this as a continuation of an earlier packet.
1577 dissect_rpc_continuation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1579 proto_item *rpc_item;
1580 proto_tree *rpc_tree;
1582 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1583 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1584 if (check_col(pinfo->cinfo, COL_INFO))
1585 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1588 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1590 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1591 proto_tree_add_text(rpc_tree, tvb, 0, -1, "Continuation data");
1596 dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1597 tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
1598 guint32 rpc_rm, gboolean first_pdu)
1601 rpc_call_info_key rpc_call_key;
1602 rpc_call_info_value *rpc_call = NULL;
1603 rpc_prog_info_value *rpc_prog = NULL;
1604 rpc_prog_info_key rpc_prog_key;
1607 unsigned int rpcvers;
1608 unsigned int prog = 0;
1609 unsigned int vers = 0;
1610 unsigned int proc = 0;
1611 flavor_t flavor = FLAVOR_UNKNOWN;
1612 unsigned int gss_proc = 0;
1613 unsigned int gss_svc = 0;
1618 unsigned int reply_state;
1619 unsigned int accept_state;
1620 unsigned int reject_state;
1622 char *msg_type_name = NULL;
1623 char *progname = NULL;
1624 char *procname = NULL;
1625 static char procname_static[20];
1627 unsigned int vers_low;
1628 unsigned int vers_high;
1630 unsigned int auth_state;
1632 proto_item *rpc_item = NULL;
1633 proto_tree *rpc_tree = NULL;
1635 proto_item *pitem = NULL;
1636 proto_tree *ptree = NULL;
1637 int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
1639 rpc_call_info_key *new_rpc_call_key;
1640 rpc_proc_info_key key;
1641 rpc_proc_info_value *value = NULL;
1642 conversation_t* conversation;
1643 static address null_address = { AT_NONE, 0, NULL };
1646 dissect_function_t *dissect_function = NULL;
1647 gboolean dissect_rpc = TRUE;
1650 * Check to see whether this looks like an RPC call or reply.
1652 if (!tvb_bytes_exist(tvb, offset, 8)) {
1653 /* Captured data in packet isn't enough to let us tell. */
1657 /* both directions need at least this */
1658 msg_type = tvb_get_ntohl(tvb, offset + 4);
1663 /* check for RPC call */
1664 if (!tvb_bytes_exist(tvb, offset, 16)) {
1665 /* Captured data in packet isn't enough to let us
1670 /* XID can be anything, we don't check it.
1671 We already have the message type.
1672 Check whether an RPC version number of 2 is in the
1673 location where it would be, and that an RPC program
1674 number we know about is in the location where it would be. */
1675 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1676 if (tvb_get_ntohl(tvb, offset + 8) != 2 ||
1677 ((rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key))
1679 /* They're not, so it's probably not an RPC call. */
1685 /* Check for RPC reply. A reply must match a call that
1686 we've seen, and the reply must be sent to the same
1687 port and address that the call came from, and must
1688 come from the port to which the call was sent.
1690 If the transport is connection-oriented (we check, for
1691 now, only for "pinfo->ptype" of PT_TCP), we take
1692 into account the address from which the call was sent
1693 and the address to which the call was sent, because
1694 the addresses of the two endpoints should be the same
1695 for all calls and replies.
1697 If the transport is connectionless, we don't worry
1698 about the address to which the call was sent and from
1699 which the reply was sent, because there's no
1700 guarantee that the reply will come from the address
1701 to which the call was sent. */
1702 if (pinfo->ptype == PT_TCP) {
1703 conversation = find_conversation(&pinfo->src,
1704 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1705 pinfo->destport, 0);
1708 * XXX - can we just use NO_ADDR_B? Unfortunately,
1709 * you currently still have to pass a non-null
1710 * pointer for the second address argument even
1713 conversation = find_conversation(&null_address,
1714 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1715 pinfo->destport, 0);
1717 if (conversation == NULL) {
1718 /* We haven't seen an RPC call for that conversation,
1719 so we can't check for a reply to that call. */
1723 /* The XIDs of the call and reply must match. */
1724 rpc_call_key.xid = tvb_get_ntohl(tvb, offset + 0);
1725 rpc_call_key.conversation = conversation;
1726 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1727 if (rpc_call == NULL) {
1728 /* The XID doesn't match a call from that
1729 conversation, so it's probably not an RPC reply. */
1732 /* pass rpc_info to subdissectors */
1733 rpc_call->request=FALSE;
1734 pinfo->private_data=rpc_call;
1738 /* The putative message type field contains neither
1739 RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1746 * This is RPC-over-TCP; check if this is the last
1749 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
1751 * This isn't the last fragment.
1752 * If we're doing reassembly, just return
1753 * TRUE to indicate that this looks like
1754 * the beginning of an RPC message,
1755 * and let them do fragment reassembly.
1762 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1763 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1766 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1768 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1771 show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
1776 xid = tvb_get_ntohl(tvb, offset + 0);
1778 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1779 offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1782 msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1784 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1785 offset+4, 4, msg_type);
1793 /* we know already the proto-entry, the ETT-const,
1795 proto = rpc_prog->proto;
1796 ett = rpc_prog->ett;
1797 progname = rpc_prog->progname;
1799 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1801 proto_tree_add_uint(rpc_tree,
1802 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1805 prog = tvb_get_ntohl(tvb, offset + 4);
1808 proto_tree_add_uint_format(rpc_tree,
1809 hf_rpc_program, tvb, offset+4, 4, prog,
1810 "Program: %s (%u)", progname, prog);
1813 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1814 /* Set the protocol name to the underlying
1816 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1819 vers = tvb_get_ntohl(tvb, offset+8);
1821 proto_tree_add_uint(rpc_tree,
1822 hf_rpc_programversion, tvb, offset+8, 4, vers);
1825 proc = tvb_get_ntohl(tvb, offset+12);
1831 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1832 dissect_function = value->dissect_call;
1833 procname = value->name;
1836 /* happens only with strange program versions or
1837 non-existing dissectors */
1839 dissect_function = NULL;
1841 sprintf(procname_static, "proc-%u", proc);
1842 procname = procname_static;
1845 /* Check for RPCSEC_GSS and AUTH_GSSAPI */
1846 if (tvb_bytes_exist(tvb, offset+16, 4)) {
1847 switch (tvb_get_ntohl(tvb, offset+16)) {
1851 * It's GSS-API authentication...
1853 if (tvb_bytes_exist(tvb, offset+28, 8)) {
1855 * ...and we have the procedure
1856 * and service information for it.
1858 flavor = FLAVOR_GSSAPI;
1859 gss_proc = tvb_get_ntohl(tvb, offset+28);
1860 gss_svc = tvb_get_ntohl(tvb, offset+36);
1863 * ...but the procedure and service
1864 * information isn't available.
1866 flavor = FLAVOR_GSSAPI_NO_INFO;
1872 * AUTH_GSSAPI flavor. If auth_msg is TRUE,
1873 * then this is an AUTH_GSSAPI message and
1874 * not an application level message.
1876 if (tvb_bytes_exist(tvb, offset+28, 4)) {
1877 if (tvb_get_ntohl(tvb, offset+28)) {
1878 flavor = FLAVOR_AUTHGSSAPI_MSG;
1881 match_strval(gss_proc,
1882 rpc_authgssapi_proc);
1884 flavor = FLAVOR_AUTHGSSAPI;
1891 * It's not GSS-API authentication.
1893 flavor = FLAVOR_NOT_GSSAPI;
1899 proto_tree_add_uint_format(rpc_tree,
1900 hf_rpc_procedure, tvb, offset+12, 4, proc,
1901 "Procedure: %s (%u)", procname, proc);
1904 if (check_col(pinfo->cinfo, COL_INFO)) {
1906 col_clear(pinfo->cinfo, COL_INFO);
1908 col_append_fstr(pinfo->cinfo, COL_INFO, " ; ");
1909 col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s XID 0x%x",
1916 /* Keep track of the address and port whence the call came,
1917 and the port to which the call is being sent, so that
1918 we can match up calls with replies.
1920 If the transport is connection-oriented (we check, for
1921 now, only for "pinfo->ptype" of PT_TCP), we take
1922 into account the address from which the call was sent
1923 and the address to which the call was sent, because
1924 the addresses of the two endpoints should be the same
1925 for all calls and replies.
1927 If the transport is connectionless, we don't worry
1928 about the address to which the call was sent and from
1929 which the reply was sent, because there's no
1930 guarantee that the reply will come from the address
1931 to which the call was sent. */
1932 if (pinfo->ptype == PT_TCP) {
1933 conversation = find_conversation(&pinfo->src,
1934 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1935 pinfo->destport, 0);
1938 * XXX - can we just use NO_ADDR_B? Unfortunately,
1939 * you currently still have to pass a non-null
1940 * pointer for the second address argument even
1943 conversation = find_conversation(&pinfo->src,
1944 &null_address, pinfo->ptype, pinfo->srcport,
1945 pinfo->destport, 0);
1947 if (conversation == NULL) {
1948 /* It's not part of any conversation - create a new
1950 if (pinfo->ptype == PT_TCP) {
1951 conversation = conversation_new(&pinfo->src,
1952 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1953 pinfo->destport, 0);
1955 conversation = conversation_new(&pinfo->src,
1956 &null_address, pinfo->ptype, pinfo->srcport,
1957 pinfo->destport, 0);
1961 /* Make the dissector for this conversation the non-heuristic
1963 conversation_set_dissector(conversation,
1964 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1966 /* prepare the key data */
1967 rpc_call_key.xid = xid;
1968 rpc_call_key.conversation = conversation;
1970 /* look up the request */
1971 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1972 if (rpc_call != NULL) {
1973 /* We've seen a request with this XID, with the same
1974 source and destination, before - but was it
1976 if (pinfo->fd->num != rpc_call->req_num) {
1977 /* No, so it's a duplicate request.
1979 if (check_col(pinfo->cinfo, COL_INFO)) {
1980 col_append_fstr(pinfo->cinfo, COL_INFO,
1981 " dup XID 0x%x", xid);
1983 proto_tree_add_uint_hidden(rpc_tree,
1984 hf_rpc_dup, tvb, 0,0, xid);
1985 proto_tree_add_uint_hidden(rpc_tree,
1986 hf_rpc_call_dup, tvb, 0,0, xid);
1992 /* Prepare the value data.
1993 "req_num" and "rep_num" are frame numbers;
1994 frame numbers are 1-origin, so we use 0
1995 to mean "we don't yet know in which frame
1996 the reply for this call appears". */
1997 new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1998 *new_rpc_call_key = rpc_call_key;
1999 rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
2000 rpc_call->req_num = pinfo->fd->num;
2001 rpc_call->rep_num = 0;
2002 rpc_call->prog = prog;
2003 rpc_call->vers = vers;
2004 rpc_call->proc = proc;
2005 rpc_call->private_data = NULL;
2006 rpc_call->xid = xid;
2007 rpc_call->flavor = flavor;
2008 rpc_call->gss_proc = gss_proc;
2009 rpc_call->gss_svc = gss_svc;
2010 rpc_call->proc_info = value;
2011 rpc_call->req_time.secs=pinfo->fd->abs_secs;
2012 rpc_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
2015 g_hash_table_insert(rpc_calls, new_rpc_call_key,
2019 if(rpc_call && rpc_call->rep_num){
2020 proto_tree_add_uint_format(rpc_tree, hf_rpc_repframe,
2021 tvb, 0, 0, rpc_call->rep_num,
2022 "The reply to this request is in frame %u",
2028 offset = dissect_rpc_cred(tvb, rpc_tree, offset);
2029 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type);
2031 /* pass rpc_info to subdissectors */
2032 rpc_call->request=TRUE;
2033 pinfo->private_data=rpc_call;
2035 /* go to the next dissector */
2037 break; /* end of RPC call */
2040 /* we know already the type from the calling routine,
2041 and we already have "rpc_call" set above. */
2042 prog = rpc_call->prog;
2043 vers = rpc_call->vers;
2044 proc = rpc_call->proc;
2045 flavor = rpc_call->flavor;
2046 gss_proc = rpc_call->gss_proc;
2047 gss_svc = rpc_call->gss_svc;
2049 if (rpc_call->proc_info != NULL) {
2050 dissect_function = rpc_call->proc_info->dissect_reply;
2051 if (rpc_call->proc_info->name != NULL) {
2052 procname = rpc_call->proc_info->name;
2055 sprintf(procname_static, "proc-%u", proc);
2056 procname = procname_static;
2061 dissect_function = NULL;
2063 sprintf(procname_static, "proc-%u", proc);
2064 procname = procname_static;
2068 * If this is an AUTH_GSSAPI message, then the RPC procedure
2069 * is not an application procedure, but rather an auth level
2070 * procedure, so it would be misleading to print the RPC
2071 * procname. Replace the RPC procname with the corresponding
2072 * AUTH_GSSAPI procname.
2074 if (flavor == FLAVOR_AUTHGSSAPI_MSG) {
2075 procname = match_strval(gss_proc, rpc_authgssapi_proc);
2078 rpc_prog_key.prog = prog;
2079 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
2082 progname = "Unknown";
2085 proto = rpc_prog->proto;
2086 ett = rpc_prog->ett;
2087 progname = rpc_prog->progname;
2089 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2090 /* Set the protocol name to the underlying
2092 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
2096 if (check_col(pinfo->cinfo, COL_INFO)) {
2098 col_clear(pinfo->cinfo, COL_INFO);
2100 col_append_fstr(pinfo->cinfo, COL_INFO, " ; ");
2101 col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s XID 0x%x",
2109 proto_tree_add_uint_format(rpc_tree,
2110 hf_rpc_program, tvb, 0, 0, prog,
2111 "Program: %s (%u)", progname, prog);
2112 proto_tree_add_uint(rpc_tree,
2113 hf_rpc_programversion, tvb, 0, 0, vers);
2114 proto_tree_add_uint_format(rpc_tree,
2115 hf_rpc_procedure, tvb, 0, 0, proc,
2116 "Procedure: %s (%u)", procname, proc);
2119 reply_state = tvb_get_ntohl(tvb,offset+0);
2121 proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
2122 offset+0, 4, reply_state);
2126 /* Indicate the frame to which this is a reply. */
2127 if(rpc_call && rpc_call->req_num){
2128 proto_tree_add_uint_format(rpc_tree, hf_rpc_reqframe,
2129 tvb, 0, 0, rpc_call->req_num,
2130 "This is a reply to a request in frame %u",
2132 ns.secs= pinfo->fd->abs_secs-rpc_call->req_time.secs;
2133 ns.nsecs=pinfo->fd->abs_usecs*1000-rpc_call->req_time.nsecs;
2135 ns.nsecs+=1000000000;
2138 proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
2143 if (rpc_call->rep_num == 0) {
2144 /* We have not yet seen a reply to that call, so
2145 this must be the first reply; remember its
2147 rpc_call->rep_num = pinfo->fd->num;
2149 /* We have seen a reply to this call - but was it
2151 if (rpc_call->rep_num != pinfo->fd->num) {
2152 /* No, so it's a duplicate reply.
2154 if (check_col(pinfo->cinfo, COL_INFO)) {
2155 col_append_fstr(pinfo->cinfo, COL_INFO,
2156 " dup XID 0x%x", xid);
2158 proto_tree_add_uint_hidden(rpc_tree,
2159 hf_rpc_dup, tvb, 0,0, xid);
2160 proto_tree_add_uint_hidden(rpc_tree,
2161 hf_rpc_reply_dup, tvb, 0,0, xid);
2167 switch (reply_state) {
2170 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type);
2171 accept_state = tvb_get_ntohl(tvb,offset+0);
2173 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
2174 offset+0, 4, accept_state);
2177 switch (accept_state) {
2180 /* go to the next dissector */
2184 vers_low = tvb_get_ntohl(tvb,offset+0);
2185 vers_high = tvb_get_ntohl(tvb,offset+4);
2187 proto_tree_add_uint(rpc_tree,
2188 hf_rpc_programversion_min,
2189 tvb, offset+0, 4, vers_low);
2190 proto_tree_add_uint(rpc_tree,
2191 hf_rpc_programversion_max,
2192 tvb, offset+4, 4, vers_high);
2197 * There's no protocol reply, so don't
2198 * try to dissect it.
2200 dissect_rpc = FALSE;
2205 * There's no protocol reply, so don't
2206 * try to dissect it.
2208 dissect_rpc = FALSE;
2214 reject_state = tvb_get_ntohl(tvb,offset+0);
2216 proto_tree_add_uint(rpc_tree,
2217 hf_rpc_state_reject, tvb, offset+0, 4,
2222 if (reject_state==RPC_MISMATCH) {
2223 vers_low = tvb_get_ntohl(tvb,offset+0);
2224 vers_high = tvb_get_ntohl(tvb,offset+4);
2226 proto_tree_add_uint(rpc_tree,
2228 tvb, offset+0, 4, vers_low);
2229 proto_tree_add_uint(rpc_tree,
2231 tvb, offset+4, 4, vers_high);
2234 } else if (reject_state==AUTH_ERROR) {
2235 auth_state = tvb_get_ntohl(tvb,offset+0);
2237 proto_tree_add_uint(rpc_tree,
2238 hf_rpc_state_auth, tvb, offset+0, 4,
2245 * There's no protocol reply, so don't
2246 * try to dissect it.
2248 dissect_rpc = FALSE;
2253 * This isn't a valid reply state, so we have
2254 * no clue what's going on; don't try to dissect
2255 * the protocol reply.
2257 dissect_rpc = FALSE;
2260 break; /* end of RPC reply */
2264 * The switch statement at the top returned if
2265 * this was neither an RPC call nor a reply.
2267 g_assert_not_reached();
2270 /* now we know, that RPC was shorter */
2272 proto_item_set_end(rpc_item, tvb, offset);
2277 * There's no RPC call or reply here; just dissect
2278 * whatever's left as data.
2280 call_dissector(data_handle,
2281 tvb_new_subset(tvb, offset, -1, -1), pinfo, rpc_tree);
2285 /* create here the program specific sub-tree */
2286 if (tree && (flavor != FLAVOR_AUTHGSSAPI_MSG)) {
2287 pitem = proto_tree_add_item(tree, proto, tvb, offset, -1,
2290 ptree = proto_item_add_subtree(pitem, ett);
2294 proto_tree_add_uint(ptree,
2295 hf_rpc_programversion, tvb, 0, 0, vers);
2296 if (rpc_prog->procedure_hfs->len > vers)
2297 procedure_hf = g_array_index(rpc_prog->procedure_hfs, int, vers);
2300 * No such element in the GArray.
2304 if (procedure_hf != 0 && procedure_hf != -1) {
2305 proto_tree_add_uint(ptree,
2306 procedure_hf, tvb, 0, 0, proc);
2308 proto_tree_add_uint_format(ptree,
2309 hf_rpc_procedure, tvb, 0, 0, proc,
2310 "Procedure: %s (%u)", procname, proc);
2315 /* we must queue this packet to the tap system before we actually
2316 call the subdissectors since short packets (i.e. nfs read reply)
2317 will cause an exception and execution would never reach the call
2318 to tap_queue_packet() in that case
2320 tap_queue_packet(rpc_tap, pinfo, rpc_call);
2323 if (!proto_is_protocol_enabled(proto))
2324 dissect_function = NULL;
2327 * Handle RPCSEC_GSS and AUTH_GSSAPI specially.
2331 case FLAVOR_UNKNOWN:
2333 * We don't know the authentication flavor, so we can't
2334 * dissect the payload.
2336 proto_tree_add_text(ptree, tvb, offset, -1,
2337 "Unknown authentication flavor - cannot dissect");
2340 case FLAVOR_NOT_GSSAPI:
2342 * It's not GSS-API authentication. Just dissect the
2345 offset = call_dissect_function(tvb, pinfo, ptree, offset,
2346 dissect_function, progname);
2349 case FLAVOR_GSSAPI_NO_INFO:
2351 * It's GSS-API authentication, but we don't have the
2352 * procedure and service information, so we can't dissect
2355 proto_tree_add_text(ptree, tvb, offset, -1,
2356 "GSS-API authentication, but procedure and service unknown - cannot dissect");
2361 * It's GSS-API authentication, and we have the procedure
2362 * and service information; process the GSS-API stuff,
2363 * and process the payload if there is any.
2367 case RPCSEC_GSS_INIT:
2368 case RPCSEC_GSS_CONTINUE_INIT:
2369 if (msg_type == RPC_CALL) {
2370 offset = dissect_rpc_authgss_initarg(tvb,
2371 ptree, offset, pinfo);
2374 offset = dissect_rpc_authgss_initres(tvb,
2375 ptree, offset, pinfo);
2379 case RPCSEC_GSS_DATA:
2380 if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2381 offset = call_dissect_function(tvb,
2382 pinfo, ptree, offset,
2386 else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2387 offset = dissect_rpc_authgss_integ_data(tvb,
2388 pinfo, ptree, offset,
2392 else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2393 offset = dissect_rpc_authgss_priv_data(tvb,
2403 case FLAVOR_AUTHGSSAPI_MSG:
2405 * This is an AUTH_GSSAPI message. It contains data
2406 * only for the authentication procedure and not for the
2407 * application level RPC procedure. Reset the column
2408 * protocol and info fields to indicate that this is
2409 * an RPC auth level message, then process the args.
2411 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2412 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
2414 if (check_col(pinfo->cinfo, COL_INFO)) {
2415 col_clear(pinfo->cinfo, COL_INFO);
2416 col_append_fstr(pinfo->cinfo, COL_INFO,
2418 match_strval(gss_proc, rpc_authgssapi_proc),
2419 msg_type_name, xid);
2424 case AUTH_GSSAPI_INIT:
2425 case AUTH_GSSAPI_CONTINUE_INIT:
2426 case AUTH_GSSAPI_MSG:
2427 if (msg_type == RPC_CALL) {
2428 offset = dissect_rpc_authgssapi_initarg(tvb,
2429 rpc_tree, offset, pinfo);
2431 offset = dissect_rpc_authgssapi_initres(tvb,
2432 rpc_tree, offset, pinfo);
2436 case AUTH_GSSAPI_DESTROY:
2437 offset = dissect_rpc_data(tvb, rpc_tree,
2438 hf_rpc_authgss_data, offset);
2441 case AUTH_GSSAPI_EXIT:
2445 /* Adjust the length to account for the auth message. */
2447 proto_item_set_end(rpc_item, tvb, offset);
2451 case FLAVOR_AUTHGSSAPI:
2453 * An RPC with AUTH_GSSAPI authentication. The data
2454 * portion is always private, so don't call the dissector.
2456 offset = dissect_auth_gssapi_data(tvb, ptree, offset);
2460 /* dissect any remaining bytes (incomplete dissection) as pure data in
2462 call_dissector(data_handle,
2463 tvb_new_subset(tvb, offset, -1, -1), pinfo, ptree);
2466 /* XXX this should really loop over all fhandles registred for the frame */
2467 if(nfs_fhandle_reqrep_matching){
2468 nfs_fhandle_data_t *fhd;
2471 if(rpc_call && rpc_call->rep_num){
2472 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2473 nfs_fhandle_frame_table,
2474 (gconstpointer)rpc_call->rep_num);
2476 dissect_fhandle_hidden(pinfo,
2482 if(rpc_call && rpc_call->req_num){
2483 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2484 nfs_fhandle_frame_table,
2485 (gconstpointer)rpc_call->req_num);
2487 dissect_fhandle_hidden(pinfo,
2499 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2501 return dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2506 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2508 if (!dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2510 if (tvb_length(tvb) != 0)
2511 dissect_rpc_continuation(tvb, pinfo, tree);
2516 /* Defragmentation of RPC-over-TCP records */
2517 /* table to hold defragmented RPC records */
2518 static GHashTable *rpc_fragment_table = NULL;
2520 static GHashTable *rpc_reassembly_table = NULL;
2521 static GMemChunk *rpc_fragment_key_chunk = NULL;
2522 static int rpc_fragment_init_count = 200;
2524 typedef struct _rpc_fragment_key {
2533 rpc_fragment_hash(gconstpointer k)
2535 const rpc_fragment_key *key = (const rpc_fragment_key *)k;
2537 return key->conv_id + key->seq;
2541 rpc_fragment_equal(gconstpointer k1, gconstpointer k2)
2543 const rpc_fragment_key *key1 = (const rpc_fragment_key *)k1;
2544 const rpc_fragment_key *key2 = (const rpc_fragment_key *)k2;
2546 return key1->conv_id == key2->conv_id &&
2547 key1->seq == key2->seq;
2551 show_rpc_fragheader(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2553 proto_item *hdr_item;
2554 proto_tree *hdr_tree;
2558 fraglen = rpc_rm & RPC_RM_FRAGLEN;
2560 hdr_item = proto_tree_add_text(tree, tvb, 0, 4,
2561 "Fragment header: %s%u %s",
2562 (rpc_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
2563 fraglen, plurality(fraglen, "byte", "bytes"));
2564 hdr_tree = proto_item_add_subtree(hdr_item, ett_rpc_fraghdr);
2566 proto_tree_add_boolean(hdr_tree, hf_rpc_lastfrag, tvb, 0, 4,
2568 proto_tree_add_uint(hdr_tree, hf_rpc_fraglen, tvb, 0, 4,
2574 show_rpc_fragment(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2578 * Show the fragment header and the data for the fragment.
2580 show_rpc_fragheader(tvb, tree, rpc_rm);
2581 proto_tree_add_text(tree, tvb, 4, -1, "Fragment Data");
2586 make_frag_tree(tvbuff_t *tvb, proto_tree *tree, int proto, gint ett,
2589 proto_item *frag_item;
2590 proto_tree *frag_tree;
2593 return; /* nothing to do */
2595 frag_item = proto_tree_add_protocol_format(tree, proto, tvb, 0, -1,
2596 "%s Fragment", proto_get_protocol_name(proto));
2597 frag_tree = proto_item_add_subtree(frag_item, ett);
2598 show_rpc_fragment(tvb, frag_tree, rpc_rm);
2602 show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
2603 guint32 rpc_rm, fragment_data *ipfd_head, packet_info *pinfo)
2606 return; /* don't do any work */
2608 if (tvb != frag_tvb) {
2610 * This message was not all in one fragment,
2611 * so show the fragment header *and* the data
2612 * for the fragment (which is the last fragment),
2613 * and a tree with information about all fragments.
2615 show_rpc_fragment(frag_tvb, tree, rpc_rm);
2618 * Show a tree with information about all fragments.
2620 show_fragment_tree(ipfd_head, &rpc_frag_items, tree, pinfo, tvb);
2623 * This message was all in one fragment, so just show
2624 * the fragment header.
2626 show_rpc_fragheader(tvb, tree, rpc_rm);
2631 call_message_dissector(tvbuff_t *tvb, tvbuff_t *rec_tvb, packet_info *pinfo,
2632 proto_tree *tree, tvbuff_t *frag_tvb, rec_dissector_t dissector,
2633 fragment_data *ipfd_head, guint32 rpc_rm, gboolean first_pdu)
2635 const char *saved_proto;
2636 volatile gboolean rpc_succeeded;
2639 * Catch the ReportedBoundsError exception; if
2640 * this particular message happens to get a
2641 * ReportedBoundsError exception, that doesn't
2642 * mean that we should stop dissecting RPC
2643 * messages within this frame or chunk of
2646 * If it gets a BoundsError, we can stop, as there's
2647 * nothing more to see, so we just re-throw it.
2649 saved_proto = pinfo->current_proto;
2650 rpc_succeeded = FALSE;
2652 rpc_succeeded = (*dissector)(rec_tvb, pinfo, tree,
2653 frag_tvb, ipfd_head, TRUE, rpc_rm, first_pdu);
2655 CATCH(BoundsError) {
2658 CATCH(ReportedBoundsError) {
2659 show_reported_bounds_error(tvb, pinfo, tree);
2660 pinfo->current_proto = saved_proto;
2663 * We treat this as a "successful" dissection of
2664 * an RPC packet, as "dissect_rpc_message()"
2665 * *did* decide it was an RPC packet, throwing
2666 * an exception while dissecting it as such.
2668 rpc_succeeded = TRUE;
2671 return rpc_succeeded;
2675 dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
2676 proto_tree *tree, rec_dissector_t dissector, gboolean is_heur,
2677 int proto, int ett, gboolean defragment, gboolean first_pdu)
2679 struct tcpinfo *tcpinfo = pinfo->private_data;
2680 guint32 seq = tcpinfo->seq + offset;
2682 volatile gint32 len;
2684 gint tvb_len, tvb_reported_len;
2686 gboolean rpc_succeeded;
2687 gboolean save_fragmented;
2688 rpc_fragment_key old_rfk, *rfk, *new_rfk;
2689 conversation_t *conversation;
2690 fragment_data *ipfd_head;
2694 * Get the record mark.
2696 if (!tvb_bytes_exist(tvb, offset, 4)) {
2698 * XXX - we should somehow arrange to handle
2699 * a record mark split across TCP segments.
2701 return 0; /* not enough to tell if it's valid */
2703 rpc_rm = tvb_get_ntohl(tvb, offset);
2705 len = rpc_rm & RPC_RM_FRAGLEN;
2708 * Do TCP desegmentation, if enabled.
2710 * XXX - reject fragments bigger than 2 megabytes.
2711 * This is arbitrary, but should at least prevent
2712 * some crashes from either packets with really
2713 * large RPC-over-TCP fragments or from stuff that's
2714 * not really valid for this protocol.
2716 if (len > 2*1024*1024)
2717 return 0; /* pretend it's not valid */
2718 if (rpc_desegment) {
2719 seglen = tvb_length_remaining(tvb, offset + 4);
2721 if (len > seglen && pinfo->can_desegment) {
2723 * This frame doesn't have all of the
2724 * data for this message, but we can do
2727 * If this is a heuristic dissector, just
2728 * return 0 - we don't want to try to get
2729 * more data, as that's too likely to cause
2730 * us to misidentify this as valid.
2732 * If this isn't a heuristic dissector,
2733 * we've already identified this conversation
2734 * as containing data for this protocol, as we
2735 * saw valid data in previous frames. Try to
2739 return 0; /* not valid */
2741 pinfo->desegment_offset = offset;
2742 pinfo->desegment_len = len - seglen;
2743 return -pinfo->desegment_len;
2747 len += 4; /* include record mark */
2748 tvb_len = tvb_length_remaining(tvb, offset);
2749 tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2752 if (tvb_reported_len > len)
2753 tvb_reported_len = len;
2754 frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2758 * If we're not defragmenting, just hand this to the
2763 * This is the first fragment we've seen, and it's also
2764 * the last fragment; that means the record wasn't
2765 * fragmented. Hand the dissector the tvbuff for the
2766 * fragment as the tvbuff for the record.
2772 * Mark this as fragmented, so if somebody throws an
2773 * exception, we don't report it as a malformed frame.
2775 save_fragmented = pinfo->fragmented;
2776 pinfo->fragmented = TRUE;
2777 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
2778 tree, frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu);
2779 pinfo->fragmented = save_fragmented;
2781 return 0; /* not RPC */
2786 * First, we check to see if this fragment is part of a record
2787 * that we're in the process of defragmenting.
2789 * The key is the conversation ID for the conversation to which
2790 * the packet belongs and the current sequence number.
2791 * We must first find the conversation and, if we don't find
2792 * one, create it. We know this is running over TCP, so the
2793 * conversation should not wildcard either address or port.
2795 conversation = find_conversation(&pinfo->src, &pinfo->dst,
2796 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2797 if (conversation == NULL) {
2799 * It's not part of any conversation - create a new one.
2801 conversation = conversation_new(&pinfo->src, &pinfo->dst,
2802 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2804 old_rfk.conv_id = conversation->index;
2806 rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
2810 * This fragment was not found in our table, so it doesn't
2811 * contain a continuation of a higher-level PDU.
2812 * Is it the last fragment?
2814 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2816 * This isn't the last fragment, so we don't
2817 * have the complete record.
2819 * It's the first fragment we've seen, so if
2820 * it's truly the first fragment of the record,
2821 * and it has enough data, the dissector can at
2822 * least check whether it looks like a valid
2823 * message, as it contains the start of the
2826 * The dissector should not dissect anything
2827 * if the "last fragment" flag isn't set in
2828 * the record marker, so it shouldn't throw
2831 if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
2832 NULL, TRUE, rpc_rm, first_pdu))
2833 return 0; /* not valid */
2836 * OK, now start defragmentation with that
2837 * fragment. Add this fragment, and set up
2838 * next packet/sequence number as well.
2840 * We must remember this fragment.
2843 rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2844 rfk->conv_id = conversation->index;
2847 rfk->start_seq = seq;
2848 g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
2851 * Start defragmentation.
2853 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4,
2854 pinfo, rfk->start_seq, rpc_fragment_table,
2855 rfk->offset, len - 4, TRUE);
2858 * Make sure that defragmentation isn't complete;
2859 * it shouldn't be, as this is the first fragment
2860 * we've seen, and the "last fragment" bit wasn't
2863 g_assert(ipfd_head == NULL);
2865 new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2866 new_rfk->conv_id = rfk->conv_id;
2867 new_rfk->seq = seq + len;
2868 new_rfk->offset = rfk->offset + len - 4;
2869 new_rfk->start_seq = rfk->start_seq;
2870 g_hash_table_insert(rpc_reassembly_table, new_rfk,
2874 * This is part of a fragmented record,
2875 * but it's not the first part.
2876 * Show it as a record marker plus data, under
2877 * a top-level tree for this protocol.
2879 make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
2882 * No more processing need be done, as we don't
2883 * have a complete record.
2889 * This is the first fragment we've seen, and it's also
2890 * the last fragment; that means the record wasn't
2891 * fragmented. Hand the dissector the tvbuff for the
2892 * fragment as the tvbuff for the record.
2898 * OK, this fragment was found, which means it continues
2899 * a record. This means we must defragment it.
2900 * Add it to the defragmentation lists.
2902 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4, pinfo,
2903 rfk->start_seq, rpc_fragment_table,
2904 rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
2906 if (ipfd_head == NULL) {
2908 * fragment_add_multiple_ok() returned NULL.
2909 * This means that defragmentation is not
2912 * We must add an entry to the hash table with
2913 * the sequence number following this fragment
2914 * as the starting sequence number, so that when
2915 * we see that fragment we'll find that entry.
2917 * XXX - as TCP stream data is not currently
2918 * guaranteed to be provided in order to dissectors,
2919 * RPC fragments aren't guaranteed to be provided
2922 new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2923 new_rfk->conv_id = rfk->conv_id;
2924 new_rfk->seq = seq + len;
2925 new_rfk->offset = rfk->offset + len - 4;
2926 new_rfk->start_seq = rfk->start_seq;
2927 g_hash_table_insert(rpc_reassembly_table, new_rfk,
2931 * This is part of a fragmented record,
2932 * but it's not the first part.
2933 * Show it as a record marker plus data, under
2934 * a top-level tree for this protocol,
2935 * but don't hand it to the dissector
2937 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
2940 * No more processing need be done, as we don't
2941 * have a complete record.
2947 * It's completely defragmented.
2949 * We only call subdissector for the last fragment.
2950 * XXX - this assumes in-order delivery of RPC
2951 * fragments, which requires in-order delivery of TCP
2954 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2956 * Well, it's defragmented, but this isn't
2957 * the last fragment; this probably means
2958 * this isn't the first pass, so we don't
2959 * need to start defragmentation.
2961 * This is part of a fragmented record,
2962 * but it's not the first part.
2963 * Show it as a record marker plus data, under
2964 * a top-level tree for this protocol,
2965 * but don't show it to the dissector.
2967 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
2970 * No more processing need be done, as we
2971 * only disssect the data with the last
2978 * OK, this is the last segment.
2979 * Create a tvbuff for the defragmented
2984 * Create a new TVB structure for
2985 * defragmented data.
2987 rec_tvb = tvb_new_real_data(ipfd_head->data,
2988 ipfd_head->datalen, ipfd_head->datalen);
2991 * Add this tvb as a child to the original
2994 tvb_set_child_real_data_tvbuff(tvb, rec_tvb);
2997 * Add defragmented data to the data source list.
2999 add_new_data_source(pinfo, rec_tvb, "Defragmented");
3003 * We have something to hand to the RPC message
3006 if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
3007 frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu))
3008 return 0; /* not RPC */
3015 * NEED_MORE_DATA, if we don't have enough data to dissect anything;
3017 * IS_RPC, if we dissected at least one message in its entirety
3020 * IS_NOT_RPC, if we found no RPC message.
3028 static rpc_tcp_return_t
3029 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3033 gboolean saw_rpc = FALSE;
3034 gboolean first_pdu = TRUE;
3037 while (tvb_reported_length_remaining(tvb, offset) != 0) {
3039 * Process this fragment.
3041 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
3042 dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
3043 rpc_defragment, first_pdu);
3047 * We need more data from the TCP stream for
3050 return NEED_MORE_DATA;
3054 * It's not RPC. Stop processing.
3060 If the length indicates that the PDU continues beyond
3061 the end of this tvb, then tell TCP about it so that it
3062 knows where the next PDU starts.
3063 This is to help TCP detect when PDUs are not aligned to
3064 segment boundaries and allow it to find RPC headers
3065 that starts in the middle of a TCP segment.
3067 if(!pinfo->fd->flags.visited){
3068 if(len>tvb_reported_length_remaining(tvb, offset)){
3069 pinfo->want_pdu_tracking=2;
3070 pinfo->bytes_until_next_pdu=len-tvb_reported_length_remaining(tvb, offset);
3076 return saw_rpc ? IS_RPC : IS_NOT_RPC;
3080 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3082 switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
3091 /* "Can't happen" */
3092 g_assert_not_reached();
3098 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3100 if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
3101 dissect_rpc_continuation(tvb, pinfo, tree);
3104 /* Discard any state we've saved. */
3106 rpc_init_protocol(void)
3108 if (rpc_calls != NULL) {
3109 g_hash_table_destroy(rpc_calls);
3112 if (rpc_indir_calls != NULL) {
3113 g_hash_table_destroy(rpc_indir_calls);
3114 rpc_indir_calls = NULL;
3116 if (rpc_call_info_key_chunk != NULL) {
3117 g_mem_chunk_destroy(rpc_call_info_key_chunk);
3118 rpc_call_info_key_chunk = NULL;
3120 if (rpc_call_info_value_chunk != NULL) {
3121 g_mem_chunk_destroy(rpc_call_info_value_chunk);
3122 rpc_call_info_value_chunk = NULL;
3124 if (rpc_fragment_key_chunk != NULL) {
3125 g_mem_chunk_destroy(rpc_fragment_key_chunk);
3126 rpc_fragment_key_chunk = NULL;
3128 if (rpc_reassembly_table != NULL) {
3129 g_hash_table_destroy(rpc_reassembly_table);
3130 rpc_reassembly_table = NULL;
3133 rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3134 rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3135 rpc_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
3136 sizeof(rpc_call_info_key),
3137 200 * sizeof(rpc_call_info_key),
3139 rpc_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
3140 sizeof(rpc_call_info_value),
3141 200 * sizeof(rpc_call_info_value),
3143 rpc_fragment_key_chunk = g_mem_chunk_new("rpc_fragment_key_chunk",
3144 sizeof(rpc_fragment_key),
3145 rpc_fragment_init_count*sizeof(rpc_fragment_key),
3147 rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
3148 rpc_fragment_equal);
3150 fragment_table_init(&rpc_fragment_table);
3153 /* will be called once from register.c at startup time */
3155 proto_register_rpc(void)
3157 static hf_register_info hf[] = {
3158 { &hf_rpc_reqframe, {
3159 "Request Frame", "rpc.reqframe", FT_FRAMENUM, BASE_NONE,
3160 NULL, 0, "Request Frame", HFILL }},
3161 { &hf_rpc_repframe, {
3162 "Reply Frame", "rpc.repframe", FT_FRAMENUM, BASE_NONE,
3163 NULL, 0, "Reply Frame", HFILL }},
3164 { &hf_rpc_lastfrag, {
3165 "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
3166 &yesno, RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
3167 { &hf_rpc_fraglen, {
3168 "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
3169 NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
3171 "XID", "rpc.xid", FT_UINT32, BASE_HEX,
3172 NULL, 0, "XID", HFILL }},
3173 { &hf_rpc_msgtype, {
3174 "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
3175 VALS(rpc_msg_type), 0, "Message Type", HFILL }},
3176 { &hf_rpc_state_reply, {
3177 "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
3178 VALS(rpc_reply_state), 0, "Reply State", HFILL }},
3179 { &hf_rpc_state_accept, {
3180 "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
3181 VALS(rpc_accept_state), 0, "Accept State", HFILL }},
3182 { &hf_rpc_state_reject, {
3183 "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
3184 VALS(rpc_reject_state), 0, "Reject State", HFILL }},
3185 { &hf_rpc_state_auth, {
3186 "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
3187 VALS(rpc_auth_state), 0, "Auth State", HFILL }},
3188 { &hf_rpc_version, {
3189 "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
3190 NULL, 0, "RPC Version", HFILL }},
3191 { &hf_rpc_version_min, {
3192 "RPC Version (Minimum)", "rpc.version.min", FT_UINT32,
3193 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3194 { &hf_rpc_version_max, {
3195 "RPC Version (Maximum)", "rpc.version.max", FT_UINT32,
3196 BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
3197 { &hf_rpc_program, {
3198 "Program", "rpc.program", FT_UINT32, BASE_DEC,
3199 NULL, 0, "Program", HFILL }},
3200 { &hf_rpc_programversion, {
3201 "Program Version", "rpc.programversion", FT_UINT32,
3202 BASE_DEC, NULL, 0, "Program Version", HFILL }},
3203 { &hf_rpc_programversion_min, {
3204 "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32,
3205 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3206 { &hf_rpc_programversion_max, {
3207 "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32,
3208 BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
3209 { &hf_rpc_procedure, {
3210 "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
3211 NULL, 0, "Procedure", HFILL }},
3212 { &hf_rpc_auth_flavor, {
3213 "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
3214 VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
3215 { &hf_rpc_auth_length, {
3216 "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
3217 NULL, 0, "Length", HFILL }},
3218 { &hf_rpc_auth_stamp, {
3219 "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
3220 NULL, 0, "Stamp", HFILL }},
3221 { &hf_rpc_auth_uid, {
3222 "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
3223 NULL, 0, "UID", HFILL }},
3224 { &hf_rpc_auth_gid, {
3225 "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
3226 NULL, 0, "GID", HFILL }},
3227 { &hf_rpc_authgss_v, {
3228 "GSS Version", "rpc.authgss.version", FT_UINT32,
3229 BASE_DEC, NULL, 0, "GSS Version", HFILL }},
3230 { &hf_rpc_authgss_proc, {
3231 "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
3232 BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
3233 { &hf_rpc_authgss_seq, {
3234 "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
3235 BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
3236 { &hf_rpc_authgss_svc, {
3237 "GSS Service", "rpc.authgss.service", FT_UINT32,
3238 BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
3239 { &hf_rpc_authgss_ctx, {
3240 "GSS Context", "rpc.authgss.context", FT_BYTES,
3241 BASE_HEX, NULL, 0, "GSS Context", HFILL }},
3242 { &hf_rpc_authgss_major, {
3243 "GSS Major Status", "rpc.authgss.major", FT_UINT32,
3244 BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
3245 { &hf_rpc_authgss_minor, {
3246 "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
3247 BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
3248 { &hf_rpc_authgss_window, {
3249 "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
3250 BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
3251 { &hf_rpc_authgss_token_length, {
3252 "GSS Token Length", "rpc.authgss.token_length", FT_UINT32,
3253 BASE_DEC, NULL, 0, "GSS Token Length", HFILL }},
3254 { &hf_rpc_authgss_data_length, {
3255 "Length", "rpc.authgss.data.length", FT_UINT32,
3256 BASE_DEC, NULL, 0, "Length", HFILL }},
3257 { &hf_rpc_authgss_data, {
3258 "GSS Data", "rpc.authgss.data", FT_BYTES,
3259 BASE_HEX, NULL, 0, "GSS Data", HFILL }},
3260 { &hf_rpc_authgss_checksum, {
3261 "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
3262 BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
3263 { &hf_rpc_authgssapi_v, {
3264 "AUTH_GSSAPI Version", "rpc.authgssapi.version",
3265 FT_UINT32, BASE_DEC, NULL, 0, "AUTH_GSSAPI Version",
3267 { &hf_rpc_authgssapi_msg, {
3268 "AUTH_GSSAPI Message", "rpc.authgssapi.message",
3269 FT_BOOLEAN, BASE_NONE, &yesno, 0, "AUTH_GSSAPI Message",
3271 { &hf_rpc_authgssapi_msgv, {
3272 "Msg Version", "rpc.authgssapi.msgversion",
3273 FT_UINT32, BASE_DEC, NULL, 0, "Msg Version",
3275 { &hf_rpc_authgssapi_handle, {
3276 "Client Handle", "rpc.authgssapi.handle",
3277 FT_BYTES, BASE_HEX, NULL, 0, "Client Handle", HFILL }},
3278 { &hf_rpc_authgssapi_isn, {
3279 "Signed ISN", "rpc.authgssapi.isn",
3280 FT_BYTES, BASE_HEX, NULL, 0, "Signed ISN", HFILL }},
3281 { &hf_rpc_authdes_namekind, {
3282 "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
3283 VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
3284 { &hf_rpc_authdes_netname, {
3285 "Netname", "rpc.authdes.netname", FT_STRING,
3286 BASE_DEC, NULL, 0, "Netname", HFILL }},
3287 { &hf_rpc_authdes_convkey, {
3288 "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
3289 BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
3290 { &hf_rpc_authdes_window, {
3291 "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
3292 BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
3293 { &hf_rpc_authdes_nickname, {
3294 "Nickname", "rpc.authdes.nickname", FT_UINT32,
3295 BASE_HEX, NULL, 0, "Nickname", HFILL }},
3296 { &hf_rpc_authdes_timestamp, {
3297 "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
3298 BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
3299 { &hf_rpc_authdes_windowverf, {
3300 "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
3301 BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
3302 { &hf_rpc_authdes_timeverf, {
3303 "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
3304 BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
3305 { &hf_rpc_auth_machinename, {
3306 "Machine Name", "rpc.auth.machinename", FT_STRING,
3307 BASE_DEC, NULL, 0, "Machine Name", HFILL }},
3309 "Duplicate Transaction", "rpc.dup", FT_UINT32, BASE_DEC,
3310 NULL, 0, "Duplicate Transaction", HFILL }},
3311 { &hf_rpc_call_dup, {
3312 "Duplicate Call", "rpc.call.dup", FT_UINT32, BASE_DEC,
3313 NULL, 0, "Duplicate Call", HFILL }},
3314 { &hf_rpc_reply_dup, {
3315 "Duplicate Reply", "rpc.reply.dup", FT_UINT32, BASE_DEC,
3316 NULL, 0, "Duplicate Reply", HFILL }},
3317 { &hf_rpc_value_follows, {
3318 "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
3319 &yesno, 0, "Value Follows", HFILL }},
3320 { &hf_rpc_array_len, {
3321 "num", "rpc.array.len", FT_UINT32, BASE_DEC,
3322 NULL, 0, "Length of RPC array", HFILL }},
3325 "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
3326 NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
3328 { &hf_rpc_fragment_overlap,
3329 { "Fragment overlap", "rpc.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3330 "Fragment overlaps with other fragments", HFILL }},
3332 { &hf_rpc_fragment_overlap_conflict,
3333 { "Conflicting data in fragment overlap", "rpc.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3334 "Overlapping fragments contained conflicting data", HFILL }},
3336 { &hf_rpc_fragment_multiple_tails,
3337 { "Multiple tail fragments found", "rpc.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3338 "Several tails were found when defragmenting the packet", HFILL }},
3340 { &hf_rpc_fragment_too_long_fragment,
3341 { "Fragment too long", "rpc.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3342 "Fragment contained data past end of packet", HFILL }},
3344 { &hf_rpc_fragment_error,
3345 { "Defragmentation error", "rpc.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3346 "Defragmentation error due to illegal fragments", HFILL }},
3349 { "RPC Fragment", "rpc.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3350 "RPC Fragment", HFILL }},
3352 { &hf_rpc_fragments,
3353 { "RPC Fragments", "rpc.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3354 "RPC Fragments", HFILL }},
3356 static gint *ett[] = {
3368 &ett_rpc_authgssapi_msg,
3370 module_t *rpc_module;
3372 proto_rpc = proto_register_protocol("Remote Procedure Call",
3374 proto_register_field_array(proto_rpc, hf, array_length(hf));
3375 proto_register_subtree_array(ett, array_length(ett));
3376 register_init_routine(&rpc_init_protocol);
3378 rpc_module = prefs_register_protocol(proto_rpc, NULL);
3379 prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
3380 "Desegment all RPC-over-TCP messages",
3381 "Whether the RPC dissector should desegment all RPC-over-TCP messages",
3383 prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
3384 "Defragment all RPC-over-TCP messages",
3385 "Whether the RPC dissector should defragment multi-fragment RPC-over-TCP messages",
3388 register_dissector("rpc", dissect_rpc, proto_rpc);
3389 rpc_handle = find_dissector("rpc");
3390 register_dissector("rpc-tcp", dissect_rpc_tcp, proto_rpc);
3391 rpc_tcp_handle = find_dissector("rpc-tcp");
3392 rpc_tap = register_tap("rpc");
3395 * Init the hash tables. Dissectors for RPC protocols must
3396 * have a "handoff registration" routine that registers the
3397 * protocol with RPC; they must not do it in their protocol
3398 * registration routine, as their protocol registration
3399 * routine might be called before this routine is called and
3400 * thus might be called before the hash tables are initialized,
3401 * but it's guaranteed that all protocol registration routines
3402 * will be called before any handoff registration routines
3405 rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
3406 rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
3410 proto_reg_handoff_rpc(void)
3412 dissector_handle_t rpc_tcp_handle;
3413 dissector_handle_t rpc_udp_handle;
3415 /* tcp/udp port 111 is used by portmapper which is an onc-rpc service.
3416 we register onc-rpc on this port so that we can choose RPC in
3417 the list offered by DecodeAs, and so that traffic to or from
3418 port 111 from or to a higher-numbered port is dissected as RPC
3419 even if there's a dissector registered on the other port (it's
3420 probably RPC traffic from some randomly-chosen port that happens
3421 to match some port for which we have a dissector)
3423 rpc_tcp_handle = create_dissector_handle(dissect_rpc_tcp, proto_rpc);
3424 dissector_add("tcp.port", 111, rpc_tcp_handle);
3425 rpc_udp_handle = create_dissector_handle(dissect_rpc, proto_rpc);
3426 dissector_add("udp.port", 111, rpc_udp_handle);
3428 heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
3429 heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
3430 gssapi_handle = find_dissector("gssapi");
3431 data_handle = find_dissector("data");