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