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