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