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