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