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