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