Move the following files from /trunk to /trunk/epan:
[metze/wireshark/wip.git] / epan / dissectors / packet-rpc.c
1 /* packet-rpc.c
2  * Routines for rpc dissection
3  * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
4  *
5  * $Id$
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 <epan/prefs.h>
42 #include <epan/reassemble.h>
43 #include "rpc_defrag.h"
44 #include "packet-nfs.h"
45 #include <epan/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 whence the call came, and the
1373                    port to which the call is being sent, so that we can
1374                    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 also take
1378                    into account the port from which the call was sent
1379                    and the address to which the call was sent, because
1380                    the addresses and ports of the two endpoints should be
1381                    the same for all calls and replies.  (XXX - what if
1382                    the connection is broken and re-established?)
1383
1384                    If the transport is connectionless, we don't worry
1385                    about the address to which the call was sent and from
1386                    which the reply was sent, because there's no
1387                    guarantee that the reply will come from the address
1388                    to which the call was sent.  We also don't worry about
1389                    the port *from* which the call was sent and *to* which
1390                    the reply was sent, because some clients (*cough* OS X
1391                    NFS client *cough) might send retransmissions from a
1392                    different port from the original request. */
1393                 if (pinfo->ptype == PT_TCP) {
1394                         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1395                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1396                             pinfo->destport, 0);
1397                 } else {
1398                         /*
1399                          * XXX - you currently still have to pass a non-null
1400                          * pointer for the second address argument even
1401                          * if you use NO_ADDR_B.
1402                          */
1403                         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1404                             &null_address, pinfo->ptype, pinfo->destport,
1405                             0, NO_ADDR_B|NO_PORT_B);
1406                 }
1407                 if (conversation == NULL) {
1408                         /* It's not part of any conversation - create a new
1409                            one.
1410
1411                            XXX - this should never happen, as we should've
1412                            created a conversation for it in the RPC
1413                            dissector. */
1414                         if (pinfo->ptype == PT_TCP) {
1415                                 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
1416                                     &pinfo->dst, pinfo->ptype, pinfo->srcport,
1417                                     pinfo->destport, 0);
1418                         } else {
1419                                 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
1420                                     &null_address, pinfo->ptype, pinfo->destport,
1421                                     0, NO_ADDR2|NO_PORT2);
1422                         }
1423                 }
1424
1425                 /* Make the dissector for this conversation the non-heuristic
1426                    RPC dissector. */
1427                 conversation_set_dissector(conversation,
1428                     (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1429
1430                 /* Prepare the key data.
1431
1432                    Dissectors for RPC procedure calls and replies shouldn't
1433                    create new tvbuffs, and we don't create one ourselves,
1434                    so we should have been handed the tvbuff for this RPC call;
1435                    as such, the XID is at offset 0 in this tvbuff. */
1436                 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1437                 rpc_call_key.conversation = conversation;
1438
1439                 /* look up the request */
1440                 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1441                 if (rpc_call == NULL) {
1442                         /* We didn't find it; create a new entry.
1443                            Prepare the value data.
1444                            Not all of it is needed for handling indirect
1445                            calls, so we set a bunch of items to 0. */
1446                         new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1447                         *new_rpc_call_key = rpc_call_key;
1448                         rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1449                         rpc_call->req_num = 0;
1450                         rpc_call->rep_num = 0;
1451                         rpc_call->prog = prog;
1452                         rpc_call->vers = vers;
1453                         rpc_call->proc = proc;
1454                         rpc_call->private_data = NULL;
1455
1456                         /*
1457                          * XXX - what about RPCSEC_GSS?
1458                          * Do we have to worry about it?
1459                          */
1460                         rpc_call->flavor = FLAVOR_NOT_GSSAPI;
1461                         rpc_call->gss_proc = 0;
1462                         rpc_call->gss_svc = 0;
1463                         rpc_call->proc_info = value;
1464                         /* store it */
1465                         g_hash_table_insert(rpc_indir_calls, new_rpc_call_key,
1466                             rpc_call);
1467                 }
1468         }
1469         else {
1470                 /* We don't know the procedure.
1471                    Happens only with strange program versions or
1472                    non-existing dissectors.
1473                    Just show the arguments as opaque data. */
1474                 offset = dissect_rpc_data(tvb, tree, args_id,
1475                     offset);
1476                 return offset;
1477         }
1478
1479         if ( tree )
1480         {
1481                 proto_tree_add_text(tree, tvb, offset, 4,
1482                         "Argument length: %u",
1483                         tvb_get_ntohl(tvb, offset));
1484         }
1485         offset += 4;
1486
1487         /* Dissect the arguments */
1488         offset = call_dissect_function(tvb, pinfo, tree, offset,
1489                         dissect_function, NULL);
1490         return offset;
1491 }
1492
1493 /*
1494  * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1495  * dissector.
1496  */
1497 int
1498 dissect_rpc_indir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1499     int offset, int result_id, int prog_id, int vers_id, int proc_id)
1500 {
1501         conversation_t* conversation;
1502         static address null_address = { AT_NONE, 0, NULL };
1503         rpc_call_info_key rpc_call_key;
1504         rpc_call_info_value *rpc_call;
1505         char *procname = NULL;
1506         char procname_static[20];
1507         dissect_function_t *dissect_function = NULL;
1508
1509         /* Look for the matching call in the hash table of indirect
1510            calls.  A reply must match a call that we've seen, and the
1511            reply must be sent to the same address that the call came
1512            from, and must come from the port to which the call was sent.
1513
1514            If the transport is connection-oriented (we check, for
1515            now, only for "pinfo->ptype" of PT_TCP), we take
1516            into account the port from which the call was sent
1517            and the address to which the call was sent, because
1518            the addresses and ports of the two endpoints should be
1519            the same for all calls and replies.
1520
1521            If the transport is connectionless, we don't worry
1522            about the address to which the call was sent and from
1523            which the reply was sent, because there's no
1524            guarantee that the reply will come from the address
1525            to which the call was sent.  We also don't worry about
1526            the port *from* which the call was sent and *to* which
1527            the reply was sent, because some clients (*cough* OS X
1528            NFS client *cough) might send retransmissions from a
1529            different port from the original request. */
1530         if (pinfo->ptype == PT_TCP) {
1531                 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1532                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1533         } else {
1534                 /*
1535                  * XXX - you currently still have to pass a non-null
1536                  * pointer for the second address argument even
1537                  * if you use NO_ADDR_B.
1538                  */
1539                 conversation = find_conversation(pinfo->fd->num, &pinfo->dst, &null_address,
1540                     pinfo->ptype, pinfo->srcport, 0, NO_ADDR_B|NO_PORT_B);
1541         }
1542         if (conversation == NULL) {
1543                 /* We haven't seen an RPC call for that conversation,
1544                    so we can't check for a reply to that call.
1545                    Just show the reply stuff as opaque data. */
1546                 offset = dissect_rpc_data(tvb, tree, result_id,
1547                     offset);
1548                 return offset;
1549         }
1550
1551         /* The XIDs of the call and reply must match. */
1552         rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1553         rpc_call_key.conversation = conversation;
1554         rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1555         if (rpc_call == NULL) {
1556                 /* The XID doesn't match a call from that
1557                    conversation, so it's probably not an RPC reply.
1558                    Just show the reply stuff as opaque data. */
1559                 offset = dissect_rpc_data(tvb, tree, result_id,
1560                     offset);
1561                 return offset;
1562         }
1563
1564         if (rpc_call->proc_info != NULL) {
1565                 dissect_function = rpc_call->proc_info->dissect_reply;
1566                 if (rpc_call->proc_info->name != NULL) {
1567                         procname = rpc_call->proc_info->name;
1568                 }
1569                 else {
1570                         sprintf(procname_static, "proc-%u", rpc_call->proc);
1571                         procname = procname_static;
1572                 }
1573         }
1574         else {
1575 #if 0
1576                 dissect_function = NULL;
1577 #endif
1578                 sprintf(procname_static, "proc-%u", rpc_call->proc);
1579                 procname = procname_static;
1580         }
1581
1582         if ( tree )
1583         {
1584                 /* Put the program, version, and procedure into the tree. */
1585                 proto_tree_add_uint_format(tree, prog_id, tvb,
1586                         0, 0, rpc_call->prog, "Program: %s (%u)",
1587                         rpc_prog_name(rpc_call->prog), rpc_call->prog);
1588                 proto_tree_add_uint(tree, vers_id, tvb, 0, 0, rpc_call->vers);
1589                 proto_tree_add_uint_format(tree, proc_id, tvb,
1590                         0, 0, rpc_call->proc, "Procedure: %s (%u)",
1591                         procname, rpc_call->proc);
1592         }
1593
1594         if (dissect_function == NULL) {
1595                 /* We don't know how to dissect the reply procedure.
1596                    Just show the reply stuff as opaque data. */
1597                 offset = dissect_rpc_data(tvb, tree, result_id,
1598                     offset);
1599                 return offset;
1600         }
1601
1602         if (tree) {
1603                 /* Put the length of the reply value into the tree. */
1604                 proto_tree_add_text(tree, tvb, offset, 4,
1605                         "Argument length: %u",
1606                         tvb_get_ntohl(tvb, offset));
1607         }
1608         offset += 4;
1609
1610         /* Dissect the return value */
1611         offset = call_dissect_function(tvb, pinfo, tree, offset,
1612                         dissect_function, NULL);
1613         return offset;
1614 }
1615
1616 /*
1617  * Just mark this as a continuation of an earlier packet.
1618  */
1619 static void
1620 dissect_rpc_continuation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1621 {
1622         proto_item *rpc_item;
1623         proto_tree *rpc_tree;
1624
1625         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1626                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1627         if (check_col(pinfo->cinfo, COL_INFO))
1628                 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1629
1630         if (tree) {
1631                 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1632                                 FALSE);
1633                 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1634                 proto_tree_add_text(rpc_tree, tvb, 0, -1, "Continuation data");
1635         }
1636 }
1637
1638 static gboolean
1639 dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1640     tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
1641     guint32 rpc_rm, gboolean first_pdu)
1642 {
1643         guint32 msg_type;
1644         rpc_call_info_key rpc_call_key;
1645         rpc_call_info_value *rpc_call = NULL;
1646         rpc_prog_info_value *rpc_prog = NULL;
1647         rpc_prog_info_key rpc_prog_key;
1648
1649         unsigned int xid;
1650         unsigned int rpcvers;
1651         unsigned int prog = 0;
1652         unsigned int vers = 0;
1653         unsigned int proc = 0;
1654         flavor_t flavor = FLAVOR_UNKNOWN;
1655         unsigned int gss_proc = 0;
1656         unsigned int gss_svc = 0;
1657         protocol_t *proto = NULL;
1658         int     proto_id = 0;
1659         int     ett = 0;
1660         int     procedure_hf;
1661
1662         unsigned int reply_state;
1663         unsigned int accept_state;
1664         unsigned int reject_state;
1665
1666         char *msg_type_name = NULL;
1667         char *progname = NULL;
1668         char *procname = NULL;
1669         static char procname_static[20];
1670
1671         unsigned int vers_low;
1672         unsigned int vers_high;
1673
1674         unsigned int auth_state;
1675
1676         proto_item *rpc_item = NULL;
1677         proto_tree *rpc_tree = NULL;
1678
1679         proto_item *pitem = NULL;
1680         proto_tree *ptree = NULL;
1681         int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
1682
1683         rpc_call_info_key       *new_rpc_call_key;
1684         rpc_proc_info_key       key;
1685         rpc_proc_info_value     *value = NULL;
1686         conversation_t* conversation;
1687         static address null_address = { AT_NONE, 0, NULL };
1688         nstime_t ns;
1689
1690         dissect_function_t *dissect_function = NULL;
1691         gboolean dissect_rpc = TRUE;
1692
1693
1694         /*
1695          * Check to see whether this looks like an RPC call or reply.
1696          */
1697         if (!tvb_bytes_exist(tvb, offset, 8)) {
1698                 /* Captured data in packet isn't enough to let us tell. */
1699                 return FALSE;
1700         }
1701
1702         /* both directions need at least this */
1703         msg_type = tvb_get_ntohl(tvb, offset + 4);
1704
1705         switch (msg_type) {
1706
1707         case RPC_CALL:
1708                 /* check for RPC call */
1709                 if (!tvb_bytes_exist(tvb, offset, 16)) {
1710                         /* Captured data in packet isn't enough to let us
1711                            tell. */
1712                         return FALSE;
1713                 }
1714
1715                 /* XID can be anything, so dont check it.
1716                    We already have the message type.
1717                    Check whether an RPC version number of 2 is in the
1718                    location where it would be, and that an RPC program
1719                    number we know about is in the location where it would be.
1720
1721                    XXX - Sun's snoop appears to recognize as RPC even calls
1722                    to stuff it doesn't dissect; does it just look for a 2
1723                    at that location, which seems far to weak a heuristic
1724                    (too many false positives), or does it have some additional
1725                    checks it does?
1726
1727                    We could conceivably check for any of the program numbers
1728                    in the list at
1729
1730                         ftp://ftp.tau.ac.il/pub/users/eilon/rpc/rpc
1731
1732                    and report it as RPC (but not dissect the payload if
1733                    we don't have a subdissector) if it matches. */
1734                 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1735
1736                 /* we only dissect version 2 */
1737                 if (tvb_get_ntohl(tvb, offset + 8) != 2 ){
1738                         return FALSE;
1739                 }
1740                 /* let the user be able to weaken the heuristics if he need
1741                  * to look at proprietary protocols not known
1742                  * to ethereal.
1743                  */
1744                 if(rpc_dissect_unknown_programs){
1745                         /* if the user has specified that he wants to try to 
1746                          * dissect even completely unknown RPC program numbers
1747                          * then let him do that.
1748                          * In this case we only check that the program number 
1749                          * is neither 0 nor -1 which is better than nothing.
1750                          */
1751                         if(rpc_prog_key.prog==0 || rpc_prog_key.prog==0xffffffff){
1752                                 return FALSE;
1753                         }
1754                         if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
1755                                 /* ok this is not a known rpc program so we
1756                                  * will have to fake it.
1757                                  */
1758                                 int proto_rpc_unknown_program;
1759                                 char *NAME, *Name, *name;
1760                                 static const vsff unknown_proc[] = {
1761                                         { 0,"NULL",NULL,NULL },
1762                                         { 0,NULL,NULL,NULL }
1763                                 };
1764
1765                                 NAME=g_malloc(36);
1766                                 Name=g_malloc(32);
1767                                 name=g_malloc(32);
1768                                 sprintf(NAME, "Unknown RPC Program:%d",rpc_prog_key.prog);
1769                                 sprintf(Name, "RPC:%d",rpc_prog_key.prog);
1770                                 sprintf(name, "rpc%d",rpc_prog_key.prog);
1771                                 proto_rpc_unknown_program = proto_register_protocol(NAME, Name, name);
1772
1773                                 rpc_init_prog(proto_rpc_unknown_program, rpc_prog_key.prog, ett_rpc_unknown_program);
1774                                 rpc_init_proc_table(rpc_prog_key.prog, tvb_get_ntohl(tvb, offset + 16), unknown_proc, hf_rpc_procedure);
1775
1776                         }
1777                 }
1778                 if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
1779                         /* They're not, so it's probably not an RPC call. */
1780                         return FALSE;
1781                 }
1782                 break;
1783
1784         case RPC_REPLY:
1785                 /* Check for RPC reply.  A reply must match a call that
1786                    we've seen, and the reply must be sent to the same
1787                    address that the call came from, and must come from
1788                    the port to which the call was sent.
1789
1790                    If the transport is connection-oriented (we check, for
1791                    now, only for "pinfo->ptype" of PT_TCP), we take
1792                    into account the port from which the call was sent
1793                    and the address to which the call was sent, because
1794                    the addresses and ports of the two endpoints should be
1795                    the same for all calls and replies.
1796
1797                    If the transport is connectionless, we don't worry
1798                    about the address to which the call was sent and from
1799                    which the reply was sent, because there's no
1800                    guarantee that the reply will come from the address
1801                    to which the call was sent.  We also don't worry about
1802                    the port *from* which the call was sent and *to* which
1803                    the reply was sent, because some clients (*cough* OS X
1804                    NFS client *cough) might send retransmissions from a
1805                    different port from the original request. */
1806                 if (pinfo->ptype == PT_TCP) {
1807                         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1808                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1809                             pinfo->destport, 0);
1810                 } else {
1811                         /*
1812                          * XXX - you currently still have to pass a non-null
1813                          * pointer for the second address argument even
1814                          * if you use NO_ADDR_B.
1815                          */
1816                         conversation = find_conversation(pinfo->fd->num, &pinfo->dst,
1817                             &null_address, pinfo->ptype, pinfo->srcport,
1818                             0, NO_ADDR_B|NO_PORT_B);
1819                 }
1820                 if (conversation == NULL) {
1821                         /* We haven't seen an RPC call for that conversation,
1822                            so we can't check for a reply to that call. */
1823                         return FALSE;
1824                 }
1825
1826                 /* The XIDs of the call and reply must match. */
1827                 rpc_call_key.xid = tvb_get_ntohl(tvb, offset + 0);
1828                 rpc_call_key.conversation = conversation;
1829                 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1830                 if (rpc_call == NULL) {
1831                         /* The XID doesn't match a call from that
1832                            conversation, so it's probably not an RPC reply. */
1833                         return FALSE;
1834                 }
1835                 /* pass rpc_info to subdissectors */
1836                 rpc_call->request=FALSE;
1837                 pinfo->private_data=rpc_call;
1838                 break;
1839
1840         default:
1841                 /* The putative message type field contains neither
1842                    RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1843                    reply. */
1844                 return FALSE;
1845         }
1846
1847         if (is_tcp) {
1848                 /*
1849                  * This is RPC-over-TCP; check if this is the last
1850                  * fragment.
1851                  */
1852                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
1853                         /*
1854                          * This isn't the last fragment.
1855                          * If we're doing reassembly, just return
1856                          * TRUE to indicate that this looks like
1857                          * the beginning of an RPC message,
1858                          * and let them do fragment reassembly.
1859                          */
1860                         if (rpc_defragment)
1861                                 return TRUE;
1862                 }
1863         }
1864
1865         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1866                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1867
1868         if (tree) {
1869                 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1870                     FALSE);
1871                 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1872
1873                 if (is_tcp) {
1874                         show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
1875                             ipfd_head, pinfo);
1876                 }
1877         }
1878
1879         xid      = tvb_get_ntohl(tvb, offset + 0);
1880         if (rpc_tree) {
1881                 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1882                         offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1883         }
1884
1885         msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1886         if (rpc_tree) {
1887                 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1888                         offset+4, 4, msg_type);
1889                 proto_item_append_text(rpc_item, ", Type:%s XID:0x%08x", msg_type_name, xid);
1890         }
1891
1892         offset += 8;
1893
1894         switch (msg_type) {
1895
1896         case RPC_CALL:
1897                 /* we know already the proto-entry, the ETT-const,
1898                    and "rpc_prog" */
1899                 proto = rpc_prog->proto;
1900                 proto_id = rpc_prog->proto_id;
1901                 ett = rpc_prog->ett;
1902                 progname = rpc_prog->progname;
1903
1904                 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1905                 if (rpc_tree) {
1906                         proto_tree_add_uint(rpc_tree,
1907                                 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1908                 }
1909
1910                 prog = tvb_get_ntohl(tvb, offset + 4);
1911
1912                 if (rpc_tree) {
1913                         proto_tree_add_uint_format(rpc_tree,
1914                                 hf_rpc_program, tvb, offset+4, 4, prog,
1915                                 "Program: %s (%u)", progname, prog);
1916                 }
1917
1918                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1919                         /* Set the protocol name to the underlying
1920                            program name. */
1921                         col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1922                 }
1923
1924                 vers = tvb_get_ntohl(tvb, offset+8);
1925                 if (rpc_tree) {
1926                         proto_tree_add_uint(rpc_tree,
1927                                 hf_rpc_programversion, tvb, offset+8, 4, vers);
1928                 }
1929
1930                 proc = tvb_get_ntohl(tvb, offset+12);
1931
1932                 key.prog = prog;
1933                 key.vers = vers;
1934                 key.proc = proc;
1935
1936                 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1937                         dissect_function = value->dissect_call;
1938                         procname = value->name;
1939                 }
1940                 else {
1941                         /* happens only with strange program versions or
1942                            non-existing dissectors */
1943 #if 0
1944                         dissect_function = NULL;
1945 #endif
1946                         sprintf(procname_static, "proc-%u", proc);
1947                         procname = procname_static;
1948                 }
1949
1950                 /* Check for RPCSEC_GSS and AUTH_GSSAPI */
1951                 if (tvb_bytes_exist(tvb, offset+16, 4)) {
1952                         switch (tvb_get_ntohl(tvb, offset+16)) {
1953
1954                         case RPCSEC_GSS:
1955                                 /*
1956                                  * It's GSS-API authentication...
1957                                  */
1958                                 if (tvb_bytes_exist(tvb, offset+28, 8)) {
1959                                         /*
1960                                          * ...and we have the procedure
1961                                          * and service information for it.
1962                                          */
1963                                         flavor = FLAVOR_GSSAPI;
1964                                         gss_proc = tvb_get_ntohl(tvb, offset+28);
1965                                         gss_svc = tvb_get_ntohl(tvb, offset+36);
1966                                 } else {
1967                                         /*
1968                                          * ...but the procedure and service
1969                                          * information isn't available.
1970                                          */
1971                                         flavor = FLAVOR_GSSAPI_NO_INFO;
1972                                 }
1973                                 break;
1974
1975                         case AUTH_GSSAPI:
1976                                 /*
1977                                  * AUTH_GSSAPI flavor.  If auth_msg is TRUE,
1978                                  * then this is an AUTH_GSSAPI message and
1979                                  * not an application level message.
1980                                  */
1981                                 if (tvb_bytes_exist(tvb, offset+28, 4)) {
1982                                         if (tvb_get_ntohl(tvb, offset+28)) {
1983                                                 flavor = FLAVOR_AUTHGSSAPI_MSG;
1984                                                 gss_proc = proc;
1985                                                 procname =
1986                                                     match_strval(gss_proc,
1987                                                     rpc_authgssapi_proc);
1988                                         } else {
1989                                                 flavor = FLAVOR_AUTHGSSAPI;
1990                                         }
1991                                 }
1992                                 break;
1993
1994                         default:
1995                                 /*
1996                                  * It's not GSS-API authentication.
1997                                  */
1998                                 flavor = FLAVOR_NOT_GSSAPI;
1999                                 break;
2000                         }
2001                 }
2002
2003                 if (rpc_tree) {
2004                         proto_tree_add_uint_format(rpc_tree,
2005                                 hf_rpc_procedure, tvb, offset+12, 4, proc,
2006                                 "Procedure: %s (%u)", procname, proc);
2007                 }
2008
2009                 if (check_col(pinfo->cinfo, COL_INFO)) {
2010                         if (first_pdu)
2011                                 col_clear(pinfo->cinfo, COL_INFO);
2012                         else
2013                                 col_append_fstr(pinfo->cinfo, COL_INFO, "  ; ");
2014                         col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2015                                 vers,
2016                                 procname,
2017                                 msg_type_name);
2018                 }
2019
2020                 /* Keep track of the address whence the call came, and the
2021                    port to which the call is being sent, so that we can
2022                    match up calls with replies.
2023
2024                    If the transport is connection-oriented (we check, for
2025                    now, only for "pinfo->ptype" of PT_TCP), we also take
2026                    into account the port from which the call was sent
2027                    and the address to which the call was sent, because
2028                    the addresses and ports of the two endpoints should be
2029                    the same for all calls and replies.  (XXX - what if
2030                    the connection is broken and re-established?)
2031
2032                    If the transport is connectionless, we don't worry
2033                    about the address to which the call was sent and from
2034                    which the reply was sent, because there's no
2035                    guarantee that the reply will come from the address
2036                    to which the call was sent.  We also don't worry about
2037                    the port *from* which the call was sent and *to* which
2038                    the reply was sent, because some clients (*cough* OS X
2039                    NFS client *cough) might send retransmissions from a
2040                    different port from the original request. */
2041                 if (pinfo->ptype == PT_TCP) {
2042                         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
2043                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
2044                             pinfo->destport, 0);
2045                 } else {
2046                         /*
2047                          * XXX - you currently still have to pass a non-null
2048                          * pointer for the second address argument even
2049                          * if you use NO_ADDR_B.
2050                          */
2051                         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
2052                             &null_address, pinfo->ptype, pinfo->destport,
2053                             0, NO_ADDR_B|NO_PORT_B);
2054                 }
2055                 if (conversation == NULL) {
2056                         /* It's not part of any conversation - create a new
2057                            one. */
2058                         if (pinfo->ptype == PT_TCP) {
2059                                 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
2060                                     &pinfo->dst, pinfo->ptype, pinfo->srcport,
2061                                     pinfo->destport, 0);
2062                         } else {
2063                                 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
2064                                     &null_address, pinfo->ptype, pinfo->destport,
2065                                     0, NO_ADDR2|NO_PORT2);
2066                         }
2067                 }
2068
2069                 /* Make the dissector for this conversation the non-heuristic
2070                    RPC dissector. */
2071                 conversation_set_dissector(conversation,
2072                         (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
2073
2074                 /* prepare the key data */
2075                 rpc_call_key.xid = xid;
2076                 rpc_call_key.conversation = conversation;
2077
2078                 /* look up the request */
2079                 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
2080                 if (rpc_call) {
2081                         /* We've seen a request with this XID, with the same
2082                            source and destination, before - but was it
2083                            *this* request? */
2084                         if (pinfo->fd->num != rpc_call->req_num) {
2085                                 /* No, so it's a duplicate request.
2086                                    Mark it as such. */
2087                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2088                                         col_prepend_fstr(pinfo->cinfo, COL_INFO,
2089                                                 "[RPC retransmission of #%d]", rpc_call->req_num);
2090                                 }
2091                                 proto_tree_add_item(rpc_tree,
2092                                         hf_rpc_dup, tvb, 0,0, TRUE);
2093                                 proto_tree_add_uint(rpc_tree,
2094                                         hf_rpc_call_dup, tvb, 0,0, rpc_call->req_num);
2095                         }
2096                         if(rpc_call->rep_num){
2097                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2098                                         col_append_fstr(pinfo->cinfo, COL_INFO," (Reply In %d)", rpc_call->rep_num);
2099                                 }
2100                         }
2101                 } else {
2102                         /* Prepare the value data.
2103                            "req_num" and "rep_num" are frame numbers;
2104                            frame numbers are 1-origin, so we use 0
2105                            to mean "we don't yet know in which frame
2106                            the reply for this call appears". */
2107                         new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
2108                         *new_rpc_call_key = rpc_call_key;
2109                         rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
2110                         rpc_call->req_num = pinfo->fd->num;
2111                         rpc_call->rep_num = 0;
2112                         rpc_call->prog = prog;
2113                         rpc_call->vers = vers;
2114                         rpc_call->proc = proc;
2115                         rpc_call->private_data = NULL;
2116                         rpc_call->xid = xid;
2117                         rpc_call->flavor = flavor;
2118                         rpc_call->gss_proc = gss_proc;
2119                         rpc_call->gss_svc = gss_svc;
2120                         rpc_call->proc_info = value;
2121                         rpc_call->req_time.secs=pinfo->fd->abs_secs;
2122                         rpc_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
2123
2124                         /* store it */
2125                         g_hash_table_insert(rpc_calls, new_rpc_call_key,
2126                             rpc_call);
2127                 }
2128
2129                 if(rpc_call && rpc_call->rep_num){
2130                         proto_tree_add_uint_format(rpc_tree, hf_rpc_repframe,
2131                             tvb, 0, 0, rpc_call->rep_num,
2132                             "The reply to this request is in frame %u",
2133                             rpc_call->rep_num);
2134                 }
2135
2136                 offset += 16;
2137
2138                 offset = dissect_rpc_cred(tvb, rpc_tree, offset);
2139                 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2140
2141                 /* pass rpc_info to subdissectors */
2142                 rpc_call->request=TRUE;
2143                 pinfo->private_data=rpc_call;
2144
2145                 /* go to the next dissector */
2146
2147                 break;  /* end of RPC call */
2148
2149         case RPC_REPLY:
2150                 /* we know already the type from the calling routine,
2151                    and we already have "rpc_call" set above. */
2152                 prog = rpc_call->prog;
2153                 vers = rpc_call->vers;
2154                 proc = rpc_call->proc;
2155                 flavor = rpc_call->flavor;
2156                 gss_proc = rpc_call->gss_proc;
2157                 gss_svc = rpc_call->gss_svc;
2158
2159                 if (rpc_call->proc_info != NULL) {
2160                         dissect_function = rpc_call->proc_info->dissect_reply;
2161                         if (rpc_call->proc_info->name != NULL) {
2162                                 procname = rpc_call->proc_info->name;
2163                         }
2164                         else {
2165                                 sprintf(procname_static, "proc-%u", proc);
2166                                 procname = procname_static;
2167                         }
2168                 }
2169                 else {
2170 #if 0
2171                         dissect_function = NULL;
2172 #endif
2173                         sprintf(procname_static, "proc-%u", proc);
2174                         procname = procname_static;
2175                 }
2176
2177                 /*
2178                  * If this is an AUTH_GSSAPI message, then the RPC procedure
2179                  * is not an application procedure, but rather an auth level
2180                  * procedure, so it would be misleading to print the RPC
2181                  * procname.  Replace the RPC procname with the corresponding
2182                  * AUTH_GSSAPI procname.
2183                  */
2184                 if (flavor == FLAVOR_AUTHGSSAPI_MSG) {
2185                         procname = match_strval(gss_proc, rpc_authgssapi_proc);
2186                 }
2187
2188                 rpc_prog_key.prog = prog;
2189                 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
2190                         proto = NULL;
2191                         proto_id = 0;
2192                         ett = 0;
2193                         progname = "Unknown";
2194                 }
2195                 else {
2196                         proto = rpc_prog->proto;
2197                         proto_id = rpc_prog->proto_id;
2198                         ett = rpc_prog->ett;
2199                         progname = rpc_prog->progname;
2200
2201                         if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2202                                 /* Set the protocol name to the underlying
2203                                    program name. */
2204                                 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
2205                         }
2206                 }
2207
2208                 if (check_col(pinfo->cinfo, COL_INFO)) {
2209                         if (first_pdu)
2210                                 col_clear(pinfo->cinfo, COL_INFO);
2211                         else
2212                                 col_append_fstr(pinfo->cinfo, COL_INFO, "  ; ");
2213                         col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2214                                 vers,
2215                                 procname,
2216                                 msg_type_name);
2217                 }
2218
2219                 if (rpc_tree) {
2220                         proto_tree_add_uint_format(rpc_tree,
2221                                 hf_rpc_program, tvb, 0, 0, prog,
2222                                 "Program: %s (%u)", progname, prog);
2223                         proto_tree_add_uint(rpc_tree,
2224                                 hf_rpc_programversion, tvb, 0, 0, vers);
2225                         proto_tree_add_uint_format(rpc_tree,
2226                                 hf_rpc_procedure, tvb, 0, 0, proc,
2227                                 "Procedure: %s (%u)", procname, proc);
2228                 }
2229
2230                 reply_state = tvb_get_ntohl(tvb,offset+0);
2231                 if (rpc_tree) {
2232                         proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
2233                                 offset+0, 4, reply_state);
2234                 }
2235                 offset += 4;
2236
2237                 /* Indicate the frame to which this is a reply. */
2238                 if(rpc_call && rpc_call->req_num){
2239                         proto_tree_add_uint_format(rpc_tree, hf_rpc_reqframe,
2240                             tvb, 0, 0, rpc_call->req_num,
2241                             "This is a reply to a request in frame %u",
2242                             rpc_call->req_num);
2243                         ns.secs= pinfo->fd->abs_secs-rpc_call->req_time.secs;
2244                         ns.nsecs=pinfo->fd->abs_usecs*1000-rpc_call->req_time.nsecs;
2245                         if(ns.nsecs<0){
2246                                 ns.nsecs+=1000000000;
2247                                 ns.secs--;
2248                         }
2249                         proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
2250                                 &ns);
2251
2252                         if (check_col(pinfo->cinfo, COL_INFO)) {
2253                                 col_append_fstr(pinfo->cinfo, COL_INFO," (Call In %d)", rpc_call->req_num);
2254                         }
2255                 }
2256
2257
2258                 if ((!rpc_call) || (rpc_call->rep_num == 0)) {
2259                         /* We have not yet seen a reply to that call, so
2260                            this must be the first reply; remember its
2261                            frame number. */
2262                         rpc_call->rep_num = pinfo->fd->num;
2263                 } else {
2264                         /* We have seen a reply to this call - but was it
2265                            *this* reply? */
2266                         if (rpc_call->rep_num != pinfo->fd->num) {
2267                                 /* No, so it's a duplicate reply.
2268                                    Mark it as such. */
2269                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2270                                         col_prepend_fstr(pinfo->cinfo, COL_INFO,
2271                                                 "[RPC duplicate of #%d]", rpc_call->rep_num);
2272                                 }
2273                                 proto_tree_add_item(rpc_tree,
2274                                         hf_rpc_dup, tvb, 0,0, TRUE);
2275                                 proto_tree_add_uint(rpc_tree,
2276                                         hf_rpc_reply_dup, tvb, 0,0, rpc_call->rep_num);
2277                         }
2278                 }
2279
2280                 switch (reply_state) {
2281
2282                 case MSG_ACCEPTED:
2283                         offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2284                         accept_state = tvb_get_ntohl(tvb,offset+0);
2285                         if (rpc_tree) {
2286                                 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
2287                                         offset+0, 4, accept_state);
2288                         }
2289                         offset += 4;
2290                         switch (accept_state) {
2291
2292                         case SUCCESS:
2293                                 /* go to the next dissector */
2294                                 break;
2295
2296                         case PROG_MISMATCH:
2297                                 vers_low = tvb_get_ntohl(tvb,offset+0);
2298                                 vers_high = tvb_get_ntohl(tvb,offset+4);
2299                                 if (rpc_tree) {
2300                                         proto_tree_add_uint(rpc_tree,
2301                                                 hf_rpc_programversion_min,
2302                                                 tvb, offset+0, 4, vers_low);
2303                                         proto_tree_add_uint(rpc_tree,
2304                                                 hf_rpc_programversion_max,
2305                                                 tvb, offset+4, 4, vers_high);
2306                                 }
2307                                 offset += 8;
2308
2309                                 /*
2310                                  * There's no protocol reply, so don't
2311                                  * try to dissect it.
2312                                  */
2313                                 dissect_rpc = FALSE;
2314                                 break;
2315
2316                         default:
2317                                 /*
2318                                  * There's no protocol reply, so don't
2319                                  * try to dissect it.
2320                                  */
2321                                 dissect_rpc = FALSE;
2322                                 break;
2323                         }
2324                         break;
2325
2326                 case MSG_DENIED:
2327                         reject_state = tvb_get_ntohl(tvb,offset+0);
2328                         if (rpc_tree) {
2329                                 proto_tree_add_uint(rpc_tree,
2330                                         hf_rpc_state_reject, tvb, offset+0, 4,
2331                                         reject_state);
2332                         }
2333                         offset += 4;
2334
2335                         if (reject_state==RPC_MISMATCH) {
2336                                 vers_low = tvb_get_ntohl(tvb,offset+0);
2337                                 vers_high = tvb_get_ntohl(tvb,offset+4);
2338                                 if (rpc_tree) {
2339                                         proto_tree_add_uint(rpc_tree,
2340                                                 hf_rpc_version_min,
2341                                                 tvb, offset+0, 4, vers_low);
2342                                         proto_tree_add_uint(rpc_tree,
2343                                                 hf_rpc_version_max,
2344                                                 tvb, offset+4, 4, vers_high);
2345                                 }
2346                                 offset += 8;
2347                         } else if (reject_state==AUTH_ERROR) {
2348                                 auth_state = tvb_get_ntohl(tvb,offset+0);
2349                                 if (rpc_tree) {
2350                                         proto_tree_add_uint(rpc_tree,
2351                                                 hf_rpc_state_auth, tvb, offset+0, 4,
2352                                                 auth_state);
2353                                 }
2354                                 offset += 4;
2355                         }
2356
2357                         /*
2358                          * There's no protocol reply, so don't
2359                          * try to dissect it.
2360                          */
2361                         dissect_rpc = FALSE;
2362                         break;
2363
2364                 default:
2365                         /*
2366                          * This isn't a valid reply state, so we have
2367                          * no clue what's going on; don't try to dissect
2368                          * the protocol reply.
2369                          */
2370                         dissect_rpc = FALSE;
2371                         break;
2372                 }
2373                 break; /* end of RPC reply */
2374
2375         default:
2376                 /*
2377                  * The switch statement at the top returned if
2378                  * this was neither an RPC call nor a reply.
2379                  */
2380                 g_assert_not_reached();
2381         }
2382
2383         /* now we know, that RPC was shorter */
2384         if (rpc_item) {
2385                 proto_item_set_end(rpc_item, tvb, offset);
2386         }
2387
2388         if (!dissect_rpc) {
2389                 /*
2390                  * There's no RPC call or reply here; just dissect
2391                  * whatever's left as data.
2392                  */
2393                 call_dissector(data_handle,
2394                     tvb_new_subset(tvb, offset, -1, -1), pinfo, rpc_tree);
2395                 return TRUE;
2396         }
2397
2398         /* create here the program specific sub-tree */
2399         if (tree && (flavor != FLAVOR_AUTHGSSAPI_MSG)) {
2400                 pitem = proto_tree_add_item(tree, proto_id, tvb, offset, -1,
2401                     FALSE);
2402                 if (pitem) {
2403                         ptree = proto_item_add_subtree(pitem, ett);
2404                 }
2405
2406                 if (ptree) {
2407                         proto_tree_add_uint(ptree,
2408                                 hf_rpc_programversion, tvb, 0, 0, vers);
2409                         if (rpc_prog->procedure_hfs->len > vers)
2410                                 procedure_hf = g_array_index(rpc_prog->procedure_hfs, int, vers);
2411                         else {
2412                                 /*
2413                                  * No such element in the GArray.
2414                                  */
2415                                 procedure_hf = 0;
2416                         }
2417                         if (procedure_hf != 0 && procedure_hf != -1) {
2418                                 proto_tree_add_uint(ptree,
2419                                         procedure_hf, tvb, 0, 0, proc);
2420                         } else {
2421                                 proto_tree_add_uint_format(ptree,
2422                                         hf_rpc_procedure, tvb, 0, 0, proc,
2423                                         "Procedure: %s (%u)", procname, proc);
2424                         }
2425                 }
2426         }
2427
2428         /* we must queue this packet to the tap system before we actually
2429            call the subdissectors since short packets (i.e. nfs read reply)
2430            will cause an exception and execution would never reach the call
2431            to tap_queue_packet() in that case
2432         */
2433         tap_queue_packet(rpc_tap, pinfo, rpc_call);
2434
2435         /* proto==0 if this is an unknown program */
2436         if( (proto==0) || !proto_is_protocol_enabled(proto)){
2437                 dissect_function = NULL;
2438         }
2439
2440         /*
2441          * Handle RPCSEC_GSS and AUTH_GSSAPI specially.
2442          */
2443         switch (flavor) {
2444
2445         case FLAVOR_UNKNOWN:
2446                 /*
2447                  * We don't know the authentication flavor, so we can't
2448                  * dissect the payload.
2449                  */
2450                 proto_tree_add_text(ptree, tvb, offset, -1,
2451                     "Unknown authentication flavor - cannot dissect");
2452                 return TRUE;
2453
2454         case FLAVOR_NOT_GSSAPI:
2455                 /*
2456                  * It's not GSS-API authentication.  Just dissect the
2457                  * payload.
2458                  */
2459                 offset = call_dissect_function(tvb, pinfo, ptree, offset,
2460                                 dissect_function, progname);
2461                 break;
2462
2463         case FLAVOR_GSSAPI_NO_INFO:
2464                 /*
2465                  * It's GSS-API authentication, but we don't have the
2466                  * procedure and service information, so we can't dissect
2467                  * the payload.
2468                  */
2469                 proto_tree_add_text(ptree, tvb, offset, -1,
2470                     "GSS-API authentication, but procedure and service unknown - cannot dissect");
2471                 return TRUE;
2472
2473         case FLAVOR_GSSAPI:
2474                 /*
2475                  * It's GSS-API authentication, and we have the procedure
2476                  * and service information; process the GSS-API stuff,
2477                  * and process the payload if there is any.
2478                  */
2479                 switch (gss_proc) {
2480
2481                 case RPCSEC_GSS_INIT:
2482                 case RPCSEC_GSS_CONTINUE_INIT:
2483                         if (msg_type == RPC_CALL) {
2484                                 offset = dissect_rpc_authgss_initarg(tvb,
2485                                         ptree, offset, pinfo);
2486                         }
2487                         else {
2488                                 offset = dissect_rpc_authgss_initres(tvb,
2489                                         ptree, offset, pinfo);
2490                         }
2491                         break;
2492
2493                 case RPCSEC_GSS_DATA:
2494                         if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2495                                 offset = call_dissect_function(tvb,
2496                                                 pinfo, ptree, offset,
2497                                                 dissect_function,
2498                                                 progname);
2499                         }
2500                         else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2501                                 offset = dissect_rpc_authgss_integ_data(tvb,
2502                                                 pinfo, ptree, offset,
2503                                                 dissect_function,
2504                                                 progname);
2505                         }
2506                         else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2507                                 offset = dissect_rpc_authgss_priv_data(tvb,
2508                                                 ptree, offset);
2509                         }
2510                         break;
2511
2512                 default:
2513                         break;
2514                 }
2515                 break;
2516
2517         case FLAVOR_AUTHGSSAPI_MSG:
2518                 /*
2519                  * This is an AUTH_GSSAPI message.  It contains data
2520                  * only for the authentication procedure and not for the
2521                  * application level RPC procedure.  Reset the column
2522                  * protocol and info fields to indicate that this is
2523                  * an RPC auth level message, then process the args.
2524                  */
2525                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2526                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
2527                 }
2528                 if (check_col(pinfo->cinfo, COL_INFO)) {
2529                         col_clear(pinfo->cinfo, COL_INFO);
2530                         col_append_fstr(pinfo->cinfo, COL_INFO,
2531                             "%s %s XID 0x%x",
2532                             match_strval(gss_proc, rpc_authgssapi_proc),
2533                             msg_type_name, xid);
2534                 }
2535
2536                 switch (gss_proc) {
2537
2538                 case AUTH_GSSAPI_INIT:
2539                 case AUTH_GSSAPI_CONTINUE_INIT:
2540                 case AUTH_GSSAPI_MSG:
2541                         if (msg_type == RPC_CALL) {
2542                             offset = dissect_rpc_authgssapi_initarg(tvb, 
2543                                 rpc_tree, offset, pinfo);
2544                         } else {
2545                             offset = dissect_rpc_authgssapi_initres(tvb, 
2546                                 rpc_tree, offset, pinfo);
2547                         }
2548                         break;
2549
2550                 case AUTH_GSSAPI_DESTROY:
2551                         offset = dissect_rpc_data(tvb, rpc_tree,
2552                             hf_rpc_authgss_data, offset);
2553                         break;
2554
2555                 case AUTH_GSSAPI_EXIT:
2556                         break;
2557                 }
2558
2559                 /* Adjust the length to account for the auth message. */
2560                 if (rpc_item) {
2561                         proto_item_set_end(rpc_item, tvb, offset);
2562                 }
2563                 break;
2564
2565         case FLAVOR_AUTHGSSAPI:
2566                 /*
2567                  * An RPC with AUTH_GSSAPI authentication.  The data
2568                  * portion is always private, so don't call the dissector.
2569                  */
2570                 offset = dissect_auth_gssapi_data(tvb, ptree, offset);
2571                 break;
2572         }
2573
2574         if (tvb_length_remaining(tvb, offset) > 0) {  
2575           /* 
2576            * dissect any remaining bytes (incomplete dissection) as pure 
2577            * data in the ptree 
2578            */
2579
2580           call_dissector(data_handle,
2581               tvb_new_subset(tvb, offset, -1, -1), pinfo, ptree);
2582         }
2583
2584         /* XXX this should really loop over all fhandles registred for the frame */
2585         if(nfs_fhandle_reqrep_matching){
2586                 nfs_fhandle_data_t *fhd;
2587                 switch (msg_type) {
2588                 case RPC_CALL:
2589                         if(rpc_call && rpc_call->rep_num){
2590                                 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2591                                         nfs_fhandle_frame_table,
2592                                         GINT_TO_POINTER(rpc_call->rep_num));
2593                                 if(fhd){
2594                                         dissect_fhandle_hidden(pinfo,
2595                                                 ptree, fhd);
2596                                 }
2597                         }
2598                         break;
2599                 case RPC_REPLY:
2600                         if(rpc_call && rpc_call->req_num){
2601                                 fhd=(nfs_fhandle_data_t *)g_hash_table_lookup(
2602                                         nfs_fhandle_frame_table,
2603                                         GINT_TO_POINTER(rpc_call->req_num));
2604                                 if(fhd){
2605                                         dissect_fhandle_hidden(pinfo,
2606                                                 ptree, fhd);
2607                                 }
2608                         }
2609                         break;
2610                 }
2611         }
2612
2613         return TRUE;
2614 }
2615
2616 static gboolean
2617 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2618 {
2619         return dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2620             TRUE);
2621 }
2622
2623 static void
2624 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2625 {
2626         if (!dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2627             TRUE)) {
2628                 if (tvb_length(tvb) != 0)
2629                         dissect_rpc_continuation(tvb, pinfo, tree);
2630         }
2631 }
2632
2633
2634 /* Defragmentation of RPC-over-TCP records */
2635 /* table to hold defragmented RPC records */
2636 static GHashTable *rpc_fragment_table = NULL;
2637
2638 static GHashTable *rpc_reassembly_table = NULL;
2639 static GMemChunk *rpc_fragment_key_chunk = NULL;
2640 static int rpc_fragment_init_count = 200;
2641
2642 typedef struct _rpc_fragment_key {
2643         guint32 conv_id;
2644         guint32 seq;
2645         guint32 offset;
2646         /* xxx */
2647         guint32 start_seq;
2648 } rpc_fragment_key;
2649
2650 static guint
2651 rpc_fragment_hash(gconstpointer k)
2652 {
2653         const rpc_fragment_key *key = (const rpc_fragment_key *)k;
2654
2655         return key->conv_id + key->seq;
2656 }
2657
2658 static gint
2659 rpc_fragment_equal(gconstpointer k1, gconstpointer k2)
2660 {
2661         const rpc_fragment_key *key1 = (const rpc_fragment_key *)k1;
2662         const rpc_fragment_key *key2 = (const rpc_fragment_key *)k2;
2663
2664         return key1->conv_id == key2->conv_id &&
2665             key1->seq == key2->seq;
2666 }
2667
2668 static void
2669 show_rpc_fragheader(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2670 {
2671         proto_item *hdr_item;
2672         proto_tree *hdr_tree;
2673         guint32 fraglen;
2674
2675         if (tree) {
2676                 fraglen = rpc_rm & RPC_RM_FRAGLEN;
2677
2678                 hdr_item = proto_tree_add_text(tree, tvb, 0, 4,
2679                     "Fragment header: %s%u %s",
2680                     (rpc_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
2681                     fraglen, plurality(fraglen, "byte", "bytes"));
2682                 hdr_tree = proto_item_add_subtree(hdr_item, ett_rpc_fraghdr);
2683
2684                 proto_tree_add_boolean(hdr_tree, hf_rpc_lastfrag, tvb, 0, 4,
2685                     rpc_rm);
2686                 proto_tree_add_uint(hdr_tree, hf_rpc_fraglen, tvb, 0, 4,
2687                     rpc_rm);
2688         }
2689 }
2690
2691 static void
2692 show_rpc_fragment(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2693 {
2694         if (tree) {
2695                 /*
2696                  * Show the fragment header and the data for the fragment.
2697                  */
2698                 show_rpc_fragheader(tvb, tree, rpc_rm);
2699                 proto_tree_add_text(tree, tvb, 4, -1, "Fragment Data");
2700         }
2701 }
2702
2703 static void
2704 make_frag_tree(tvbuff_t *tvb, proto_tree *tree, int proto, gint ett,
2705     guint32 rpc_rm)
2706 {
2707         proto_item *frag_item;
2708         proto_tree *frag_tree;
2709
2710         if (tree == NULL)
2711                 return;         /* nothing to do */
2712
2713         frag_item = proto_tree_add_protocol_format(tree, proto, tvb, 0, -1,
2714             "%s Fragment", proto_get_protocol_name(proto));
2715         frag_tree = proto_item_add_subtree(frag_item, ett);
2716         show_rpc_fragment(tvb, frag_tree, rpc_rm);
2717 }
2718
2719 void
2720 show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
2721     guint32 rpc_rm, fragment_data *ipfd_head, packet_info *pinfo)
2722 {
2723         if (tree == NULL)
2724                 return;         /* don't do any work */
2725
2726         if (tvb != frag_tvb) {
2727                 /*
2728                  * This message was not all in one fragment,
2729                  * so show the fragment header *and* the data
2730                  * for the fragment (which is the last fragment),
2731                  * and a tree with information about all fragments.
2732                  */
2733                 show_rpc_fragment(frag_tvb, tree, rpc_rm);
2734
2735                 /*
2736                  * Show a tree with information about all fragments.
2737                  */
2738                 show_fragment_tree(ipfd_head, &rpc_frag_items, tree, pinfo, tvb);
2739         } else {
2740                 /*
2741                  * This message was all in one fragment, so just show
2742                  * the fragment header.
2743                  */
2744                 show_rpc_fragheader(tvb, tree, rpc_rm);
2745         }
2746 }
2747
2748 static gboolean
2749 call_message_dissector(tvbuff_t *tvb, tvbuff_t *rec_tvb, packet_info *pinfo,
2750     proto_tree *tree, tvbuff_t *frag_tvb, rec_dissector_t dissector,
2751     fragment_data *ipfd_head, guint32 rpc_rm, gboolean first_pdu)
2752 {
2753         const char *saved_proto;
2754         volatile gboolean rpc_succeeded;
2755
2756         /*
2757          * Catch the ReportedBoundsError exception; if
2758          * this particular message happens to get a
2759          * ReportedBoundsError exception, that doesn't
2760          * mean that we should stop dissecting RPC
2761          * messages within this frame or chunk of
2762          * reassembled data.
2763          *
2764          * If it gets a BoundsError, we can stop, as there's
2765          * nothing more to see, so we just re-throw it.
2766          */
2767         saved_proto = pinfo->current_proto;
2768         rpc_succeeded = FALSE;
2769         TRY {
2770                 rpc_succeeded = (*dissector)(rec_tvb, pinfo, tree,
2771                     frag_tvb, ipfd_head, TRUE, rpc_rm, first_pdu);
2772         }
2773         CATCH(BoundsError) {
2774                 RETHROW;
2775         }
2776         CATCH(ReportedBoundsError) {
2777                 show_reported_bounds_error(tvb, pinfo, tree);
2778                 pinfo->current_proto = saved_proto;
2779
2780                 /*
2781                  * We treat this as a "successful" dissection of
2782                  * an RPC packet, as "dissect_rpc_message()"
2783                  * *did* decide it was an RPC packet, throwing
2784                  * an exception while dissecting it as such.
2785                  */
2786                 rpc_succeeded = TRUE;
2787         }
2788         ENDTRY;
2789         return rpc_succeeded;
2790 }
2791
2792 int
2793 dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
2794     proto_tree *tree, rec_dissector_t dissector, gboolean is_heur,
2795     int proto, int ett, gboolean defragment, gboolean first_pdu)
2796 {
2797         struct tcpinfo *tcpinfo = pinfo->private_data;
2798         guint32 seq = tcpinfo->seq + offset;
2799         guint32 rpc_rm;
2800         volatile gint32 len;
2801         gint32 seglen;
2802         gint tvb_len, tvb_reported_len;
2803         tvbuff_t *frag_tvb;
2804         gboolean rpc_succeeded;
2805         gboolean save_fragmented;
2806         rpc_fragment_key old_rfk, *rfk, *new_rfk;
2807         conversation_t *conversation;
2808         fragment_data *ipfd_head;
2809         tvbuff_t *rec_tvb;
2810
2811         /*
2812          * Get the record mark.
2813          */
2814         if (!tvb_bytes_exist(tvb, offset, 4)) {
2815                 /*
2816                  * XXX - we should somehow arrange to handle
2817                  * a record mark split across TCP segments.
2818                  */
2819                 return 0;       /* not enough to tell if it's valid */
2820         }
2821         rpc_rm = tvb_get_ntohl(tvb, offset);
2822
2823         len = rpc_rm & RPC_RM_FRAGLEN;
2824
2825         /*
2826          * Do TCP desegmentation, if enabled.
2827          *
2828          * reject fragments bigger than this preference setting.
2829          * This is arbitrary, but should at least prevent
2830          * some crashes from either packets with really
2831          * large RPC-over-TCP fragments or from stuff that's
2832          * not really valid for this protocol.
2833          */
2834         if (len > max_rpc_tcp_pdu_size)
2835                 return 0;       /* pretend it's not valid */
2836         if (rpc_desegment) {
2837                 seglen = tvb_length_remaining(tvb, offset + 4);
2838
2839                 if (len > seglen && pinfo->can_desegment) {
2840                         /*
2841                          * This frame doesn't have all of the
2842                          * data for this message, but we can do
2843                          * reassembly on it.
2844                          *
2845                          * If this is a heuristic dissector, just
2846                          * return 0 - we don't want to try to get
2847                          * more data, as that's too likely to cause
2848                          * us to misidentify this as valid.
2849                          *
2850                          * XXX - this means that we won't
2851                          * recognize the first fragment of a
2852                          * multi-fragment RPC operation unless
2853                          * we've already identified this
2854                          * conversation as being an RPC
2855                          * conversation (and thus aren't running
2856                          * heuristically) - that would be a problem
2857                          * if, for example, the first segment were
2858                          * the beginning of a large NFS WRITE.
2859                          *
2860                          * If this isn't a heuristic dissector,
2861                          * we've already identified this conversation
2862                          * as containing data for this protocol, as we
2863                          * saw valid data in previous frames.  Try to
2864                          * get more data.
2865                          */
2866                         if (is_heur)
2867                                 return 0;       /* not valid */
2868                         else {
2869                                 pinfo->desegment_offset = offset;
2870                                 pinfo->desegment_len = len - seglen;
2871                                 return -((gint32) pinfo->desegment_len);
2872                         }
2873                 }
2874         }
2875         len += 4;       /* include record mark */
2876         tvb_len = tvb_length_remaining(tvb, offset);
2877         tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2878         if (tvb_len > len)
2879                 tvb_len = len;
2880         if (tvb_reported_len > len)
2881                 tvb_reported_len = len;
2882         frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2883             tvb_reported_len);
2884
2885         /*
2886          * If we're not defragmenting, just hand this to the
2887          * disssector.
2888          */
2889         if (!defragment) {
2890                 /*
2891                  * This is the first fragment we've seen, and it's also
2892                  * the last fragment; that means the record wasn't
2893                  * fragmented.  Hand the dissector the tvbuff for the
2894                  * fragment as the tvbuff for the record.
2895                  */
2896                 rec_tvb = frag_tvb;
2897                 ipfd_head = NULL;
2898
2899                 /*
2900                  * Mark this as fragmented, so if somebody throws an
2901                  * exception, we don't report it as a malformed frame.
2902                  */
2903                 save_fragmented = pinfo->fragmented;
2904                 pinfo->fragmented = TRUE;
2905                 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
2906                     tree, frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu);
2907                 pinfo->fragmented = save_fragmented;
2908                 if (!rpc_succeeded)
2909                         return 0;       /* not RPC */
2910                 return len;
2911         }
2912
2913         /*
2914          * First, we check to see if this fragment is part of a record
2915          * that we're in the process of defragmenting.
2916          *
2917          * The key is the conversation ID for the conversation to which
2918          * the packet belongs and the current sequence number.
2919          * We must first find the conversation and, if we don't find
2920          * one, create it.  We know this is running over TCP, so the
2921          * conversation should not wildcard either address or port.
2922          */
2923         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2924             pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2925         if (conversation == NULL) {
2926                 /*
2927                  * It's not part of any conversation - create a new one.
2928                  */
2929                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2930                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2931         }
2932         old_rfk.conv_id = conversation->index;
2933         old_rfk.seq = seq;
2934         rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
2935
2936         if (rfk == NULL) {
2937                 /*
2938                  * This fragment was not found in our table, so it doesn't
2939                  * contain a continuation of a higher-level PDU.
2940                  * Is it the last fragment?
2941                  */
2942                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2943                         /*
2944                          * This isn't the last fragment, so we don't
2945                          * have the complete record.
2946                          *
2947                          * It's the first fragment we've seen, so if
2948                          * it's truly the first fragment of the record,
2949                          * and it has enough data, the dissector can at
2950                          * least check whether it looks like a valid
2951                          * message, as it contains the start of the
2952                          * message.
2953                          *
2954                          * The dissector should not dissect anything
2955                          * if the "last fragment" flag isn't set in
2956                          * the record marker, so it shouldn't throw
2957                          * an exception.
2958                          */
2959                         if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
2960                             NULL, TRUE, rpc_rm, first_pdu))
2961                                 return 0;       /* not valid */
2962
2963                         /*
2964                          * OK, now start defragmentation with that
2965                          * fragment.  Add this fragment, and set up
2966                          * next packet/sequence number as well.
2967                          *
2968                          * We must remember this fragment.
2969                          */
2970
2971                         rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2972                         rfk->conv_id = conversation->index;
2973                         rfk->seq = seq;
2974                         rfk->offset = 0;
2975                         rfk->start_seq = seq;
2976                         g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
2977
2978                         /*
2979                          * Start defragmentation.
2980                          */
2981                         ipfd_head = fragment_add_multiple_ok(tvb, offset + 4,
2982                             pinfo, rfk->start_seq, rpc_fragment_table,
2983                             rfk->offset, len - 4, TRUE);
2984
2985                         /*
2986                          * Make sure that defragmentation isn't complete;
2987                          * it shouldn't be, as this is the first fragment
2988                          * we've seen, and the "last fragment" bit wasn't
2989                          * set on it.
2990                          */
2991                         g_assert(ipfd_head == NULL);
2992
2993                         new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2994                         new_rfk->conv_id = rfk->conv_id;
2995                         new_rfk->seq = seq + len;
2996                         new_rfk->offset = rfk->offset + len - 4;
2997                         new_rfk->start_seq = rfk->start_seq;
2998                         g_hash_table_insert(rpc_reassembly_table, new_rfk,
2999                             new_rfk);
3000
3001                         /*
3002                          * This is part of a fragmented record,
3003                          * but it's not the first part.
3004                          * Show it as a record marker plus data, under
3005                          * a top-level tree for this protocol.
3006                          */
3007                         make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
3008
3009                         /*
3010                          * No more processing need be done, as we don't
3011                          * have a complete record.
3012                          */
3013                         return len;
3014                 }
3015
3016                 /*
3017                  * This is the first fragment we've seen, and it's also
3018                  * the last fragment; that means the record wasn't
3019                  * fragmented.  Hand the dissector the tvbuff for the
3020                  * fragment as the tvbuff for the record.
3021                  */
3022                 rec_tvb = frag_tvb;
3023                 ipfd_head = NULL;
3024         } else {
3025                 /*
3026                  * OK, this fragment was found, which means it continues
3027                  * a record.  This means we must defragment it.
3028                  * Add it to the defragmentation lists.
3029                  */
3030                 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4, pinfo,
3031                     rfk->start_seq, rpc_fragment_table,
3032                     rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
3033
3034                 if (ipfd_head == NULL) {
3035                         /*
3036                          * fragment_add_multiple_ok() returned NULL.
3037                          * This means that defragmentation is not
3038                          * completed yet.
3039                          *
3040                          * We must add an entry to the hash table with
3041                          * the sequence number following this fragment
3042                          * as the starting sequence number, so that when
3043                          * we see that fragment we'll find that entry.
3044                          *
3045                          * XXX - as TCP stream data is not currently
3046                          * guaranteed to be provided in order to dissectors,
3047                          * RPC fragments aren't guaranteed to be provided
3048                          * in order, either.
3049                          */
3050                         new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
3051                         new_rfk->conv_id = rfk->conv_id;
3052                         new_rfk->seq = seq + len;
3053                         new_rfk->offset = rfk->offset + len - 4;
3054                         new_rfk->start_seq = rfk->start_seq;
3055                         g_hash_table_insert(rpc_reassembly_table, new_rfk,
3056                             new_rfk);
3057
3058                         /*
3059                          * This is part of a fragmented record,
3060                          * but it's not the first part.
3061                          * Show it as a record marker plus data, under
3062                          * a top-level tree for this protocol,
3063                          * but don't hand it to the dissector
3064                          */
3065                         make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3066
3067                         /*
3068                          * No more processing need be done, as we don't
3069                          * have a complete record.
3070                          */
3071                         return len;
3072                 }
3073
3074                 /*
3075                  * It's completely defragmented.
3076                  *
3077                  * We only call subdissector for the last fragment.
3078                  * XXX - this assumes in-order delivery of RPC
3079                  * fragments, which requires in-order delivery of TCP
3080                  * segments.
3081                  */
3082                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
3083                         /*
3084                          * Well, it's defragmented, but this isn't
3085                          * the last fragment; this probably means
3086                          * this isn't the first pass, so we don't
3087                          * need to start defragmentation.
3088                          *
3089                          * This is part of a fragmented record,
3090                          * but it's not the first part.
3091                          * Show it as a record marker plus data, under
3092                          * a top-level tree for this protocol,
3093                          * but don't show it to the dissector.
3094                          */
3095                         make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3096
3097                         /*
3098                          * No more processing need be done, as we
3099                          * only disssect the data with the last
3100                          * fragment.
3101                          */
3102                         return len;
3103                 }
3104
3105                 /*
3106                  * OK, this is the last segment.
3107                  * Create a tvbuff for the defragmented
3108                  * record.
3109                  */
3110
3111                 /*
3112                  * Create a new TVB structure for
3113                  * defragmented data.
3114                  */
3115                 rec_tvb = tvb_new_real_data(ipfd_head->data,
3116                     ipfd_head->datalen, ipfd_head->datalen);
3117
3118                 /*
3119                  * Add this tvb as a child to the original
3120                  * one.
3121                  */
3122                 tvb_set_child_real_data_tvbuff(tvb, rec_tvb);
3123
3124                 /*
3125                  * Add defragmented data to the data source list.
3126                  */
3127                 add_new_data_source(pinfo, rec_tvb, "Defragmented");
3128         }
3129
3130         /*
3131          * We have something to hand to the RPC message
3132          * dissector.
3133          */
3134         if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
3135             frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu))
3136                 return 0;       /* not RPC */
3137         return len;
3138 }
3139
3140 /*
3141  * Can return:
3142  *
3143  *      NEED_MORE_DATA, if we don't have enough data to dissect anything;
3144  *
3145  *      IS_RPC, if we dissected at least one message in its entirety
3146  *      as RPC;
3147  *
3148  *      IS_NOT_RPC, if we found no RPC message.
3149  */
3150 typedef enum {
3151         NEED_MORE_DATA,
3152         IS_RPC,
3153         IS_NOT_RPC
3154 } rpc_tcp_return_t;
3155
3156 static rpc_tcp_return_t
3157 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3158     gboolean is_heur)
3159 {
3160         int offset = 0;
3161         gboolean saw_rpc = FALSE;
3162         gboolean first_pdu = TRUE;
3163         int len;
3164
3165         while (tvb_reported_length_remaining(tvb, offset) != 0) {
3166                 /*
3167                  * Process this fragment.
3168                  */
3169                 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
3170                     dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
3171                     rpc_defragment, first_pdu);
3172                 first_pdu = FALSE;
3173                 if (len < 0) {
3174                         /*
3175                          * We need more data from the TCP stream for
3176                          * this fragment.
3177                          */
3178                         return NEED_MORE_DATA;
3179                 }
3180                 if (len == 0) {
3181                         /*
3182                          * It's not RPC.  Stop processing.
3183                          */
3184                         break;
3185                 }
3186
3187                 /* PDU tracking
3188                   If the length indicates that the PDU continues beyond
3189                   the end of this tvb, then tell TCP about it so that it
3190                   knows where the next PDU starts.
3191                   This is to help TCP detect when PDUs are not aligned to
3192                   segment boundaries and allow it to find RPC headers
3193                   that starts in the middle of a TCP segment.
3194                 */
3195                 if(!pinfo->fd->flags.visited){
3196                         if(len>tvb_reported_length_remaining(tvb, offset)){
3197                                 pinfo->want_pdu_tracking=2;
3198                                 pinfo->bytes_until_next_pdu=len-tvb_reported_length_remaining(tvb, offset);
3199                         }
3200                 }
3201                 offset += len;
3202                 saw_rpc = TRUE;
3203         }
3204         return saw_rpc ? IS_RPC : IS_NOT_RPC;
3205 }
3206
3207 static gboolean
3208 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3209 {
3210         switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
3211
3212         case IS_RPC:
3213                 return TRUE;
3214
3215         case IS_NOT_RPC:
3216                 return FALSE;
3217
3218         default:
3219                 /* "Can't happen" */
3220                 g_assert_not_reached();
3221                 return FALSE;
3222         }
3223 }
3224
3225 static void
3226 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3227 {
3228         if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
3229                 dissect_rpc_continuation(tvb, pinfo, tree);
3230 }
3231
3232 /* Discard any state we've saved. */
3233 static void
3234 rpc_init_protocol(void)
3235 {
3236         if (rpc_calls != NULL) {
3237                 g_hash_table_destroy(rpc_calls);
3238                 rpc_calls = NULL;
3239         }
3240         if (rpc_indir_calls != NULL) {
3241                 g_hash_table_destroy(rpc_indir_calls);
3242                 rpc_indir_calls = NULL;
3243         }
3244         if (rpc_call_info_key_chunk != NULL) {
3245                 g_mem_chunk_destroy(rpc_call_info_key_chunk);
3246                 rpc_call_info_key_chunk = NULL;
3247         }
3248         if (rpc_call_info_value_chunk != NULL) {
3249                 g_mem_chunk_destroy(rpc_call_info_value_chunk);
3250                 rpc_call_info_value_chunk = NULL;
3251         }
3252         if (rpc_fragment_key_chunk != NULL) {
3253                 g_mem_chunk_destroy(rpc_fragment_key_chunk);
3254                 rpc_fragment_key_chunk = NULL;
3255         }
3256         if (rpc_reassembly_table != NULL) {
3257                 g_hash_table_destroy(rpc_reassembly_table);
3258                 rpc_reassembly_table = NULL;
3259         }
3260
3261         rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3262         rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
3263         rpc_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
3264             sizeof(rpc_call_info_key),
3265             200 * sizeof(rpc_call_info_key),
3266             G_ALLOC_ONLY);
3267         rpc_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
3268             sizeof(rpc_call_info_value),
3269             200 * sizeof(rpc_call_info_value),
3270             G_ALLOC_ONLY);
3271         rpc_fragment_key_chunk = g_mem_chunk_new("rpc_fragment_key_chunk",
3272             sizeof(rpc_fragment_key),
3273             rpc_fragment_init_count*sizeof(rpc_fragment_key),
3274             G_ALLOC_ONLY);
3275         rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
3276             rpc_fragment_equal);
3277
3278         fragment_table_init(&rpc_fragment_table);
3279 }
3280
3281 /* will be called once from register.c at startup time */
3282 void
3283 proto_register_rpc(void)
3284 {
3285         static hf_register_info hf[] = {
3286                 { &hf_rpc_reqframe, {
3287                         "Request Frame", "rpc.reqframe", FT_FRAMENUM, BASE_NONE,
3288                         NULL, 0, "Request Frame", HFILL }},
3289                 { &hf_rpc_repframe, {
3290                         "Reply Frame", "rpc.repframe", FT_FRAMENUM, BASE_NONE,
3291                         NULL, 0, "Reply Frame", HFILL }},
3292                 { &hf_rpc_lastfrag, {
3293                         "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
3294                         &yesno, RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
3295                 { &hf_rpc_fraglen, {
3296                         "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
3297                         NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
3298                 { &hf_rpc_xid, {
3299                         "XID", "rpc.xid", FT_UINT32, BASE_HEX,
3300                         NULL, 0, "XID", HFILL }},
3301                 { &hf_rpc_msgtype, {
3302                         "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
3303                         VALS(rpc_msg_type), 0, "Message Type", HFILL }},
3304                 { &hf_rpc_state_reply, {
3305                         "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
3306                         VALS(rpc_reply_state), 0, "Reply State", HFILL }},
3307                 { &hf_rpc_state_accept, {
3308                         "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
3309                         VALS(rpc_accept_state), 0, "Accept State", HFILL }},
3310                 { &hf_rpc_state_reject, {
3311                         "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
3312                         VALS(rpc_reject_state), 0, "Reject State", HFILL }},
3313                 { &hf_rpc_state_auth, {
3314                         "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
3315                         VALS(rpc_auth_state), 0, "Auth State", HFILL }},
3316                 { &hf_rpc_version, {
3317                         "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
3318                         NULL, 0, "RPC Version", HFILL }},
3319                 { &hf_rpc_version_min, {
3320                         "RPC Version (Minimum)", "rpc.version.min", FT_UINT32,
3321                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3322                 { &hf_rpc_version_max, {
3323                         "RPC Version (Maximum)", "rpc.version.max", FT_UINT32,
3324                         BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
3325                 { &hf_rpc_program, {
3326                         "Program", "rpc.program", FT_UINT32, BASE_DEC,
3327                         NULL, 0, "Program", HFILL }},
3328                 { &hf_rpc_programversion, {
3329                         "Program Version", "rpc.programversion", FT_UINT32,
3330                         BASE_DEC, NULL, 0, "Program Version", HFILL }},
3331                 { &hf_rpc_programversion_min, {
3332                         "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32,
3333                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3334                 { &hf_rpc_programversion_max, {
3335                         "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32,
3336                         BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
3337                 { &hf_rpc_procedure, {
3338                         "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
3339                         NULL, 0, "Procedure", HFILL }},
3340                 { &hf_rpc_auth_flavor, {
3341                         "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
3342                         VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
3343                 { &hf_rpc_auth_length, {
3344                         "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
3345                         NULL, 0, "Length", HFILL }},
3346                 { &hf_rpc_auth_stamp, {
3347                         "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
3348                         NULL, 0, "Stamp", HFILL }},
3349                 { &hf_rpc_auth_uid, {
3350                         "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
3351                         NULL, 0, "UID", HFILL }},
3352                 { &hf_rpc_auth_gid, {
3353                         "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
3354                         NULL, 0, "GID", HFILL }},
3355                 { &hf_rpc_authgss_v, {
3356                         "GSS Version", "rpc.authgss.version", FT_UINT32,
3357                         BASE_DEC, NULL, 0, "GSS Version", HFILL }},
3358                 { &hf_rpc_authgss_proc, {
3359                         "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
3360                         BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
3361                 { &hf_rpc_authgss_seq, {
3362                         "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
3363                         BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
3364                 { &hf_rpc_authgss_svc, {
3365                         "GSS Service", "rpc.authgss.service", FT_UINT32,
3366                         BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
3367                 { &hf_rpc_authgss_ctx, {
3368                         "GSS Context", "rpc.authgss.context", FT_BYTES,
3369                         BASE_HEX, NULL, 0, "GSS Context", HFILL }},
3370                 { &hf_rpc_authgss_major, {
3371                         "GSS Major Status", "rpc.authgss.major", FT_UINT32,
3372                         BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
3373                 { &hf_rpc_authgss_minor, {
3374                         "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
3375                         BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
3376                 { &hf_rpc_authgss_window, {
3377                         "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
3378                         BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
3379                 { &hf_rpc_authgss_token_length, {
3380                         "GSS Token Length", "rpc.authgss.token_length", FT_UINT32,
3381                         BASE_DEC, NULL, 0, "GSS Token Length", HFILL }},
3382                 { &hf_rpc_authgss_data_length, {
3383                         "Length", "rpc.authgss.data.length", FT_UINT32,
3384                         BASE_DEC, NULL, 0, "Length", HFILL }},
3385                 { &hf_rpc_authgss_data, {
3386                         "GSS Data", "rpc.authgss.data", FT_BYTES,
3387                         BASE_HEX, NULL, 0, "GSS Data", HFILL }},
3388                 { &hf_rpc_authgss_checksum, {
3389                         "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
3390                         BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
3391                 { &hf_rpc_authgssapi_v, {
3392                         "AUTH_GSSAPI Version", "rpc.authgssapi.version",
3393                         FT_UINT32, BASE_DEC, NULL, 0, "AUTH_GSSAPI Version",
3394                         HFILL }},
3395                 { &hf_rpc_authgssapi_msg, {
3396                         "AUTH_GSSAPI Message", "rpc.authgssapi.message",
3397                         FT_BOOLEAN, BASE_NONE, &yesno, 0, "AUTH_GSSAPI Message",
3398                         HFILL }},
3399                 { &hf_rpc_authgssapi_msgv, {
3400                         "Msg Version", "rpc.authgssapi.msgversion",
3401                         FT_UINT32, BASE_DEC, NULL, 0, "Msg Version",
3402                         HFILL }},
3403                 { &hf_rpc_authgssapi_handle, {
3404                         "Client Handle", "rpc.authgssapi.handle",
3405                         FT_BYTES, BASE_HEX, NULL, 0, "Client Handle", HFILL }},
3406                 { &hf_rpc_authgssapi_isn, {
3407                         "Signed ISN", "rpc.authgssapi.isn",
3408                         FT_BYTES, BASE_HEX, NULL, 0, "Signed ISN", HFILL }},
3409                 { &hf_rpc_authdes_namekind, {
3410                         "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
3411                         VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
3412                 { &hf_rpc_authdes_netname, {
3413                         "Netname", "rpc.authdes.netname", FT_STRING,
3414                         BASE_DEC, NULL, 0, "Netname", HFILL }},
3415                 { &hf_rpc_authdes_convkey, {
3416                         "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
3417                         BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
3418                 { &hf_rpc_authdes_window, {
3419                         "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
3420                         BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
3421                 { &hf_rpc_authdes_nickname, {
3422                         "Nickname", "rpc.authdes.nickname", FT_UINT32,
3423                         BASE_HEX, NULL, 0, "Nickname", HFILL }},
3424                 { &hf_rpc_authdes_timestamp, {
3425                         "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
3426                         BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
3427                 { &hf_rpc_authdes_windowverf, {
3428                         "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
3429                         BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
3430                 { &hf_rpc_authdes_timeverf, {
3431                         "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
3432                         BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
3433                 { &hf_rpc_auth_machinename, {
3434                         "Machine Name", "rpc.auth.machinename", FT_STRING,
3435                         BASE_DEC, NULL, 0, "Machine Name", HFILL }},
3436                 { &hf_rpc_dup, {
3437                         "Duplicate Call/Reply", "rpc.dup", FT_NONE, BASE_NONE,
3438                         NULL, 0, "Duplicate Call/Reply", HFILL }},
3439                 { &hf_rpc_call_dup, {
3440                         "Duplicate to the call in", "rpc.call.dup", FT_FRAMENUM, BASE_DEC,
3441                         NULL, 0, "This is a duplicate to the call in frame", HFILL }},
3442                 { &hf_rpc_reply_dup, {
3443                         "Duplicate to the reply in", "rpc.reply.dup", FT_FRAMENUM, BASE_DEC,
3444                         NULL, 0, "This is a duplicate to the reply in frame", HFILL }},
3445                 { &hf_rpc_value_follows, {
3446                         "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
3447                         &yesno, 0, "Value Follows", HFILL }},
3448                 { &hf_rpc_array_len, {
3449                         "num", "rpc.array.len", FT_UINT32, BASE_DEC,
3450                         NULL, 0, "Length of RPC array", HFILL }},
3451
3452                 { &hf_rpc_time, {
3453                         "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
3454                         NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
3455
3456                 { &hf_rpc_fragment_overlap,
3457                 { "Fragment overlap",   "rpc.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3458                         "Fragment overlaps with other fragments", HFILL }},
3459
3460                 { &hf_rpc_fragment_overlap_conflict,
3461                 { "Conflicting data in fragment overlap",       "rpc.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3462                         "Overlapping fragments contained conflicting data", HFILL }},
3463
3464                 { &hf_rpc_fragment_multiple_tails,
3465                 { "Multiple tail fragments found",      "rpc.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3466                         "Several tails were found when defragmenting the packet", HFILL }},
3467
3468                 { &hf_rpc_fragment_too_long_fragment,
3469                 { "Fragment too long",  "rpc.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3470                         "Fragment contained data past end of packet", HFILL }},
3471
3472                 { &hf_rpc_fragment_error,
3473                 { "Defragmentation error", "rpc.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3474                         "Defragmentation error due to illegal fragments", HFILL }},
3475
3476                 { &hf_rpc_fragment,
3477                 { "RPC Fragment", "rpc.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3478                         "RPC Fragment", HFILL }},
3479
3480                 { &hf_rpc_fragments,
3481                 { "RPC Fragments", "rpc.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3482                         "RPC Fragments", HFILL }},
3483         };
3484         static gint *ett[] = {
3485                 &ett_rpc,
3486                 &ett_rpc_fragments,
3487                 &ett_rpc_fragment,
3488                 &ett_rpc_fraghdr,
3489                 &ett_rpc_string,
3490                 &ett_rpc_cred,
3491                 &ett_rpc_verf,
3492                 &ett_rpc_gids,
3493                 &ett_rpc_gss_token,
3494                 &ett_rpc_gss_data,
3495                 &ett_rpc_array,
3496                 &ett_rpc_authgssapi_msg,
3497                 &ett_rpc_unknown_program,
3498         };
3499         module_t *rpc_module;
3500
3501         proto_rpc = proto_register_protocol("Remote Procedure Call",
3502             "RPC", "rpc");
3503         /* this is a dummy dissector for all those unknown rpc programs */
3504         proto_register_field_array(proto_rpc, hf, array_length(hf));
3505         proto_register_subtree_array(ett, array_length(ett));
3506         register_init_routine(&rpc_init_protocol);
3507
3508         rpc_module = prefs_register_protocol(proto_rpc, NULL);
3509         prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
3510             "Reassemble RPC over TCP messages\nspanning multiple TCP segments",
3511             "Whether the RPC dissector should reassemble messages spanning multiple TCP segments."
3512             " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3513                 &rpc_desegment);
3514         prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
3515                 "Reassemble fragmented RPC-over-TCP messages",
3516                 "Whether the RPC dissector should defragment RPC-over-TCP messages.",
3517                 &rpc_defragment);
3518
3519         prefs_register_uint_preference(rpc_module, "max_tcp_pdu_size", "Maximum size of a RPC-over-TCP PDU",
3520                 "Set the maximum size of RPCoverTCP PDUs. "
3521                 " If the size field of the record marker is larger "
3522                 "than this value it will not be considered a valid RPC PDU.",
3523                  10, &max_rpc_tcp_pdu_size);
3524
3525         prefs_register_bool_preference(rpc_module, "dissect_unknown_programs",
3526                 "Dissect unknown RPC program numbers",
3527                 "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.",
3528                 &rpc_dissect_unknown_programs);
3529
3530         register_dissector("rpc", dissect_rpc, proto_rpc);
3531         rpc_handle = find_dissector("rpc");
3532         register_dissector("rpc-tcp", dissect_rpc_tcp, proto_rpc);
3533         rpc_tcp_handle = find_dissector("rpc-tcp");
3534         rpc_tap = register_tap("rpc");
3535
3536         /*
3537          * Init the hash tables.  Dissectors for RPC protocols must
3538          * have a "handoff registration" routine that registers the
3539          * protocol with RPC; they must not do it in their protocol
3540          * registration routine, as their protocol registration
3541          * routine might be called before this routine is called and
3542          * thus might be called before the hash tables are initialized,
3543          * but it's guaranteed that all protocol registration routines
3544          * will be called before any handoff registration routines
3545          * are called.
3546          */
3547         rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
3548         rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
3549 }
3550
3551 void
3552 proto_reg_handoff_rpc(void)
3553 {
3554         dissector_handle_t rpc_tcp_handle;
3555         dissector_handle_t rpc_udp_handle;
3556
3557         /* tcp/udp port 111 is used by portmapper which is an onc-rpc service.
3558            we register onc-rpc on this port so that we can choose RPC in
3559            the list offered by DecodeAs, and so that traffic to or from
3560            port 111 from or to a higher-numbered port is dissected as RPC
3561            even if there's a dissector registered on the other port (it's
3562            probably RPC traffic from some randomly-chosen port that happens
3563            to match some port for which we have a dissector)
3564         */
3565         rpc_tcp_handle = create_dissector_handle(dissect_rpc_tcp, proto_rpc);
3566         dissector_add("tcp.port", 111, rpc_tcp_handle);
3567         rpc_udp_handle = create_dissector_handle(dissect_rpc, proto_rpc);
3568         dissector_add("udp.port", 111, rpc_udp_handle);
3569
3570         heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
3571         heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
3572         gssapi_handle = find_dissector("gssapi");
3573         data_handle = find_dissector("data");
3574 }