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