2 * Routines for rpc dissection
3 * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
5 * $Id: packet-rpc.c,v 1.87 2002/02/18 23:51:55 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"
52 * RFC 1831, "RPC: Remote Procedure Call Protocol Specification
55 * RFC 1832, "XDR: External Data Representation Standard";
57 * RFC 2203, "RPCSEC_GSS Protocol Specification".
61 * RFC 2695, "Authentication Mechanisms for ONC RPC"
63 * although we don't currently dissect AUTH_DES or AUTH_KERB.
66 /* desegmentation of RPC over TCP */
67 static gboolean rpc_desegment = TRUE;
69 /* defragmentation of fragmented RPC over TCP records */
70 static gboolean rpc_defragment = FALSE;
72 static struct true_false_string yesno = { "Yes", "No" };
75 static const value_string rpc_msg_type[] = {
77 { RPC_REPLY, "Reply" },
81 static const value_string rpc_reply_state[] = {
82 { MSG_ACCEPTED, "accepted" },
83 { MSG_DENIED, "denied" },
87 const value_string rpc_auth_flavor[] = {
88 { AUTH_NULL, "AUTH_NULL" },
89 { AUTH_UNIX, "AUTH_UNIX" },
90 { AUTH_SHORT, "AUTH_SHORT" },
91 { AUTH_DES, "AUTH_DES" },
92 { RPCSEC_GSS, "RPCSEC_GSS" },
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 value_string rpc_authgss_svc[] = {
105 { RPCSEC_GSS_SVC_NONE, "rpcsec_gss_svc_none" },
106 { RPCSEC_GSS_SVC_INTEGRITY, "rpcsec_gss_svc_integrity" },
107 { RPCSEC_GSS_SVC_PRIVACY, "rpcsec_gss_svc_privacy" },
111 static const value_string rpc_accept_state[] = {
112 { SUCCESS, "RPC executed successfully" },
113 { PROG_UNAVAIL, "remote hasn't exported program" },
114 { PROG_MISMATCH, "remote can't support version #" },
115 { PROC_UNAVAIL, "program can't support procedure" },
116 { GARBAGE_ARGS, "procedure can't decode params" },
120 static const value_string rpc_reject_state[] = {
121 { RPC_MISMATCH, "RPC_MISMATCH" },
122 { AUTH_ERROR, "AUTH_ERROR" },
126 static const value_string rpc_auth_state[] = {
127 { AUTH_BADCRED, "bad credential (seal broken)" },
128 { AUTH_REJECTEDCRED, "client must begin new session" },
129 { AUTH_BADVERF, "bad verifier (seal broken)" },
130 { AUTH_REJECTEDVERF, "verifier expired or replayed" },
131 { AUTH_TOOWEAK, "rejected for security reasons" },
132 { RPCSEC_GSSCREDPROB, "GSS credential problem" },
133 { RPCSEC_GSSCTXPROB, "GSS context problem" },
137 static const value_string rpc_authdes_namekind[] = {
138 { AUTHDES_NAMEKIND_FULLNAME, "ADN_FULLNAME" },
139 { AUTHDES_NAMEKIND_NICKNAME, "ADN_NICKNAME" },
143 /* the protocol number */
144 static int proto_rpc = -1;
145 static int hf_rpc_lastfrag = -1;
146 static int hf_rpc_fraglen = -1;
147 static int hf_rpc_xid = -1;
148 static int hf_rpc_msgtype = -1;
149 static int hf_rpc_version = -1;
150 static int hf_rpc_version_min = -1;
151 static int hf_rpc_version_max = -1;
152 static int hf_rpc_program = -1;
153 static int hf_rpc_programversion = -1;
154 static int hf_rpc_programversion_min = -1;
155 static int hf_rpc_programversion_max = -1;
156 static int hf_rpc_procedure = -1;
157 static int hf_rpc_auth_flavor = -1;
158 static int hf_rpc_auth_length = -1;
159 static int hf_rpc_auth_machinename = -1;
160 static int hf_rpc_auth_stamp = -1;
161 static int hf_rpc_auth_uid = -1;
162 static int hf_rpc_auth_gid = -1;
163 static int hf_rpc_authgss_v = -1;
164 static int hf_rpc_authgss_proc = -1;
165 static int hf_rpc_authgss_seq = -1;
166 static int hf_rpc_authgss_svc = -1;
167 static int hf_rpc_authgss_ctx = -1;
168 static int hf_rpc_authgss_major = -1;
169 static int hf_rpc_authgss_minor = -1;
170 static int hf_rpc_authgss_window = -1;
171 static int hf_rpc_authgss_token = -1;
172 static int hf_rpc_authgss_data_length = -1;
173 static int hf_rpc_authgss_data = -1;
174 static int hf_rpc_authgss_checksum = -1;
175 static int hf_rpc_authdes_namekind = -1;
176 static int hf_rpc_authdes_netname = -1;
177 static int hf_rpc_authdes_convkey = -1;
178 static int hf_rpc_authdes_window = -1;
179 static int hf_rpc_authdes_nickname = -1;
180 static int hf_rpc_authdes_timestamp = -1;
181 static int hf_rpc_authdes_windowverf = -1;
182 static int hf_rpc_authdes_timeverf = -1;
183 static int hf_rpc_state_accept = -1;
184 static int hf_rpc_state_reply = -1;
185 static int hf_rpc_state_reject = -1;
186 static int hf_rpc_state_auth = -1;
187 static int hf_rpc_dup = -1;
188 static int hf_rpc_call_dup = -1;
189 static int hf_rpc_reply_dup = -1;
190 static int hf_rpc_value_follows = -1;
191 static int hf_rpc_array_len = -1;
192 static int hf_rpc_time = -1;
194 static gint ett_rpc = -1;
195 static gint ett_rpc_fragments = -1;
196 static gint ett_rpc_fraghdr = -1;
197 static gint ett_rpc_string = -1;
198 static gint ett_rpc_cred = -1;
199 static gint ett_rpc_verf = -1;
200 static gint ett_rpc_gids = -1;
201 static gint ett_rpc_gss_data = -1;
202 static gint ett_rpc_array = -1;
204 static dissector_handle_t rpc_tcp_handle;
205 static dissector_handle_t rpc_handle;
206 static dissector_handle_t data_handle;
208 /* Hash table with info on RPC program numbers */
209 static GHashTable *rpc_progs;
211 /* Hash table with info on RPC procedure numbers */
212 static GHashTable *rpc_procs;
214 typedef struct _rpc_proc_info_key {
220 typedef struct _rpc_proc_info_value {
222 dissect_function_t *dissect_call;
223 dissect_function_t *dissect_reply;
224 } rpc_proc_info_value;
226 typedef struct _rpc_prog_info_key {
230 typedef struct _rpc_prog_info_value {
234 } rpc_prog_info_value;
236 static void dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
237 static void dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
239 /***********************************/
240 /* Hash array with procedure names */
241 /***********************************/
245 rpc_proc_equal(gconstpointer k1, gconstpointer k2)
247 rpc_proc_info_key* key1 = (rpc_proc_info_key*) k1;
248 rpc_proc_info_key* key2 = (rpc_proc_info_key*) k2;
250 return ((key1->prog == key2->prog &&
251 key1->vers == key2->vers &&
252 key1->proc == key2->proc) ?
256 /* calculate a hash key */
258 rpc_proc_hash(gconstpointer k)
260 rpc_proc_info_key* key = (rpc_proc_info_key*) k;
262 return (key->prog ^ (key->vers<<16) ^ (key->proc<<24));
266 /* insert some entries */
268 rpc_init_proc_table(guint prog, guint vers, const vsff *proc_table)
272 for (proc = proc_table ; proc->strptr!=NULL; proc++) {
273 rpc_proc_info_key *key;
274 rpc_proc_info_value *value;
276 key = (rpc_proc_info_key *) g_malloc(sizeof(rpc_proc_info_key));
279 key->proc = proc->value;
281 value = (rpc_proc_info_value *) g_malloc(sizeof(rpc_proc_info_value));
282 value->name = proc->strptr;
283 value->dissect_call = proc->dissect_call;
284 value->dissect_reply = proc->dissect_reply;
286 g_hash_table_insert(rpc_procs,key,value);
290 /* return the name associated with a previously registered procedure. */
291 char *rpc_proc_name(guint32 prog, guint32 vers, guint32 proc)
293 rpc_proc_info_key key;
294 rpc_proc_info_value *value;
296 static char procname_static[20];
302 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL)
303 procname = value->name;
305 /* happens only with strange program versions or
306 non-existing dissectors */
307 sprintf(procname_static, "proc-%u", key.proc);
308 procname = procname_static;
313 /*----------------------------------------*/
314 /* end of Hash array with procedure names */
315 /*----------------------------------------*/
318 /*********************************/
319 /* Hash array with program names */
320 /*********************************/
324 rpc_prog_equal(gconstpointer k1, gconstpointer k2)
326 rpc_prog_info_key* key1 = (rpc_prog_info_key*) k1;
327 rpc_prog_info_key* key2 = (rpc_prog_info_key*) k2;
329 return ((key1->prog == key2->prog) ?
334 /* calculate a hash key */
336 rpc_prog_hash(gconstpointer k)
338 rpc_prog_info_key* key = (rpc_prog_info_key*) k;
345 rpc_init_prog(int proto, guint32 prog, int ett)
347 rpc_prog_info_key *key;
348 rpc_prog_info_value *value;
350 key = (rpc_prog_info_key *) g_malloc(sizeof(rpc_prog_info_key));
353 value = (rpc_prog_info_value *) g_malloc(sizeof(rpc_prog_info_value));
354 value->proto = proto;
356 value->progname = proto_get_protocol_short_name(proto);
358 g_hash_table_insert(rpc_progs,key,value);
361 /* return the name associated with a previously registered program. This
362 should probably eventually be expanded to use the rpc YP/NIS map
363 so that it can give names for programs not handled by ethereal */
364 char *rpc_prog_name(guint32 prog)
366 char *progname = NULL;
367 rpc_prog_info_key rpc_prog_key;
368 rpc_prog_info_value *rpc_prog;
370 rpc_prog_key.prog = prog;
371 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
372 progname = "Unknown";
375 progname = rpc_prog->progname;
381 /*--------------------------------------*/
382 /* end of Hash array with program names */
383 /*--------------------------------------*/
385 typedef struct _rpc_call_info_key {
387 conversation_t *conversation;
390 static GMemChunk *rpc_call_info_key_chunk;
392 static GMemChunk *rpc_call_info_value_chunk;
394 static GHashTable *rpc_calls;
396 static GHashTable *rpc_indir_calls;
400 rpc_call_equal(gconstpointer k1, gconstpointer k2)
402 rpc_call_info_key* key1 = (rpc_call_info_key*) k1;
403 rpc_call_info_key* key2 = (rpc_call_info_key*) k2;
405 return (key1->xid == key2->xid &&
406 key1->conversation == key2->conversation);
410 /* calculate a hash key */
412 rpc_call_hash(gconstpointer k)
414 rpc_call_info_key* key = (rpc_call_info_key*) k;
416 return key->xid + (guint32)(key->conversation);
421 rpc_roundup(unsigned int a)
423 unsigned int mod = a % 4;
424 return a + ((mod)? 4-mod : 0);
429 dissect_rpc_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
430 int hfindex, int offset)
433 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
439 dissect_rpc_uint32(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
440 int hfindex, int offset)
443 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
449 dissect_rpc_uint64(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
450 int hfindex, int offset)
452 header_field_info *hfinfo;
454 hfinfo = proto_registrar_get_nth(hfindex);
455 g_assert(hfinfo->type == FT_UINT64);
457 proto_tree_add_item(tree, hfindex, tvb, offset, 8, FALSE);
464 dissect_rpc_opaque_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
465 proto_tree *tree, int hfindex, gboolean string_data,
466 char **string_buffer_ret)
468 proto_item *string_item = NULL;
469 proto_tree *string_tree = NULL;
470 int old_offset = offset;
472 guint32 string_length;
473 guint32 string_length_full;
474 guint32 string_length_packet;
475 guint32 string_length_captured;
476 guint32 string_length_copy;
480 guint32 fill_length_packet;
481 guint32 fill_length_captured;
482 guint32 fill_length_copy;
486 char *string_buffer = NULL;
487 char *string_buffer_print = NULL;
489 string_length = tvb_get_ntohl(tvb,offset+0);
490 string_length_full = rpc_roundup(string_length);
491 string_length_captured = tvb_length_remaining(tvb, offset + 4);
492 string_length_packet = tvb_reported_length_remaining(tvb, offset + 4);
493 if (string_length_captured < string_length) {
494 /* truncated string */
495 string_length_copy = string_length_captured;
498 fill_length_copy = 0;
499 if (string_length_packet < string_length)
500 exception = ReportedBoundsError;
502 exception = BoundsError;
505 /* full string data */
506 string_length_copy = string_length;
507 fill_length = string_length_full - string_length;
508 fill_length_captured = tvb_length_remaining(tvb,
509 offset + 4 + string_length);
510 fill_length_packet = tvb_reported_length_remaining(tvb,
511 offset + 4 + string_length);
512 if (fill_length_captured < fill_length) {
513 /* truncated fill bytes */
514 fill_length_copy = fill_length_packet;
516 if (fill_length_packet < fill_length)
517 exception = ReportedBoundsError;
519 exception = BoundsError;
522 /* full fill bytes */
523 fill_length_copy = fill_length;
527 string_buffer = (char*)g_malloc(string_length_copy +
528 (string_data ? 1 : 0));
529 tvb_memcpy(tvb,string_buffer,offset+4,string_length_copy);
531 string_buffer[string_length_copy] = '\0';
533 /* calculate a nice printable string */
535 if (string_length != string_length_copy) {
537 /* alloc maximum data area */
538 string_buffer_print = (char*)g_malloc(string_length_copy + 12 + 1);
539 /* copy over the data */
540 memcpy(string_buffer_print,string_buffer,string_length_copy);
541 /* append a 0 byte for sure printing */
542 string_buffer_print[string_length_copy] = '\0';
543 /* append <TRUNCATED> */
544 /* This way, we get the TRUNCATED even
545 in the case of totally wrong packets,
546 where \0 are inside the string.
547 TRUNCATED will appear at the
548 first \0 or at the end (where we
549 put the securing \0).
551 strcat(string_buffer_print,"<TRUNCATED>");
554 string_buffer_print = g_strdup("<DATA><TRUNCATED>");
559 string_buffer_print = g_strdup(string_buffer);
562 string_buffer_print = g_strdup("<DATA>");
567 string_buffer_print = g_strdup("<EMPTY>");
571 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
572 "%s: %s", proto_registrar_get_name(hfindex), string_buffer_print);
574 proto_tree_add_string_hidden(tree, hfindex, tvb, offset+4,
575 string_length_copy, string_buffer);
578 string_tree = proto_item_add_subtree(string_item, ett_rpc_string);
582 proto_tree_add_text(string_tree, tvb,offset+0,4,
583 "length: %u", string_length);
588 proto_tree_add_string_format(string_tree,
589 hfindex, tvb, offset, string_length_copy,
591 "contents: %s", string_buffer_print);
593 proto_tree_add_bytes_format(string_tree,
594 hfindex, tvb, offset, string_length_copy,
596 "contents: %s", string_buffer_print);
599 offset += string_length_copy;
602 if (fill_truncated) {
603 proto_tree_add_text(string_tree, tvb,
604 offset,fill_length_copy,
605 "fill bytes: opaque data<TRUNCATED>");
608 proto_tree_add_text(string_tree, tvb,
609 offset,fill_length_copy,
610 "fill bytes: opaque data");
613 offset += fill_length_copy;
617 proto_item_set_len(string_item, offset - old_offset);
620 if (string_buffer != NULL) g_free (string_buffer );
621 if (string_buffer_print != NULL) {
622 if (string_buffer_ret != NULL)
623 *string_buffer_ret = string_buffer_print;
625 g_free (string_buffer_print);
629 * If the data was truncated, throw the appropriate exception,
630 * so that dissection stops and the frame is properly marked.
639 dissect_rpc_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
640 int hfindex, int offset, char **string_buffer_ret)
642 offset = dissect_rpc_opaque_data(tvb, offset, pinfo, tree,
643 hfindex, TRUE, string_buffer_ret);
649 dissect_rpc_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
650 int hfindex, int offset)
652 offset = dissect_rpc_opaque_data(tvb, offset, pinfo, tree, hfindex,
660 dissect_rpc_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
661 int offset, dissect_function_t *rpc_list_dissector)
663 guint32 value_follows;
666 value_follows = tvb_get_ntohl(tvb, offset+0);
667 proto_tree_add_boolean(tree,hf_rpc_value_follows, tvb,
668 offset+0, 4, value_follows);
670 if (value_follows == 1) {
671 offset = rpc_list_dissector(tvb, offset, pinfo, tree);
682 dissect_rpc_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
683 int offset, dissect_function_t *rpc_array_dissector,
686 proto_item* lock_item;
687 proto_tree* lock_tree;
689 int old_offset = offset;
691 num = tvb_get_ntohl(tvb, offset);
694 proto_tree_add_none_format(tree, hfindex, tvb, offset, 4,
701 lock_item = proto_tree_add_item(tree, hfindex, tvb, offset, -1, FALSE);
703 lock_tree = proto_item_add_subtree(lock_item, ett_rpc_array);
705 offset = dissect_rpc_uint32(tvb, pinfo, lock_tree,
706 hf_rpc_array_len, offset);
709 offset = rpc_array_dissector(tvb, offset, pinfo, lock_tree);
712 proto_item_set_len(lock_item, offset-old_offset);
717 dissect_rpc_authunix_cred(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
726 proto_tree *gtree = NULL;
728 stamp = tvb_get_ntohl(tvb,offset+0);
730 proto_tree_add_uint(tree, hf_rpc_auth_stamp, tvb,
734 offset = dissect_rpc_string(tvb, pinfo, tree,
735 hf_rpc_auth_machinename, offset, NULL);
737 uid = tvb_get_ntohl(tvb,offset+0);
739 proto_tree_add_uint(tree, hf_rpc_auth_uid, tvb,
743 gid = tvb_get_ntohl(tvb,offset+0);
745 proto_tree_add_uint(tree, hf_rpc_auth_gid, tvb,
749 gids_count = tvb_get_ntohl(tvb,offset+0);
751 gitem = proto_tree_add_text(tree, tvb,
752 offset, 4+gids_count*4, "Auxiliary GIDs");
753 gtree = proto_item_add_subtree(gitem, ett_rpc_gids);
757 for (gids_i = 0 ; gids_i < gids_count ; gids_i++) {
758 gids_entry = tvb_get_ntohl(tvb,offset+0);
760 proto_tree_add_uint(gtree, hf_rpc_auth_gid, tvb,
761 offset, 4, gids_entry);
764 /* how can I NOW change the gitem to print a list with
765 the first 16 gids? */
771 dissect_rpc_authgss_cred(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
778 agc_v = tvb_get_ntohl(tvb, offset+0);
780 proto_tree_add_uint(tree, hf_rpc_authgss_v,
781 tvb, offset+0, 4, agc_v);
784 agc_proc = tvb_get_ntohl(tvb, offset+0);
786 proto_tree_add_uint(tree, hf_rpc_authgss_proc,
787 tvb, offset+0, 4, agc_proc);
790 agc_seq = tvb_get_ntohl(tvb, offset+0);
792 proto_tree_add_uint(tree, hf_rpc_authgss_seq,
793 tvb, offset+0, 4, agc_seq);
796 agc_svc = tvb_get_ntohl(tvb, offset+0);
798 proto_tree_add_uint(tree, hf_rpc_authgss_svc,
799 tvb, offset+0, 4, agc_svc);
802 offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_ctx,
809 dissect_rpc_authdes_desblock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
810 int hfindex, int offset)
815 value_high = tvb_get_ntohl(tvb, offset + 0);
816 value_low = tvb_get_ntohl(tvb, offset + 4);
819 proto_tree_add_text(tree, tvb, offset, 8,
820 "%s: 0x%x%08x", proto_registrar_get_name(hfindex), value_high,
828 dissect_rpc_authdes_cred(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
834 adc_namekind = tvb_get_ntohl(tvb, offset+0);
836 proto_tree_add_uint(tree, hf_rpc_authdes_namekind,
837 tvb, offset+0, 4, adc_namekind);
842 case AUTHDES_NAMEKIND_FULLNAME:
843 offset = dissect_rpc_string(tvb, pinfo, tree,
844 hf_rpc_authdes_netname, offset, NULL);
845 offset = dissect_rpc_authdes_desblock(tvb, pinfo, tree,
846 hf_rpc_authdes_convkey, offset);
847 window = tvb_get_ntohl(tvb, offset+0);
848 proto_tree_add_uint(tree, hf_rpc_authdes_window, tvb, offset+0, 4,
853 case AUTHDES_NAMEKIND_NICKNAME:
854 nickname = tvb_get_ntohl(tvb, offset+0);
855 proto_tree_add_uint(tree, hf_rpc_authdes_nickname, tvb, offset+0, 4,
865 dissect_rpc_cred(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
873 flavor = tvb_get_ntohl(tvb,offset+0);
874 length = tvb_get_ntohl(tvb,offset+4);
875 length = rpc_roundup(length);
878 citem = proto_tree_add_text(tree, tvb, offset,
879 8+length, "Credentials");
880 ctree = proto_item_add_subtree(citem, ett_rpc_cred);
881 proto_tree_add_uint(ctree, hf_rpc_auth_flavor, tvb,
882 offset+0, 4, flavor);
883 proto_tree_add_uint(ctree, hf_rpc_auth_length, tvb,
884 offset+4, 4, length);
888 dissect_rpc_authunix_cred(tvb, pinfo, ctree, offset+8);
896 dissect_rpc_authdes_cred(tvb, pinfo, ctree, offset+8);
900 dissect_rpc_authgss_cred(tvb, pinfo, ctree, offset+8);
904 proto_tree_add_text(ctree, tvb, offset+8,
905 length,"opaque data");
909 offset += 8 + length;
914 /* AUTH_DES verifiers are asymmetrical, so we need to know what type of
915 * verifier we're decoding (CALL or REPLY).
918 dissect_rpc_verf(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset, int msg_type)
926 flavor = tvb_get_ntohl(tvb,offset+0);
927 length = tvb_get_ntohl(tvb,offset+4);
928 length = rpc_roundup(length);
931 vitem = proto_tree_add_text(tree, tvb, offset,
932 8+length, "Verifier");
933 vtree = proto_item_add_subtree(vitem, ett_rpc_verf);
934 proto_tree_add_uint(vtree, hf_rpc_auth_flavor, tvb,
935 offset+0, 4, flavor);
939 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
940 offset+4, 4, length);
941 dissect_rpc_authunix_cred(tvb, pinfo, vtree, offset+8);
944 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
945 offset+4, 4, length);
947 if (msg_type == RPC_CALL)
951 dissect_rpc_authdes_desblock(tvb, pinfo, vtree,
952 hf_rpc_authdes_timestamp, offset+8);
953 window = tvb_get_ntohl(tvb, offset+16);
954 proto_tree_add_uint(vtree, hf_rpc_authdes_windowverf, tvb,
955 offset+16, 4, window);
959 /* must be an RPC_REPLY */
962 dissect_rpc_authdes_desblock(tvb, pinfo, vtree,
963 hf_rpc_authdes_timeverf, offset+8);
964 nickname = tvb_get_ntohl(tvb, offset+16);
965 proto_tree_add_uint(vtree, hf_rpc_authdes_nickname, tvb,
966 offset+16, 4, nickname);
970 dissect_rpc_data(tvb, pinfo, vtree,
971 hf_rpc_authgss_checksum, offset+4);
974 proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
975 offset+4, 4, length);
977 proto_tree_add_text(vtree, tvb, offset+8,
978 length, "opaque data");
982 offset += 8 + length;
988 dissect_rpc_authgss_initarg(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
990 offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_token,
996 dissect_rpc_authgss_initres(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
998 int major, minor, window;
1000 offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_ctx,
1003 major = tvb_get_ntohl(tvb,offset+0);
1005 proto_tree_add_uint(tree, hf_rpc_authgss_major, tvb,
1006 offset+0, 4, major);
1009 minor = tvb_get_ntohl(tvb,offset+0);
1011 proto_tree_add_uint(tree, hf_rpc_authgss_minor, tvb,
1012 offset+0, 4, minor);
1015 window = tvb_get_ntohl(tvb,offset+0);
1017 proto_tree_add_uint(tree, hf_rpc_authgss_window, tvb,
1018 offset+0, 4, window);
1021 offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_token,
1029 call_dissect_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1030 int offset, dissect_function_t* dissect_function, const char *progname)
1032 const char *saved_proto;
1034 if (dissect_function != NULL) {
1035 /* set the current protocol name */
1036 saved_proto = pinfo->current_proto;
1037 if (progname != NULL)
1038 pinfo->current_proto = progname;
1040 /* call the dissector for the next level */
1041 offset = dissect_function(tvb, offset, pinfo, tree);
1043 /* restore the protocol name */
1044 pinfo->current_proto = saved_proto;
1052 dissect_rpc_authgss_integ_data(tvbuff_t *tvb, packet_info *pinfo,
1053 proto_tree *tree, int offset,
1054 dissect_function_t* dissect_function,
1055 const char *progname)
1057 guint32 length, seq;
1060 proto_tree *gtree = NULL;
1062 length = tvb_get_ntohl(tvb, offset+0);
1063 length = rpc_roundup(length);
1064 seq = tvb_get_ntohl(tvb, offset+4);
1067 gitem = proto_tree_add_text(tree, tvb, offset,
1068 4+length, "GSS Data");
1069 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_data);
1070 proto_tree_add_uint(gtree, hf_rpc_authgss_data_length,
1071 tvb, offset+0, 4, length);
1072 proto_tree_add_uint(gtree, hf_rpc_authgss_seq,
1073 tvb, offset+4, 4, seq);
1077 if (dissect_function != NULL) {
1079 call_dissect_function(tvb, pinfo, gtree, offset,
1080 dissect_function, progname);
1082 offset += length - 4;
1083 offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_checksum,
1090 dissect_rpc_authgss_priv_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1092 offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_data,
1098 * Dissect the arguments to an indirect call; used by the portmapper/RPCBIND
1101 * Record this call in a hash table, similar to the hash table for
1102 * direct calls, so we can find it when dissecting an indirect call reply.
1105 dissect_rpc_indir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1106 int offset, int args_id, guint32 prog, guint32 vers, guint32 proc)
1108 conversation_t* conversation;
1109 static address null_address = { AT_NONE, 0, NULL };
1110 rpc_proc_info_key key;
1111 rpc_proc_info_value *value;
1112 rpc_call_info_value *rpc_call;
1113 rpc_call_info_key rpc_call_key;
1114 rpc_call_info_key *new_rpc_call_key;
1115 dissect_function_t *dissect_function = NULL;
1120 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1121 dissect_function = value->dissect_call;
1123 /* Keep track of the address and port whence the call came,
1124 and the port to which the call is being sent, so that
1125 we can match up calls with replies.
1127 If the transport is connection-oriented (we check, for
1128 now, only for "pinfo->ptype" of PT_TCP), we take
1129 into account the address from which the call was sent
1130 and the address to which the call was sent, because
1131 the addresses of the two endpoints should be the same
1132 for all calls and replies.
1134 If the transport is connectionless, we don't worry
1135 about the address to which the call was sent and from
1136 which the reply was sent, because there's no
1137 guarantee that the reply will come from the address
1138 to which the call was sent. */
1139 if (pinfo->ptype == PT_TCP) {
1140 conversation = find_conversation(&pinfo->src,
1141 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1142 pinfo->destport, 0);
1145 * XXX - can we just use NO_ADDR_B? Unfortunately,
1146 * you currently still have to pass a non-null
1147 * pointer for the second address argument even
1150 conversation = find_conversation(&pinfo->src,
1151 &null_address, pinfo->ptype, pinfo->srcport,
1152 pinfo->destport, 0);
1154 if (conversation == NULL) {
1155 /* It's not part of any conversation - create a new
1158 XXX - this should never happen, as we should've
1159 created a conversation for it in the RPC
1161 if (pinfo->ptype == PT_TCP) {
1162 conversation = conversation_new(&pinfo->src,
1163 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1164 pinfo->destport, 0);
1166 conversation = conversation_new(&pinfo->src,
1167 &null_address, pinfo->ptype, pinfo->srcport,
1168 pinfo->destport, 0);
1172 /* Make the dissector for this conversation the non-heuristic
1174 conversation_set_dissector(conversation,
1175 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1177 /* Prepare the key data.
1179 Dissectors for RPC procedure calls and replies shouldn't
1180 create new tvbuffs, and we don't create one ourselves,
1181 so we should have been handed the tvbuff for this RPC call;
1182 as such, the XID is at offset 0 in this tvbuff. */
1183 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1184 rpc_call_key.conversation = conversation;
1186 /* look up the request */
1187 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1188 if (rpc_call == NULL) {
1189 /* We didn't find it; create a new entry.
1190 Prepare the value data.
1191 Not all of it is needed for handling indirect
1192 calls, so we set a bunch of items to 0. */
1193 new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1194 *new_rpc_call_key = rpc_call_key;
1195 rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1196 rpc_call->req_num = 0;
1197 rpc_call->rep_num = 0;
1198 rpc_call->prog = prog;
1199 rpc_call->vers = vers;
1200 rpc_call->proc = proc;
1203 * XXX - what about RPCSEC_GSS?
1204 * Do we have to worry about it?
1206 rpc_call->flavor = FLAVOR_NOT_GSSAPI;
1207 rpc_call->gss_proc = 0;
1208 rpc_call->gss_svc = 0;
1209 rpc_call->proc_info = value;
1211 g_hash_table_insert(rpc_indir_calls, new_rpc_call_key,
1216 /* We don't know the procedure.
1217 Happens only with strange program versions or
1218 non-existing dissectors.
1219 Just show the arguments as opaque data. */
1220 offset = dissect_rpc_data(tvb, pinfo, tree, args_id,
1227 proto_tree_add_text(tree, tvb, offset, 4,
1228 "Argument length: %u",
1229 tvb_get_ntohl(tvb, offset));
1233 /* Dissect the arguments */
1234 offset = call_dissect_function(tvb, pinfo, tree, offset,
1235 dissect_function, NULL);
1240 * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1244 dissect_rpc_indir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1245 int offset, int result_id, int prog_id, int vers_id, int proc_id)
1247 conversation_t* conversation;
1248 static address null_address = { AT_NONE, 0, NULL };
1249 rpc_call_info_key rpc_call_key;
1250 rpc_call_info_value *rpc_call;
1251 char *procname = NULL;
1252 char procname_static[20];
1253 dissect_function_t *dissect_function = NULL;
1255 /* Look for the matching call in the hash table of indirect
1256 calls. A reply must match a call that we've seen, and the
1257 reply must be sent to the same port and address that the
1258 call came from, and must come from the port to which the
1261 If the transport is connection-oriented (we check, for
1262 now, only for "pinfo->ptype" of PT_TCP), we take
1263 into account the address from which the call was sent
1264 and the address to which the call was sent, because
1265 the addresses of the two endpoints should be the same
1266 for all calls and replies.
1268 If the transport is connectionless, we don't worry
1269 about the address to which the call was sent and from
1270 which the reply was sent, because there's no
1271 guarantee that the reply will come from the address
1272 to which the call was sent. */
1273 if (pinfo->ptype == PT_TCP) {
1274 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1275 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1278 * XXX - can we just use NO_ADDR_B? Unfortunately,
1279 * you currently still have to pass a non-null
1280 * pointer for the second address argument even
1283 conversation = find_conversation(&null_address, &pinfo->dst,
1284 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1286 if (conversation == NULL) {
1287 /* We haven't seen an RPC call for that conversation,
1288 so we can't check for a reply to that call.
1289 Just show the reply stuff as opaque data. */
1290 offset = dissect_rpc_data(tvb, pinfo, tree, result_id,
1295 /* The XIDs of the call and reply must match. */
1296 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1297 rpc_call_key.conversation = conversation;
1298 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1299 if (rpc_call == NULL) {
1300 /* The XID doesn't match a call from that
1301 conversation, so it's probably not an RPC reply.
1302 Just show the reply stuff as opaque data. */
1303 offset = dissect_rpc_data(tvb, pinfo, tree, result_id,
1308 if (rpc_call->proc_info != NULL) {
1309 dissect_function = rpc_call->proc_info->dissect_reply;
1310 if (rpc_call->proc_info->name != NULL) {
1311 procname = rpc_call->proc_info->name;
1314 sprintf(procname_static, "proc-%u", rpc_call->proc);
1315 procname = procname_static;
1320 dissect_function = NULL;
1322 sprintf(procname_static, "proc-%u", rpc_call->proc);
1323 procname = procname_static;
1328 /* Put the program, version, and procedure into the tree. */
1329 proto_tree_add_uint_format(tree, prog_id, tvb,
1330 0, 0, rpc_call->prog, "Program: %s (%u)",
1331 rpc_prog_name(rpc_call->prog), rpc_call->prog);
1332 proto_tree_add_uint(tree, vers_id, tvb, 0, 0, rpc_call->vers);
1333 proto_tree_add_uint_format(tree, proc_id, tvb,
1334 0, 0, rpc_call->proc, "Procedure: %s (%u)",
1335 procname, rpc_call->proc);
1338 if (dissect_function == NULL) {
1339 /* We don't know how to dissect the reply procedure.
1340 Just show the reply stuff as opaque data. */
1341 offset = dissect_rpc_data(tvb, pinfo, tree, result_id,
1347 /* Put the length of the reply value into the tree. */
1348 proto_tree_add_text(tree, tvb, offset, 4,
1349 "Argument length: %u",
1350 tvb_get_ntohl(tvb, offset));
1354 /* Dissect the return value */
1355 offset = call_dissect_function(tvb, pinfo, tree, offset,
1356 dissect_function, NULL);
1361 * Just mark this as a continuation of an earlier packet.
1364 dissect_rpc_continuation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1366 proto_item *rpc_item;
1367 proto_tree *rpc_tree;
1369 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1370 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1371 if (check_col(pinfo->cinfo, COL_INFO))
1372 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1375 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1377 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1378 proto_tree_add_text(rpc_tree, tvb, 0, -1, "Continuation data");
1383 dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1384 tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
1388 rpc_call_info_key rpc_call_key;
1389 rpc_call_info_value *rpc_call = NULL;
1390 rpc_prog_info_value *rpc_prog = NULL;
1391 rpc_prog_info_key rpc_prog_key;
1394 unsigned int rpcvers;
1395 unsigned int prog = 0;
1396 unsigned int vers = 0;
1397 unsigned int proc = 0;
1398 flavor_t flavor = FLAVOR_UNKNOWN;
1399 unsigned int gss_proc = 0;
1400 unsigned int gss_svc = 0;
1404 unsigned int reply_state;
1405 unsigned int accept_state;
1406 unsigned int reject_state;
1408 char *msg_type_name = NULL;
1409 char *progname = NULL;
1410 char *procname = NULL;
1411 static char procname_static[20];
1413 unsigned int vers_low;
1414 unsigned int vers_high;
1416 unsigned int auth_state;
1418 proto_item *rpc_item = NULL;
1419 proto_tree *rpc_tree = NULL;
1421 proto_item *pitem = NULL;
1422 proto_tree *ptree = NULL;
1423 int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
1424 int offset_old = offset;
1426 rpc_call_info_key *new_rpc_call_key;
1427 rpc_proc_info_key key;
1428 rpc_proc_info_value *value = NULL;
1429 conversation_t* conversation;
1430 static address null_address = { AT_NONE, 0, NULL };
1433 dissect_function_t *dissect_function = NULL;
1436 * Check to see whether this looks like an RPC call or reply.
1438 if (!tvb_bytes_exist(tvb, offset, 8)) {
1439 /* Captured data in packet isn't enough to let us tell. */
1443 /* both directions need at least this */
1444 msg_type = tvb_get_ntohl(tvb, offset + 4);
1449 /* check for RPC call */
1450 if (!tvb_bytes_exist(tvb, offset, 16)) {
1451 /* Captured data in packet isn't enough to let us
1456 /* XID can be anything, we don't check it.
1457 We already have the message type.
1458 Check whether an RPC version number of 2 is in the
1459 location where it would be, and that an RPC program
1460 number we know about is in the location where it would be. */
1461 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1462 if (tvb_get_ntohl(tvb, offset + 8) != 2 ||
1463 ((rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key))
1465 /* They're not, so it's probably not an RPC call. */
1471 /* Check for RPC reply. A reply must match a call that
1472 we've seen, and the reply must be sent to the same
1473 port and address that the call came from, and must
1474 come from the port to which the call was sent.
1476 If the transport is connection-oriented (we check, for
1477 now, only for "pinfo->ptype" of PT_TCP), we take
1478 into account the address from which the call was sent
1479 and the address to which the call was sent, because
1480 the addresses of the two endpoints should be the same
1481 for all calls and replies.
1483 If the transport is connectionless, we don't worry
1484 about the address to which the call was sent and from
1485 which the reply was sent, because there's no
1486 guarantee that the reply will come from the address
1487 to which the call was sent. */
1488 if (pinfo->ptype == PT_TCP) {
1489 conversation = find_conversation(&pinfo->src,
1490 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1491 pinfo->destport, 0);
1494 * XXX - can we just use NO_ADDR_B? Unfortunately,
1495 * you currently still have to pass a non-null
1496 * pointer for the second address argument even
1499 conversation = find_conversation(&null_address,
1500 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1501 pinfo->destport, 0);
1503 if (conversation == NULL) {
1504 /* We haven't seen an RPC call for that conversation,
1505 so we can't check for a reply to that call. */
1509 /* The XIDs of the call and reply must match. */
1510 rpc_call_key.xid = tvb_get_ntohl(tvb, offset + 0);
1511 rpc_call_key.conversation = conversation;
1512 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1513 if (rpc_call == NULL) {
1514 /* The XID doesn't match a call from that
1515 conversation, so it's probably not an RPC reply. */
1518 /* pass rpc_info to subdissectors */
1519 rpc_call->request=FALSE;
1520 pinfo->private_data=rpc_call;
1524 /* The putative message type field contains neither
1525 RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1532 * This is RPC-over-TCP; check if this is the last
1535 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
1537 * This isn't the last fragment.
1538 * If we're doing reassembly, just return
1539 * TRUE to indicate that this looks like
1540 * the beginning of an RPC message,
1541 * and let them do fragment reassembly.
1548 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1549 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1550 if (check_col(pinfo->cinfo, COL_INFO))
1551 col_clear(pinfo->cinfo, COL_INFO);
1554 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1556 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1559 show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
1564 xid = tvb_get_ntohl(tvb, offset + 0);
1566 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1567 offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1570 msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1572 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1573 offset+4, 4, msg_type);
1581 /* we know already the proto-entry, the ETT-const,
1583 proto = rpc_prog->proto;
1584 ett = rpc_prog->ett;
1585 progname = rpc_prog->progname;
1587 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1589 proto_tree_add_uint(rpc_tree,
1590 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1593 prog = tvb_get_ntohl(tvb, offset + 4);
1596 proto_tree_add_uint_format(rpc_tree,
1597 hf_rpc_program, tvb, offset+4, 4, prog,
1598 "Program: %s (%u)", progname, prog);
1601 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1602 /* Set the protocol name to the underlying
1604 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1607 vers = tvb_get_ntohl(tvb, offset+8);
1609 proto_tree_add_uint(rpc_tree,
1610 hf_rpc_programversion, tvb, offset+8, 4, vers);
1613 proc = tvb_get_ntohl(tvb, offset+12);
1619 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1620 dissect_function = value->dissect_call;
1621 procname = value->name;
1624 /* happens only with strange program versions or
1625 non-existing dissectors */
1627 dissect_function = NULL;
1629 sprintf(procname_static, "proc-%u", proc);
1630 procname = procname_static;
1634 proto_tree_add_uint_format(rpc_tree,
1635 hf_rpc_procedure, tvb, offset+12, 4, proc,
1636 "Procedure: %s (%u)", procname, proc);
1639 if (check_col(pinfo->cinfo, COL_INFO)) {
1640 col_add_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s XID 0x%x",
1647 /* Check for RPCSEC_GSS */
1648 if (tvb_bytes_exist(tvb, offset+16, 4)) {
1649 switch (tvb_get_ntohl(tvb, offset+16)) {
1653 * It's GSS-API authentication...
1655 if (tvb_bytes_exist(tvb, offset+28, 8)) {
1657 * ...and we have the procedure
1658 * and service information for it.
1660 flavor = FLAVOR_GSSAPI;
1661 gss_proc = tvb_get_ntohl(tvb, offset+28);
1662 gss_svc = tvb_get_ntohl(tvb, offset+36);
1665 * ...but the procedure and service
1666 * information isn't available.
1668 flavor = FLAVOR_GSSAPI_NO_INFO;
1674 * It's not GSS-API authentication.
1676 flavor = FLAVOR_NOT_GSSAPI;
1681 /* Keep track of the address and port whence the call came,
1682 and the port to which the call is being sent, so that
1683 we can match up calls with replies.
1685 If the transport is connection-oriented (we check, for
1686 now, only for "pinfo->ptype" of PT_TCP), we take
1687 into account the address from which the call was sent
1688 and the address to which the call was sent, because
1689 the addresses of the two endpoints should be the same
1690 for all calls and replies.
1692 If the transport is connectionless, we don't worry
1693 about the address to which the call was sent and from
1694 which the reply was sent, because there's no
1695 guarantee that the reply will come from the address
1696 to which the call was sent. */
1697 if (pinfo->ptype == PT_TCP) {
1698 conversation = find_conversation(&pinfo->src,
1699 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1700 pinfo->destport, 0);
1703 * XXX - can we just use NO_ADDR_B? Unfortunately,
1704 * you currently still have to pass a non-null
1705 * pointer for the second address argument even
1708 conversation = find_conversation(&pinfo->src,
1709 &null_address, pinfo->ptype, pinfo->srcport,
1710 pinfo->destport, 0);
1712 if (conversation == NULL) {
1713 /* It's not part of any conversation - create a new
1715 if (pinfo->ptype == PT_TCP) {
1716 conversation = conversation_new(&pinfo->src,
1717 &pinfo->dst, pinfo->ptype, pinfo->srcport,
1718 pinfo->destport, 0);
1720 conversation = conversation_new(&pinfo->src,
1721 &null_address, pinfo->ptype, pinfo->srcport,
1722 pinfo->destport, 0);
1726 /* Make the dissector for this conversation the non-heuristic
1728 conversation_set_dissector(conversation,
1729 (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1731 /* prepare the key data */
1732 rpc_call_key.xid = xid;
1733 rpc_call_key.conversation = conversation;
1735 /* look up the request */
1736 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1737 if (rpc_call != NULL) {
1738 /* We've seen a request with this XID, with the same
1739 source and destination, before - but was it
1741 if (pinfo->fd->num != rpc_call->req_num) {
1742 /* No, so it's a duplicate request.
1744 if (check_col(pinfo->cinfo, COL_INFO)) {
1745 col_append_fstr(pinfo->cinfo, COL_INFO,
1746 " dup XID 0x%x", xid);
1748 proto_tree_add_uint_hidden(rpc_tree,
1749 hf_rpc_dup, tvb, 0,0, xid);
1750 proto_tree_add_uint_hidden(rpc_tree,
1751 hf_rpc_call_dup, tvb, 0,0, xid);
1757 /* Prepare the value data.
1758 "req_num" and "rep_num" are frame numbers;
1759 frame numbers are 1-origin, so we use 0
1760 to mean "we don't yet know in which frame
1761 the reply for this call appears". */
1762 new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1763 *new_rpc_call_key = rpc_call_key;
1764 rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1765 rpc_call->req_num = pinfo->fd->num;
1766 rpc_call->rep_num = 0;
1767 rpc_call->prog = prog;
1768 rpc_call->vers = vers;
1769 rpc_call->proc = proc;
1770 rpc_call->xid = xid;
1771 rpc_call->flavor = flavor;
1772 rpc_call->gss_proc = gss_proc;
1773 rpc_call->gss_svc = gss_svc;
1774 rpc_call->proc_info = value;
1775 rpc_call->req_time.secs=pinfo->fd->abs_secs;
1776 rpc_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
1779 g_hash_table_insert(rpc_calls, new_rpc_call_key,
1785 offset = dissect_rpc_cred(tvb, pinfo, rpc_tree, offset);
1786 offset = dissect_rpc_verf(tvb, pinfo, rpc_tree, offset, msg_type);
1788 /* pass rpc_info to subdissectors */
1789 rpc_call->request=TRUE;
1790 pinfo->private_data=rpc_call;
1792 /* go to the next dissector */
1794 break; /* end of RPC call */
1797 /* we know already the type from the calling routine,
1798 and we already have "rpc_call" set above. */
1799 prog = rpc_call->prog;
1800 vers = rpc_call->vers;
1801 proc = rpc_call->proc;
1802 flavor = rpc_call->flavor;
1803 gss_proc = rpc_call->gss_proc;
1804 gss_svc = rpc_call->gss_svc;
1806 /* Indicate the frame to which this is a reply. */
1807 proto_tree_add_text(rpc_tree, tvb, 0, 0,
1808 "This is a reply to a request in frame %u",
1810 ns.secs= pinfo->fd->abs_secs-rpc_call->req_time.secs;
1811 ns.nsecs=pinfo->fd->abs_usecs*1000-rpc_call->req_time.nsecs;
1813 ns.nsecs+=1000000000;
1816 proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
1821 if (rpc_call->proc_info != NULL) {
1822 dissect_function = rpc_call->proc_info->dissect_reply;
1823 if (rpc_call->proc_info->name != NULL) {
1824 procname = rpc_call->proc_info->name;
1827 sprintf(procname_static, "proc-%u", proc);
1828 procname = procname_static;
1833 dissect_function = NULL;
1835 sprintf(procname_static, "proc-%u", proc);
1836 procname = procname_static;
1839 rpc_prog_key.prog = prog;
1840 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
1843 progname = "Unknown";
1846 proto = rpc_prog->proto;
1847 ett = rpc_prog->ett;
1848 progname = rpc_prog->progname;
1850 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1851 /* Set the protocol name to the underlying
1853 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1857 if (check_col(pinfo->cinfo, COL_INFO)) {
1858 col_add_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s XID 0x%x",
1866 proto_tree_add_uint_format(rpc_tree,
1867 hf_rpc_program, tvb, 0, 0, prog,
1868 "Program: %s (%u)", progname, prog);
1869 proto_tree_add_uint(rpc_tree,
1870 hf_rpc_programversion, tvb, 0, 0, vers);
1871 proto_tree_add_uint_format(rpc_tree,
1872 hf_rpc_procedure, tvb, 0, 0, proc,
1873 "Procedure: %s (%u)", procname, proc);
1876 if (rpc_call->rep_num == 0) {
1877 /* We have not yet seen a reply to that call, so
1878 this must be the first reply; remember its
1880 rpc_call->rep_num = pinfo->fd->num;
1882 /* We have seen a reply to this call - but was it
1884 if (rpc_call->rep_num != pinfo->fd->num) {
1885 /* No, so it's a duplicate reply.
1887 if (check_col(pinfo->cinfo, COL_INFO)) {
1888 col_append_fstr(pinfo->cinfo, COL_INFO,
1889 " dup XID 0x%x", xid);
1891 proto_tree_add_uint_hidden(rpc_tree,
1892 hf_rpc_dup, tvb, 0,0, xid);
1893 proto_tree_add_uint_hidden(rpc_tree,
1894 hf_rpc_reply_dup, tvb, 0,0, xid);
1900 reply_state = tvb_get_ntohl(tvb,offset+0);
1902 proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
1903 offset+0, 4, reply_state);
1907 if (reply_state == MSG_ACCEPTED) {
1908 offset = dissect_rpc_verf(tvb, pinfo, rpc_tree, offset, msg_type);
1909 accept_state = tvb_get_ntohl(tvb,offset+0);
1911 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
1912 offset+0, 4, accept_state);
1915 switch (accept_state) {
1918 /* go to the next dissector */
1922 vers_low = tvb_get_ntohl(tvb,offset+0);
1923 vers_high = tvb_get_ntohl(tvb,offset+4);
1925 proto_tree_add_uint(rpc_tree,
1926 hf_rpc_programversion_min,
1927 tvb, offset+0, 4, vers_low);
1928 proto_tree_add_uint(rpc_tree,
1929 hf_rpc_programversion_max,
1930 tvb, offset+4, 4, vers_high);
1939 } else if (reply_state == MSG_DENIED) {
1940 reject_state = tvb_get_ntohl(tvb,offset+0);
1942 proto_tree_add_uint(rpc_tree,
1943 hf_rpc_state_reject, tvb, offset+0, 4,
1948 if (reject_state==RPC_MISMATCH) {
1949 vers_low = tvb_get_ntohl(tvb,offset+0);
1950 vers_high = tvb_get_ntohl(tvb,offset+4);
1952 proto_tree_add_uint(rpc_tree,
1954 tvb, offset+0, 4, vers_low);
1955 proto_tree_add_uint(rpc_tree,
1957 tvb, offset+4, 4, vers_high);
1960 } else if (reject_state==AUTH_ERROR) {
1961 auth_state = tvb_get_ntohl(tvb,offset+0);
1963 proto_tree_add_uint(rpc_tree,
1964 hf_rpc_state_auth, tvb, offset+0, 4,
1970 break; /* end of RPC reply */
1974 * The switch statement at the top returned if
1975 * this was neither an RPC call nor a reply.
1977 g_assert_not_reached();
1980 /* now we know, that RPC was shorter */
1982 proto_item_set_len(rpc_item, offset - offset_old);
1985 /* create here the program specific sub-tree */
1987 pitem = proto_tree_add_item(tree, proto, tvb, offset, -1,
1990 ptree = proto_item_add_subtree(pitem, ett);
1994 proto_tree_add_uint(ptree,
1995 hf_rpc_programversion, tvb, 0, 0, vers);
1996 proto_tree_add_uint_format(ptree,
1997 hf_rpc_procedure, tvb, 0, 0, proc,
1998 "Procedure: %s (%u)", procname, proc);
2002 if (!proto_is_protocol_enabled(proto))
2003 dissect_function = NULL;
2006 * Handle RPCSEC_GSS specially.
2010 case FLAVOR_UNKNOWN:
2012 * We don't know the authentication flavor, so we can't
2013 * dissect the payload.
2015 proto_tree_add_text(ptree, tvb, offset, -1,
2016 "Unknown authentication flavor - cannot dissect");
2019 case FLAVOR_NOT_GSSAPI:
2021 * It's not GSS-API authentication. Just dissect the
2024 offset = call_dissect_function(tvb, pinfo, ptree, offset,
2025 dissect_function, progname);
2028 case FLAVOR_GSSAPI_NO_INFO:
2030 * It's GSS-API authentication, but we don't have the
2031 * procedure and service information, so we can't dissect
2034 proto_tree_add_text(ptree, tvb, offset, -1,
2035 "GSS-API authentication, but procedure and service unknown - cannot dissect");
2040 * It's GSS-API authentication, and we have the procedure
2041 * and service information; process the GSS-API stuff,
2042 * and process the payload if there is any.
2046 case RPCSEC_GSS_INIT:
2047 case RPCSEC_GSS_CONTINUE_INIT:
2048 if (msg_type == RPC_CALL) {
2049 offset = dissect_rpc_authgss_initarg(tvb,
2050 pinfo, ptree, offset);
2053 offset = dissect_rpc_authgss_initres(tvb,
2054 pinfo, ptree, offset);
2058 case RPCSEC_GSS_DATA:
2059 if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2060 offset = call_dissect_function(tvb,
2061 pinfo, ptree, offset,
2065 else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2066 offset = dissect_rpc_authgss_integ_data(tvb,
2067 pinfo, ptree, offset,
2071 else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2072 offset = dissect_rpc_authgss_priv_data(tvb,
2073 pinfo, ptree, offset);
2082 /* dissect any remaining bytes (incomplete dissection) as pure data in
2084 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, ptree);
2090 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2092 return dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0);
2096 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2098 if (!dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0))
2099 dissect_rpc_continuation(tvb, pinfo, tree);
2102 /* Defragmentation of RPC-over-TCP records */
2103 /* table to hold defragmented RPC records */
2104 static GHashTable *rpc_fragment_table = NULL;
2106 static GHashTable *rpc_reassembly_table = NULL;
2107 static GMemChunk *rpc_fragment_key_chunk = NULL;
2108 static int rpc_fragment_init_count = 200;
2110 typedef struct _rpc_fragment_key {
2119 rpc_fragment_hash(gconstpointer k)
2121 rpc_fragment_key *key = (rpc_fragment_key *)k;
2123 return key->conv_id + key->seq;
2127 rpc_fragment_equal(gconstpointer k1, gconstpointer k2)
2129 rpc_fragment_key *key1 = (rpc_fragment_key *)k1;
2130 rpc_fragment_key *key2 = (rpc_fragment_key *)k2;
2132 return key1->conv_id == key2->conv_id &&
2133 key1->seq == key2->seq;
2137 show_rpc_fragheader(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2139 proto_item *hdr_item;
2140 proto_tree *hdr_tree;
2144 fraglen = rpc_rm & RPC_RM_FRAGLEN;
2146 hdr_item = proto_tree_add_text(tree, tvb, 0, 4,
2147 "Fragment header: %s%u %s",
2148 (rpc_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
2149 fraglen, plurality(fraglen, "byte", "bytes"));
2150 hdr_tree = proto_item_add_subtree(hdr_item, ett_rpc_fraghdr);
2152 proto_tree_add_boolean(hdr_tree, hf_rpc_lastfrag, tvb, 0, 4,
2154 proto_tree_add_uint(hdr_tree, hf_rpc_fraglen, tvb, 0, 4,
2160 show_rpc_fragment(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2164 * Show the fragment header and the data for the fragment.
2166 show_rpc_fragheader(tvb, tree, rpc_rm);
2167 proto_tree_add_text(tree, tvb, 4, -1, "Fragment Data");
2172 make_frag_tree(tvbuff_t *tvb, proto_tree *tree, int proto, gint ett,
2175 proto_item *frag_item;
2176 proto_tree *frag_tree;
2179 return; /* nothing to do */
2181 frag_item = proto_tree_add_protocol_format(tree, proto, tvb, 0, -1,
2182 "%s Fragment", proto_get_protocol_name(proto));
2183 frag_tree = proto_item_add_subtree(frag_item, ett);
2184 show_rpc_fragment(tvb, frag_tree, rpc_rm);
2188 show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
2189 guint32 rpc_rm, fragment_data *ipfd_head)
2191 proto_tree *st = NULL;
2192 proto_item *si = NULL;
2193 fragment_data *ipfd;
2196 return; /* don't do any work */
2198 if (tvb != frag_tvb) {
2200 * This message was not all in one fragment,
2201 * so show the fragment header *and* the data
2202 * for the fragment (which is the last fragment),
2203 * and a tree with information about all fragments.
2205 show_rpc_fragment(frag_tvb, tree, rpc_rm);
2208 * Show a tree with information about all fragments.
2210 si = proto_tree_add_text(tree, tvb, 0, 0, "Fragments");
2211 st = proto_item_add_subtree(si, ett_rpc_fragments);
2212 for (ipfd = ipfd_head->next; ipfd != NULL; ipfd = ipfd->next) {
2213 proto_tree_add_text(st, tvb, 0, 0,
2217 ipfd->offset + ipfd->len - 1);
2221 * This message was all in one fragment, so just show
2222 * the fragment header.
2224 show_rpc_fragheader(tvb, tree, rpc_rm);
2229 call_message_dissector(tvbuff_t *tvb, tvbuff_t *rec_tvb, packet_info *pinfo,
2230 proto_tree *tree, tvbuff_t *frag_tvb, rec_dissector_t dissector,
2231 fragment_data *ipfd_head, guint32 rpc_rm)
2233 const char *saved_proto;
2234 volatile gboolean rpc_succeeded;
2237 * Catch the ReportedBoundsError exception; if
2238 * this particular message happens to get a
2239 * ReportedBoundsError exception, that doesn't
2240 * mean that we should stop dissecting RPC
2241 * messages within this frame or chunk of
2244 * If it gets a BoundsError, we can stop, as there's
2245 * nothing more to see, so we just re-throw it.
2247 saved_proto = pinfo->current_proto;
2248 rpc_succeeded = FALSE;
2250 rpc_succeeded = (*dissector)(rec_tvb, pinfo, tree,
2251 frag_tvb, ipfd_head, TRUE, rpc_rm);
2253 CATCH(BoundsError) {
2256 CATCH(ReportedBoundsError) {
2257 show_reported_bounds_error(tvb, pinfo, tree);
2258 pinfo->current_proto = saved_proto;
2261 * We treat this as a "successful" dissection of
2262 * an RPC packet, as "dissect_rpc_message()"
2263 * *did* decide it was an RPC packet, throwing
2264 * an exception while dissecting it as such.
2266 rpc_succeeded = TRUE;
2269 return rpc_succeeded;
2273 dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
2274 proto_tree *tree, rec_dissector_t dissector, gboolean is_heur,
2275 int proto, int ett, gboolean defragment)
2277 struct tcpinfo *tcpinfo = pinfo->private_data;
2278 guint32 seq = tcpinfo->seq + offset;
2280 volatile gint32 len;
2282 gint tvb_len, tvb_reported_len;
2284 gboolean rpc_succeeded;
2285 gboolean save_fragmented;
2286 rpc_fragment_key old_rfk, *rfk, *new_rfk;
2287 conversation_t *conversation;
2288 fragment_data *ipfd_head;
2290 fragment_data *ipfd;
2293 * Get the record mark.
2295 if (!tvb_bytes_exist(tvb, offset, 4)) {
2297 * XXX - we should somehow arrange to handle
2298 * a record mark split across TCP segments.
2300 return 0; /* not enough to tell if it's valid */
2302 rpc_rm = tvb_get_ntohl(tvb, offset);
2304 len = rpc_rm & RPC_RM_FRAGLEN;
2307 * Do TCP desegmentation, if enabled.
2309 * XXX - reject fragments bigger than 2 megabytes.
2310 * This is arbitrary, but should at least prevent
2311 * some crashes from either packets with really
2312 * large RPC-over-TCP fragments or from stuff that's
2313 * not really valid for this protocol.
2315 if (len > 2*1024*1024)
2316 return 0; /* pretend it's not valid */
2317 if (rpc_desegment) {
2318 seglen = tvb_length_remaining(tvb, offset + 4);
2320 if (len > seglen && pinfo->can_desegment) {
2322 * This frame doesn't have all of the
2323 * data for this message, but we can do
2326 * If this is a heuristic dissector, just
2327 * return 0 - we don't want to try to get
2328 * more data, as that's too likely to cause
2329 * us to misidentify this as valid.
2331 * If this isn't a heuristic dissector,
2332 * we've already identified this conversation
2333 * as containing data for this protocol, as we
2334 * saw valid data in previous frames. Try to
2338 return 0; /* not valid */
2340 pinfo->desegment_offset = offset;
2341 pinfo->desegment_len = len - seglen;
2342 return -pinfo->desegment_len;
2346 len += 4; /* include record mark */
2347 tvb_len = tvb_length_remaining(tvb, offset);
2348 tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2351 if (tvb_reported_len > len)
2352 tvb_reported_len = len;
2353 frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2357 * If we're not defragmenting, just hand this to the
2362 * This is the first fragment we've seen, and it's also
2363 * the last fragment; that means the record wasn't
2364 * fragmented. Hand the dissector the tvbuff for the
2365 * fragment as the tvbuff for the record.
2371 * Mark this as fragmented, so if somebody throws an
2372 * exception, we don't report it as a malformed frame.
2374 save_fragmented = pinfo->fragmented;
2375 pinfo->fragmented = TRUE;
2376 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
2377 tree, frag_tvb, dissector, ipfd_head, rpc_rm);
2378 pinfo->fragmented = save_fragmented;
2380 return 0; /* not RPC */
2385 * First, we check to see if this fragment is part of a record
2386 * that we're in the process of defragmenting.
2388 * The key is the conversation ID for the conversation to which
2389 * the packet belongs and the current sequence number.
2390 * We must first find the conversation and, if we don't find
2391 * one, create it. We know this is running over TCP, so the
2392 * conversation should not wildcard either address or port.
2394 conversation = find_conversation(&pinfo->src, &pinfo->dst,
2395 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2396 if (conversation == NULL) {
2398 * It's not part of any conversation - create a new one.
2400 conversation = conversation_new(&pinfo->src, &pinfo->dst,
2401 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2403 old_rfk.conv_id = conversation->index;
2405 rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
2409 * This fragment was not found in our table, so it doesn't
2410 * contain a continuation of a higher-level PDU.
2411 * Is it the last fragment?
2413 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2415 * This isn't the last fragment, so we don't
2416 * have the complete record.
2418 * It's the first fragment we've seen, so if
2419 * it's truly the first fragment of the record,
2420 * and it has enough data, the dissector can at
2421 * least check whether it looks like a valid
2422 * message, as it contains the start of the
2425 * The dissector should not dissect anything
2426 * if the "last fragment" flag isn't set in
2427 * the record marker, so it shouldn't throw
2430 if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
2431 NULL, TRUE, rpc_rm))
2432 return 0; /* not valid */
2435 * OK, now start defragmentation with that
2436 * fragment. Add this fragment, and set up
2437 * next packet/sequence number as well.
2439 * We must remember this fragment.
2442 rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2443 rfk->conv_id = conversation->index;
2446 rfk->start_seq = seq;
2447 g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
2450 * Start defragmentation.
2452 ipfd_head = fragment_add(tvb, offset + 4, pinfo,
2453 rfk->start_seq, rpc_fragment_table,
2454 rfk->offset, len - 4, TRUE);
2457 * Make sure that defragmentation isn't complete;
2458 * it shouldn't be, as this is the first fragment
2459 * we've seen, and the "last fragment" bit wasn't
2462 g_assert(ipfd_head == NULL);
2464 new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2465 new_rfk->conv_id = rfk->conv_id;
2466 new_rfk->seq = seq + len;
2467 new_rfk->offset = rfk->offset + len - 4;
2468 new_rfk->start_seq = rfk->start_seq;
2469 g_hash_table_insert(rpc_reassembly_table, new_rfk,
2473 * This is part of a fragmented record,
2474 * but it's not the first part.
2475 * Show it as a record marker plus data, under
2476 * a top-level tree for this protocol.
2478 make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
2481 * No more processing need be done, as we don't
2482 * have a complete record.
2488 * This is the first fragment we've seen, and it's also
2489 * the last fragment; that means the record wasn't
2490 * fragmented. Hand the dissector the tvbuff for the
2491 * fragment as the tvbuff for the record.
2497 * OK, this fragment was found, which means it continues
2498 * a record. This means we must defragment it.
2499 * Add it to the defragmentation lists.
2501 ipfd_head = fragment_add(tvb, offset + 4, pinfo,
2502 rfk->start_seq, rpc_fragment_table,
2503 rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
2505 if (ipfd_head == NULL) {
2507 * fragment_add() returned NULL, This means that
2508 * defragmentation is not completed yet.
2510 * We must add an entry to the hash table with
2511 * the sequence number following this fragment
2512 * as the starting sequence number, so that when
2513 * we see that fragment we'll find that entry.
2515 * XXX - as TCP stream data is not currently
2516 * guaranteed to be provided in order to dissectors,
2517 * RPC fragments aren't guaranteed to be provided
2520 new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2521 new_rfk->conv_id = rfk->conv_id;
2522 new_rfk->seq = seq + len;
2523 new_rfk->offset = rfk->offset + len - 4;
2524 new_rfk->start_seq = rfk->start_seq;
2525 g_hash_table_insert(rpc_reassembly_table, new_rfk,
2529 * This is part of a fragmented record,
2530 * but it's not the first part.
2531 * Show it as a record marker plus data, under
2532 * a top-level tree for this protocol,
2533 * but don't hand it to the dissector
2535 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
2538 * No more processing need be done, as we don't
2539 * have a complete record.
2545 * It's completely defragmented.
2547 * We only call subdissector for the last fragment.
2548 * XXX - this assumes in-order delivery of RPC
2549 * fragments, which requires in-order delivery of TCP
2552 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2554 * Well, it's defragmented, but this isn't
2555 * the last fragment; this probably means
2556 * this isn't the first pass, so we don't
2557 * need to start defragmentation.
2559 * This is part of a fragmented record,
2560 * but it's not the first part.
2561 * Show it as a record marker plus data, under
2562 * a top-level tree for this protocol,
2563 * but don't show it to the dissector.
2565 make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
2568 * No more processing need be done, as we
2569 * only disssect the data with the last
2576 * OK, this is the last segment.
2577 * Create a tvbuff for the defragmented
2582 * Create a new TVB structure for
2583 * defragmented data.
2585 rec_tvb = tvb_new_real_data(ipfd_head->data,
2586 ipfd_head->datalen, ipfd_head->datalen);
2589 * Add this tvb as a child to the original
2592 tvb_set_child_real_data_tvbuff(tvb, rec_tvb);
2595 * Add defragmented data to the data source list.
2597 add_new_data_source(pinfo->fd, rec_tvb, "Defragmented");
2601 * We have something to hand to the RPC message
2604 if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
2605 frag_tvb, dissector, ipfd_head, rpc_rm))
2606 return 0; /* not RPC */
2613 * NEED_MORE_DATA, if we don't have enough data to dissect anything;
2615 * IS_RPC, if we dissected at least one message in its entirety
2618 * IS_NOT_RPC, if we found no RPC message.
2626 static rpc_tcp_return_t
2627 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2631 gboolean saw_rpc = FALSE;
2634 while (tvb_reported_length_remaining(tvb, offset) != 0) {
2636 * Process this fragment.
2638 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
2639 dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
2643 * We need more data from the TCP stream for
2646 return NEED_MORE_DATA;
2650 * It's not RPC. Stop processing.
2658 return saw_rpc ? IS_RPC : IS_NOT_RPC;
2662 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2664 switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
2673 /* "Can't happen" */
2674 g_assert_not_reached();
2680 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2682 if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
2683 dissect_rpc_continuation(tvb, pinfo, tree);
2686 /* Discard any state we've saved. */
2688 rpc_init_protocol(void)
2690 if (rpc_calls != NULL) {
2691 g_hash_table_destroy(rpc_calls);
2694 if (rpc_indir_calls != NULL) {
2695 g_hash_table_destroy(rpc_indir_calls);
2696 rpc_indir_calls = NULL;
2698 if (rpc_call_info_key_chunk != NULL) {
2699 g_mem_chunk_destroy(rpc_call_info_key_chunk);
2700 rpc_call_info_key_chunk = NULL;
2702 if (rpc_call_info_value_chunk != NULL) {
2703 g_mem_chunk_destroy(rpc_call_info_value_chunk);
2704 rpc_call_info_value_chunk = NULL;
2706 if (rpc_fragment_key_chunk != NULL) {
2707 g_mem_chunk_destroy(rpc_fragment_key_chunk);
2708 rpc_fragment_key_chunk = NULL;
2710 if (rpc_reassembly_table != NULL) {
2711 g_hash_table_destroy(rpc_reassembly_table);
2712 rpc_reassembly_table = NULL;
2715 rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
2716 rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
2717 rpc_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
2718 sizeof(rpc_call_info_key),
2719 200 * sizeof(rpc_call_info_key),
2721 rpc_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
2722 sizeof(rpc_call_info_value),
2723 200 * sizeof(rpc_call_info_value),
2725 rpc_fragment_key_chunk = g_mem_chunk_new("rpc_fragment_key_chunk",
2726 sizeof(rpc_fragment_key),
2727 rpc_fragment_init_count*sizeof(rpc_fragment_key),
2729 rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
2730 rpc_fragment_equal);
2732 fragment_table_init(&rpc_fragment_table);
2735 /* will be called once from register.c at startup time */
2737 proto_register_rpc(void)
2739 static hf_register_info hf[] = {
2740 { &hf_rpc_lastfrag, {
2741 "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
2742 &yesno, RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
2743 { &hf_rpc_fraglen, {
2744 "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
2745 NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
2747 "XID", "rpc.xid", FT_UINT32, BASE_HEX,
2748 NULL, 0, "XID", HFILL }},
2749 { &hf_rpc_msgtype, {
2750 "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
2751 VALS(rpc_msg_type), 0, "Message Type", HFILL }},
2752 { &hf_rpc_state_reply, {
2753 "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
2754 VALS(rpc_reply_state), 0, "Reply State", HFILL }},
2755 { &hf_rpc_state_accept, {
2756 "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
2757 VALS(rpc_accept_state), 0, "Accept State", HFILL }},
2758 { &hf_rpc_state_reject, {
2759 "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
2760 VALS(rpc_reject_state), 0, "Reject State", HFILL }},
2761 { &hf_rpc_state_auth, {
2762 "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
2763 VALS(rpc_auth_state), 0, "Auth State", HFILL }},
2764 { &hf_rpc_version, {
2765 "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
2766 NULL, 0, "RPC Version", HFILL }},
2767 { &hf_rpc_version_min, {
2768 "RPC Version (Minimum)", "rpc.version.min", FT_UINT32,
2769 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
2770 { &hf_rpc_version_max, {
2771 "RPC Version (Maximum)", "rpc.version.max", FT_UINT32,
2772 BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
2773 { &hf_rpc_program, {
2774 "Program", "rpc.program", FT_UINT32, BASE_DEC,
2775 NULL, 0, "Program", HFILL }},
2776 { &hf_rpc_programversion, {
2777 "Program Version", "rpc.programversion", FT_UINT32,
2778 BASE_DEC, NULL, 0, "Program Version", HFILL }},
2779 { &hf_rpc_programversion_min, {
2780 "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32,
2781 BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
2782 { &hf_rpc_programversion_max, {
2783 "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32,
2784 BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
2785 { &hf_rpc_procedure, {
2786 "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
2787 NULL, 0, "Procedure", HFILL }},
2788 { &hf_rpc_auth_flavor, {
2789 "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
2790 VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
2791 { &hf_rpc_auth_length, {
2792 "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
2793 NULL, 0, "Length", HFILL }},
2794 { &hf_rpc_auth_stamp, {
2795 "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
2796 NULL, 0, "Stamp", HFILL }},
2797 { &hf_rpc_auth_uid, {
2798 "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
2799 NULL, 0, "UID", HFILL }},
2800 { &hf_rpc_auth_gid, {
2801 "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
2802 NULL, 0, "GID", HFILL }},
2803 { &hf_rpc_authgss_v, {
2804 "GSS Version", "rpc.authgss.version", FT_UINT32,
2805 BASE_DEC, NULL, 0, "GSS Version", HFILL }},
2806 { &hf_rpc_authgss_proc, {
2807 "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
2808 BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
2809 { &hf_rpc_authgss_seq, {
2810 "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
2811 BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
2812 { &hf_rpc_authgss_svc, {
2813 "GSS Service", "rpc.authgss.service", FT_UINT32,
2814 BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
2815 { &hf_rpc_authgss_ctx, {
2816 "GSS Context", "rpc.authgss.context", FT_BYTES,
2817 BASE_HEX, NULL, 0, "GSS Context", HFILL }},
2818 { &hf_rpc_authgss_major, {
2819 "GSS Major Status", "rpc.authgss.major", FT_UINT32,
2820 BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
2821 { &hf_rpc_authgss_minor, {
2822 "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
2823 BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
2824 { &hf_rpc_authgss_window, {
2825 "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
2826 BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
2827 { &hf_rpc_authgss_token, {
2828 "GSS Token", "rpc.authgss.token", FT_BYTES,
2829 BASE_HEX, NULL, 0, "GSS Token", HFILL }},
2830 { &hf_rpc_authgss_data_length, {
2831 "Length", "rpc.authgss.data.length", FT_UINT32,
2832 BASE_DEC, NULL, 0, "Length", HFILL }},
2833 { &hf_rpc_authgss_data, {
2834 "GSS Data", "rpc.authgss.data", FT_BYTES,
2835 BASE_HEX, NULL, 0, "GSS Data", HFILL }},
2836 { &hf_rpc_authgss_checksum, {
2837 "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
2838 BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
2839 { &hf_rpc_authdes_namekind, {
2840 "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
2841 VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
2842 { &hf_rpc_authdes_netname, {
2843 "Netname", "rpc.authdes.netname", FT_STRING,
2844 BASE_DEC, NULL, 0, "Netname", HFILL }},
2845 { &hf_rpc_authdes_convkey, {
2846 "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
2847 BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
2848 { &hf_rpc_authdes_window, {
2849 "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
2850 BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
2851 { &hf_rpc_authdes_nickname, {
2852 "Nickname", "rpc.authdes.nickname", FT_UINT32,
2853 BASE_HEX, NULL, 0, "Nickname", HFILL }},
2854 { &hf_rpc_authdes_timestamp, {
2855 "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
2856 BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
2857 { &hf_rpc_authdes_windowverf, {
2858 "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
2859 BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
2860 { &hf_rpc_authdes_timeverf, {
2861 "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
2862 BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
2863 { &hf_rpc_auth_machinename, {
2864 "Machine Name", "rpc.auth.machinename", FT_STRING,
2865 BASE_DEC, NULL, 0, "Machine Name", HFILL }},
2867 "Duplicate Transaction", "rpc.dup", FT_UINT32, BASE_DEC,
2868 NULL, 0, "Duplicate Transaction", HFILL }},
2869 { &hf_rpc_call_dup, {
2870 "Duplicate Call", "rpc.call.dup", FT_UINT32, BASE_DEC,
2871 NULL, 0, "Duplicate Call", HFILL }},
2872 { &hf_rpc_reply_dup, {
2873 "Duplicate Reply", "rpc.reply.dup", FT_UINT32, BASE_DEC,
2874 NULL, 0, "Duplicate Reply", HFILL }},
2875 { &hf_rpc_value_follows, {
2876 "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
2877 &yesno, 0, "Value Follows", HFILL }},
2878 { &hf_rpc_array_len, {
2879 "num", "rpc.array.len", FT_UINT32, BASE_DEC,
2880 NULL, 0, "Length of RPC array", HFILL }},
2883 "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
2884 NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
2887 static gint *ett[] = {
2898 module_t *rpc_module;
2900 proto_rpc = proto_register_protocol("Remote Procedure Call",
2902 proto_register_field_array(proto_rpc, hf, array_length(hf));
2903 proto_register_subtree_array(ett, array_length(ett));
2904 register_init_routine(&rpc_init_protocol);
2905 rpc_tcp_handle = create_dissector_handle(dissect_rpc_tcp, proto_rpc);
2906 rpc_handle = create_dissector_handle(dissect_rpc, proto_rpc);
2908 rpc_module = prefs_register_protocol(proto_rpc, NULL);
2909 prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
2910 "Desegment all RPC-over-TCP messages",
2911 "Whether the RPC dissector should desegment all RPC-over-TCP messages",
2913 prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
2914 "Defragment all RPC-over-TCP messages",
2915 "Whether the RPC dissector should defragment multi-fragment RPC-over-TCP messages",
2919 * Init the hash tables. Dissectors for RPC protocols must
2920 * have a "handoff registration" routine that registers the
2921 * protocol with RPC; they must not do it in their protocol
2922 * registration routine, as their protocol registration
2923 * routine might be called before this routine is called and
2924 * thus might be called before the hash tables are initialized,
2925 * but it's guaranteed that all protocol registration routines
2926 * will be called before any handoff registration routines
2929 rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
2930 rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
2934 proto_reg_handoff_rpc(void)
2936 heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
2937 heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
2938 data_handle = find_dissector("data");