Un-#if out "samr_dissect_get_alias_membership_response()", to serve as a
[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.90 2002/04/03 13:24:12 girlich 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 static 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 static 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 static 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 static 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 static 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 static 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, 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, 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, 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,
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, proto_tree *tree,
640     int hfindex, int offset, char **string_buffer_ret)
641 {
642         offset = dissect_rpc_opaque_data(tvb, offset, tree,
643             hfindex, TRUE, string_buffer_ret);
644         return offset;
645 }
646
647
648 int
649 dissect_rpc_data(tvbuff_t *tvb, proto_tree *tree,
650     int hfindex, int offset)
651 {
652         offset = dissect_rpc_opaque_data(tvb, offset, 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, 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, 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, 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, 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, tree, hf_rpc_authgss_ctx,
803                         offset);
804         
805         return offset;
806 }
807
808 static int
809 dissect_rpc_authdes_desblock(tvbuff_t *tvb, 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, 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, tree, 
844                         hf_rpc_authdes_netname, offset, NULL);
845                 offset = dissect_rpc_authdes_desblock(tvb, 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, 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, ctree, offset+8);
889                         break;
890                 /*
891                 case AUTH_SHORT:
892
893                 break;
894                 */
895                 case AUTH_DES:
896                         dissect_rpc_authdes_cred(tvb, ctree, offset+8);
897                         break;
898                         
899                 case RPCSEC_GSS:
900                         dissect_rpc_authgss_cred(tvb, 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, 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, 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, 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, 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, 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, proto_tree* tree, int offset)
989 {
990         offset = dissect_rpc_data(tvb, tree, hf_rpc_authgss_token,
991                         offset);
992         return offset;
993 }
994
995 static int
996 dissect_rpc_authgss_initres(tvbuff_t* tvb, proto_tree* tree, int offset)
997 {
998         int major, minor, window;
999         
1000         offset = dissect_rpc_data(tvb, 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, 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, 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, proto_tree *tree, int offset)
1091 {
1092         offset = dissect_rpc_data(tvb, 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, 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, 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, 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, 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, rpc_tree, offset);
1786                 offset = dissect_rpc_verf(tvb, 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, 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                                         ptree, offset);
2051                         }
2052                         else {
2053                                 offset = dissect_rpc_authgss_initres(tvb,
2054                                         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                                                 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, -1, "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, ipfd->offset, ipfd->len,
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
2291         /*
2292          * Get the record mark.
2293          */
2294         if (!tvb_bytes_exist(tvb, offset, 4)) {
2295                 /*
2296                  * XXX - we should somehow arrange to handle
2297                  * a record mark split across TCP segments.
2298                  */
2299                 return 0;       /* not enough to tell if it's valid */
2300         }
2301         rpc_rm = tvb_get_ntohl(tvb, offset);
2302
2303         len = rpc_rm & RPC_RM_FRAGLEN;
2304
2305         /*
2306          * Do TCP desegmentation, if enabled.
2307          *
2308          * XXX - reject fragments bigger than 2 megabytes.
2309          * This is arbitrary, but should at least prevent
2310          * some crashes from either packets with really
2311          * large RPC-over-TCP fragments or from stuff that's
2312          * not really valid for this protocol.
2313          */
2314         if (len > 2*1024*1024)
2315                 return 0;       /* pretend it's not valid */
2316         if (rpc_desegment) {
2317                 seglen = tvb_length_remaining(tvb, offset + 4);
2318
2319                 if (len > seglen && pinfo->can_desegment) {
2320                         /*
2321                          * This frame doesn't have all of the
2322                          * data for this message, but we can do
2323                          * reassembly on it.
2324                          *
2325                          * If this is a heuristic dissector, just
2326                          * return 0 - we don't want to try to get
2327                          * more data, as that's too likely to cause
2328                          * us to misidentify this as valid.
2329                          *
2330                          * If this isn't a heuristic dissector,
2331                          * we've already identified this conversation
2332                          * as containing data for this protocol, as we
2333                          * saw valid data in previous frames.  Try to
2334                          * get more data.
2335                          */
2336                         if (is_heur)
2337                                 return 0;       /* not valid */
2338                         else {
2339                                 pinfo->desegment_offset = offset;
2340                                 pinfo->desegment_len = len - seglen;
2341                                 return -pinfo->desegment_len;
2342                         }
2343                 }
2344         }
2345         len += 4;       /* include record mark */
2346         tvb_len = tvb_length_remaining(tvb, offset);
2347         tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2348         if (tvb_len > len)
2349                 tvb_len = len;
2350         if (tvb_reported_len > len)
2351                 tvb_reported_len = len;
2352         frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2353             tvb_reported_len);
2354
2355         /*
2356          * If we're not defragmenting, just hand this to the
2357          * disssector.
2358          */
2359         if (!defragment) {
2360                 /*
2361                  * This is the first fragment we've seen, and it's also
2362                  * the last fragment; that means the record wasn't
2363                  * fragmented.  Hand the dissector the tvbuff for the
2364                  * fragment as the tvbuff for the record.
2365                  */
2366                 rec_tvb = frag_tvb;
2367                 ipfd_head = NULL;
2368
2369                 /*
2370                  * Mark this as fragmented, so if somebody throws an
2371                  * exception, we don't report it as a malformed frame.
2372                  */
2373                 save_fragmented = pinfo->fragmented;
2374                 pinfo->fragmented = TRUE;
2375                 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
2376                     tree, frag_tvb, dissector, ipfd_head, rpc_rm);
2377                 pinfo->fragmented = save_fragmented;
2378                 if (!rpc_succeeded)
2379                         return 0;       /* not RPC */
2380                 return len;
2381         }
2382
2383         /*
2384          * First, we check to see if this fragment is part of a record
2385          * that we're in the process of defragmenting.
2386          *
2387          * The key is the conversation ID for the conversation to which
2388          * the packet belongs and the current sequence number.
2389          * We must first find the conversation and, if we don't find
2390          * one, create it.  We know this is running over TCP, so the
2391          * conversation should not wildcard either address or port.
2392          */
2393         conversation = find_conversation(&pinfo->src, &pinfo->dst,
2394             pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2395         if (conversation == NULL) {
2396                 /*
2397                  * It's not part of any conversation - create a new one.
2398                  */
2399                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
2400                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
2401         }
2402         old_rfk.conv_id = conversation->index;
2403         old_rfk.seq = seq;
2404         rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
2405
2406         if (rfk == NULL) {
2407                 /*
2408                  * This fragment was not found in our table, so it doesn't
2409                  * contain a continuation of a higher-level PDU.
2410                  * Is it the last fragment?
2411                  */
2412                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2413                         /*
2414                          * This isn't the last fragment, so we don't
2415                          * have the complete record.
2416                          *
2417                          * It's the first fragment we've seen, so if
2418                          * it's truly the first fragment of the record,
2419                          * and it has enough data, the dissector can at
2420                          * least check whether it looks like a valid
2421                          * message, as it contains the start of the
2422                          * message.
2423                          *
2424                          * The dissector should not dissect anything
2425                          * if the "last fragment" flag isn't set in
2426                          * the record marker, so it shouldn't throw
2427                          * an exception.
2428                          */
2429                         if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
2430                             NULL, TRUE, rpc_rm))
2431                                 return 0;       /* not valid */
2432
2433                         /*
2434                          * OK, now start defragmentation with that
2435                          * fragment.  Add this fragment, and set up
2436                          * next packet/sequence number as well.
2437                          *
2438                          * We must remember this fragment.
2439                          */
2440
2441                         rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2442                         rfk->conv_id = conversation->index;
2443                         rfk->seq = seq;
2444                         rfk->offset = 0;
2445                         rfk->start_seq = seq;
2446                         g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
2447
2448                         /*
2449                          * Start defragmentation.
2450                          */
2451                         ipfd_head = fragment_add(tvb, offset + 4, pinfo,
2452                             rfk->start_seq, rpc_fragment_table,
2453                             rfk->offset, len - 4, TRUE);
2454
2455                         /*
2456                          * Make sure that defragmentation isn't complete;
2457                          * it shouldn't be, as this is the first fragment
2458                          * we've seen, and the "last fragment" bit wasn't
2459                          * set on it.
2460                          */
2461                         g_assert(ipfd_head == NULL);
2462
2463                         new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2464                         new_rfk->conv_id = rfk->conv_id;
2465                         new_rfk->seq = seq + len;
2466                         new_rfk->offset = rfk->offset + len - 4;
2467                         new_rfk->start_seq = rfk->start_seq;
2468                         g_hash_table_insert(rpc_reassembly_table, new_rfk,
2469                             new_rfk);
2470
2471                         /*
2472                          * This is part of a fragmented record,
2473                          * but it's not the first part.
2474                          * Show it as a record marker plus data, under
2475                          * a top-level tree for this protocol.
2476                          */
2477                         make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
2478
2479                         /*
2480                          * No more processing need be done, as we don't
2481                          * have a complete record.
2482                          */
2483                         return len;
2484                 }
2485
2486                 /*
2487                  * This is the first fragment we've seen, and it's also
2488                  * the last fragment; that means the record wasn't
2489                  * fragmented.  Hand the dissector the tvbuff for the
2490                  * fragment as the tvbuff for the record.
2491                  */
2492                 rec_tvb = frag_tvb;
2493                 ipfd_head = NULL;
2494         } else {
2495                 /*
2496                  * OK, this fragment was found, which means it continues
2497                  * a record.  This means we must defragment it.
2498                  * Add it to the defragmentation lists.
2499                  */
2500                 ipfd_head = fragment_add(tvb, offset + 4, pinfo,
2501                     rfk->start_seq, rpc_fragment_table,
2502                     rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
2503
2504                 if (ipfd_head == NULL) {
2505                         /*
2506                          * fragment_add() returned NULL, This means that 
2507                          * defragmentation is not completed yet.
2508                          *
2509                          * We must add an entry to the hash table with
2510                          * the sequence number following this fragment
2511                          * as the starting sequence number, so that when
2512                          * we see that fragment we'll find that entry.
2513                          *
2514                          * XXX - as TCP stream data is not currently
2515                          * guaranteed to be provided in order to dissectors,
2516                          * RPC fragments aren't guaranteed to be provided
2517                          * in order, either.
2518                          */
2519                         new_rfk = g_mem_chunk_alloc(rpc_fragment_key_chunk);
2520                         new_rfk->conv_id = rfk->conv_id;
2521                         new_rfk->seq = seq + len;
2522                         new_rfk->offset = rfk->offset + len - 4;
2523                         new_rfk->start_seq = rfk->start_seq;
2524                         g_hash_table_insert(rpc_reassembly_table, new_rfk,
2525                             new_rfk);
2526
2527                         /*
2528                          * This is part of a fragmented record,
2529                          * but it's not the first part.
2530                          * Show it as a record marker plus data, under
2531                          * a top-level tree for this protocol,
2532                          * but don't hand it to the dissector
2533                          */
2534                         make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
2535
2536                         /*
2537                          * No more processing need be done, as we don't
2538                          * have a complete record.
2539                          */
2540                         return len;
2541                 }
2542
2543                 /*
2544                  * It's completely defragmented.
2545                  *
2546                  * We only call subdissector for the last fragment.
2547                  * XXX - this assumes in-order delivery of RPC
2548                  * fragments, which requires in-order delivery of TCP
2549                  * segments.
2550                  */
2551                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2552                         /*
2553                          * Well, it's defragmented, but this isn't
2554                          * the last fragment; this probably means
2555                          * this isn't the first pass, so we don't
2556                          * need to start defragmentation.
2557                          *
2558                          * This is part of a fragmented record,
2559                          * but it's not the first part.
2560                          * Show it as a record marker plus data, under
2561                          * a top-level tree for this protocol,
2562                          * but don't show it to the dissector.
2563                          */
2564                         make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
2565
2566                         /*
2567                          * No more processing need be done, as we
2568                          * only disssect the data with the last
2569                          * fragment.
2570                          */
2571                         return len;
2572                 }
2573
2574                 /*
2575                  * OK, this is the last segment.
2576                  * Create a tvbuff for the defragmented
2577                  * record.
2578                  */
2579
2580                 /*
2581                  * Create a new TVB structure for
2582                  * defragmented data.
2583                  */
2584                 rec_tvb = tvb_new_real_data(ipfd_head->data,
2585                     ipfd_head->datalen, ipfd_head->datalen);
2586
2587                 /*
2588                  * Add this tvb as a child to the original
2589                  * one.
2590                  */
2591                 tvb_set_child_real_data_tvbuff(tvb, rec_tvb);
2592
2593                 /*
2594                  * Add defragmented data to the data source list.
2595                  */
2596                 add_new_data_source(pinfo->fd, rec_tvb, "Defragmented");
2597         }
2598
2599         /*
2600          * We have something to hand to the RPC message
2601          * dissector.
2602          */
2603         if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
2604             frag_tvb, dissector, ipfd_head, rpc_rm))
2605                 return 0;       /* not RPC */
2606         return len;
2607 }
2608
2609 /*
2610  * Can return:
2611  *
2612  *      NEED_MORE_DATA, if we don't have enough data to dissect anything;
2613  *
2614  *      IS_RPC, if we dissected at least one message in its entirety
2615  *      as RPC;
2616  *
2617  *      IS_NOT_RPC, if we found no RPC message.
2618  */
2619 typedef enum {
2620         NEED_MORE_DATA,
2621         IS_RPC,
2622         IS_NOT_RPC
2623 } rpc_tcp_return_t;
2624
2625 static rpc_tcp_return_t
2626 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2627     gboolean is_heur)
2628 {
2629         int offset = 0;
2630         gboolean saw_rpc = FALSE;
2631         int len;
2632
2633         while (tvb_reported_length_remaining(tvb, offset) != 0) {
2634                 /*
2635                  * Process this fragment.
2636                  */
2637                 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
2638                     dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
2639                     rpc_defragment);
2640                 if (len < 0) {
2641                         /*
2642                          * We need more data from the TCP stream for
2643                          * this fragment.
2644                          */
2645                         return NEED_MORE_DATA;
2646                 }
2647                 if (len == 0) {
2648                         /*
2649                          * It's not RPC.  Stop processing.
2650                          */
2651                         break;
2652                 }
2653
2654                 offset += len;
2655                 saw_rpc = TRUE;
2656         }
2657         return saw_rpc ? IS_RPC : IS_NOT_RPC;
2658 }
2659
2660 static gboolean
2661 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2662 {
2663         switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
2664
2665         case IS_RPC:
2666                 return TRUE;
2667
2668         case IS_NOT_RPC:
2669                 return FALSE;
2670
2671         default:
2672                 /* "Can't happen" */
2673                 g_assert_not_reached();
2674                 return FALSE;
2675         }
2676 }
2677
2678 static void
2679 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2680 {
2681         if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
2682                 dissect_rpc_continuation(tvb, pinfo, tree);
2683 }
2684
2685 /* Discard any state we've saved. */
2686 static void
2687 rpc_init_protocol(void)
2688 {
2689         if (rpc_calls != NULL) {
2690                 g_hash_table_destroy(rpc_calls);
2691                 rpc_calls = NULL;
2692         }
2693         if (rpc_indir_calls != NULL) {
2694                 g_hash_table_destroy(rpc_indir_calls);
2695                 rpc_indir_calls = NULL;
2696         }
2697         if (rpc_call_info_key_chunk != NULL) {
2698                 g_mem_chunk_destroy(rpc_call_info_key_chunk);
2699                 rpc_call_info_key_chunk = NULL;
2700         }
2701         if (rpc_call_info_value_chunk != NULL) {
2702                 g_mem_chunk_destroy(rpc_call_info_value_chunk);
2703                 rpc_call_info_value_chunk = NULL;
2704         }
2705         if (rpc_fragment_key_chunk != NULL) {
2706                 g_mem_chunk_destroy(rpc_fragment_key_chunk);
2707                 rpc_fragment_key_chunk = NULL;
2708         }
2709         if (rpc_reassembly_table != NULL) {
2710                 g_hash_table_destroy(rpc_reassembly_table);
2711                 rpc_reassembly_table = NULL;
2712         }
2713
2714         rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
2715         rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
2716         rpc_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
2717             sizeof(rpc_call_info_key),
2718             200 * sizeof(rpc_call_info_key),
2719             G_ALLOC_ONLY);
2720         rpc_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
2721             sizeof(rpc_call_info_value),
2722             200 * sizeof(rpc_call_info_value),
2723             G_ALLOC_ONLY);
2724         rpc_fragment_key_chunk = g_mem_chunk_new("rpc_fragment_key_chunk",
2725             sizeof(rpc_fragment_key),
2726             rpc_fragment_init_count*sizeof(rpc_fragment_key),
2727             G_ALLOC_ONLY);
2728         rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
2729             rpc_fragment_equal);
2730
2731         fragment_table_init(&rpc_fragment_table);
2732 }
2733
2734 /* will be called once from register.c at startup time */
2735 void
2736 proto_register_rpc(void)
2737 {
2738         static hf_register_info hf[] = {
2739                 { &hf_rpc_lastfrag, {
2740                         "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
2741                         &yesno, RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
2742                 { &hf_rpc_fraglen, {
2743                         "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
2744                         NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
2745                 { &hf_rpc_xid, {
2746                         "XID", "rpc.xid", FT_UINT32, BASE_HEX,
2747                         NULL, 0, "XID", HFILL }},
2748                 { &hf_rpc_msgtype, {
2749                         "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
2750                         VALS(rpc_msg_type), 0, "Message Type", HFILL }},
2751                 { &hf_rpc_state_reply, {
2752                         "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
2753                         VALS(rpc_reply_state), 0, "Reply State", HFILL }},
2754                 { &hf_rpc_state_accept, {
2755                         "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
2756                         VALS(rpc_accept_state), 0, "Accept State", HFILL }},
2757                 { &hf_rpc_state_reject, {
2758                         "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
2759                         VALS(rpc_reject_state), 0, "Reject State", HFILL }},
2760                 { &hf_rpc_state_auth, {
2761                         "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
2762                         VALS(rpc_auth_state), 0, "Auth State", HFILL }},
2763                 { &hf_rpc_version, {
2764                         "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
2765                         NULL, 0, "RPC Version", HFILL }},
2766                 { &hf_rpc_version_min, {
2767                         "RPC Version (Minimum)", "rpc.version.min", FT_UINT32, 
2768                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
2769                 { &hf_rpc_version_max, {
2770                         "RPC Version (Maximum)", "rpc.version.max", FT_UINT32, 
2771                         BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
2772                 { &hf_rpc_program, {
2773                         "Program", "rpc.program", FT_UINT32, BASE_DEC,
2774                         NULL, 0, "Program", HFILL }},
2775                 { &hf_rpc_programversion, {
2776                         "Program Version", "rpc.programversion", FT_UINT32, 
2777                         BASE_DEC, NULL, 0, "Program Version", HFILL }},
2778                 { &hf_rpc_programversion_min, {
2779                         "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32, 
2780                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
2781                 { &hf_rpc_programversion_max, {
2782                         "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32, 
2783                         BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
2784                 { &hf_rpc_procedure, {
2785                         "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
2786                         NULL, 0, "Procedure", HFILL }},
2787                 { &hf_rpc_auth_flavor, {
2788                         "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
2789                         VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
2790                 { &hf_rpc_auth_length, {
2791                         "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
2792                         NULL, 0, "Length", HFILL }},
2793                 { &hf_rpc_auth_stamp, {
2794                         "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
2795                         NULL, 0, "Stamp", HFILL }},
2796                 { &hf_rpc_auth_uid, {
2797                         "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
2798                         NULL, 0, "UID", HFILL }},
2799                 { &hf_rpc_auth_gid, {
2800                         "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
2801                         NULL, 0, "GID", HFILL }},
2802                 { &hf_rpc_authgss_v, {
2803                         "GSS Version", "rpc.authgss.version", FT_UINT32,
2804                         BASE_DEC, NULL, 0, "GSS Version", HFILL }},
2805                 { &hf_rpc_authgss_proc, {
2806                         "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
2807                         BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
2808                 { &hf_rpc_authgss_seq, {
2809                         "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
2810                         BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
2811                 { &hf_rpc_authgss_svc, {
2812                         "GSS Service", "rpc.authgss.service", FT_UINT32,
2813                         BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
2814                 { &hf_rpc_authgss_ctx, {
2815                         "GSS Context", "rpc.authgss.context", FT_BYTES,
2816                         BASE_HEX, NULL, 0, "GSS Context", HFILL }},
2817                 { &hf_rpc_authgss_major, {
2818                         "GSS Major Status", "rpc.authgss.major", FT_UINT32,
2819                         BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
2820                 { &hf_rpc_authgss_minor, {
2821                         "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
2822                         BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
2823                 { &hf_rpc_authgss_window, {
2824                         "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
2825                         BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
2826                 { &hf_rpc_authgss_token, {
2827                         "GSS Token", "rpc.authgss.token", FT_BYTES,
2828                         BASE_HEX, NULL, 0, "GSS Token", HFILL }},
2829                 { &hf_rpc_authgss_data_length, {
2830                         "Length", "rpc.authgss.data.length", FT_UINT32,
2831                         BASE_DEC, NULL, 0, "Length", HFILL }},
2832                 { &hf_rpc_authgss_data, {
2833                         "GSS Data", "rpc.authgss.data", FT_BYTES,
2834                         BASE_HEX, NULL, 0, "GSS Data", HFILL }},
2835                 { &hf_rpc_authgss_checksum, {
2836                         "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
2837                         BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
2838                 { &hf_rpc_authdes_namekind, {
2839                         "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
2840                         VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
2841                 { &hf_rpc_authdes_netname, {
2842                         "Netname", "rpc.authdes.netname", FT_STRING,
2843                         BASE_DEC, NULL, 0, "Netname", HFILL }},
2844                 { &hf_rpc_authdes_convkey, {
2845                         "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
2846                         BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
2847                 { &hf_rpc_authdes_window, {
2848                         "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
2849                         BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
2850                 { &hf_rpc_authdes_nickname, {
2851                         "Nickname", "rpc.authdes.nickname", FT_UINT32, 
2852                         BASE_HEX, NULL, 0, "Nickname", HFILL }},
2853                 { &hf_rpc_authdes_timestamp, {
2854                         "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
2855                         BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
2856                 { &hf_rpc_authdes_windowverf, {
2857                         "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
2858                         BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
2859                 { &hf_rpc_authdes_timeverf, {
2860                         "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
2861                         BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
2862                 { &hf_rpc_auth_machinename, {
2863                         "Machine Name", "rpc.auth.machinename", FT_STRING, 
2864                         BASE_DEC, NULL, 0, "Machine Name", HFILL }},
2865                 { &hf_rpc_dup, {
2866                         "Duplicate Transaction", "rpc.dup", FT_UINT32, BASE_DEC,
2867                         NULL, 0, "Duplicate Transaction", HFILL }},
2868                 { &hf_rpc_call_dup, {
2869                         "Duplicate Call", "rpc.call.dup", FT_UINT32, BASE_DEC,
2870                         NULL, 0, "Duplicate Call", HFILL }},
2871                 { &hf_rpc_reply_dup, {
2872                         "Duplicate Reply", "rpc.reply.dup", FT_UINT32, BASE_DEC,
2873                         NULL, 0, "Duplicate Reply", HFILL }},
2874                 { &hf_rpc_value_follows, {
2875                         "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
2876                         &yesno, 0, "Value Follows", HFILL }},
2877                 { &hf_rpc_array_len, {
2878                         "num", "rpc.array.len", FT_UINT32, BASE_DEC,
2879                         NULL, 0, "Length of RPC array", HFILL }},
2880
2881                 { &hf_rpc_time, {
2882                         "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
2883                         NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
2884
2885         };
2886         static gint *ett[] = {
2887                 &ett_rpc,
2888                 &ett_rpc_fragments,
2889                 &ett_rpc_fraghdr,
2890                 &ett_rpc_string,
2891                 &ett_rpc_cred,
2892                 &ett_rpc_verf,
2893                 &ett_rpc_gids,
2894                 &ett_rpc_gss_data,
2895                 &ett_rpc_array,
2896         };
2897         module_t *rpc_module;
2898
2899         proto_rpc = proto_register_protocol("Remote Procedure Call",
2900             "RPC", "rpc");
2901         proto_register_field_array(proto_rpc, hf, array_length(hf));
2902         proto_register_subtree_array(ett, array_length(ett));
2903         register_init_routine(&rpc_init_protocol);
2904         rpc_tcp_handle = create_dissector_handle(dissect_rpc_tcp, proto_rpc);
2905         rpc_handle = create_dissector_handle(dissect_rpc, proto_rpc);
2906
2907         rpc_module = prefs_register_protocol(proto_rpc, NULL);
2908         prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
2909                 "Desegment all RPC-over-TCP messages",
2910                 "Whether the RPC dissector should desegment all RPC-over-TCP messages",
2911                 &rpc_desegment);
2912         prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
2913                 "Defragment all RPC-over-TCP messages",
2914                 "Whether the RPC dissector should defragment multi-fragment RPC-over-TCP messages",
2915                 &rpc_defragment);
2916
2917         /*
2918          * Init the hash tables.  Dissectors for RPC protocols must
2919          * have a "handoff registration" routine that registers the
2920          * protocol with RPC; they must not do it in their protocol
2921          * registration routine, as their protocol registration
2922          * routine might be called before this routine is called and
2923          * thus might be called before the hash tables are initialized,
2924          * but it's guaranteed that all protocol registration routines
2925          * will be called before any handoff registration routines
2926          * are called.
2927          */
2928         rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
2929         rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
2930 }
2931
2932 void
2933 proto_reg_handoff_rpc(void)
2934 {
2935         heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
2936         heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
2937         data_handle = find_dissector("data");
2938 }