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