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