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