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