From Clinton Work: dissect Cisco PID 0x010b as STP (it's actually their
[obnox/wireshark/wip.git] / packet-rpc.c
1 /* packet-rpc.c
2  * Routines for rpc dissection
3  * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
4  *
5  * $Id: packet-rpc.c,v 1.143 2004/04/07 03:57:34 sahlberg Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from packet-smb.c
12  *
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.
17  *
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.
22  *
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.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <glib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <epan/packet.h>
37 #include <epan/conversation.h>
38 #include "packet-rpc.h"
39 #include "packet-frame.h"
40 #include "packet-tcp.h"
41 #include "prefs.h"
42 #include "reassemble.h"
43 #include "rpc_defrag.h"
44 #include "packet-nfs.h"
45 #include "tap.h"
46
47 /*
48  * See:
49  *
50  *      RFC 1831, "RPC: Remote Procedure Call Protocol Specification
51  *      Version 2";
52  *
53  *      RFC 1832, "XDR: External Data Representation Standard";
54  *
55  *      RFC 2203, "RPCSEC_GSS Protocol Specification".
56  *
57  * See also
58  *
59  *      RFC 2695, "Authentication Mechanisms for ONC RPC"
60  *
61  *      although we don't currently dissect AUTH_DES or AUTH_KERB.
62  */
63
64 /* desegmentation of RPC over TCP */
65 static gboolean rpc_desegment = TRUE;
66
67 /* defragmentation of fragmented RPC over TCP records */
68 static gboolean rpc_defragment = FALSE;
69
70 /* try to dissect RPC packets for programs that are not known
71  * (proprietary ones) by ethereal.
72  */
73 static gboolean rpc_dissect_unknown_programs = FALSE;
74
75
76 static struct true_false_string yesno = { "Yes", "No" };
77
78 static int rpc_tap = -1;
79
80 static const value_string rpc_msg_type[] = {
81         { RPC_CALL, "Call" },
82         { RPC_REPLY, "Reply" },
83         { 0, NULL }
84 };
85
86 static const value_string rpc_reply_state[] = {
87         { MSG_ACCEPTED, "accepted" },
88         { MSG_DENIED, "denied" },
89         { 0, NULL }
90 };
91
92 const value_string rpc_auth_flavor[] = {
93         { AUTH_NULL, "AUTH_NULL" },
94         { AUTH_UNIX, "AUTH_UNIX" },
95         { AUTH_SHORT, "AUTH_SHORT" },
96         { AUTH_DES, "AUTH_DES" },
97         { RPCSEC_GSS, "RPCSEC_GSS" },
98         { AUTH_GSSAPI, "AUTH_GSSAPI" },
99         { 0, NULL }
100 };
101
102 static const value_string rpc_authgss_proc[] = {
103         { RPCSEC_GSS_DATA, "RPCSEC_GSS_DATA" },
104         { RPCSEC_GSS_INIT, "RPCSEC_GSS_INIT" },
105         { RPCSEC_GSS_CONTINUE_INIT, "RPCSEC_GSS_CONTINUE_INIT" },
106         { RPCSEC_GSS_DESTROY, "RPCSEC_GSS_DESTROY" },
107         { 0, NULL }
108 };
109
110 static const value_string rpc_authgssapi_proc[] = {
111         { AUTH_GSSAPI_EXIT, "AUTH_GSSAPI_EXIT" },
112         { AUTH_GSSAPI_INIT, "AUTH_GSSAPI_INIT" },
113         { AUTH_GSSAPI_CONTINUE_INIT, "AUTH_GSSAPI_CONTINUE_INIT" },
114         { AUTH_GSSAPI_MSG, "AUTH_GSSAPI_MSG" },
115         { AUTH_GSSAPI_DESTROY, "AUTH_GSSAPI_DESTROY" },
116         { 0, NULL }
117 };
118
119 value_string rpc_authgss_svc[] = {
120         { RPCSEC_GSS_SVC_NONE, "rpcsec_gss_svc_none" },
121         { RPCSEC_GSS_SVC_INTEGRITY, "rpcsec_gss_svc_integrity" },
122         { RPCSEC_GSS_SVC_PRIVACY, "rpcsec_gss_svc_privacy" },
123         { 0, NULL }
124 };
125
126 static const value_string rpc_accept_state[] = {
127         { SUCCESS, "RPC executed successfully" },
128         { PROG_UNAVAIL, "remote hasn't exported program" },
129         { PROG_MISMATCH, "remote can't support version #" },
130         { PROC_UNAVAIL, "program can't support procedure" },
131         { GARBAGE_ARGS, "procedure can't decode params" },
132         { 0, NULL }
133 };
134
135 static const value_string rpc_reject_state[] = {
136         { RPC_MISMATCH, "RPC_MISMATCH" },
137         { AUTH_ERROR, "AUTH_ERROR" },
138         { 0, NULL }
139 };
140
141 static const value_string rpc_auth_state[] = {
142         { AUTH_BADCRED, "bad credential (seal broken)" },
143         { AUTH_REJECTEDCRED, "client must begin new session" },
144         { AUTH_BADVERF, "bad verifier (seal broken)" },
145         { AUTH_REJECTEDVERF, "verifier expired or replayed" },
146         { AUTH_TOOWEAK, "rejected for security reasons" },
147         { RPCSEC_GSSCREDPROB, "GSS credential problem" },
148         { RPCSEC_GSSCTXPROB, "GSS context problem" },
149         { 0, NULL }
150 };
151
152 static const value_string rpc_authdes_namekind[] = {
153         { AUTHDES_NAMEKIND_FULLNAME, "ADN_FULLNAME" },
154         { AUTHDES_NAMEKIND_NICKNAME, "ADN_NICKNAME" },
155         { 0, NULL }
156 };
157
158 /* the protocol number */
159 static int proto_rpc = -1;
160 static int hf_rpc_reqframe = -1;
161 static int hf_rpc_repframe = -1;
162 static int hf_rpc_lastfrag = -1;
163 static int hf_rpc_fraglen = -1;
164 static int hf_rpc_xid = -1;
165 static int hf_rpc_msgtype = -1;
166 static int hf_rpc_version = -1;
167 static int hf_rpc_version_min = -1;
168 static int hf_rpc_version_max = -1;
169 static int hf_rpc_program = -1;
170 static int hf_rpc_programversion = -1;
171 static int hf_rpc_programversion_min = -1;
172 static int hf_rpc_programversion_max = -1;
173 static int hf_rpc_procedure = -1;
174 static int hf_rpc_auth_flavor = -1;
175 static int hf_rpc_auth_length = -1;
176 static int hf_rpc_auth_machinename = -1;
177 static int hf_rpc_auth_stamp = -1;
178 static int hf_rpc_auth_uid = -1;
179 static int hf_rpc_auth_gid = -1;
180 static int hf_rpc_authgss_v = -1;
181 static int hf_rpc_authgss_proc = -1;
182 static int hf_rpc_authgss_seq = -1;
183 static int hf_rpc_authgss_svc = -1;
184 static int hf_rpc_authgss_ctx = -1;
185 static int hf_rpc_authgss_major = -1;
186 static int hf_rpc_authgss_minor = -1;
187 static int hf_rpc_authgss_window = -1;
188 static int hf_rpc_authgss_token_length = -1;
189 static int hf_rpc_authgss_data_length = -1;
190 static int hf_rpc_authgss_data = -1;
191 static int hf_rpc_authgss_checksum = -1;
192 static int hf_rpc_authgssapi_v = -1;
193 static int hf_rpc_authgssapi_msg = -1;
194 static int hf_rpc_authgssapi_msgv = -1;
195 static int hf_rpc_authgssapi_handle = -1;
196 static int hf_rpc_authgssapi_isn = -1;
197 static int hf_rpc_authdes_namekind = -1;
198 static int hf_rpc_authdes_netname = -1;
199 static int hf_rpc_authdes_convkey = -1;
200 static int hf_rpc_authdes_window = -1;
201 static int hf_rpc_authdes_nickname = -1;
202 static int hf_rpc_authdes_timestamp = -1;
203 static int hf_rpc_authdes_windowverf = -1;
204 static int hf_rpc_authdes_timeverf = -1;
205 static int hf_rpc_state_accept = -1;
206 static int hf_rpc_state_reply = -1;
207 static int hf_rpc_state_reject = -1;
208 static int hf_rpc_state_auth = -1;
209 static int hf_rpc_dup = -1;
210 static int hf_rpc_call_dup = -1;
211 static int hf_rpc_reply_dup = -1;
212 static int hf_rpc_value_follows = -1;
213 static int hf_rpc_array_len = -1;
214 static int hf_rpc_time = -1;
215 static int hf_rpc_fragments = -1;
216 static int hf_rpc_fragment = -1;
217 static int hf_rpc_fragment_overlap = -1;
218 static int hf_rpc_fragment_overlap_conflict = -1;
219 static int hf_rpc_fragment_multiple_tails = -1;
220 static int hf_rpc_fragment_too_long_fragment = -1;
221 static int hf_rpc_fragment_error = -1;
222
223 static gint ett_rpc = -1;
224 static gint ett_rpc_unknown_program = -1;
225 static gint ett_rpc_fragments = -1;
226 static gint ett_rpc_fragment = -1;
227 static gint ett_rpc_fraghdr = -1;
228 static gint ett_rpc_string = -1;
229 static gint ett_rpc_cred = -1;
230 static gint ett_rpc_verf = -1;
231 static gint ett_rpc_gids = -1;
232 static gint ett_rpc_gss_token = -1;
233 static gint ett_rpc_gss_data = -1;
234 static gint ett_rpc_array = -1;
235 static gint ett_rpc_authgssapi_msg = -1;
236
237 static dissector_handle_t rpc_tcp_handle;
238 static dissector_handle_t rpc_handle;
239 static dissector_handle_t gssapi_handle;
240 static dissector_handle_t data_handle;
241
242 static int max_rpc_tcp_pdu_size = 262144;
243
244 static const fragment_items rpc_frag_items = {
245         &ett_rpc_fragment,
246         &ett_rpc_fragments,
247         &hf_rpc_fragments,
248         &hf_rpc_fragment,
249         &hf_rpc_fragment_overlap,
250         &hf_rpc_fragment_overlap_conflict,
251         &hf_rpc_fragment_multiple_tails,
252         &hf_rpc_fragment_too_long_fragment,
253         &hf_rpc_fragment_error,
254         NULL,
255         "fragments"
256 };
257
258 /* Hash table with info on RPC program numbers */
259 GHashTable *rpc_progs;
260
261 /* Hash table with info on RPC procedure numbers */
262 GHashTable *rpc_procs;
263
264 static void dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
265 static void dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
266
267 /***********************************/
268 /* Hash array with procedure names */
269 /***********************************/
270
271 /* compare 2 keys */
272 static gint
273 rpc_proc_equal(gconstpointer k1, gconstpointer k2)
274 {
275         const rpc_proc_info_key* key1 = (const rpc_proc_info_key*) k1;
276         const rpc_proc_info_key* key2 = (const rpc_proc_info_key*) k2;
277
278         return ((key1->prog == key2->prog &&
279                 key1->vers == key2->vers &&
280                 key1->proc == key2->proc) ?
281         TRUE : FALSE);
282 }
283
284 /* calculate a hash key */
285 static guint
286 rpc_proc_hash(gconstpointer k)
287 {
288         const rpc_proc_info_key* key = (const rpc_proc_info_key*) k;
289
290         return (key->prog ^ (key->vers<<16) ^ (key->proc<<24));
291 }
292
293
294 /* insert some entries */
295 void
296 rpc_init_proc_table(guint prog, guint vers, const vsff *proc_table,
297     int procedure_hf)
298 {
299         rpc_prog_info_key rpc_prog_key;
300         rpc_prog_info_value *rpc_prog;
301         const vsff *proc;
302
303         /*
304          * Add the operation number hfinfo value for this version of the
305          * program.
306          */
307         rpc_prog_key.prog = prog;
308         rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key);
309         g_assert(rpc_prog != NULL);
310         rpc_prog->procedure_hfs = g_array_set_size(rpc_prog->procedure_hfs,
311             vers);
312         g_array_insert_val(rpc_prog->procedure_hfs, vers, procedure_hf);
313
314         for (proc = proc_table ; proc->strptr!=NULL; proc++) {
315                 rpc_proc_info_key *key;
316                 rpc_proc_info_value *value;
317
318                 key = (rpc_proc_info_key *) g_malloc(sizeof(rpc_proc_info_key));
319                 key->prog = prog;
320                 key->vers = vers;
321                 key->proc = proc->value;
322
323                 value = (rpc_proc_info_value *) g_malloc(sizeof(rpc_proc_info_value));
324                 value->name = proc->strptr;
325                 value->dissect_call = proc->dissect_call;
326                 value->dissect_reply = proc->dissect_reply;
327
328                 g_hash_table_insert(rpc_procs,key,value);
329         }
330 }
331
332
333 /*      return the name associated with a previously registered procedure. */
334 char *rpc_proc_name(guint32 prog, guint32 vers, guint32 proc)
335 {
336         rpc_proc_info_key key;
337         rpc_proc_info_value *value;
338         char *procname;
339         static char procname_static[20];
340
341         key.prog = prog;
342         key.vers = vers;
343         key.proc = proc;
344
345         if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL)
346                 procname = value->name;
347         else {
348                 /* happens only with strange program versions or
349                    non-existing dissectors */
350                 sprintf(procname_static, "proc-%u", key.proc);
351                 procname = procname_static;
352         }
353         return procname;
354 }
355
356 /*----------------------------------------*/
357 /* end of Hash array with procedure names */
358 /*----------------------------------------*/
359
360
361 /*********************************/
362 /* Hash array with program names */
363 /*********************************/
364
365 /* compare 2 keys */
366 static gint
367 rpc_prog_equal(gconstpointer k1, gconstpointer k2)
368 {
369         const rpc_prog_info_key* key1 = (const rpc_prog_info_key*) k1;
370         const rpc_prog_info_key* key2 = (const rpc_prog_info_key*) k2;
371
372         return ((key1->prog == key2->prog) ?
373         TRUE : FALSE);
374 }
375
376
377 /* calculate a hash key */
378 static guint
379 rpc_prog_hash(gconstpointer k)
380 {
381         const rpc_prog_info_key* key = (const rpc_prog_info_key*) k;
382
383         return (key->prog);
384 }
385
386
387 void
388 rpc_init_prog(int proto, guint32 prog, int ett)
389 {
390         rpc_prog_info_key *key;
391         rpc_prog_info_value *value;
392
393         key = (rpc_prog_info_key *) g_malloc(sizeof(rpc_prog_info_key));
394         key->prog = prog;
395
396         value = (rpc_prog_info_value *) g_malloc(sizeof(rpc_prog_info_value));
397         value->proto = find_protocol_by_id(proto);
398         value->proto_id = proto;
399         value->ett = ett;
400         value->progname = proto_get_protocol_short_name(value->proto);
401         value->procedure_hfs = g_array_new(FALSE, TRUE, sizeof (int));
402
403         g_hash_table_insert(rpc_progs,key,value);
404 }
405
406
407
408 /*      return the hf_field associated with a previously registered program.
409 */
410 int rpc_prog_hf(guint32 prog, guint32 vers)
411 {
412         rpc_prog_info_key       rpc_prog_key;
413         rpc_prog_info_value     *rpc_prog;
414
415         rpc_prog_key.prog = prog;
416         if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key))) {
417                 return g_array_index(rpc_prog->procedure_hfs, int, vers);
418         }
419         return -1;
420 }
421
422 /*      return the name associated with a previously registered program. This
423         should probably eventually be expanded to use the rpc YP/NIS map
424         so that it can give names for programs not handled by ethereal */
425 char *rpc_prog_name(guint32 prog)
426 {
427         char *progname = NULL;
428         rpc_prog_info_key       rpc_prog_key;
429         rpc_prog_info_value     *rpc_prog;
430
431         rpc_prog_key.prog = prog;
432         if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
433                 progname = "Unknown";
434         }
435         else {
436                 progname = rpc_prog->progname;
437         }
438         return progname;
439 }
440
441
442 /*--------------------------------------*/
443 /* end of Hash array with program names */
444 /*--------------------------------------*/
445
446 typedef struct _rpc_call_info_key {
447         guint32 xid;
448         conversation_t *conversation;
449 } rpc_call_info_key;
450
451 static GMemChunk *rpc_call_info_key_chunk;
452
453 static GMemChunk *rpc_call_info_value_chunk;
454
455 static GHashTable *rpc_calls;
456
457 static GHashTable *rpc_indir_calls;
458
459 /* compare 2 keys */
460 static gint
461 rpc_call_equal(gconstpointer k1, gconstpointer k2)
462 {
463         const rpc_call_info_key* key1 = (const rpc_call_info_key*) k1;
464         const rpc_call_info_key* key2 = (const rpc_call_info_key*) k2;
465
466         return (key1->xid == key2->xid &&
467             key1->conversation == key2->conversation);
468 }
469
470
471 /* calculate a hash key */
472 static guint
473 rpc_call_hash(gconstpointer k)
474 {
475         const rpc_call_info_key* key = (const rpc_call_info_key*) k;
476
477         return key->xid + GPOINTER_TO_UINT(key->conversation);
478 }
479
480
481 unsigned int
482 rpc_roundup(unsigned int a)
483 {
484         unsigned int mod = a % 4;
485         return a + ((mod)? 4-mod : 0);
486 }
487
488
489 int
490 dissect_rpc_bool(tvbuff_t *tvb, proto_tree *tree,
491 int hfindex, int offset)
492 {
493         if (tree)
494                 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
495         return offset + 4;
496 }
497
498
499 int
500 dissect_rpc_uint32(tvbuff_t *tvb, proto_tree *tree,
501 int hfindex, int offset)
502 {
503         if (tree)
504                 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
505         return offset + 4;
506 }
507
508
509 int
510 dissect_rpc_uint64(tvbuff_t *tvb, proto_tree *tree,
511 int hfindex, int offset)
512 {
513         header_field_info       *hfinfo;
514
515         hfinfo = proto_registrar_get_nth(hfindex);
516         g_assert(hfinfo->type == FT_UINT64);
517         if (tree)
518                 proto_tree_add_item(tree, hfindex, tvb, offset, 8, FALSE);
519
520         return offset + 8;
521 }
522
523 /*
524  * We want to make this function available outside this file and 
525  * allow callers to pass a dissection function for the opaque data
526  */ 
527 int
528 dissect_rpc_opaque_data(tvbuff_t *tvb, int offset,
529     proto_tree *tree,
530     packet_info *pinfo,
531     int hfindex,
532     gboolean fixed_length, guint32 length,
533     gboolean string_data, char **string_buffer_ret,
534     dissect_function_t *dissect_it)
535 {
536         int data_offset;
537         proto_item *string_item = NULL;
538         proto_tree *string_tree = NULL;
539
540         guint32 string_length;
541         guint32 string_length_full;
542         guint32 string_length_packet;
543         guint32 string_length_captured;
544         guint32 string_length_copy;
545
546         int fill_truncated;
547         guint32 fill_length;
548         guint32 fill_length_packet;
549         guint32 fill_length_captured;
550         guint32 fill_length_copy;
551
552         int exception = 0;
553
554         char *string_buffer = NULL;
555         char *string_buffer_print = NULL;
556
557         if (fixed_length) {
558                 string_length = length;
559                 data_offset = offset;
560         }
561         else {
562                 string_length = tvb_get_ntohl(tvb,offset+0);
563                 data_offset = offset + 4;
564         }
565         string_length_captured = tvb_length_remaining(tvb, data_offset);
566         string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
567         string_length_full = rpc_roundup(string_length);
568         if (string_length_captured < string_length) {
569                 /* truncated string */
570                 string_length_copy = string_length_captured;
571                 fill_truncated = 2;
572                 fill_length = 0;
573                 fill_length_copy = 0;
574                 if (string_length_packet < string_length)
575                         exception = ReportedBoundsError;
576                 else
577                         exception = BoundsError;
578         }
579         else {
580                 /* full string data */
581                 string_length_copy = string_length;
582                 fill_length = string_length_full - string_length;
583                 fill_length_captured = tvb_length_remaining(tvb,
584                     data_offset + string_length);
585                 fill_length_packet = tvb_reported_length_remaining(tvb,
586                     data_offset + string_length);
587                 if (fill_length_captured < fill_length) {
588                         /* truncated fill bytes */
589                         fill_length_copy = fill_length_packet;
590                         fill_truncated = 1;
591                         if (fill_length_packet < fill_length)
592                                 exception = ReportedBoundsError;
593                         else
594                                 exception = BoundsError;
595                 }
596                 else {
597                         /* full fill bytes */
598                         fill_length_copy = fill_length;
599                         fill_truncated = 0;
600                 }
601         }
602
603         /*
604          * If we were passed a dissection routine, make a TVB of the data
605          * and call the dissection routine
606          */
607
608         if (dissect_it) {
609           tvbuff_t *opaque_tvb;
610
611           opaque_tvb = tvb_new_subset(tvb, data_offset, string_length_copy,
612                                       string_length);
613
614           return (*dissect_it)(opaque_tvb, offset, pinfo, tree);
615
616         }
617
618         if (string_data) {
619                 string_buffer = tvb_get_string(tvb, data_offset,
620                     string_length_copy);
621         } else {
622                 string_buffer = tvb_memdup(tvb, data_offset,
623                     string_length_copy);
624         }
625         /* calculate a nice printable string */
626         if (string_length) {
627                 if (string_length != string_length_copy) {
628                         if (string_data) {
629                                 /* alloc maximum data area */
630                                 string_buffer_print = (char*)g_malloc(string_length_copy + 12 + 1);
631                                 /* copy over the data */
632                                 memcpy(string_buffer_print,string_buffer,string_length_copy);
633                                 /* append a 0 byte for sure printing */
634                                 string_buffer_print[string_length_copy] = '\0';
635                                 /* append <TRUNCATED> */
636                                 /* This way, we get the TRUNCATED even
637                                    in the case of totally wrong packets,
638                                    where \0 are inside the string.
639                                    TRUNCATED will appear at the
640                                    first \0 or at the end (where we
641                                    put the securing \0).
642                                 */
643                                 strcat(string_buffer_print,"<TRUNCATED>");
644                         }
645                         else {
646                                 string_buffer_print = g_strdup("<DATA><TRUNCATED>");
647                         }
648                 }
649                 else {
650                         if (string_data) {
651                                 string_buffer_print = g_strdup(string_buffer);
652                         }
653                         else {
654                                 string_buffer_print = g_strdup("<DATA>");
655                         }
656                 }
657         }
658         else {
659                 string_buffer_print = g_strdup("<EMPTY>");
660         }
661
662         if (tree) {
663                 string_item = proto_tree_add_text(tree, tvb,offset+0, -1,
664                     "%s: %s", proto_registrar_get_name(hfindex),
665                     string_buffer_print);
666                 string_tree = proto_item_add_subtree(string_item,
667                     ett_rpc_string);
668         }
669         if (!fixed_length) {
670                 if (string_tree)
671                         proto_tree_add_text(string_tree, tvb,offset+0,4,
672                                 "length: %u", string_length);
673                 offset += 4;
674         }
675
676         if (string_tree) {
677                 if (string_data) {
678                         proto_tree_add_string_format(string_tree,
679                             hfindex, tvb, offset, string_length_copy,
680                             string_buffer,
681                             "contents: %s", string_buffer_print);
682                 } else {
683                         proto_tree_add_bytes_format(string_tree,
684                             hfindex, tvb, offset, string_length_copy,
685                             string_buffer,
686                             "contents: %s", string_buffer_print);
687                 }
688         }
689
690         offset += string_length_copy;
691
692         if (fill_length) {
693                 if (string_tree) {
694                         if (fill_truncated) {
695                                 proto_tree_add_text(string_tree, tvb,
696                                 offset,fill_length_copy,
697                                 "fill bytes: opaque data<TRUNCATED>");
698                         }
699                         else {
700                                 proto_tree_add_text(string_tree, tvb,
701                                 offset,fill_length_copy,
702                                 "fill bytes: opaque data");
703                         }
704                 }
705                 offset += fill_length_copy;
706         }
707
708         if (string_item)
709                 proto_item_set_end(string_item, tvb, offset);
710
711         if (string_buffer != NULL)
712                 g_free(string_buffer);
713         if (string_buffer_print != NULL) {
714                 if (string_buffer_ret != NULL)
715                         *string_buffer_ret = string_buffer_print;
716                 else
717                         g_free(string_buffer_print);
718         }
719
720         /*
721          * If the data was truncated, throw the appropriate exception,
722          * so that dissection stops and the frame is properly marked.
723          */
724         if (exception != 0)
725                 THROW(exception);
726         return offset;
727 }
728
729
730 int
731 dissect_rpc_string(tvbuff_t *tvb, proto_tree *tree,
732     int hfindex, int offset, char **string_buffer_ret)
733 {
734         offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL, 
735             hfindex, FALSE, 0, TRUE, string_buffer_ret, NULL);
736         return offset;
737 }
738
739
740 int
741 dissect_rpc_data(tvbuff_t *tvb, proto_tree *tree,
742     int hfindex, int offset)
743 {
744         offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL, 
745                                          hfindex, FALSE, 0, FALSE, NULL, NULL);
746         return offset;
747 }
748
749
750 int
751 dissect_rpc_bytes(tvbuff_t *tvb, proto_tree *tree,
752     int hfindex, int offset, guint32 length,
753     gboolean string_data, char **string_buffer_ret)
754 {
755         offset = dissect_rpc_opaque_data(tvb, offset, tree, NULL,
756             hfindex, TRUE, length, string_data, string_buffer_ret, NULL);
757         return offset;
758 }
759
760
761 int
762 dissect_rpc_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
763         int offset, dissect_function_t *rpc_list_dissector)
764 {
765         guint32 value_follows;
766
767         while (1) {
768                 value_follows = tvb_get_ntohl(tvb, offset+0);
769                 proto_tree_add_boolean(tree,hf_rpc_value_follows, tvb,
770                         offset+0, 4, value_follows);
771                 offset += 4;
772                 if (value_follows == 1) {
773                         offset = rpc_list_dissector(tvb, offset, pinfo, tree);
774                 }
775                 else {
776                         break;
777                 }
778         }
779
780         return offset;
781 }
782
783 int
784 dissect_rpc_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
785         int offset, dissect_function_t *rpc_array_dissector,
786         int hfindex)
787 {
788         proto_item* lock_item;
789         proto_tree* lock_tree;
790         guint32 num;
791
792         num = tvb_get_ntohl(tvb, offset);
793
794         if( num == 0 ){
795                 proto_tree_add_none_format(tree, hfindex, tvb, offset, 4,
796                         "no values");
797                 offset += 4;
798
799                 return offset;
800         }
801
802         lock_item = proto_tree_add_item(tree, hfindex, tvb, offset, -1, FALSE);
803
804         lock_tree = proto_item_add_subtree(lock_item, ett_rpc_array);
805
806         offset = dissect_rpc_uint32(tvb, lock_tree,
807                         hf_rpc_array_len, offset);
808
809         while (num--) {
810                 offset = rpc_array_dissector(tvb, offset, pinfo, lock_tree);
811         }
812
813         proto_item_set_end(lock_item, tvb, offset);
814         return offset;
815 }
816
817 static int
818 dissect_rpc_authunix_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
819 {
820         guint stamp;
821         guint uid;
822         guint gid;
823         guint gids_count;
824         guint gids_i;
825         guint gids_entry;
826         proto_item *gitem;
827         proto_tree *gtree = NULL;
828
829         stamp = tvb_get_ntohl(tvb,offset+0);
830         if (tree)
831                 proto_tree_add_uint(tree, hf_rpc_auth_stamp, tvb,
832                         offset+0, 4, stamp);
833         offset += 4;
834
835         offset = dissect_rpc_string(tvb, tree,
836                         hf_rpc_auth_machinename, offset, NULL);
837
838         uid = tvb_get_ntohl(tvb,offset+0);
839         if (tree)
840                 proto_tree_add_uint(tree, hf_rpc_auth_uid, tvb,
841                         offset+0, 4, uid);
842         offset += 4;
843
844         gid = tvb_get_ntohl(tvb,offset+0);
845         if (tree)
846                 proto_tree_add_uint(tree, hf_rpc_auth_gid, tvb,
847                         offset+0, 4, gid);
848         offset += 4;
849
850         gids_count = tvb_get_ntohl(tvb,offset+0);
851         if (tree) {
852                 gitem = proto_tree_add_text(tree, tvb,
853                         offset, 4+gids_count*4, "Auxiliary GIDs");
854                 gtree = proto_item_add_subtree(gitem, ett_rpc_gids);
855         }
856         offset += 4;
857
858         for (gids_i = 0 ; gids_i < gids_count ; gids_i++) {
859                 gids_entry = tvb_get_ntohl(tvb,offset+0);
860                 if (gtree)
861                 proto_tree_add_uint(gtree, hf_rpc_auth_gid, tvb,
862                         offset, 4, gids_entry);
863                 offset+=4;
864         }
865         /* how can I NOW change the gitem to print a list with
866                 the first 16 gids? */
867
868         return offset;
869 }
870
871 static int
872 dissect_rpc_authgss_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
873 {
874         guint agc_v;
875         guint agc_proc;
876         guint agc_seq;
877         guint agc_svc;
878
879         agc_v = tvb_get_ntohl(tvb, offset+0);
880         if (tree)
881                 proto_tree_add_uint(tree, hf_rpc_authgss_v,
882                                     tvb, offset+0, 4, agc_v);
883         offset += 4;
884
885         agc_proc = tvb_get_ntohl(tvb, offset+0);
886         if (tree)
887                 proto_tree_add_uint(tree, hf_rpc_authgss_proc,
888                                     tvb, offset+0, 4, agc_proc);
889         offset += 4;
890
891         agc_seq = tvb_get_ntohl(tvb, offset+0);
892         if (tree)
893                 proto_tree_add_uint(tree, hf_rpc_authgss_seq,
894                                     tvb, offset+0, 4, agc_seq);
895         offset += 4;
896
897         agc_svc = tvb_get_ntohl(tvb, offset+0);
898         if (tree)
899                 proto_tree_add_uint(tree, hf_rpc_authgss_svc,
900                                     tvb, offset+0, 4, agc_svc);
901         offset += 4;
902
903         offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
904                         offset);
905
906         return offset;
907 }
908
909 static int
910 dissect_rpc_authdes_desblock(tvbuff_t *tvb, proto_tree *tree,
911 int hfindex, int offset)
912 {
913         guint32 value_low;
914         guint32 value_high;
915
916         value_high = tvb_get_ntohl(tvb, offset + 0);
917         value_low  = tvb_get_ntohl(tvb, offset + 4);
918
919         if (tree) {
920                 proto_tree_add_text(tree, tvb, offset, 8,
921                         "%s: 0x%x%08x", proto_registrar_get_name(hfindex), value_high,
922                         value_low);
923         }
924
925         return offset + 8;
926 }
927
928 static int
929 dissect_rpc_authdes_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
930 {
931         guint adc_namekind;
932         guint window = 0;
933         guint nickname = 0;
934
935         adc_namekind = tvb_get_ntohl(tvb, offset+0);
936         if (tree)
937                 proto_tree_add_uint(tree, hf_rpc_authdes_namekind,
938                                     tvb, offset+0, 4, adc_namekind);
939         offset += 4;
940
941         switch(adc_namekind)
942         {
943         case AUTHDES_NAMEKIND_FULLNAME:
944                 offset = dissect_rpc_string(tvb, tree,
945                         hf_rpc_authdes_netname, offset, NULL);
946                 offset = dissect_rpc_authdes_desblock(tvb, tree,
947                         hf_rpc_authdes_convkey, offset);
948                 window = tvb_get_ntohl(tvb, offset+0);
949                 proto_tree_add_uint(tree, hf_rpc_authdes_window, tvb, offset+0, 4,
950                         window);
951                 offset += 4;
952                 break;
953
954         case AUTHDES_NAMEKIND_NICKNAME:
955                 nickname = tvb_get_ntohl(tvb, offset+0);
956                 proto_tree_add_uint(tree, hf_rpc_authdes_nickname, tvb, offset+0, 4,
957                         nickname);
958                 offset += 4;
959                 break;
960         }
961
962         return offset;
963 }
964
965 static int
966 dissect_rpc_authgssapi_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
967 {
968         guint agc_v;
969         guint agc_msg;
970
971         agc_v = tvb_get_ntohl(tvb, offset+0);
972         if (tree)
973                 proto_tree_add_uint(tree, hf_rpc_authgssapi_v,
974                                     tvb, offset+0, 4, agc_v);
975         offset += 4;
976
977         agc_msg = tvb_get_ntohl(tvb, offset+0);
978         if (tree)
979                 proto_tree_add_boolean(tree, hf_rpc_authgssapi_msg,
980                                     tvb, offset+0, 4, agc_msg);
981         offset += 4;
982
983         offset = dissect_rpc_data(tvb, tree, hf_rpc_authgssapi_handle,
984                         offset);
985
986         return offset;
987 }
988
989 static int
990 dissect_rpc_cred(tvbuff_t* tvb, proto_tree* tree, int offset)
991 {
992         guint flavor;
993         guint length;
994
995         proto_item *citem;
996         proto_tree *ctree;
997
998         flavor = tvb_get_ntohl(tvb,offset+0);
999         length = tvb_get_ntohl(tvb,offset+4);
1000         length = rpc_roundup(length);
1001
1002         if (tree) {
1003                 citem = proto_tree_add_text(tree, tvb, offset,
1004                                             8+length, "Credentials");
1005                 ctree = proto_item_add_subtree(citem, ett_rpc_cred);
1006                 proto_tree_add_uint(ctree, hf_rpc_auth_flavor, tvb,
1007                                     offset+0, 4, flavor);
1008                 proto_tree_add_uint(ctree, hf_rpc_auth_length, tvb,
1009                                     offset+4, 4, length);
1010
1011                 switch (flavor) {
1012                 case AUTH_UNIX:
1013                         dissect_rpc_authunix_cred(tvb, ctree, offset+8);
1014                         break;
1015                 /*
1016                 case AUTH_SHORT:
1017
1018                 break;
1019                 */
1020                 case AUTH_DES:
1021                         dissect_rpc_authdes_cred(tvb, ctree, offset+8);
1022                         break;
1023
1024                 case RPCSEC_GSS:
1025                         dissect_rpc_authgss_cred(tvb, ctree, offset+8);
1026                         break;
1027
1028                 case AUTH_GSSAPI:
1029                         dissect_rpc_authgssapi_cred(tvb, ctree, offset+8);
1030                         break;
1031
1032                 default:
1033                         if (length)
1034                                 proto_tree_add_text(ctree, tvb, offset+8,
1035                                                     length,"opaque data");
1036                 break;
1037                 }
1038         }
1039         offset += 8 + length;
1040
1041         return offset;
1042 }
1043
1044 /*
1045  * XDR opaque object, the contents of which are interpreted as a GSS-API
1046  * token.
1047  */
1048 static int
1049 dissect_rpc_authgss_token(tvbuff_t* tvb, proto_tree* tree, int offset,
1050     packet_info *pinfo)
1051 {
1052         guint32 opaque_length, rounded_length;
1053         gint len_consumed, length, reported_length;
1054         tvbuff_t *new_tvb;
1055
1056         proto_item *gitem;
1057         proto_tree *gtree = NULL;
1058
1059         opaque_length = tvb_get_ntohl(tvb, offset+0);
1060         rounded_length = rpc_roundup(opaque_length);
1061         if (tree) {
1062                 gitem = proto_tree_add_text(tree, tvb, offset,
1063                                             4+rounded_length, "GSS Token");
1064                 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_token);
1065                 proto_tree_add_uint(gtree, hf_rpc_authgss_token_length,
1066                                     tvb, offset+0, 4, opaque_length);
1067         }
1068         offset += 4;
1069         length = tvb_length_remaining(tvb, offset);
1070         reported_length = tvb_reported_length_remaining(tvb, offset);
1071         g_assert(length >= 0);
1072         g_assert(reported_length >= 0);
1073         if (length > reported_length)
1074                 length = reported_length;
1075         if ((guint32)length > opaque_length)
1076                 length = opaque_length;
1077         if ((guint32)reported_length > opaque_length)
1078                 reported_length = opaque_length;
1079         new_tvb = tvb_new_subset(tvb, offset, length, reported_length);
1080         len_consumed = call_dissector(gssapi_handle, new_tvb, pinfo, gtree);
1081         offset += len_consumed;
1082         offset = rpc_roundup(offset);
1083         return offset;
1084 }
1085
1086 /* AUTH_DES verifiers are asymmetrical, so we need to know what type of
1087  * verifier we're decoding (CALL or REPLY).
1088  */
1089 static int
1090 dissect_rpc_verf(tvbuff_t* tvb, proto_tree* tree, int offset, int msg_type,
1091                  packet_info *pinfo)
1092 {
1093         guint flavor;
1094         guint length;
1095
1096         proto_item *vitem;
1097         proto_tree *vtree;
1098
1099         flavor = tvb_get_ntohl(tvb,offset+0);
1100         length = tvb_get_ntohl(tvb,offset+4);
1101         length = rpc_roundup(length);
1102
1103         if (tree) {
1104                 vitem = proto_tree_add_text(tree, tvb, offset,
1105                                             8+length, "Verifier");
1106                 vtree = proto_item_add_subtree(vitem, ett_rpc_verf);
1107                 proto_tree_add_uint(vtree, hf_rpc_auth_flavor, tvb,
1108                                     offset+0, 4, flavor);
1109
1110                 switch (flavor) {
1111                 case AUTH_UNIX:
1112                         proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1113                                             offset+4, 4, length);
1114                         dissect_rpc_authunix_cred(tvb, vtree, offset+8);
1115                         break;
1116                 case AUTH_DES:
1117                         proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1118                                 offset+4, 4, length);
1119
1120                         if (msg_type == RPC_CALL)
1121                         {
1122                                 guint window;
1123
1124                                 dissect_rpc_authdes_desblock(tvb, vtree,
1125                                         hf_rpc_authdes_timestamp, offset+8);
1126                                 window = tvb_get_ntohl(tvb, offset+16);
1127                                 proto_tree_add_uint(vtree, hf_rpc_authdes_windowverf, tvb,
1128                                         offset+16, 4, window);
1129                         }
1130                         else
1131                         {
1132                                 /* must be an RPC_REPLY */
1133                                 guint nickname;
1134
1135                                 dissect_rpc_authdes_desblock(tvb, vtree,
1136                                         hf_rpc_authdes_timeverf, offset+8);
1137                                 nickname = tvb_get_ntohl(tvb, offset+16);
1138                                 proto_tree_add_uint(vtree, hf_rpc_authdes_nickname, tvb,
1139                                         offset+16, 4, nickname);
1140                         }
1141                         break;
1142                 case RPCSEC_GSS:
1143                         dissect_rpc_authgss_token(tvb, vtree, offset+4, pinfo);
1144                         break;
1145                 default:
1146                         proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
1147                                             offset+4, 4, length);
1148                         if (length)
1149                                 proto_tree_add_text(vtree, tvb, offset+8,
1150                                                     length, "opaque data");
1151                         break;
1152                 }
1153         }
1154         offset += 8 + length;
1155
1156         return offset;
1157 }
1158
1159 static int
1160 dissect_rpc_authgss_initarg(tvbuff_t* tvb, proto_tree* tree, int offset,
1161     packet_info *pinfo)
1162 {
1163         return dissect_rpc_authgss_token(tvb, tree, offset, pinfo);
1164 }
1165
1166 static int
1167 dissect_rpc_authgss_initres(tvbuff_t* tvb, proto_tree* tree, int offset,
1168     packet_info *pinfo)
1169 {
1170         int major, minor, window;
1171
1172         offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_ctx,
1173                         offset);
1174
1175         major = tvb_get_ntohl(tvb,offset+0);
1176         if (tree)
1177                 proto_tree_add_uint(tree, hf_rpc_authgss_major, tvb,
1178                                     offset+0, 4, major);
1179         offset += 4;
1180
1181         minor = tvb_get_ntohl(tvb,offset+0);
1182         if (tree)
1183                 proto_tree_add_uint(tree, hf_rpc_authgss_minor, tvb,
1184                                     offset+0, 4, minor);
1185         offset += 4;
1186
1187         window = tvb_get_ntohl(tvb,offset+0);
1188         if (tree)
1189                 proto_tree_add_uint(tree, hf_rpc_authgss_window, tvb,
1190                                     offset+0, 4, window);
1191         offset += 4;
1192
1193         offset = dissect_rpc_authgss_token(tvb, tree, offset, pinfo);
1194
1195         return offset;
1196 }
1197
1198 static int
1199 dissect_rpc_authgssapi_initarg(tvbuff_t* tvb, proto_tree* tree, int offset,
1200     packet_info *pinfo)
1201 {
1202         guint version;
1203         proto_item *mitem;
1204         proto_tree *mtree = NULL;
1205
1206         if (tree) {
1207             mitem = proto_tree_add_text(tree, tvb, offset, -1,
1208                 "AUTH_GSSAPI Msg");
1209             mtree = proto_item_add_subtree(mitem, ett_rpc_authgssapi_msg);
1210         }
1211         version = tvb_get_ntohl(tvb, offset+0);
1212         if (mtree) {
1213                 proto_tree_add_uint(mtree, hf_rpc_authgssapi_msgv, tvb,
1214                     offset+0, 4, version);
1215         }
1216         offset += 4;
1217
1218         offset = dissect_rpc_authgss_token(tvb, mtree, offset, pinfo);
1219
1220         return offset;
1221 }
1222
1223 static int
1224 dissect_rpc_authgssapi_initres(tvbuff_t* tvb, proto_tree* tree, int offset,
1225     packet_info *pinfo)
1226 {
1227         guint version;
1228         guint major, minor;
1229         proto_item *mitem;
1230         proto_tree *mtree = NULL;
1231
1232         if (tree) {
1233             mitem = proto_tree_add_text(tree, tvb, offset, -1,
1234                 "AUTH_GSSAPI Msg");
1235             mtree = proto_item_add_subtree(mitem, ett_rpc_authgssapi_msg);
1236         }
1237
1238         version = tvb_get_ntohl(tvb,offset+0);
1239         if (mtree) {
1240                 proto_tree_add_uint(mtree, hf_rpc_authgssapi_msgv, tvb,
1241                                     offset+0, 4, version);
1242         }
1243         offset += 4;
1244
1245         offset = dissect_rpc_data(tvb, mtree, hf_rpc_authgssapi_handle,
1246                         offset);
1247
1248         major = tvb_get_ntohl(tvb,offset+0);
1249         if (mtree) {
1250                 proto_tree_add_uint(mtree, hf_rpc_authgss_major, tvb,
1251                                     offset+0, 4, major);
1252         }
1253         offset += 4;
1254
1255         minor = tvb_get_ntohl(tvb,offset+0);
1256         if (mtree) {
1257                 proto_tree_add_uint(mtree, hf_rpc_authgss_minor, tvb,
1258                                     offset+0, 4, minor);
1259         }
1260         offset += 4;
1261
1262         offset = dissect_rpc_authgss_token(tvb, mtree, offset, pinfo);
1263
1264         offset = dissect_rpc_data(tvb, mtree, hf_rpc_authgssapi_isn, offset);
1265
1266         return offset;
1267 }
1268
1269 static int
1270 dissect_auth_gssapi_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1271 {
1272         offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1273                         offset);
1274         return offset;
1275 }
1276
1277 static int
1278 call_dissect_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1279         int offset, dissect_function_t* dissect_function, const char *progname)
1280 {
1281         const char *saved_proto;
1282
1283         if (dissect_function != NULL) {
1284                 /* set the current protocol name */
1285                 saved_proto = pinfo->current_proto;
1286                 if (progname != NULL)
1287                         pinfo->current_proto = progname;
1288
1289                 /* call the dissector for the next level */
1290                 offset = dissect_function(tvb, offset, pinfo, tree);
1291
1292                 /* restore the protocol name */
1293                 pinfo->current_proto = saved_proto;
1294         }
1295
1296         return offset;
1297 }
1298
1299
1300 static int
1301 dissect_rpc_authgss_integ_data(tvbuff_t *tvb, packet_info *pinfo,
1302         proto_tree *tree, int offset,
1303         dissect_function_t* dissect_function,
1304         const char *progname)
1305 {
1306         guint32 length, rounded_length, seq;
1307
1308         proto_item *gitem;
1309         proto_tree *gtree = NULL;
1310
1311         length = tvb_get_ntohl(tvb, offset+0);
1312         rounded_length = rpc_roundup(length);
1313         seq = tvb_get_ntohl(tvb, offset+4);
1314
1315         if (tree) {
1316                 gitem = proto_tree_add_text(tree, tvb, offset,
1317                                             4+rounded_length, "GSS Data");
1318                 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_data);
1319                 proto_tree_add_uint(gtree, hf_rpc_authgss_data_length,
1320                                     tvb, offset+0, 4, length);
1321                 proto_tree_add_uint(gtree, hf_rpc_authgss_seq,
1322                                     tvb, offset+4, 4, seq);
1323         }
1324         offset += 8;
1325
1326         if (dissect_function != NULL) {
1327                 /* offset = */
1328                 call_dissect_function(tvb, pinfo, gtree, offset,
1329                                       dissect_function, progname);
1330         }
1331         offset += rounded_length - 4;
1332         offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_checksum,
1333                         offset);
1334         return offset;
1335 }
1336
1337
1338 static int
1339 dissect_rpc_authgss_priv_data(tvbuff_t *tvb, proto_tree *tree, int offset)
1340 {
1341         offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_data,
1342                         offset);
1343         return offset;
1344 }
1345
1346 /*
1347  * Dissect the arguments to an indirect call; used by the portmapper/RPCBIND
1348  * dissector.
1349  *
1350  * Record this call in a hash table, similar to the hash table for
1351  * direct calls, so we can find it when dissecting an indirect call reply.
1352  */
1353 int
1354 dissect_rpc_indir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1355     int offset, int args_id, guint32 prog, guint32 vers, guint32 proc)
1356 {
1357         conversation_t* conversation;
1358         static address null_address = { AT_NONE, 0, NULL };
1359         rpc_proc_info_key key;
1360         rpc_proc_info_value *value;
1361         rpc_call_info_value *rpc_call;
1362         rpc_call_info_key rpc_call_key;
1363         rpc_call_info_key *new_rpc_call_key;
1364         dissect_function_t *dissect_function = NULL;
1365
1366         key.prog = prog;
1367         key.vers = vers;
1368         key.proc = proc;
1369         if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1370                 dissect_function = value->dissect_call;
1371
1372                 /* Keep track of the address and port whence the call came,
1373                    and the port to which the call is being sent, so that
1374                    we can match up calls with replies.
1375
1376                    If the transport is connection-oriented (we check, for
1377                    now, only for "pinfo->ptype" of PT_TCP), we take
1378                    into account the address from which the call was sent
1379                    and the address to which the call was sent, because
1380                    the addresses of the two endpoints should be the same
1381                    for all calls and replies.
1382
1383                    If the transport is connectionless, we don't worry
1384                    about the address to which the call was sent and from
1385                    which the reply was sent, because there's no
1386                    guarantee that the reply will come from the address
1387                    to which the call was sent. */
1388                 if (pinfo->ptype == PT_TCP) {
1389                         conversation = find_conversation(&pinfo->src,
1390                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1391                             pinfo->destport, 0);
1392                 } else {
1393                         /*
1394                          * XXX - can we just use NO_ADDR_B?  Unfortunately,
1395                          * you currently still have to pass a non-null
1396                          * pointer for the second address argument even
1397                          * if you do that.
1398                          */
1399                         conversation = find_conversation(&pinfo->src,
1400                             &null_address, pinfo->ptype, pinfo->srcport,
1401                             pinfo->destport, 0);
1402                 }
1403                 if (conversation == NULL) {
1404                         /* It's not part of any conversation - create a new
1405                            one.
1406
1407                            XXX - this should never happen, as we should've
1408                            created a conversation for it in the RPC
1409                            dissector. */
1410                         if (pinfo->ptype == PT_TCP) {
1411                                 conversation = conversation_new(&pinfo->src,
1412                                     &pinfo->dst, pinfo->ptype, pinfo->srcport,
1413                                     pinfo->destport, 0);
1414                         } else {
1415                                 conversation = conversation_new(&pinfo->src,
1416                                     &null_address, pinfo->ptype, pinfo->srcport,
1417                                     pinfo->destport, 0);
1418                         }
1419                 }
1420
1421                 /* Make the dissector for this conversation the non-heuristic
1422                    RPC dissector. */
1423                 conversation_set_dissector(conversation,
1424                     (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1425
1426                 /* Prepare the key data.
1427
1428                    Dissectors for RPC procedure calls and replies shouldn't
1429                    create new tvbuffs, and we don't create one ourselves,
1430                    so we should have been handed the tvbuff for this RPC call;
1431                    as such, the XID is at offset 0 in this tvbuff. */
1432                 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1433                 rpc_call_key.conversation = conversation;
1434
1435                 /* look up the request */
1436                 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1437                 if (rpc_call == NULL) {
1438                         /* We didn't find it; create a new entry.
1439                            Prepare the value data.
1440                            Not all of it is needed for handling indirect
1441                            calls, so we set a bunch of items to 0. */
1442                         new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1443                         *new_rpc_call_key = rpc_call_key;
1444                         rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1445                         rpc_call->req_num = 0;
1446                         rpc_call->rep_num = 0;
1447                         rpc_call->prog = prog;
1448                         rpc_call->vers = vers;
1449                         rpc_call->proc = proc;
1450                         rpc_call->private_data = NULL;
1451
1452                         /*
1453                          * XXX - what about RPCSEC_GSS?
1454                          * Do we have to worry about it?
1455                          */
1456                         rpc_call->flavor = FLAVOR_NOT_GSSAPI;
1457                         rpc_call->gss_proc = 0;
1458                         rpc_call->gss_svc = 0;
1459                         rpc_call->proc_info = value;
1460                         /* store it */
1461                         g_hash_table_insert(rpc_indir_calls, new_rpc_call_key,
1462                             rpc_call);
1463                 }
1464         }
1465         else {
1466                 /* We don't know the procedure.
1467                    Happens only with strange program versions or
1468                    non-existing dissectors.
1469                    Just show the arguments as opaque data. */
1470                 offset = dissect_rpc_data(tvb, tree, args_id,
1471                     offset);
1472                 return offset;
1473         }
1474
1475         if ( tree )
1476         {
1477                 proto_tree_add_text(tree, tvb, offset, 4,
1478                         "Argument length: %u",
1479                         tvb_get_ntohl(tvb, offset));
1480         }
1481         offset += 4;
1482
1483         /* Dissect the arguments */
1484         offset = call_dissect_function(tvb, pinfo, tree, offset,
1485                         dissect_function, NULL);
1486         return offset;
1487 }
1488
1489 /*
1490  * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1491  * dissector.
1492  */
1493 int
1494 dissect_rpc_indir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1495     int offset, int result_id, int prog_id, int vers_id, int proc_id)
1496 {
1497         conversation_t* conversation;
1498         static address null_address = { AT_NONE, 0, NULL };
1499         rpc_call_info_key rpc_call_key;
1500         rpc_call_info_value *rpc_call;
1501         char *procname = NULL;
1502         char procname_static[20];
1503         dissect_function_t *dissect_function = NULL;
1504
1505         /* Look for the matching call in the hash table of indirect
1506            calls.  A reply must match a call that we've seen, and the
1507            reply must be sent to the same port and address that the
1508            call came from, and must come from the port to which the
1509            call was sent.
1510
1511            If the transport is connection-oriented (we check, for
1512            now, only for "pinfo->ptype" of PT_TCP), we take
1513            into account the address from which the call was sent
1514            and the address to which the call was sent, because
1515            the addresses of the two endpoints should be the same
1516            for all calls and replies.
1517
1518            If the transport is connectionless, we don't worry
1519            about the address to which the call was sent and from
1520            which the reply was sent, because there's no
1521            guarantee that the reply will come from the address
1522            to which the call was sent. */
1523         if (pinfo->ptype == PT_TCP) {
1524                 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1525                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1526         } else {
1527                 /*
1528                  * XXX - can we just use NO_ADDR_B?  Unfortunately,
1529                  * you currently still have to pass a non-null
1530                  * pointer for the second address argument even
1531                  * if you do that.
1532                  */
1533                 conversation = find_conversation(&null_address, &pinfo->dst,
1534                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1535         }
1536         if (conversation == NULL) {
1537                 /* We haven't seen an RPC call for that conversation,
1538                    so we can't check for a reply to that call.
1539                    Just show the reply stuff as opaque data. */
1540                 offset = dissect_rpc_data(tvb, tree, result_id,
1541                     offset);
1542                 return offset;
1543         }
1544
1545         /* The XIDs of the call and reply must match. */
1546         rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1547         rpc_call_key.conversation = conversation;
1548         rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1549         if (rpc_call == NULL) {
1550                 /* The XID doesn't match a call from that
1551                    conversation, so it's probably not an RPC reply.
1552                    Just show the reply stuff as opaque data. */
1553                 offset = dissect_rpc_data(tvb, tree, result_id,
1554                     offset);
1555                 return offset;
1556         }
1557
1558         if (rpc_call->proc_info != NULL) {
1559                 dissect_function = rpc_call->proc_info->dissect_reply;
1560                 if (rpc_call->proc_info->name != NULL) {
1561                         procname = rpc_call->proc_info->name;
1562                 }
1563                 else {
1564                         sprintf(procname_static, "proc-%u", rpc_call->proc);
1565                         procname = procname_static;
1566                 }
1567         }
1568         else {
1569 #if 0
1570                 dissect_function = NULL;
1571 #endif
1572                 sprintf(procname_static, "proc-%u", rpc_call->proc);
1573                 procname = procname_static;
1574         }
1575
1576         if ( tree )
1577         {
1578                 /* Put the program, version, and procedure into the tree. */
1579                 proto_tree_add_uint_format(tree, prog_id, tvb,
1580                         0, 0, rpc_call->prog, "Program: %s (%u)",
1581                         rpc_prog_name(rpc_call->prog), rpc_call->prog);
1582                 proto_tree_add_uint(tree, vers_id, tvb, 0, 0, rpc_call->vers);
1583                 proto_tree_add_uint_format(tree, proc_id, tvb,
1584                         0, 0, rpc_call->proc, "Procedure: %s (%u)",
1585                         procname, rpc_call->proc);
1586         }
1587
1588         if (dissect_function == NULL) {
1589                 /* We don't know how to dissect the reply procedure.
1590                    Just show the reply stuff as opaque data. */
1591                 offset = dissect_rpc_data(tvb, tree, result_id,
1592                     offset);
1593                 return offset;
1594         }
1595
1596         if (tree) {
1597                 /* Put the length of the reply value into the tree. */
1598                 proto_tree_add_text(tree, tvb, offset, 4,
1599                         "Argument length: %u",
1600                         tvb_get_ntohl(tvb, offset));
1601         }
1602         offset += 4;
1603
1604         /* Dissect the return value */
1605         offset = call_dissect_function(tvb, pinfo, tree, offset,
1606                         dissect_function, NULL);
1607         return offset;
1608 }
1609
1610 /*
1611  * Just mark this as a continuation of an earlier packet.
1612  */
1613 static void
1614 dissect_rpc_continuation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1615 {
1616         proto_item *rpc_item;
1617         proto_tree *rpc_tree;
1618
1619         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1620                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1621         if (check_col(pinfo->cinfo, COL_INFO))
1622                 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1623
1624         if (tree) {
1625                 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1626                                 FALSE);
1627                 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1628                 proto_tree_add_text(rpc_tree, tvb, 0, -1, "Continuation data");
1629         }
1630 }
1631
1632 static gboolean
1633 dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1634     tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
1635     guint32 rpc_rm, gboolean first_pdu)
1636 {
1637         guint32 msg_type;
1638         rpc_call_info_key rpc_call_key;
1639         rpc_call_info_value *rpc_call = NULL;
1640         rpc_prog_info_value *rpc_prog = NULL;
1641         rpc_prog_info_key rpc_prog_key;
1642
1643         unsigned int xid;
1644         unsigned int rpcvers;
1645         unsigned int prog = 0;
1646         unsigned int vers = 0;
1647         unsigned int proc = 0;
1648         flavor_t flavor = FLAVOR_UNKNOWN;
1649         unsigned int gss_proc = 0;
1650         unsigned int gss_svc = 0;
1651         protocol_t *proto = NULL;
1652         int     proto_id = 0;
1653         int     ett = 0;
1654         int     procedure_hf;
1655
1656         unsigned int reply_state;
1657         unsigned int accept_state;
1658         unsigned int reject_state;
1659
1660         char *msg_type_name = NULL;
1661         char *progname = NULL;
1662         char *procname = NULL;
1663         static char procname_static[20];
1664
1665         unsigned int vers_low;
1666         unsigned int vers_high;
1667
1668         unsigned int auth_state;
1669
1670         proto_item *rpc_item = NULL;
1671         proto_tree *rpc_tree = NULL;
1672
1673         proto_item *pitem = NULL;
1674         proto_tree *ptree = NULL;
1675         int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
1676
1677         rpc_call_info_key       *new_rpc_call_key;
1678         rpc_proc_info_key       key;
1679         rpc_proc_info_value     *value = NULL;
1680         conversation_t* conversation;
1681         static address null_address = { AT_NONE, 0, NULL };
1682         nstime_t ns;
1683
1684         dissect_function_t *dissect_function = NULL;
1685         gboolean dissect_rpc = TRUE;
1686
1687
1688         /*
1689          * Check to see whether this looks like an RPC call or reply.
1690          */
1691         if (!tvb_bytes_exist(tvb, offset, 8)) {
1692                 /* Captured data in packet isn't enough to let us tell. */
1693                 return FALSE;
1694         }
1695
1696         /* both directions need at least this */
1697         msg_type = tvb_get_ntohl(tvb, offset + 4);
1698
1699         switch (msg_type) {
1700
1701         case RPC_CALL:
1702                 /* check for RPC call */
1703                 if (!tvb_bytes_exist(tvb, offset, 16)) {
1704                         /* Captured data in packet isn't enough to let us
1705                            tell. */
1706                         return FALSE;
1707                 }
1708
1709                 /* XID can be anything, so dont check it.
1710                    We already have the message type.
1711                    Check whether an RPC version number of 2 is in the
1712                    location where it would be, and that an RPC program
1713                    number we know about is in the location where it would be.
1714
1715                    XXX - Sun's snoop appears to recognize as RPC even calls
1716                    to stuff it doesn't dissect; does it just look for a 2
1717                    at that location, which seems far to weak a heuristic
1718                    (too many false positives), or does it have some additional
1719                    checks it does?
1720
1721                    We could conceivably check for any of the program numbers
1722                    in the list at
1723
1724                         ftp://ftp.tau.ac.il/pub/users/eilon/rpc/rpc
1725
1726                    and report it as RPC (but not dissect the payload if
1727                    we don't have a subdissector) if it matches. */
1728                 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1729
1730                 /* we only dissect version 2 */
1731                 if (tvb_get_ntohl(tvb, offset + 8) != 2 ){
1732                         return FALSE;
1733                 }
1734                 /* let the user be able to weaken the heuristics if he need
1735                  * to look at proprietary protocols not known
1736                  * to ethereal.
1737                  */
1738                 if(rpc_dissect_unknown_programs){
1739                         /* if the user has specified that he wants to try to 
1740                          * dissect even completely unknown RPC program numbers
1741                          * then let him do that.
1742                          * In this case we only check that the program number 
1743                          * is neither 0 nor -1 which is better than nothing.
1744                          */
1745                         if(rpc_prog_key.prog==0 || rpc_prog_key.prog==0xffffffff){
1746                                 return FALSE;
1747                         }
1748                         if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
1749                                 /* ok this is not a known rpc program so we
1750                                  * will have to fake it.
1751                                  */
1752                                 int proto_rpc_unknown_program;
1753                                 char *NAME, *Name, *name;
1754                                 static const vsff unknown_proc[] = {
1755                                         { 0,"NULL",NULL,NULL },
1756                                         { 0,NULL,NULL,NULL }
1757                                 };
1758
1759                                 NAME=g_malloc(36);
1760                                 Name=g_malloc(32);
1761                                 name=g_malloc(32);
1762                                 sprintf(NAME, "Unknown RPC Program:%d",rpc_prog_key.prog);
1763                                 sprintf(Name, "RPC:%d",rpc_prog_key.prog);
1764                                 sprintf(name, "rpc%d",rpc_prog_key.prog);
1765                                 proto_rpc_unknown_program = proto_register_protocol(NAME, Name, name);
1766
1767                                 rpc_init_prog(proto_rpc_unknown_program, rpc_prog_key.prog, ett_rpc_unknown_program);
1768                                 rpc_init_proc_table(rpc_prog_key.prog, tvb_get_ntohl(tvb, offset + 16), unknown_proc, hf_rpc_procedure);
1769
1770                         }
1771                 }
1772                 if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
1773                         /* They're not, so it's probably not an RPC call. */
1774                         return FALSE;
1775                 }
1776                 break;
1777
1778         case RPC_REPLY:
1779                 /* Check for RPC reply.  A reply must match a call that
1780                    we've seen, and the reply must be sent to the same
1781                    port and address that the call came from, and must
1782                    come from the port to which the call was sent.
1783
1784                    If the transport is connection-oriented (we check, for
1785                    now, only for "pinfo->ptype" of PT_TCP), we take
1786                    into account the address from which the call was sent
1787                    and the address to which the call was sent, because
1788                    the addresses of the two endpoints should be the same
1789                    for all calls and replies.
1790
1791                    If the transport is connectionless, we don't worry
1792                    about the address to which the call was sent and from
1793                    which the reply was sent, because there's no
1794                    guarantee that the reply will come from the address
1795                    to which the call was sent. */
1796                 if (pinfo->ptype == PT_TCP) {
1797                         conversation = find_conversation(&pinfo->src,
1798                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1799                             pinfo->destport, 0);
1800                 } else {
1801                         /*
1802                          * XXX - can we just use NO_ADDR_B?  Unfortunately,
1803                          * you currently still have to pass a non-null
1804                          * pointer for the second address argument even
1805                          * if you do that.
1806                          */
1807                         conversation = find_conversation(&null_address,
1808                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1809                             pinfo->destport, 0);
1810                 }
1811                 if (conversation == NULL) {
1812                         /* We haven't seen an RPC call for that conversation,
1813                            so we can't check for a reply to that call. */
1814                         return FALSE;
1815                 }
1816
1817                 /* The XIDs of the call and reply must match. */
1818                 rpc_call_key.xid = tvb_get_ntohl(tvb, offset + 0);
1819                 rpc_call_key.conversation = conversation;
1820                 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1821                 if (rpc_call == NULL) {
1822                         /* The XID doesn't match a call from that
1823                            conversation, so it's probably not an RPC reply. */
1824                         return FALSE;
1825                 }
1826                 /* pass rpc_info to subdissectors */
1827                 rpc_call->request=FALSE;
1828                 pinfo->private_data=rpc_call;
1829                 break;
1830
1831         default:
1832                 /* The putative message type field contains neither
1833                    RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1834                    reply. */
1835                 return FALSE;
1836         }
1837
1838         if (is_tcp) {
1839                 /*
1840                  * This is RPC-over-TCP; check if this is the last
1841                  * fragment.
1842                  */
1843                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
1844                         /*
1845                          * This isn't the last fragment.
1846                          * If we're doing reassembly, just return
1847                          * TRUE to indicate that this looks like
1848                          * the beginning of an RPC message,
1849                          * and let them do fragment reassembly.
1850                          */
1851                         if (rpc_defragment)
1852                                 return TRUE;
1853                 }
1854         }
1855
1856         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1857                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1858
1859         if (tree) {
1860                 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1861                     FALSE);
1862                 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1863
1864                 if (is_tcp) {
1865                         show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
1866                             ipfd_head, pinfo);
1867                 }
1868         }
1869
1870         xid      = tvb_get_ntohl(tvb, offset + 0);
1871         if (rpc_tree) {
1872                 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1873                         offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1874         }
1875
1876         msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1877         if (rpc_tree) {
1878                 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1879                         offset+4, 4, msg_type);
1880                 proto_item_append_text(rpc_item, ", Type:%s XID:0x%08x", msg_type_name, xid);
1881         }
1882
1883         offset += 8;
1884
1885         switch (msg_type) {
1886
1887         case RPC_CALL:
1888                 /* we know already the proto-entry, the ETT-const,
1889                    and "rpc_prog" */
1890                 proto = rpc_prog->proto;
1891                 proto_id = rpc_prog->proto_id;
1892                 ett = rpc_prog->ett;
1893                 progname = rpc_prog->progname;
1894
1895                 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1896                 if (rpc_tree) {
1897                         proto_tree_add_uint(rpc_tree,
1898                                 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1899                 }
1900
1901                 prog = tvb_get_ntohl(tvb, offset + 4);
1902
1903                 if (rpc_tree) {
1904                         proto_tree_add_uint_format(rpc_tree,
1905                                 hf_rpc_program, tvb, offset+4, 4, prog,
1906                                 "Program: %s (%u)", progname, prog);
1907                 }
1908
1909                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1910                         /* Set the protocol name to the underlying
1911                            program name. */
1912                         col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1913                 }
1914
1915                 vers = tvb_get_ntohl(tvb, offset+8);
1916                 if (rpc_tree) {
1917                         proto_tree_add_uint(rpc_tree,
1918                                 hf_rpc_programversion, tvb, offset+8, 4, vers);
1919                 }
1920
1921                 proc = tvb_get_ntohl(tvb, offset+12);
1922
1923                 key.prog = prog;
1924                 key.vers = vers;
1925                 key.proc = proc;
1926
1927                 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1928                         dissect_function = value->dissect_call;
1929                         procname = value->name;
1930                 }
1931                 else {
1932                         /* happens only with strange program versions or
1933                            non-existing dissectors */
1934 #if 0
1935                         dissect_function = NULL;
1936 #endif
1937                         sprintf(procname_static, "proc-%u", proc);
1938                         procname = procname_static;
1939                 }
1940
1941                 /* Check for RPCSEC_GSS and AUTH_GSSAPI */
1942                 if (tvb_bytes_exist(tvb, offset+16, 4)) {
1943                         switch (tvb_get_ntohl(tvb, offset+16)) {
1944
1945                         case RPCSEC_GSS:
1946                                 /*
1947                                  * It's GSS-API authentication...
1948                                  */
1949                                 if (tvb_bytes_exist(tvb, offset+28, 8)) {
1950                                         /*
1951                                          * ...and we have the procedure
1952                                          * and service information for it.
1953                                          */
1954                                         flavor = FLAVOR_GSSAPI;
1955                                         gss_proc = tvb_get_ntohl(tvb, offset+28);
1956                                         gss_svc = tvb_get_ntohl(tvb, offset+36);
1957                                 } else {
1958                                         /*
1959                                          * ...but the procedure and service
1960                                          * information isn't available.
1961                                          */
1962                                         flavor = FLAVOR_GSSAPI_NO_INFO;
1963                                 }
1964                                 break;
1965
1966                         case AUTH_GSSAPI:
1967                                 /*
1968                                  * AUTH_GSSAPI flavor.  If auth_msg is TRUE,
1969                                  * then this is an AUTH_GSSAPI message and
1970                                  * not an application level message.
1971                                  */
1972                                 if (tvb_bytes_exist(tvb, offset+28, 4)) {
1973                                         if (tvb_get_ntohl(tvb, offset+28)) {
1974                                                 flavor = FLAVOR_AUTHGSSAPI_MSG;
1975                                                 gss_proc = proc;
1976                                                 procname =
1977                                                     match_strval(gss_proc,
1978                                                     rpc_authgssapi_proc);
1979                                         } else {
1980                                                 flavor = FLAVOR_AUTHGSSAPI;
1981                                         }
1982                                 }
1983                                 break;
1984
1985                         default:
1986                                 /*
1987                                  * It's not GSS-API authentication.
1988                                  */
1989                                 flavor = FLAVOR_NOT_GSSAPI;
1990                                 break;
1991                         }
1992                 }
1993
1994                 if (rpc_tree) {
1995                         proto_tree_add_uint_format(rpc_tree,
1996                                 hf_rpc_procedure, tvb, offset+12, 4, proc,
1997                                 "Procedure: %s (%u)", procname, proc);
1998                 }
1999
2000                 if (check_col(pinfo->cinfo, COL_INFO)) {
2001                         if (first_pdu)
2002                                 col_clear(pinfo->cinfo, COL_INFO);
2003                         else
2004                                 col_append_fstr(pinfo->cinfo, COL_INFO, "  ; ");
2005                         col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2006                                 vers,
2007                                 procname,
2008                                 msg_type_name);
2009                 }
2010
2011                 /* Keep track of the address and port whence the call came,
2012                    and the port to which the call is being sent, so that
2013                    we can match up calls with replies.
2014
2015                    If the transport is connection-oriented (we check, for
2016                    now, only for "pinfo->ptype" of PT_TCP), we take
2017                    into account the address from which the call was sent
2018                    and the address to which the call was sent, because
2019                    the addresses of the two endpoints should be the same
2020                    for all calls and replies.
2021
2022                    If the transport is connectionless, we don't worry
2023                    about the address to which the call was sent and from
2024                    which the reply was sent, because there's no
2025                    guarantee that the reply will come from the address
2026                    to which the call was sent. */
2027                 if (pinfo->ptype == PT_TCP) {
2028                         conversation = find_conversation(&pinfo->src,
2029                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
2030                             pinfo->destport, 0);
2031                 } else {
2032                         /*
2033                          * XXX - can we just use NO_ADDR_B?  Unfortunately,
2034                          * you currently still have to pass a non-null
2035                          * pointer for the second address argument even
2036                          * if you do that.
2037                          */
2038                         conversation = find_conversation(&pinfo->src,
2039                             &null_address, pinfo->ptype, pinfo->srcport,
2040                             pinfo->destport, 0);
2041                 }
2042                 if (conversation == NULL) {
2043                         /* It's not part of any conversation - create a new
2044                            one. */
2045                         if (pinfo->ptype == PT_TCP) {
2046                                 conversation = conversation_new(&pinfo->src,
2047                                     &pinfo->dst, pinfo->ptype, pinfo->srcport,
2048                                     pinfo->destport, 0);
2049                         } else {
2050                                 conversation = conversation_new(&pinfo->src,
2051                                     &null_address, pinfo->ptype, pinfo->srcport,
2052                                     pinfo->destport, 0);
2053                         }
2054                 }
2055
2056                 /* Make the dissector for this conversation the non-heuristic
2057                    RPC dissector. */
2058                 conversation_set_dissector(conversation,
2059                         (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
2060
2061                 /* prepare the key data */
2062                 rpc_call_key.xid = xid;
2063                 rpc_call_key.conversation = conversation;
2064
2065                 /* look up the request */
2066                 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
2067                 if (rpc_call) {
2068                         /* We've seen a request with this XID, with the same
2069                            source and destination, before - but was it
2070                            *this* request? */
2071                         if (pinfo->fd->num != rpc_call->req_num) {
2072                                 /* No, so it's a duplicate request.
2073                                    Mark it as such. */
2074                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2075                                         col_prepend_fstr(pinfo->cinfo, COL_INFO,
2076                                                 "[RPC retransmission of #%d]", rpc_call->req_num);
2077                                 }
2078                                 proto_tree_add_item(rpc_tree,
2079                                         hf_rpc_dup, tvb, 0,0, TRUE);
2080                                 proto_tree_add_uint(rpc_tree,
2081                                         hf_rpc_call_dup, tvb, 0,0, rpc_call->req_num);
2082                         }
2083                         if(rpc_call->rep_num){
2084                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2085                                         col_append_fstr(pinfo->cinfo, COL_INFO," (Reply In %d)", rpc_call->rep_num);
2086                                 }
2087                         }
2088                 } else {
2089                         /* Prepare the value data.
2090                            "req_num" and "rep_num" are frame numbers;
2091                            frame numbers are 1-origin, so we use 0
2092                            to mean "we don't yet know in which frame
2093                            the reply for this call appears". */
2094                         new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
2095                         *new_rpc_call_key = rpc_call_key;
2096                         rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
2097                         rpc_call->req_num = pinfo->fd->num;
2098                         rpc_call->rep_num = 0;
2099                         rpc_call->prog = prog;
2100                         rpc_call->vers = vers;
2101                         rpc_call->proc = proc;
2102                         rpc_call->private_data = NULL;
2103                         rpc_call->xid = xid;
2104                         rpc_call->flavor = flavor;
2105                         rpc_call->gss_proc = gss_proc;
2106                         rpc_call->gss_svc = gss_svc;
2107                         rpc_call->proc_info = value;
2108                         rpc_call->req_time.secs=pinfo->fd->abs_secs;
2109                         rpc_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
2110
2111                         /* store it */
2112                         g_hash_table_insert(rpc_calls, new_rpc_call_key,
2113                             rpc_call);
2114                 }
2115
2116                 if(rpc_call && rpc_call->rep_num){
2117                         proto_tree_add_uint_format(rpc_tree, hf_rpc_repframe,
2118                             tvb, 0, 0, rpc_call->rep_num,
2119                             "The reply to this request is in frame %u",
2120                             rpc_call->rep_num);
2121                 }
2122
2123                 offset += 16;
2124
2125                 offset = dissect_rpc_cred(tvb, rpc_tree, offset);
2126                 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2127
2128                 /* pass rpc_info to subdissectors */
2129                 rpc_call->request=TRUE;
2130                 pinfo->private_data=rpc_call;
2131
2132                 /* go to the next dissector */
2133
2134                 break;  /* end of RPC call */
2135
2136         case RPC_REPLY:
2137                 /* we know already the type from the calling routine,
2138                    and we already have "rpc_call" set above. */
2139                 prog = rpc_call->prog;
2140                 vers = rpc_call->vers;
2141                 proc = rpc_call->proc;
2142                 flavor = rpc_call->flavor;
2143                 gss_proc = rpc_call->gss_proc;
2144                 gss_svc = rpc_call->gss_svc;
2145
2146                 if (rpc_call->proc_info != NULL) {
2147                         dissect_function = rpc_call->proc_info->dissect_reply;
2148                         if (rpc_call->proc_info->name != NULL) {
2149                                 procname = rpc_call->proc_info->name;
2150                         }
2151                         else {
2152                                 sprintf(procname_static, "proc-%u", proc);
2153                                 procname = procname_static;
2154                         }
2155                 }
2156                 else {
2157 #if 0
2158                         dissect_function = NULL;
2159 #endif
2160                         sprintf(procname_static, "proc-%u", proc);
2161                         procname = procname_static;
2162                 }
2163
2164                 /*
2165                  * If this is an AUTH_GSSAPI message, then the RPC procedure
2166                  * is not an application procedure, but rather an auth level
2167                  * procedure, so it would be misleading to print the RPC
2168                  * procname.  Replace the RPC procname with the corresponding
2169                  * AUTH_GSSAPI procname.
2170                  */
2171                 if (flavor == FLAVOR_AUTHGSSAPI_MSG) {
2172                         procname = match_strval(gss_proc, rpc_authgssapi_proc);
2173                 }
2174
2175                 rpc_prog_key.prog = prog;
2176                 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
2177                         proto = NULL;
2178                         proto_id = 0;
2179                         ett = 0;
2180                         progname = "Unknown";
2181                 }
2182                 else {
2183                         proto = rpc_prog->proto;
2184                         proto_id = rpc_prog->proto_id;
2185                         ett = rpc_prog->ett;
2186                         progname = rpc_prog->progname;
2187
2188                         if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2189                                 /* Set the protocol name to the underlying
2190                                    program name. */
2191                                 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
2192                         }
2193                 }
2194
2195                 if (check_col(pinfo->cinfo, COL_INFO)) {
2196                         if (first_pdu)
2197                                 col_clear(pinfo->cinfo, COL_INFO);
2198                         else
2199                                 col_append_fstr(pinfo->cinfo, COL_INFO, "  ; ");
2200                         col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2201                                 vers,
2202                                 procname,
2203                                 msg_type_name);
2204                 }
2205
2206                 if (rpc_tree) {
2207                         proto_tree_add_uint_format(rpc_tree,
2208                                 hf_rpc_program, tvb, 0, 0, prog,
2209                                 "Program: %s (%u)", progname, prog);
2210                         proto_tree_add_uint(rpc_tree,
2211                                 hf_rpc_programversion, tvb, 0, 0, vers);
2212                         proto_tree_add_uint_format(rpc_tree,
2213                                 hf_rpc_procedure, tvb, 0, 0, proc,
2214                                 "Procedure: %s (%u)", procname, proc);
2215                 }
2216
2217                 reply_state = tvb_get_ntohl(tvb,offset+0);
2218                 if (rpc_tree) {
2219                         proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
2220                                 offset+0, 4, reply_state);
2221                 }
2222                 offset += 4;
2223
2224                 /* Indicate the frame to which this is a reply. */
2225                 if(rpc_call && rpc_call->req_num){
2226                         proto_tree_add_uint_format(rpc_tree, hf_rpc_reqframe,
2227                             tvb, 0, 0, rpc_call->req_num,
2228                             "This is a reply to a request in frame %u",
2229                             rpc_call->req_num);
2230                         ns.secs= pinfo->fd->abs_secs-rpc_call->req_time.secs;
2231                         ns.nsecs=pinfo->fd->abs_usecs*1000-rpc_call->req_time.nsecs;
2232                         if(ns.nsecs<0){
2233                                 ns.nsecs+=1000000000;
2234                                 ns.secs--;
2235                         }
2236                         proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
2237                                 &ns);
2238
2239                         if (check_col(pinfo->cinfo, COL_INFO)) {
2240                                 col_append_fstr(pinfo->cinfo, COL_INFO," (Call In %d)", rpc_call->req_num);
2241                         }
2242                 }
2243
2244
2245                 if ((!rpc_call) || (rpc_call->rep_num == 0)) {
2246                         /* We have not yet seen a reply to that call, so
2247                            this must be the first reply; remember its
2248                            frame number. */
2249                         rpc_call->rep_num = pinfo->fd->num;
2250                 } else {
2251                         /* We have seen a reply to this call - but was it
2252                            *this* reply? */
2253                         if (rpc_call->rep_num != pinfo->fd->num) {
2254                                 /* No, so it's a duplicate reply.
2255                                    Mark it as such. */
2256                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2257                                         col_prepend_fstr(pinfo->cinfo, COL_INFO,
2258                                                 "[RPC retransmission of #%d]", rpc_call->rep_num);
2259                                 }
2260                                 proto_tree_add_item(rpc_tree,
2261                                         hf_rpc_dup, tvb, 0,0, TRUE);
2262                                 proto_tree_add_uint(rpc_tree,
2263                                         hf_rpc_reply_dup, tvb, 0,0, rpc_call->rep_num);
2264                         }
2265                 }
2266
2267                 switch (reply_state) {
2268
2269                 case MSG_ACCEPTED:
2270                         offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2271                         accept_state = tvb_get_ntohl(tvb,offset+0);
2272                         if (rpc_tree) {
2273                                 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
2274                                         offset+0, 4, accept_state);
2275                         }
2276                         offset += 4;
2277                         switch (accept_state) {
2278
2279                         case SUCCESS:
2280                                 /* go to the next dissector */
2281                                 break;
2282
2283                         case PROG_MISMATCH:
2284                                 vers_low = tvb_get_ntohl(tvb,offset+0);
2285                                 vers_high = tvb_get_ntohl(tvb,offset+4);
2286                                 if (rpc_tree) {
2287                                         proto_tree_add_uint(rpc_tree,
2288                                                 hf_rpc_programversion_min,
2289                                                 tvb, offset+0, 4, vers_low);
2290                                         proto_tree_add_uint(rpc_tree,
2291                                                 hf_rpc_programversion_max,
2292                                                 tvb, offset+4, 4, vers_high);
2293                                 }
2294                                 offset += 8;
2295
2296                                 /*
2297                                  * There's no protocol reply, so don't
2298                                  * try to dissect it.
2299                                  */
2300                                 dissect_rpc = FALSE;
2301                                 break;
2302
2303                         default:
2304                                 /*
2305                                  * There's no protocol reply, so don't
2306                                  * try to dissect it.
2307                                  */
2308                                 dissect_rpc = FALSE;
2309                                 break;
2310                         }
2311                         break;
2312
2313                 case MSG_DENIED:
2314                         reject_state = tvb_get_ntohl(tvb,offset+0);
2315                         if (rpc_tree) {
2316                                 proto_tree_add_uint(rpc_tree,
2317                                         hf_rpc_state_reject, tvb, offset+0, 4,
2318                                         reject_state);
2319                         }
2320                         offset += 4;
2321
2322                         if (reject_state==RPC_MISMATCH) {
2323                                 vers_low = tvb_get_ntohl(tvb,offset+0);
2324                                 vers_high = tvb_get_ntohl(tvb,offset+4);
2325                                 if (rpc_tree) {
2326                                         proto_tree_add_uint(rpc_tree,
2327                                                 hf_rpc_version_min,
2328                                                 tvb, offset+0, 4, vers_low);
2329                                         proto_tree_add_uint(rpc_tree,
2330                                                 hf_rpc_version_max,
2331                                                 tvb, offset+4, 4, vers_high);
2332                                 }
2333                                 offset += 8;
2334                         } else if (reject_state==AUTH_ERROR) {
2335                                 auth_state = tvb_get_ntohl(tvb,offset+0);
2336                                 if (rpc_tree) {
2337                                         proto_tree_add_uint(rpc_tree,
2338                                                 hf_rpc_state_auth, tvb, offset+0, 4,
2339                                                 auth_state);
2340                                 }
2341                                 offset += 4;
2342                         }
2343
2344                         /*
2345                          * There's no protocol reply, so don't
2346                          * try to dissect it.
2347                          */
2348                         dissect_rpc = FALSE;
2349                         break;
2350
2351                 default:
2352                         /*
2353                          * This isn't a valid reply state, so we have
2354                          * no clue what's going on; don't try to dissect
2355                          * the protocol reply.
2356                          */
2357                         dissect_rpc = FALSE;
2358                         break;
2359                 }
2360                 break; /* end of RPC reply */
2361
2362         default:
2363                 /*
2364                  * The switch statement at the top returned if
2365                  * this was neither an RPC call nor a reply.
2366                  */
2367                 g_assert_not_reached();
2368         }
2369
2370         /* now we know, that RPC was shorter */
2371         if (rpc_item) {
2372                 proto_item_set_end(rpc_item, tvb, offset);
2373         }
2374
2375         if (!dissect_rpc) {
2376                 /*
2377                  * There's no RPC call or reply here; just dissect
2378                  * whatever's left as data.
2379                  */
2380                 call_dissector(data_handle,
2381                     tvb_new_subset(tvb, offset, -1, -1), pinfo, rpc_tree);
2382                 return TRUE;
2383         }
2384
2385         /* create here the program specific sub-tree */
2386         if (tree && (flavor != FLAVOR_AUTHGSSAPI_MSG)) {
2387                 pitem = proto_tree_add_item(tree, proto_id, tvb, offset, -1,
2388                     FALSE);
2389                 if (pitem) {
2390                         ptree = proto_item_add_subtree(pitem, ett);
2391                 }
2392
2393                 if (ptree) {
2394                         proto_tree_add_uint(ptree,
2395                                 hf_rpc_programversion, tvb, 0, 0, vers);
2396                         if (rpc_prog->procedure_hfs->len > vers)
2397                                 procedure_hf = g_array_index(rpc_prog->procedure_hfs, int, vers);
2398                         else {
2399                                 /*
2400                                  * No such element in the GArray.
2401                                  */
2402                                 procedure_hf = 0;
2403                         }
2404                         if (procedure_hf != 0 && procedure_hf != -1) {
2405                                 proto_tree_add_uint(ptree,
2406                                         procedure_hf, tvb, 0, 0, proc);
2407                         } else {
2408                                 proto_tree_add_uint_format(ptree,
2409                                         hf_rpc_procedure, tvb, 0, 0, proc,
2410                                         "Procedure: %s (%u)", procname, proc);
2411                         }
2412                 }
2413         }
2414
2415         /* we must queue this packet to the tap system before we actually
2416            call the subdissectors since short packets (i.e. nfs read reply)
2417            will cause an exception and execution would never reach the call
2418            to tap_queue_packet() in that case
2419         */
2420         tap_queue_packet(rpc_tap, pinfo, rpc_call);
2421
2422         /* proto==0 if this is an unknown program */
2423         if( (proto==0) || !proto_is_protocol_enabled(proto)){
2424                 dissect_function = NULL;
2425         }
2426
2427         /*
2428          * Handle RPCSEC_GSS and AUTH_GSSAPI specially.
2429          */
2430         switch (flavor) {
2431
2432         case FLAVOR_UNKNOWN:
2433                 /*
2434                  * We don't know the authentication flavor, so we can't
2435                  * dissect the payload.
2436                  */
2437                 proto_tree_add_text(ptree, tvb, offset, -1,
2438                     "Unknown authentication flavor - cannot dissect");
2439                 return TRUE;
2440
2441         case FLAVOR_NOT_GSSAPI:
2442                 /*
2443                  * It's not GSS-API authentication.  Just dissect the
2444                  * payload.
2445                  */
2446                 offset = call_dissect_function(tvb, pinfo, ptree, offset,
2447                                 dissect_function, progname);
2448                 break;
2449
2450         case FLAVOR_GSSAPI_NO_INFO:
2451                 /*
2452                  * It's GSS-API authentication, but we don't have the
2453                  * procedure and service information, so we can't dissect
2454                  * the payload.
2455                  */
2456                 proto_tree_add_text(ptree, tvb, offset, -1,
2457                     "GSS-API authentication, but procedure and service unknown - cannot dissect");
2458                 return TRUE;
2459
2460         case FLAVOR_GSSAPI:
2461                 /*
2462                  * It's GSS-API authentication, and we have the procedure
2463                  * and service information; process the GSS-API stuff,
2464                  * and process the payload if there is any.
2465                  */
2466                 switch (gss_proc) {
2467
2468                 case RPCSEC_GSS_INIT:
2469                 case RPCSEC_GSS_CONTINUE_INIT:
2470                         if (msg_type == RPC_CALL) {
2471                                 offset = dissect_rpc_authgss_initarg(tvb,
2472                                         ptree, offset, pinfo);
2473                         }
2474                         else {
2475                                 offset = dissect_rpc_authgss_initres(tvb,
2476                                         ptree, offset, pinfo);
2477                         }
2478                         break;
2479
2480                 case RPCSEC_GSS_DATA:
2481                         if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2482                                 offset = call_dissect_function(tvb,
2483                                                 pinfo, ptree, offset,
2484                                                 dissect_function,
2485                                                 progname);
2486                         }
2487                         else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2488                                 offset = dissect_rpc_authgss_integ_data(tvb,
2489                                                 pinfo, ptree, offset,
2490                                                 dissect_function,
2491                                                 progname);
2492                         }
2493                         else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2494                                 offset = dissect_rpc_authgss_priv_data(tvb,
2495                                                 ptree, offset);
2496                         }
2497                         break;
2498
2499                 default:
2500                         break;
2501                 }
2502                 break;
2503
2504         case FLAVOR_AUTHGSSAPI_MSG:
2505                 /*
2506                  * This is an AUTH_GSSAPI message.  It contains data
2507                  * only for the authentication procedure and not for the
2508                  * application level RPC procedure.  Reset the column
2509                  * protocol and info fields to indicate that this is
2510                  * an RPC auth level message, then process the args.
2511                  */
2512                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2513                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
2514                 }
2515                 if (check_col(pinfo->cinfo, COL_INFO)) {
2516                         col_clear(pinfo->cinfo, COL_INFO);
2517                         col_append_fstr(pinfo->cinfo, COL_INFO,
2518                             "%s %s XID 0x%x",
2519                             match_strval(gss_proc, rpc_authgssapi_proc),
2520                             msg_type_name, xid);
2521                 }
2522
2523                 switch (gss_proc) {
2524
2525                 case AUTH_GSSAPI_INIT:
2526                 case AUTH_GSSAPI_CONTINUE_INIT:
2527                 case AUTH_GSSAPI_MSG:
2528                         if (msg_type == RPC_CALL) {
2529                             offset = dissect_rpc_authgssapi_initarg(tvb, 
2530                                 rpc_tree, offset, pinfo);
2531                         } else {
2532                             offset = dissect_rpc_authgssapi_initres(tvb, 
2533                                 rpc_tree, offset, pinfo);
2534                         }
2535                         break;
2536
2537                 case AUTH_GSSAPI_DESTROY:
2538                         offset = dissect_rpc_data(tvb, rpc_tree,
2539                             hf_rpc_authgss_data, offset);
2540                         break;
2541
2542                 case AUTH_GSSAPI_EXIT:
2543                         break;
2544                 }
2545
2546                 /* Adjust the length to account for the auth message. */
2547                 if (rpc_item) {
2548                         proto_item_set_end(rpc_item, tvb, offset);
2549                 }
2550                 break;
2551
2552         case FLAVOR_AUTHGSSAPI:
2553                 /*
2554                  * An RPC with AUTH_GSSAPI authentication.  The data
2555                  * portion is always private, so don't call the dissector.
2556                  */
2557                 offset = dissect_auth_gssapi_data(tvb, ptree, offset);
2558                 break;
2559         }
2560
2561         if (tvb_length_remaining(tvb, offset) > 0) {  
2562           /* 
2563            * dissect any remaining bytes (incomplete dissection) as pure 
2564            * data in the ptree 
2565            */
2566
2567           call_dissector(data_handle,
2568               tvb_new_subset(tvb, offset, -1, -1), pinfo, ptree);
2569         }
2570
2571         /* XXX this should really loop over all fhandles registred for the frame */
2572         if(nfs_fhandle_reqrep_matching){
2573                 nfs_fhandle_data_t *fhd;
2574                 switch (msg_type) {
2575                 case RPC_CALL:
2576                         if(rpc_call && rpc_call->rep_num){
2577                                 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2578                                         nfs_fhandle_frame_table,
2579                                         (gconstpointer)rpc_call->rep_num);
2580                                 if(fhd){
2581                                         dissect_fhandle_hidden(pinfo,
2582                                                 ptree, fhd);
2583                                 }
2584                         }
2585                         break;
2586                 case RPC_REPLY:
2587                         if(rpc_call && rpc_call->req_num){
2588                                 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2589                                         nfs_fhandle_frame_table,
2590                                         (gconstpointer)rpc_call->req_num);
2591                                 if(fhd){
2592                                         dissect_fhandle_hidden(pinfo,
2593                                                 ptree, fhd);
2594                                 }
2595                         }
2596                         break;
2597                 }
2598         }
2599
2600         return TRUE;
2601 }
2602
2603 static gboolean
2604 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2605 {
2606         return dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2607             TRUE);
2608 }
2609
2610 static void
2611 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2612 {
2613         if (!dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2614             TRUE)) {
2615                 if (tvb_length(tvb) != 0)
2616                         dissect_rpc_continuation(tvb, pinfo, tree);
2617         }
2618 }
2619
2620
2621 /* Defragmentation of RPC-over-TCP records */
2622 /* table to hold defragmented RPC records */
2623 static GHashTable *rpc_fragment_table = NULL;
2624
2625 static GHashTable *rpc_reassembly_table = NULL;
2626 static GMemChunk *rpc_fragment_key_chunk = NULL;
2627 static int rpc_fragment_init_count = 200;
2628
2629 typedef struct _rpc_fragment_key {
2630         guint32 conv_id;
2631         guint32 seq;
2632         guint32 offset;
2633         /* xxx */
2634         guint32 start_seq;
2635 } rpc_fragment_key;
2636
2637 static guint
2638 rpc_fragment_hash(gconstpointer k)
2639 {
2640         const rpc_fragment_key *key = (const rpc_fragment_key *)k;
2641
2642         return key->conv_id + key->seq;
2643 }
2644
2645 static gint
2646 rpc_fragment_equal(gconstpointer k1, gconstpointer k2)
2647 {
2648         const rpc_fragment_key *key1 = (const rpc_fragment_key *)k1;
2649         const rpc_fragment_key *key2 = (const rpc_fragment_key *)k2;
2650
2651         return key1->conv_id == key2->conv_id &&
2652             key1->seq == key2->seq;
2653 }
2654
2655 static void
2656 show_rpc_fragheader(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2657 {
2658         proto_item *hdr_item;
2659         proto_tree *hdr_tree;
2660         guint32 fraglen;
2661
2662         if (tree) {
2663                 fraglen = rpc_rm & RPC_RM_FRAGLEN;
2664
2665                 hdr_item = proto_tree_add_text(tree, tvb, 0, 4,
2666                     "Fragment header: %s%u %s",
2667                     (rpc_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
2668                     fraglen, plurality(fraglen, "byte", "bytes"));
2669                 hdr_tree = proto_item_add_subtree(hdr_item, ett_rpc_fraghdr);
2670
2671                 proto_tree_add_boolean(hdr_tree, hf_rpc_lastfrag, tvb, 0, 4,
2672                     rpc_rm);
2673                 proto_tree_add_uint(hdr_tree, hf_rpc_fraglen, tvb, 0, 4,
2674                     rpc_rm);
2675         }
2676 }
2677
2678 static void
2679 show_rpc_fragment(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2680 {
2681         if (tree) {
2682                 /*
2683                  * Show the fragment header and the data for the fragment.
2684                  */
2685                 show_rpc_fragheader(tvb, tree, rpc_rm);
2686                 proto_tree_add_text(tree, tvb, 4, -1, "Fragment Data");
2687         }
2688 }
2689
2690 static void
2691 make_frag_tree(tvbuff_t *tvb, proto_tree *tree, int proto, gint ett,
2692     guint32 rpc_rm)
2693 {
2694         proto_item *frag_item;
2695         proto_tree *frag_tree;
2696
2697         if (tree == NULL)
2698                 return;         /* nothing to do */
2699
2700         frag_item = proto_tree_add_protocol_format(tree, proto, tvb, 0, -1,
2701             "%s Fragment", proto_get_protocol_name(proto));
2702         frag_tree = proto_item_add_subtree(frag_item, ett);
2703         show_rpc_fragment(tvb, frag_tree, rpc_rm);
2704 }
2705
2706 void
2707 show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
2708     guint32 rpc_rm, fragment_data *ipfd_head, packet_info *pinfo)
2709 {
2710         if (tree == NULL)
2711                 return;         /* don't do any work */
2712
2713         if (tvb != frag_tvb) {
2714                 /*
2715                  * This message was not all in one fragment,
2716                  * so show the fragment header *and* the data
2717                  * for the fragment (which is the last fragment),
2718                  * and a tree with information about all fragments.
2719                  */
2720                 show_rpc_fragment(frag_tvb, tree, rpc_rm);
2721
2722                 /*
2723                  * Show a tree with information about all fragments.
2724                  */
2725                 show_fragment_tree(ipfd_head, &rpc_frag_items, tree, pinfo, tvb);
2726         } else {
2727                 /*
2728                  * This message was all in one fragment, so just show
2729                  * the fragment header.
2730                  */
2731                 show_rpc_fragheader(tvb, tree, rpc_rm);
2732         }
2733 }
2734
2735 static gboolean
2736 call_message_dissector(tvbuff_t *tvb, tvbuff_t *rec_tvb, packet_info *pinfo,
2737     proto_tree *tree, tvbuff_t *frag_tvb, rec_dissector_t dissector,
2738     fragment_data *ipfd_head, guint32 rpc_rm, gboolean first_pdu)
2739 {
2740         const char *saved_proto;
2741         volatile gboolean rpc_succeeded;
2742
2743         /*
2744          * Catch the ReportedBoundsError exception; if
2745          * this particular message happens to get a
2746          * ReportedBoundsError exception, that doesn't
2747          * mean that we should stop dissecting RPC
2748          * messages within this frame or chunk of
2749          * reassembled data.
2750          *
2751          * If it gets a BoundsError, we can stop, as there's
2752          * nothing more to see, so we just re-throw it.
2753          */
2754         saved_proto = pinfo->current_proto;
2755         rpc_succeeded = FALSE;
2756         TRY {
2757                 rpc_succeeded = (*dissector)(rec_tvb, pinfo, tree,
2758                     frag_tvb, ipfd_head, TRUE, rpc_rm, first_pdu);
2759         }
2760         CATCH(BoundsError) {
2761                 RETHROW;
2762         }
2763         CATCH(ReportedBoundsError) {
2764                 show_reported_bounds_error(tvb, pinfo, tree);
2765                 pinfo->current_proto = saved_proto;
2766
2767                 /*
2768                  * We treat this as a "successful" dissection of
2769                  * an RPC packet, as "dissect_rpc_message()"
2770                  * *did* decide it was an RPC packet, throwing
2771                  * an exception while dissecting it as such.
2772                  */
2773                 rpc_succeeded = TRUE;
2774         }
2775         ENDTRY;
2776         return rpc_succeeded;
2777 }
2778
2779 int
2780 dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
2781     proto_tree *tree, rec_dissector_t dissector, gboolean is_heur,
2782     int proto, int ett, gboolean defragment, gboolean first_pdu)
2783 {
2784         struct tcpinfo *tcpinfo = pinfo->private_data;
2785         guint32 seq = tcpinfo->seq + offset;
2786         guint32 rpc_rm;
2787         volatile gint32 len;
2788         gint32 seglen;
2789         gint tvb_len, tvb_reported_len;
2790         tvbuff_t *frag_tvb;
2791         gboolean rpc_succeeded;
2792         gboolean save_fragmented;
2793         rpc_fragment_key old_rfk, *rfk, *new_rfk;
2794         conversation_t *conversation;
2795         fragment_data *ipfd_head;
2796         tvbuff_t *rec_tvb;
2797
2798         /*
2799          * Get the record mark.
2800          */
2801         if (!tvb_bytes_exist(tvb, offset, 4)) {
2802                 /*
2803                  * XXX - we should somehow arrange to handle
2804                  * a record mark split across TCP segments.
2805                  */
2806                 return 0;       /* not enough to tell if it's valid */
2807         }
2808         rpc_rm = tvb_get_ntohl(tvb, offset);
2809
2810         len = rpc_rm & RPC_RM_FRAGLEN;
2811
2812         /*
2813          * Do TCP desegmentation, if enabled.
2814          *
2815          * reject fragments bigger than this preference setting.
2816          * This is arbitrary, but should at least prevent
2817          * some crashes from either packets with really
2818          * large RPC-over-TCP fragments or from stuff that's
2819          * not really valid for this protocol.
2820          */
2821         if (len > max_rpc_tcp_pdu_size)
2822                 return 0;       /* pretend it's not valid */
2823         if (rpc_desegment) {
2824                 seglen = tvb_length_remaining(tvb, offset + 4);
2825
2826                 if (len > seglen && pinfo->can_desegment) {
2827                         /*
2828                          * This frame doesn't have all of the
2829                          * data for this message, but we can do
2830                          * reassembly on it.
2831                          *
2832                          * If this is a heuristic dissector, just
2833                          * return 0 - we don't want to try to get
2834                          * more data, as that's too likely to cause
2835                          * us to misidentify this as valid.
2836                          *
2837                          * XXX - this means that we won't
2838                          * recognize the first fragment of a
2839                          * multi-fragment RPC operation unless
2840                          * we've already identified this
2841                          * conversation as being an RPC
2842                          * conversation (and thus aren't running
2843                          * heuristically) - that would be a problem
2844                          * if, for example, the first segment were
2845                          * the beginning of a large NFS WRITE.
2846                          *
2847                          * If this isn't a heuristic dissector,
2848                          * we've already identified this conversation
2849                          * as containing data for this protocol, as we
2850                          * saw valid data in previous frames.  Try to
2851                          * get more data.
2852                          */
2853                         if (is_heur)
2854                                 return 0;       /* not valid */
2855                         else {
2856                                 pinfo->desegment_offset = offset;
2857                                 pinfo->desegment_len = len - seglen;
2858                                 return -((gint32) pinfo->desegment_len);
2859                         }
2860                 }
2861         }
2862         len += 4;       /* include record mark */
2863         tvb_len = tvb_length_remaining(tvb, offset);
2864         tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2865         if (tvb_len > len)
2866                 tvb_len = len;
2867         if (tvb_reported_len > len)
2868                 tvb_reported_len = len;
2869         frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2870             tvb_reported_len);
2871
2872         /*
2873          * If we're not defragmenting, just hand this to the
2874          * disssector.
2875          */
2876         if (!defragment) {
2877                 /*
2878                  * This is the first fragment we've seen, and it's also
2879                  * the last fragment; that means the record wasn't
2880                  * fragmented.  Hand the dissector the tvbuff for the
2881                  * fragment as the tvbuff for the record.
2882                  */
2883                 rec_tvb = frag_tvb;
2884                 ipfd_head = NULL;
2885
2886                 /*
2887                  * Mark this as fragmented, so if somebody throws an
2888                  * exception, we don't report it as a malformed frame.
2889                  */
2890                 save_fragmented = pinfo->fragmented;
2891                 pinfo->fragmented = TRUE;
2892                 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
2893                     tree, frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu);
2894                 pinfo->fragmented = save_fragmented;
2895                 if (!rpc_succeeded)
2896                         return 0;       /* not RPC */
2897                 return len;
2898         }
2899
2900         /*
2901          * First, we check to see if this fragment is part of a record
2902          * that we're in the process of defragmenting.
2903          *
2904          * The key is the conversation ID for the conversation to which
2905          * the packet belongs and the current sequence number.
2906          * We must first find the conversation and, if we don't find
2907          * one, create it.  We know this is running over TCP, so the
2908          * conversation should not wildcard either address or port.
2909          */
2910         conversation = find_conversation(&pinfo->src, &pinfo->dst,
2911             pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2912         if (conversation == NULL) {
2913                 /*
2914                  * It's not part of any conversation - create a new one.
2915                  */
2916                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
2917                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2918         }
2919         old_rfk.conv_id = conversation->index;
2920         old_rfk.seq = seq;
2921         rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
2922
2923         if (rfk == NULL) {
2924                 /*
2925                  * This fragment was not found in our table, so it doesn't
2926                  * contain a continuation of a higher-level PDU.
2927                  * Is it the last fragment?
2928                  */
2929                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2930                         /*
2931                          * This isn't the last fragment, so we don't
2932                          * have the complete record.
2933                          *
2934                          * It's the first fragment we've seen, so if
2935                          * it's truly the first fragment of the record,
2936                          * and it has enough data, the dissector can at
2937                          * least check whether it looks like a valid
2938                          * message, as it contains the start of the
2939                          * message.
2940                          *
2941                          * The dissector should not dissect anything
2942                          * if the "last fragment" flag isn't set in
2943                          * the record marker, so it shouldn't throw
2944                          * an exception.
2945                          */
2946                         if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
2947                             NULL, TRUE, rpc_rm, first_pdu))
2948                                 return 0;       /* not valid */
2949
2950                         /*
2951                          * OK, now start defragmentation with that
2952                          * fragment.  Add this fragment, and set up
2953                          * next packet/sequence number as well.
2954                          *
2955                          * We must remember this fragment.
2956                          */
2957
2958                         rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2959                         rfk->conv_id = conversation->index;
2960                         rfk->seq = seq;
2961                         rfk->offset = 0;
2962                         rfk->start_seq = seq;
2963                         g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
2964
2965                         /*
2966                          * Start defragmentation.
2967                          */
2968                         ipfd_head = fragment_add_multiple_ok(tvb, offset + 4,
2969                             pinfo, rfk->start_seq, rpc_fragment_table,
2970                             rfk->offset, len - 4, TRUE);
2971
2972                         /*
2973                          * Make sure that defragmentation isn't complete;
2974                          * it shouldn't be, as this is the first fragment
2975                          * we've seen, and the "last fragment" bit wasn't
2976                          * set on it.
2977                          */
2978                         g_assert(ipfd_head == NULL);
2979
2980                         new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2981                         new_rfk->conv_id = rfk->conv_id;
2982                         new_rfk->seq = seq + len;
2983                         new_rfk->offset = rfk->offset + len - 4;
2984                         new_rfk->start_seq = rfk->start_seq;
2985                         g_hash_table_insert(rpc_reassembly_table, new_rfk,
2986                             new_rfk);
2987
2988                         /*
2989                          * This is part of a fragmented record,
2990                          * but it's not the first part.
2991                          * Show it as a record marker plus data, under
2992                          * a top-level tree for this protocol.
2993                          */
2994                         make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
2995
2996                         /*
2997                          * No more processing need be done, as we don't
2998                          * have a complete record.
2999                          */
3000                         return len;
3001                 }
3002
3003                 /*
3004                  * This is the first fragment we've seen, and it's also
3005                  * the last fragment; that means the record wasn't
3006                  * fragmented.  Hand the dissector the tvbuff for the
3007                  * fragment as the tvbuff for the record.
3008                  */
3009                 rec_tvb = frag_tvb;
3010                 ipfd_head = NULL;
3011         } else {
3012                 /*
3013                  * OK, this fragment was found, which means it continues
3014                  * a record.  This means we must defragment it.
3015                  * Add it to the defragmentation lists.
3016                  */
3017                 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4, pinfo,
3018                     rfk->start_seq, rpc_fragment_table,
3019                     rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
3020
3021                 if (ipfd_head == NULL) {
3022                         /*
3023                          * fragment_add_multiple_ok() returned NULL.
3024                          * This means that defragmentation is not
3025                          * completed yet.
3026                          *
3027                          * We must add an entry to the hash table with
3028                          * the sequence number following this fragment
3029                          * as the starting sequence number, so that when
3030                          * we see that fragment we'll find that entry.
3031                          *
3032                          * XXX - as TCP stream data is not currently
3033                          * guaranteed to be provided in order to dissectors,
3034                          * RPC fragments aren't guaranteed to be provided
3035                          * in order, either.
3036                          */
3037                         new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
3038                         new_rfk->conv_id = rfk->conv_id;
3039                         new_rfk->seq = seq + len;
3040                         new_rfk->offset = rfk->offset + len - 4;
3041                         new_rfk->start_seq = rfk->start_seq;
3042                         g_hash_table_insert(rpc_reassembly_table, new_rfk,
3043                             new_rfk);
3044
3045                         /*
3046                          * This is part of a fragmented record,
3047                          * but it's not the first part.
3048                          * Show it as a record marker plus data, under
3049                          * a top-level tree for this protocol,
3050                          * but don't hand it to the dissector
3051                          */
3052                         make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3053
3054                         /*
3055                          * No more processing need be done, as we don't
3056                          * have a complete record.
3057                          */
3058                         return len;
3059                 }
3060
3061                 /*
3062                  * It's completely defragmented.
3063                  *
3064                  * We only call subdissector for the last fragment.
3065                  * XXX - this assumes in-order delivery of RPC
3066                  * fragments, which requires in-order delivery of TCP
3067                  * segments.
3068                  */
3069                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
3070                         /*
3071                          * Well, it's defragmented, but this isn't
3072                          * the last fragment; this probably means
3073                          * this isn't the first pass, so we don't
3074                          * need to start defragmentation.
3075                          *
3076                          * This is part of a fragmented record,
3077                          * but it's not the first part.
3078                          * Show it as a record marker plus data, under
3079                          * a top-level tree for this protocol,
3080                          * but don't show it to the dissector.
3081                          */
3082                         make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3083
3084                         /*
3085                          * No more processing need be done, as we
3086                          * only disssect the data with the last
3087                          * fragment.
3088                          */
3089                         return len;
3090                 }
3091
3092                 /*
3093                  * OK, this is the last segment.
3094                  * Create a tvbuff for the defragmented
3095                  * record.
3096                  */
3097
3098                 /*
3099                  * Create a new TVB structure for
3100                  * defragmented data.
3101                  */
3102                 rec_tvb = tvb_new_real_data(ipfd_head->data,
3103                     ipfd_head->datalen, ipfd_head->datalen);
3104
3105                 /*
3106                  * Add this tvb as a child to the original
3107                  * one.
3108                  */
3109                 tvb_set_child_real_data_tvbuff(tvb, rec_tvb);
3110
3111                 /*
3112                  * Add defragmented data to the data source list.
3113                  */
3114                 add_new_data_source(pinfo, rec_tvb, "Defragmented");
3115         }
3116
3117         /*
3118          * We have something to hand to the RPC message
3119          * dissector.
3120          */
3121         if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
3122             frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu))
3123                 return 0;       /* not RPC */
3124         return len;
3125 }
3126
3127 /*
3128  * Can return:
3129  *
3130  *      NEED_MORE_DATA, if we don't have enough data to dissect anything;
3131  *
3132  *      IS_RPC, if we dissected at least one message in its entirety
3133  *      as RPC;
3134  *
3135  *      IS_NOT_RPC, if we found no RPC message.
3136  */
3137 typedef enum {
3138         NEED_MORE_DATA,
3139         IS_RPC,
3140         IS_NOT_RPC
3141 } rpc_tcp_return_t;
3142
3143 static rpc_tcp_return_t
3144 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3145     gboolean is_heur)
3146 {
3147         int offset = 0;
3148         gboolean saw_rpc = FALSE;
3149         gboolean first_pdu = TRUE;
3150         int len;
3151
3152         while (tvb_reported_length_remaining(tvb, offset) != 0) {
3153                 /*
3154                  * Process this fragment.
3155                  */
3156                 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
3157                     dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
3158                     rpc_defragment, first_pdu);
3159                 first_pdu = FALSE;
3160                 if (len < 0) {
3161                         /*
3162                          * We need more data from the TCP stream for
3163                          * this fragment.
3164                          */
3165                         return NEED_MORE_DATA;
3166                 }
3167                 if (len == 0) {
3168                         /*
3169                          * It's not RPC.  Stop processing.
3170                          */
3171                         break;
3172                 }
3173
3174                 /* PDU tracking
3175                   If the length indicates that the PDU continues beyond
3176                   the end of this tvb, then tell TCP about it so that it
3177                   knows where the next PDU starts.
3178                   This is to help TCP detect when PDUs are not aligned to
3179                   segment boundaries and allow it to find RPC headers
3180                   that starts in the middle of a TCP segment.
3181                 */
3182                 if(!pinfo->fd->flags.visited){
3183                         if(len>tvb_reported_length_remaining(tvb, offset)){
3184                                 pinfo->want_pdu_tracking=2;
3185                                 pinfo->bytes_until_next_pdu=len-tvb_reported_length_remaining(tvb, offset);
3186                         }
3187                 }
3188                 offset += len;
3189                 saw_rpc = TRUE;
3190         }
3191         return saw_rpc ? IS_RPC : IS_NOT_RPC;
3192 }
3193
3194 static gboolean
3195 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3196 {
3197         switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
3198
3199         case IS_RPC:
3200                 return TRUE;
3201
3202         case IS_NOT_RPC:
3203                 return FALSE;
3204
3205         default:
3206                 /* "Can't happen" */
3207                 g_assert_not_reached();
3208                 return FALSE;
3209         }
3210 }
3211
3212 static void
3213 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3214 {
3215         if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
3216                 dissect_rpc_continuation(tvb, pinfo, tree);
3217 }
3218
3219 /* Discard any state we've saved. */
3220 static void
3221 rpc_init_protocol(void)
3222 {
3223         if (rpc_calls != NULL) {
3224                 g_hash_table_destroy(rpc_calls);
3225                 rpc_calls = NULL;
3226         }
3227         if (rpc_indir_calls != NULL) {
3228                 g_hash_table_destroy(rpc_indir_calls);
3229                 rpc_indir_calls = NULL;
3230         }
3231         if (rpc_call_info_key_chunk != NULL) {
3232                 g_mem_chunk_destroy(rpc_call_info_key_chunk);
3233                 rpc_call_info_key_chunk = NULL;
3234         }
3235         if (rpc_call_info_value_chunk != NULL) {
3236                 g_mem_chunk_destroy(rpc_call_info_value_chunk);
3237                 rpc_call_info_value_chunk = NULL;
3238         }
3239         if (rpc_fragment_key_chunk != NULL) {
3240                 g_mem_chunk_destroy(rpc_fragment_key_chunk);
3241                 rpc_fragment_key_chunk = NULL;
3242         }
3243         if (rpc_reassembly_table != NULL) {
3244                 g_hash_table_destroy(rpc_reassembly_table);
3245                 rpc_reassembly_table = NULL;
3246         }
3247
3248         rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3249         rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3250         rpc_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
3251             sizeof(rpc_call_info_key),
3252             200 * sizeof(rpc_call_info_key),
3253             G_ALLOC_ONLY);
3254         rpc_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
3255             sizeof(rpc_call_info_value),
3256             200 * sizeof(rpc_call_info_value),
3257             G_ALLOC_ONLY);
3258         rpc_fragment_key_chunk = g_mem_chunk_new("rpc_fragment_key_chunk",
3259             sizeof(rpc_fragment_key),
3260             rpc_fragment_init_count*sizeof(rpc_fragment_key),
3261             G_ALLOC_ONLY);
3262         rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
3263             rpc_fragment_equal);
3264
3265         fragment_table_init(&rpc_fragment_table);
3266 }
3267
3268 /* will be called once from register.c at startup time */
3269 void
3270 proto_register_rpc(void)
3271 {
3272         static hf_register_info hf[] = {
3273                 { &hf_rpc_reqframe, {
3274                         "Request Frame", "rpc.reqframe", FT_FRAMENUM, BASE_NONE,
3275                         NULL, 0, "Request Frame", HFILL }},
3276                 { &hf_rpc_repframe, {
3277                         "Reply Frame", "rpc.repframe", FT_FRAMENUM, BASE_NONE,
3278                         NULL, 0, "Reply Frame", HFILL }},
3279                 { &hf_rpc_lastfrag, {
3280                         "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
3281                         &yesno, RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
3282                 { &hf_rpc_fraglen, {
3283                         "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
3284                         NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
3285                 { &hf_rpc_xid, {
3286                         "XID", "rpc.xid", FT_UINT32, BASE_HEX,
3287                         NULL, 0, "XID", HFILL }},
3288                 { &hf_rpc_msgtype, {
3289                         "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
3290                         VALS(rpc_msg_type), 0, "Message Type", HFILL }},
3291                 { &hf_rpc_state_reply, {
3292                         "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
3293                         VALS(rpc_reply_state), 0, "Reply State", HFILL }},
3294                 { &hf_rpc_state_accept, {
3295                         "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
3296                         VALS(rpc_accept_state), 0, "Accept State", HFILL }},
3297                 { &hf_rpc_state_reject, {
3298                         "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
3299                         VALS(rpc_reject_state), 0, "Reject State", HFILL }},
3300                 { &hf_rpc_state_auth, {
3301                         "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
3302                         VALS(rpc_auth_state), 0, "Auth State", HFILL }},
3303                 { &hf_rpc_version, {
3304                         "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
3305                         NULL, 0, "RPC Version", HFILL }},
3306                 { &hf_rpc_version_min, {
3307                         "RPC Version (Minimum)", "rpc.version.min", FT_UINT32,
3308                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3309                 { &hf_rpc_version_max, {
3310                         "RPC Version (Maximum)", "rpc.version.max", FT_UINT32,
3311                         BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
3312                 { &hf_rpc_program, {
3313                         "Program", "rpc.program", FT_UINT32, BASE_DEC,
3314                         NULL, 0, "Program", HFILL }},
3315                 { &hf_rpc_programversion, {
3316                         "Program Version", "rpc.programversion", FT_UINT32,
3317                         BASE_DEC, NULL, 0, "Program Version", HFILL }},
3318                 { &hf_rpc_programversion_min, {
3319                         "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32,
3320                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3321                 { &hf_rpc_programversion_max, {
3322                         "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32,
3323                         BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
3324                 { &hf_rpc_procedure, {
3325                         "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
3326                         NULL, 0, "Procedure", HFILL }},
3327                 { &hf_rpc_auth_flavor, {
3328                         "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
3329                         VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
3330                 { &hf_rpc_auth_length, {
3331                         "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
3332                         NULL, 0, "Length", HFILL }},
3333                 { &hf_rpc_auth_stamp, {
3334                         "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
3335                         NULL, 0, "Stamp", HFILL }},
3336                 { &hf_rpc_auth_uid, {
3337                         "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
3338                         NULL, 0, "UID", HFILL }},
3339                 { &hf_rpc_auth_gid, {
3340                         "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
3341                         NULL, 0, "GID", HFILL }},
3342                 { &hf_rpc_authgss_v, {
3343                         "GSS Version", "rpc.authgss.version", FT_UINT32,
3344                         BASE_DEC, NULL, 0, "GSS Version", HFILL }},
3345                 { &hf_rpc_authgss_proc, {
3346                         "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
3347                         BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
3348                 { &hf_rpc_authgss_seq, {
3349                         "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
3350                         BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
3351                 { &hf_rpc_authgss_svc, {
3352                         "GSS Service", "rpc.authgss.service", FT_UINT32,
3353                         BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
3354                 { &hf_rpc_authgss_ctx, {
3355                         "GSS Context", "rpc.authgss.context", FT_BYTES,
3356                         BASE_HEX, NULL, 0, "GSS Context", HFILL }},
3357                 { &hf_rpc_authgss_major, {
3358                         "GSS Major Status", "rpc.authgss.major", FT_UINT32,
3359                         BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
3360                 { &hf_rpc_authgss_minor, {
3361                         "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
3362                         BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
3363                 { &hf_rpc_authgss_window, {
3364                         "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
3365                         BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
3366                 { &hf_rpc_authgss_token_length, {
3367                         "GSS Token Length", "rpc.authgss.token_length", FT_UINT32,
3368                         BASE_DEC, NULL, 0, "GSS Token Length", HFILL }},
3369                 { &hf_rpc_authgss_data_length, {
3370                         "Length", "rpc.authgss.data.length", FT_UINT32,
3371                         BASE_DEC, NULL, 0, "Length", HFILL }},
3372                 { &hf_rpc_authgss_data, {
3373                         "GSS Data", "rpc.authgss.data", FT_BYTES,
3374                         BASE_HEX, NULL, 0, "GSS Data", HFILL }},
3375                 { &hf_rpc_authgss_checksum, {
3376                         "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
3377                         BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
3378                 { &hf_rpc_authgssapi_v, {
3379                         "AUTH_GSSAPI Version", "rpc.authgssapi.version",
3380                         FT_UINT32, BASE_DEC, NULL, 0, "AUTH_GSSAPI Version",
3381                         HFILL }},
3382                 { &hf_rpc_authgssapi_msg, {
3383                         "AUTH_GSSAPI Message", "rpc.authgssapi.message",
3384                         FT_BOOLEAN, BASE_NONE, &yesno, 0, "AUTH_GSSAPI Message",
3385                         HFILL }},
3386                 { &hf_rpc_authgssapi_msgv, {
3387                         "Msg Version", "rpc.authgssapi.msgversion",
3388                         FT_UINT32, BASE_DEC, NULL, 0, "Msg Version",
3389                         HFILL }},
3390                 { &hf_rpc_authgssapi_handle, {
3391                         "Client Handle", "rpc.authgssapi.handle",
3392                         FT_BYTES, BASE_HEX, NULL, 0, "Client Handle", HFILL }},
3393                 { &hf_rpc_authgssapi_isn, {
3394                         "Signed ISN", "rpc.authgssapi.isn",
3395                         FT_BYTES, BASE_HEX, NULL, 0, "Signed ISN", HFILL }},
3396                 { &hf_rpc_authdes_namekind, {
3397                         "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
3398                         VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
3399                 { &hf_rpc_authdes_netname, {
3400                         "Netname", "rpc.authdes.netname", FT_STRING,
3401                         BASE_DEC, NULL, 0, "Netname", HFILL }},
3402                 { &hf_rpc_authdes_convkey, {
3403                         "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
3404                         BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
3405                 { &hf_rpc_authdes_window, {
3406                         "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
3407                         BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
3408                 { &hf_rpc_authdes_nickname, {
3409                         "Nickname", "rpc.authdes.nickname", FT_UINT32,
3410                         BASE_HEX, NULL, 0, "Nickname", HFILL }},
3411                 { &hf_rpc_authdes_timestamp, {
3412                         "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
3413                         BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
3414                 { &hf_rpc_authdes_windowverf, {
3415                         "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
3416                         BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
3417                 { &hf_rpc_authdes_timeverf, {
3418                         "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
3419                         BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
3420                 { &hf_rpc_auth_machinename, {
3421                         "Machine Name", "rpc.auth.machinename", FT_STRING,
3422                         BASE_DEC, NULL, 0, "Machine Name", HFILL }},
3423                 { &hf_rpc_dup, {
3424                         "Duplicate Call/Reply", "rpc.dup", FT_NONE, BASE_NONE,
3425                         NULL, 0, "Duplicate Call/Reply", HFILL }},
3426                 { &hf_rpc_call_dup, {
3427                         "Duplicate to the call in", "rpc.call.dup", FT_FRAMENUM, BASE_DEC,
3428                         NULL, 0, "This is a duplicate to the call in frame", HFILL }},
3429                 { &hf_rpc_reply_dup, {
3430                         "Duplicate to the reply in", "rpc.reply.dup", FT_FRAMENUM, BASE_DEC,
3431                         NULL, 0, "This is a duplicate to the reply in frame", HFILL }},
3432                 { &hf_rpc_value_follows, {
3433                         "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
3434                         &yesno, 0, "Value Follows", HFILL }},
3435                 { &hf_rpc_array_len, {
3436                         "num", "rpc.array.len", FT_UINT32, BASE_DEC,
3437                         NULL, 0, "Length of RPC array", HFILL }},
3438
3439                 { &hf_rpc_time, {
3440                         "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
3441                         NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
3442
3443                 { &hf_rpc_fragment_overlap,
3444                 { "Fragment overlap",   "rpc.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3445                         "Fragment overlaps with other fragments", HFILL }},
3446
3447                 { &hf_rpc_fragment_overlap_conflict,
3448                 { "Conflicting data in fragment overlap",       "rpc.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3449                         "Overlapping fragments contained conflicting data", HFILL }},
3450
3451                 { &hf_rpc_fragment_multiple_tails,
3452                 { "Multiple tail fragments found",      "rpc.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3453                         "Several tails were found when defragmenting the packet", HFILL }},
3454
3455                 { &hf_rpc_fragment_too_long_fragment,
3456                 { "Fragment too long",  "rpc.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3457                         "Fragment contained data past end of packet", HFILL }},
3458
3459                 { &hf_rpc_fragment_error,
3460                 { "Defragmentation error", "rpc.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3461                         "Defragmentation error due to illegal fragments", HFILL }},
3462
3463                 { &hf_rpc_fragment,
3464                 { "RPC Fragment", "rpc.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3465                         "RPC Fragment", HFILL }},
3466
3467                 { &hf_rpc_fragments,
3468                 { "RPC Fragments", "rpc.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3469                         "RPC Fragments", HFILL }},
3470         };
3471         static gint *ett[] = {
3472                 &ett_rpc,
3473                 &ett_rpc_fragments,
3474                 &ett_rpc_fragment,
3475                 &ett_rpc_fraghdr,
3476                 &ett_rpc_string,
3477                 &ett_rpc_cred,
3478                 &ett_rpc_verf,
3479                 &ett_rpc_gids,
3480                 &ett_rpc_gss_token,
3481                 &ett_rpc_gss_data,
3482                 &ett_rpc_array,
3483                 &ett_rpc_authgssapi_msg,
3484                 &ett_rpc_unknown_program,
3485         };
3486         module_t *rpc_module;
3487
3488         proto_rpc = proto_register_protocol("Remote Procedure Call",
3489             "RPC", "rpc");
3490         /* this is a dummy dissector for all those unknown rpc programs */
3491         proto_register_field_array(proto_rpc, hf, array_length(hf));
3492         proto_register_subtree_array(ett, array_length(ett));
3493         register_init_routine(&rpc_init_protocol);
3494
3495         rpc_module = prefs_register_protocol(proto_rpc, NULL);
3496         prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
3497                 "Desegment all RPC-over-TCP messages",
3498                 "Whether the RPC dissector should desegment all RPC-over-TCP messages",
3499                 &rpc_desegment);
3500         prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
3501                 "Defragment all RPC-over-TCP messages",
3502                 "Whether the RPC dissector should defragment multi-fragment RPC-over-TCP messages",
3503                 &rpc_defragment);
3504
3505         prefs_register_uint_preference(rpc_module, "max_tcp_pdu_size", "Maximum size of a RPC-over-TCP PDU",
3506                 "Set the maximum size of RPCoverTCP PDUs. "
3507                 " If the size field of the record marker is larger "
3508                 "than this value it will not be considered a valid RPC PDU",
3509                  10, &max_rpc_tcp_pdu_size);
3510
3511         prefs_register_bool_preference(rpc_module, "dissect_unknown_programs",
3512                 "Dissect unknown RPC program numbers",
3513                 "Whether the RPC dissector should attempt to dissect RPC PDUs containing programs that are not known to Ethereal. This will make the heuristics significantly weaker and elevate the risk for falsely identifying and misdissecting packets significantly.",
3514                 &rpc_dissect_unknown_programs);
3515
3516         register_dissector("rpc", dissect_rpc, proto_rpc);
3517         rpc_handle = find_dissector("rpc");
3518         register_dissector("rpc-tcp", dissect_rpc_tcp, proto_rpc);
3519         rpc_tcp_handle = find_dissector("rpc-tcp");
3520         rpc_tap = register_tap("rpc");
3521
3522         /*
3523          * Init the hash tables.  Dissectors for RPC protocols must
3524          * have a "handoff registration" routine that registers the
3525          * protocol with RPC; they must not do it in their protocol
3526          * registration routine, as their protocol registration
3527          * routine might be called before this routine is called and
3528          * thus might be called before the hash tables are initialized,
3529          * but it's guaranteed that all protocol registration routines
3530          * will be called before any handoff registration routines
3531          * are called.
3532          */
3533         rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
3534         rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
3535 }
3536
3537 void
3538 proto_reg_handoff_rpc(void)
3539 {
3540         dissector_handle_t rpc_tcp_handle;
3541         dissector_handle_t rpc_udp_handle;
3542
3543         /* tcp/udp port 111 is used by portmapper which is an onc-rpc service.
3544            we register onc-rpc on this port so that we can choose RPC in
3545            the list offered by DecodeAs, and so that traffic to or from
3546            port 111 from or to a higher-numbered port is dissected as RPC
3547            even if there's a dissector registered on the other port (it's
3548            probably RPC traffic from some randomly-chosen port that happens
3549            to match some port for which we have a dissector)
3550         */
3551         rpc_tcp_handle = create_dissector_handle(dissect_rpc_tcp, proto_rpc);
3552         dissector_add("tcp.port", 111, rpc_tcp_handle);
3553         rpc_udp_handle = create_dissector_handle(dissect_rpc, proto_rpc);
3554         dissector_add("udp.port", 111, rpc_udp_handle);
3555
3556         heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
3557         heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
3558         gssapi_handle = find_dissector("gssapi");
3559         data_handle = find_dissector("data");
3560 }