68ecfbae12d307eb7431fc9fa5259ce5df4e7286
[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         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1630                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1631         if (check_col(pinfo->cinfo, COL_INFO))
1632                 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1633
1634         if (tree) {
1635                 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1636                                 FALSE);
1637                 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1638                 proto_tree_add_text(rpc_tree, tvb, 0, -1, "Continuation data");
1639         }
1640 }
1641
1642
1643 /**
1644  *  Produce a dummy RPC program entry for the given RPC program key
1645  *  and version values.
1646  */
1647
1648 static void  make_fake_rpc_prog_if_needed (rpc_prog_info_key *prpc_prog_key,
1649                                                                                                                  guint prog_ver)
1650 {
1651
1652 rpc_prog_info_value *rpc_prog = NULL;
1653
1654
1655         /* sanity check: no one uses versions > 10 */
1656         if(prog_ver>10){
1657                 return;
1658         }
1659
1660         if( (rpc_prog = g_hash_table_lookup(rpc_progs, prpc_prog_key)) == NULL) {
1661                 /* ok this is not a known rpc program so we
1662                  * will have to fake it.
1663                  */
1664                 int proto_rpc_unknown_program;
1665                 char *NAME, *Name, *name;
1666                 static const vsff unknown_proc[] = {
1667                         { 0,"NULL",NULL,NULL },
1668                         { 0,NULL,NULL,NULL }
1669                 };
1670
1671                 NAME=g_malloc(36);
1672                 Name=g_malloc(32);
1673                 name=g_malloc(32);
1674                 g_snprintf(NAME, 36, "Unknown RPC Program:%d",prpc_prog_key->prog);
1675                 g_snprintf(Name, 32, "RPC:%d",prpc_prog_key->prog);
1676                 g_snprintf(name, 32, "rpc%d",prpc_prog_key->prog);
1677                 proto_rpc_unknown_program = proto_register_protocol(NAME, Name, name);
1678
1679                 rpc_init_prog(proto_rpc_unknown_program, prpc_prog_key->prog, ett_rpc_unknown_program);
1680                 rpc_init_proc_table(prpc_prog_key->prog, prog_ver, unknown_proc, hf_rpc_procedure);
1681
1682         }
1683 }
1684
1685
1686 static gboolean
1687 dissect_rpc_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1688     tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
1689     guint32 rpc_rm, gboolean first_pdu)
1690 {
1691         guint32 msg_type;
1692         rpc_call_info_value *rpc_call = NULL;
1693         rpc_prog_info_value *rpc_prog = NULL;
1694         rpc_prog_info_key rpc_prog_key;
1695
1696         unsigned int xid;
1697         unsigned int rpcvers;
1698         unsigned int prog = 0;
1699         unsigned int vers = 0;
1700         unsigned int proc = 0;
1701         flavor_t flavor = FLAVOR_UNKNOWN;
1702         unsigned int gss_proc = 0;
1703         unsigned int gss_svc = 0;
1704         protocol_t *proto = NULL;
1705         int     proto_id = 0;
1706         int     ett = 0;
1707         int     procedure_hf;
1708
1709         unsigned int reply_state;
1710         unsigned int accept_state;
1711         unsigned int reject_state;
1712
1713         const char *msg_type_name = NULL;
1714         const char *progname = NULL;
1715         char *procname = NULL;
1716
1717         unsigned int vers_low;
1718         unsigned int vers_high;
1719
1720         unsigned int auth_state;
1721
1722         proto_item *rpc_item = NULL;
1723         proto_tree *rpc_tree = NULL;
1724
1725         proto_item *pitem = NULL;
1726         proto_tree *ptree = NULL;
1727         int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
1728
1729         rpc_proc_info_key       key;
1730         rpc_proc_info_value     *value = NULL;
1731         conversation_t* conversation;
1732         static address null_address = { AT_NONE, 0, NULL };
1733         nstime_t ns;
1734
1735         dissect_function_t *dissect_function = NULL;
1736         gboolean dissect_rpc = TRUE;
1737
1738         rpc_conv_info_t *rpc_conv_info=NULL;
1739
1740
1741         /*
1742          * Check to see whether this looks like an RPC call or reply.
1743          */
1744         if (!tvb_bytes_exist(tvb, offset, 8)) {
1745                 /* Captured data in packet isn't enough to let us tell. */
1746                 return FALSE;
1747         }
1748
1749         /* both directions need at least this */
1750         msg_type = tvb_get_ntohl(tvb, offset + 4);
1751
1752         switch (msg_type) {
1753
1754         case RPC_CALL:
1755                 /* check for RPC call */
1756                 if (!tvb_bytes_exist(tvb, offset, 16)) {
1757                         /* Captured data in packet isn't enough to let us
1758                            tell. */
1759                         return FALSE;
1760                 }
1761
1762                 /* XID can be anything, so dont check it.
1763                    We already have the message type.
1764                    Check whether an RPC version number of 2 is in the
1765                    location where it would be, and that an RPC program
1766                    number we know about is in the location where it would be.
1767
1768                    XXX - Sun's snoop appears to recognize as RPC even calls
1769                    to stuff it doesn't dissect; does it just look for a 2
1770                    at that location, which seems far to weak a heuristic
1771                    (too many false positives), or does it have some additional
1772                    checks it does?
1773
1774                    We could conceivably check for any of the program numbers
1775                    in the list at
1776
1777                         ftp://ftp.tau.ac.il/pub/users/eilon/rpc/rpc
1778
1779                    and report it as RPC (but not dissect the payload if
1780                    we don't have a subdissector) if it matches. */
1781                 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1782
1783                 /* we only dissect version 2 */
1784                 if (tvb_get_ntohl(tvb, offset + 8) != 2 ){
1785                         return FALSE;
1786                 }
1787                 /* let the user be able to weaken the heuristics if he need
1788                  * to look at proprietary protocols not known
1789                  * to wireshark.
1790                  */
1791                 if(rpc_dissect_unknown_programs){
1792                         guint32 version;
1793
1794                         /* if the user has specified that he wants to try to
1795                          * dissect even completely unknown RPC program numbers
1796                          * then let him do that.
1797                          * In this case we only check that the program number
1798                          * is neither 0 nor -1 which is better than nothing.
1799                          */
1800                         if(rpc_prog_key.prog==0 || rpc_prog_key.prog==0xffffffff){
1801                                 return FALSE;
1802                         }
1803                         version=tvb_get_ntohl(tvb, offset+16);
1804                         make_fake_rpc_prog_if_needed (&rpc_prog_key, version);
1805                 }
1806                 if( (rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key)) == NULL) {
1807                         /* They're not, so it's probably not an RPC call. */
1808                         return FALSE;
1809                 }
1810                 break;
1811
1812         case RPC_REPLY:
1813                 /* Check for RPC reply.  A reply must match a call that
1814                    we've seen, and the reply must be sent to the same
1815                    address that the call came from, and must come from
1816                    the port to which the call was sent.
1817
1818                    If the transport is connection-oriented (we check, for
1819                    now, only for "pinfo->ptype" of PT_TCP), we take
1820                    into account the port from which the call was sent
1821                    and the address to which the call was sent, because
1822                    the addresses and ports of the two endpoints should be
1823                    the same for all calls and replies.
1824
1825                    If the transport is connectionless, we don't worry
1826                    about the address to which the call was sent and from
1827                    which the reply was sent, because there's no
1828                    guarantee that the reply will come from the address
1829                    to which the call was sent.  We also don't worry about
1830                    the port *from* which the call was sent and *to* which
1831                    the reply was sent, because some clients (*cough* OS X
1832                    NFS client *cough) might send retransmissions from a
1833                    different port from the original request. */
1834                 if (pinfo->ptype == PT_TCP) {
1835                         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
1836                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1837                             pinfo->destport, 0);
1838                 } else {
1839                         /*
1840                          * XXX - you currently still have to pass a non-null
1841                          * pointer for the second address argument even
1842                          * if you use NO_ADDR_B.
1843                          */
1844                         conversation = find_conversation(pinfo->fd->num, &pinfo->dst,
1845                             &null_address, pinfo->ptype, pinfo->srcport,
1846                             0, NO_ADDR_B|NO_PORT_B);
1847                 }
1848                 if (conversation == NULL) {
1849                         /* We haven't seen an RPC call for that conversation,
1850                            so we can't check for a reply to that call. */
1851                         return FALSE;
1852                 }
1853                 /*
1854                  * Do we already have a state structure for this conv
1855                  */
1856                 rpc_conv_info = conversation_get_proto_data(conversation, proto_rpc);
1857                 if (!rpc_conv_info) {
1858                         /* No.  Attach that information to the conversation, and add
1859                          * it to the list of information structures.
1860                          */
1861                         rpc_conv_info = se_alloc(sizeof(rpc_conv_info_t));
1862                         rpc_conv_info->xids=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "rpc_xids");
1863
1864                         conversation_add_proto_data(conversation, proto_rpc, rpc_conv_info);
1865                 }
1866
1867                 /* The XIDs of the call and reply must match. */
1868                 xid = tvb_get_ntohl(tvb, offset + 0);
1869                 rpc_call = se_tree_lookup32(rpc_conv_info->xids, xid);
1870                 if (rpc_call == NULL) {
1871                         /* The XID doesn't match a call from that
1872                            conversation, so it's probably not an RPC reply. */
1873
1874                         /* unless we're permitted to scan for embedded records
1875                          * and this is a connection-oriented transport, give up */
1876                         if ((! rpc_find_fragment_start) || (pinfo->ptype != PT_TCP)) {
1877                                 return FALSE;
1878                         }
1879
1880                         /* in parse-partials, so define a dummy conversation for this reply */
1881                         rpc_call = se_alloc(sizeof(rpc_call_info_value));
1882                         rpc_call->req_num = 0;
1883                         rpc_call->rep_num = pinfo->fd->num;
1884                         rpc_call->prog = 0;
1885                         rpc_call->vers = 0;
1886                         rpc_call->proc = 0;
1887                         rpc_call->private_data = NULL;
1888                         rpc_call->xid = xid;
1889                         rpc_call->flavor = FLAVOR_NOT_GSSAPI;  /* total punt */
1890                         rpc_call->gss_proc = 0;
1891                         rpc_call->gss_svc = 0;
1892                         rpc_call->proc_info = value;
1893                         rpc_call->req_time = pinfo->fd->abs_ts;
1894
1895                         /* store it */
1896                         se_tree_insert32(rpc_conv_info->xids, xid, (void *)rpc_call);
1897
1898                         /* and fake up a matching program */
1899                         rpc_prog_key.prog = rpc_call->prog;
1900                 }
1901
1902                 /* pass rpc_info to subdissectors */
1903                 rpc_call->request=FALSE;
1904                 pinfo->private_data=rpc_call;
1905                 break;
1906
1907         default:
1908                 /* The putative message type field contains neither
1909                    RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1910                    reply. */
1911                 return FALSE;
1912         }
1913
1914         if (is_tcp) {
1915                 /*
1916                  * This is RPC-over-TCP; check if this is the last
1917                  * fragment.
1918                  */
1919                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
1920                         /*
1921                          * This isn't the last fragment.
1922                          * If we're doing reassembly, just return
1923                          * TRUE to indicate that this looks like
1924                          * the beginning of an RPC message,
1925                          * and let them do fragment reassembly.
1926                          */
1927                         if (rpc_defragment)
1928                                 return TRUE;
1929                 }
1930         }
1931
1932         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1933                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1934
1935         if (tree) {
1936                 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0, -1,
1937                     FALSE);
1938                 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1939
1940                 if (is_tcp) {
1941                         show_rpc_fraginfo(tvb, frag_tvb, rpc_tree, rpc_rm,
1942                             ipfd_head, pinfo);
1943                 }
1944         }
1945
1946         xid      = tvb_get_ntohl(tvb, offset + 0);
1947         if (rpc_tree) {
1948                 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1949                         offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1950         }
1951
1952         msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1953         if (rpc_tree) {
1954                 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1955                         offset+4, 4, msg_type);
1956                 proto_item_append_text(rpc_item, ", Type:%s XID:0x%08x", msg_type_name, xid);
1957         }
1958
1959         offset += 8;
1960
1961         switch (msg_type) {
1962
1963         case RPC_CALL:
1964                 /* we know already the proto-entry, the ETT-const,
1965                    and "rpc_prog" */
1966                 proto = rpc_prog->proto;
1967                 proto_id = rpc_prog->proto_id;
1968                 ett = rpc_prog->ett;
1969                 progname = rpc_prog->progname;
1970
1971                 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1972                 if (rpc_tree) {
1973                         proto_tree_add_uint(rpc_tree,
1974                                 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1975                 }
1976
1977                 prog = tvb_get_ntohl(tvb, offset + 4);
1978
1979                 if (rpc_tree) {
1980                         proto_tree_add_uint_format(rpc_tree,
1981                                 hf_rpc_program, tvb, offset+4, 4, prog,
1982                                 "Program: %s (%u)", progname, prog);
1983                 }
1984
1985                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1986                         /* Set the protocol name to the underlying
1987                            program name. */
1988                         col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1989                 }
1990
1991                 vers = tvb_get_ntohl(tvb, offset+8);
1992                 if (rpc_tree) {
1993                         proto_tree_add_uint(rpc_tree,
1994                                 hf_rpc_programversion, tvb, offset+8, 4, vers);
1995                 }
1996
1997                 proc = tvb_get_ntohl(tvb, offset+12);
1998
1999                 key.prog = prog;
2000                 key.vers = vers;
2001                 key.proc = proc;
2002
2003                 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
2004                         dissect_function = value->dissect_call;
2005                         procname = (char *)value->name;
2006                 }
2007                 else {
2008                         /* happens only with strange program versions or
2009                            non-existing dissectors */
2010 #if 0
2011                         dissect_function = NULL;
2012 #endif
2013                         procname=ep_alloc(20);
2014                         g_snprintf(procname, 20, "proc-%u", proc);
2015                 }
2016
2017                 /* Check for RPCSEC_GSS and AUTH_GSSAPI */
2018                 if (tvb_bytes_exist(tvb, offset+16, 4)) {
2019                         switch (tvb_get_ntohl(tvb, offset+16)) {
2020
2021                         case RPCSEC_GSS:
2022                                 /*
2023                                  * It's GSS-API authentication...
2024                                  */
2025                                 if (tvb_bytes_exist(tvb, offset+28, 8)) {
2026                                         /*
2027                                          * ...and we have the procedure
2028                                          * and service information for it.
2029                                          */
2030                                         flavor = FLAVOR_GSSAPI;
2031                                         gss_proc = tvb_get_ntohl(tvb, offset+28);
2032                                         gss_svc = tvb_get_ntohl(tvb, offset+36);
2033                                 } else {
2034                                         /*
2035                                          * ...but the procedure and service
2036                                          * information isn't available.
2037                                          */
2038                                         flavor = FLAVOR_GSSAPI_NO_INFO;
2039                                 }
2040                                 break;
2041
2042                         case AUTH_GSSAPI:
2043                                 /*
2044                                  * AUTH_GSSAPI flavor.  If auth_msg is TRUE,
2045                                  * then this is an AUTH_GSSAPI message and
2046                                  * not an application level message.
2047                                  */
2048                                 if (tvb_bytes_exist(tvb, offset+28, 4)) {
2049                                         if (tvb_get_ntohl(tvb, offset+28)) {
2050                                                 flavor = FLAVOR_AUTHGSSAPI_MSG;
2051                                                 gss_proc = proc;
2052                                                 procname = (char *)
2053                                                     val_to_str(gss_proc,
2054                                                     rpc_authgssapi_proc, "Unknown (%d)");
2055                                         } else {
2056                                                 flavor = FLAVOR_AUTHGSSAPI;
2057                                         }
2058                                 }
2059                                 break;
2060
2061                         default:
2062                                 /*
2063                                  * It's not GSS-API authentication.
2064                                  */
2065                                 flavor = FLAVOR_NOT_GSSAPI;
2066                                 break;
2067                         }
2068                 }
2069
2070                 if (rpc_tree) {
2071                         proto_tree_add_uint_format(rpc_tree,
2072                                 hf_rpc_procedure, tvb, offset+12, 4, proc,
2073                                 "Procedure: %s (%u)", procname, proc);
2074                 }
2075
2076                 if (check_col(pinfo->cinfo, COL_INFO)) {
2077                         if (first_pdu)
2078                                 col_clear(pinfo->cinfo, COL_INFO);
2079                         else
2080                                 col_append_str(pinfo->cinfo, COL_INFO, "  ; ");
2081                         col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2082                                 vers,
2083                                 procname,
2084                                 msg_type_name);
2085                 }
2086
2087                 /* Keep track of the address whence the call came, and the
2088                    port to which the call is being sent, so that we can
2089                    match up calls with replies.
2090
2091                    If the transport is connection-oriented (we check, for
2092                    now, only for "pinfo->ptype" of PT_TCP), we also take
2093                    into account the port from which the call was sent
2094                    and the address to which the call was sent, because
2095                    the addresses and ports of the two endpoints should be
2096                    the same for all calls and replies.  (XXX - what if
2097                    the connection is broken and re-established?)
2098
2099                    If the transport is connectionless, we don't worry
2100                    about the address to which the call was sent and from
2101                    which the reply was sent, because there's no
2102                    guarantee that the reply will come from the address
2103                    to which the call was sent.  We also don't worry about
2104                    the port *from* which the call was sent and *to* which
2105                    the reply was sent, because some clients (*cough* OS X
2106                    NFS client *cough) might send retransmissions from a
2107                    different port from the original request. */
2108                 if (pinfo->ptype == PT_TCP) {
2109                         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
2110                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
2111                             pinfo->destport, 0);
2112                 } else {
2113                         /*
2114                          * XXX - you currently still have to pass a non-null
2115                          * pointer for the second address argument even
2116                          * if you use NO_ADDR_B.
2117                          */
2118                         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
2119                             &null_address, pinfo->ptype, pinfo->destport,
2120                             0, NO_ADDR_B|NO_PORT_B);
2121                 }
2122                 if (conversation == NULL) {
2123                         /* It's not part of any conversation - create a new
2124                            one. */
2125                         if (pinfo->ptype == PT_TCP) {
2126                                 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
2127                                     &pinfo->dst, pinfo->ptype, pinfo->srcport,
2128                                     pinfo->destport, 0);
2129                         } else {
2130                                 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
2131                                     &null_address, pinfo->ptype, pinfo->destport,
2132                                     0, NO_ADDR2|NO_PORT2);
2133                         }
2134                 }
2135                 /*
2136                  * Do we already have a state structure for this conv
2137                  */
2138                 rpc_conv_info = conversation_get_proto_data(conversation, proto_rpc);
2139                 if (!rpc_conv_info) {
2140                         /* No.  Attach that information to the conversation, and add
2141                          * it to the list of information structures.
2142                          */
2143                         rpc_conv_info = se_alloc(sizeof(rpc_conv_info_t));
2144                         rpc_conv_info->xids=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "rpc_xids");
2145
2146                         conversation_add_proto_data(conversation, proto_rpc, rpc_conv_info);
2147                 }
2148
2149
2150                 /* Make the dissector for this conversation the non-heuristic
2151                    RPC dissector. */
2152                 conversation_set_dissector(conversation,
2153                         (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
2154
2155                 /* look up the request */
2156                 rpc_call = se_tree_lookup32(rpc_conv_info->xids, xid);
2157                 if (rpc_call) {
2158                         /* We've seen a request with this XID, with the same
2159                            source and destination, before - but was it
2160                            *this* request? */
2161                         if (pinfo->fd->num != rpc_call->req_num) {
2162                                 /* No, so it's a duplicate request.
2163                                    Mark it as such. */
2164                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2165                                         col_prepend_fstr(pinfo->cinfo, COL_INFO,
2166                                                 "[RPC retransmission of #%d]", rpc_call->req_num);
2167                                 }
2168                                 proto_tree_add_item(rpc_tree,
2169                                         hf_rpc_dup, tvb, 0,0, TRUE);
2170                                 proto_tree_add_uint(rpc_tree,
2171                                         hf_rpc_call_dup, tvb, 0,0, rpc_call->req_num);
2172                         }
2173                         if(rpc_call->rep_num){
2174                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2175                                         col_append_fstr(pinfo->cinfo, COL_INFO," (Reply In %d)", rpc_call->rep_num);
2176                                 }
2177                         }
2178                 } else {
2179                         /* Prepare the value data.
2180                            "req_num" and "rep_num" are frame numbers;
2181                            frame numbers are 1-origin, so we use 0
2182                            to mean "we don't yet know in which frame
2183                            the reply for this call appears". */
2184                         rpc_call = se_alloc(sizeof(rpc_call_info_value));
2185                         rpc_call->req_num = pinfo->fd->num;
2186                         rpc_call->rep_num = 0;
2187                         rpc_call->prog = prog;
2188                         rpc_call->vers = vers;
2189                         rpc_call->proc = proc;
2190                         rpc_call->private_data = NULL;
2191                         rpc_call->xid = xid;
2192                         rpc_call->flavor = flavor;
2193                         rpc_call->gss_proc = gss_proc;
2194                         rpc_call->gss_svc = gss_svc;
2195                         rpc_call->proc_info = value;
2196                         rpc_call->req_time = pinfo->fd->abs_ts;
2197
2198                         /* store it */
2199                         se_tree_insert32(rpc_conv_info->xids, xid, (void *)rpc_call);
2200                 }
2201
2202                 if(rpc_call && rpc_call->rep_num){
2203                         proto_item *tmp_item;
2204
2205                         tmp_item=proto_tree_add_uint_format(rpc_tree, hf_rpc_reqframe,
2206                             tvb, 0, 0, rpc_call->rep_num,
2207                             "The reply to this request is in frame %u",
2208                             rpc_call->rep_num);
2209                         PROTO_ITEM_SET_GENERATED(tmp_item);
2210                 }
2211
2212                 offset += 16;
2213
2214                 offset = dissect_rpc_cred(tvb, rpc_tree, offset);
2215                 offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2216
2217                 /* pass rpc_info to subdissectors */
2218                 rpc_call->request=TRUE;
2219                 pinfo->private_data=rpc_call;
2220
2221                 /* go to the next dissector */
2222
2223                 break;  /* end of RPC call */
2224
2225         case RPC_REPLY:
2226                 /* we know already the type from the calling routine,
2227                    and we already have "rpc_call" set above. */
2228                 prog = rpc_call->prog;
2229                 vers = rpc_call->vers;
2230                 proc = rpc_call->proc;
2231                 flavor = rpc_call->flavor;
2232                 gss_proc = rpc_call->gss_proc;
2233                 gss_svc = rpc_call->gss_svc;
2234
2235                 if (rpc_call->proc_info != NULL) {
2236                         dissect_function = rpc_call->proc_info->dissect_reply;
2237                         if (rpc_call->proc_info->name != NULL) {
2238                                 procname = (char *)rpc_call->proc_info->name;
2239                         }
2240                         else {
2241                                 procname=ep_alloc(20);
2242                                 g_snprintf(procname, 20, "proc-%u", proc);
2243                         }
2244                 }
2245                 else {
2246 #if 0
2247                         dissect_function = NULL;
2248 #endif
2249                         procname=ep_alloc(20);
2250                         g_snprintf(procname, 20, "proc-%u", proc);
2251                 }
2252
2253                 /*
2254                  * If this is an AUTH_GSSAPI message, then the RPC procedure
2255                  * is not an application procedure, but rather an auth level
2256                  * procedure, so it would be misleading to print the RPC
2257                  * procname.  Replace the RPC procname with the corresponding
2258                  * AUTH_GSSAPI procname.
2259                  */
2260                 if (flavor == FLAVOR_AUTHGSSAPI_MSG) {
2261                         procname = (char *)match_strval(gss_proc, rpc_authgssapi_proc);
2262                 }
2263
2264                 rpc_prog_key.prog = prog;
2265                 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
2266                         proto = NULL;
2267                         proto_id = 0;
2268                         ett = 0;
2269                         progname = "Unknown";
2270                 }
2271                 else {
2272                         proto = rpc_prog->proto;
2273                         proto_id = rpc_prog->proto_id;
2274                         ett = rpc_prog->ett;
2275                         progname = rpc_prog->progname;
2276
2277                         if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2278                                 /* Set the protocol name to the underlying
2279                                    program name. */
2280                                 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
2281                         }
2282                 }
2283
2284                 if (check_col(pinfo->cinfo, COL_INFO)) {
2285                         if (first_pdu)
2286                                 col_clear(pinfo->cinfo, COL_INFO);
2287                         else
2288                                 col_append_str(pinfo->cinfo, COL_INFO, "  ; ");
2289                         col_append_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s",
2290                                 vers,
2291                                 procname,
2292                                 msg_type_name);
2293                 }
2294
2295                 if (rpc_tree) {
2296                         proto_item *tmp_item;
2297                         tmp_item=proto_tree_add_uint_format(rpc_tree,
2298                                 hf_rpc_program, tvb, 0, 0, prog,
2299                                 "Program: %s (%u)", progname, prog);
2300                         PROTO_ITEM_SET_GENERATED(tmp_item);
2301                         tmp_item=proto_tree_add_uint(rpc_tree,
2302                                 hf_rpc_programversion, tvb, 0, 0, vers);
2303                         PROTO_ITEM_SET_GENERATED(tmp_item);
2304                         tmp_item=proto_tree_add_uint_format(rpc_tree,
2305                                 hf_rpc_procedure, tvb, 0, 0, proc,
2306                                 "Procedure: %s (%u)", procname, proc);
2307                         PROTO_ITEM_SET_GENERATED(tmp_item);
2308                 }
2309
2310                 reply_state = tvb_get_ntohl(tvb,offset+0);
2311                 if (rpc_tree) {
2312                         proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
2313                                 offset+0, 4, reply_state);
2314                 }
2315                 offset += 4;
2316
2317                 /* Indicate the frame to which this is a reply. */
2318                 if(rpc_call && rpc_call->req_num){
2319                         proto_item *tmp_item;
2320
2321                         tmp_item=proto_tree_add_uint_format(rpc_tree, hf_rpc_repframe,
2322                             tvb, 0, 0, rpc_call->req_num,
2323                             "This is a reply to a request in frame %u",
2324                             rpc_call->req_num);
2325                         PROTO_ITEM_SET_GENERATED(tmp_item);
2326
2327                         nstime_delta(&ns, &pinfo->fd->abs_ts, &rpc_call->req_time);
2328                         tmp_item=proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
2329                                 &ns);
2330                         PROTO_ITEM_SET_GENERATED(tmp_item);
2331
2332                         if (check_col(pinfo->cinfo, COL_INFO)) {
2333                                 col_append_fstr(pinfo->cinfo, COL_INFO," (Call In %d)", rpc_call->req_num);
2334                         }
2335                 }
2336
2337
2338                 if ((!rpc_call) || (rpc_call->rep_num == 0)) {
2339                         /* We have not yet seen a reply to that call, so
2340                            this must be the first reply; remember its
2341                            frame number. */
2342                         rpc_call->rep_num = pinfo->fd->num;
2343                 } else {
2344                         /* We have seen a reply to this call - but was it
2345                            *this* reply? */
2346                         if (rpc_call->rep_num != pinfo->fd->num) {
2347                                 proto_item *tmp_item;
2348
2349                                 /* No, so it's a duplicate reply.
2350                                    Mark it as such. */
2351                                 if (check_col(pinfo->cinfo, COL_INFO)) {
2352                                         col_prepend_fstr(pinfo->cinfo, COL_INFO,
2353                                                 "[RPC duplicate of #%d]", rpc_call->rep_num);
2354                                 }
2355                                 tmp_item=proto_tree_add_item(rpc_tree,
2356                                         hf_rpc_dup, tvb, 0,0, TRUE);
2357                                 PROTO_ITEM_SET_GENERATED(tmp_item);
2358
2359                                 tmp_item=proto_tree_add_uint(rpc_tree,
2360                                         hf_rpc_reply_dup, tvb, 0,0, rpc_call->rep_num);
2361                                 PROTO_ITEM_SET_GENERATED(tmp_item);
2362                         }
2363                 }
2364
2365                 switch (reply_state) {
2366
2367                 case MSG_ACCEPTED:
2368                         offset = dissect_rpc_verf(tvb, rpc_tree, offset, msg_type, pinfo);
2369                         accept_state = tvb_get_ntohl(tvb,offset+0);
2370                         if (rpc_tree) {
2371                                 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
2372                                         offset+0, 4, accept_state);
2373                         }
2374                         offset += 4;
2375                         switch (accept_state) {
2376
2377                         case SUCCESS:
2378                                 /* go to the next dissector */
2379                                 break;
2380
2381                         case PROG_MISMATCH:
2382                                 vers_low = tvb_get_ntohl(tvb,offset+0);
2383                                 vers_high = tvb_get_ntohl(tvb,offset+4);
2384                                 if (rpc_tree) {
2385                                         proto_tree_add_uint(rpc_tree,
2386                                                 hf_rpc_programversion_min,
2387                                                 tvb, offset+0, 4, vers_low);
2388                                         proto_tree_add_uint(rpc_tree,
2389                                                 hf_rpc_programversion_max,
2390                                                 tvb, offset+4, 4, vers_high);
2391                                 }
2392                                 offset += 8;
2393
2394                                 /*
2395                                  * There's no protocol reply, so don't
2396                                  * try to dissect it.
2397                                  */
2398                                 dissect_rpc = FALSE;
2399                                 break;
2400
2401                         default:
2402                                 /*
2403                                  * There's no protocol reply, so don't
2404                                  * try to dissect it.
2405                                  */
2406                                 dissect_rpc = FALSE;
2407                                 break;
2408                         }
2409                         break;
2410
2411                 case MSG_DENIED:
2412                         reject_state = tvb_get_ntohl(tvb,offset+0);
2413                         if (rpc_tree) {
2414                                 proto_tree_add_uint(rpc_tree,
2415                                         hf_rpc_state_reject, tvb, offset+0, 4,
2416                                         reject_state);
2417                         }
2418                         offset += 4;
2419
2420                         if (reject_state==RPC_MISMATCH) {
2421                                 vers_low = tvb_get_ntohl(tvb,offset+0);
2422                                 vers_high = tvb_get_ntohl(tvb,offset+4);
2423                                 if (rpc_tree) {
2424                                         proto_tree_add_uint(rpc_tree,
2425                                                 hf_rpc_version_min,
2426                                                 tvb, offset+0, 4, vers_low);
2427                                         proto_tree_add_uint(rpc_tree,
2428                                                 hf_rpc_version_max,
2429                                                 tvb, offset+4, 4, vers_high);
2430                                 }
2431                                 offset += 8;
2432                         } else if (reject_state==AUTH_ERROR) {
2433                                 auth_state = tvb_get_ntohl(tvb,offset+0);
2434                                 if (rpc_tree) {
2435                                         proto_tree_add_uint(rpc_tree,
2436                                                 hf_rpc_state_auth, tvb, offset+0, 4,
2437                                                 auth_state);
2438                                 }
2439                                 offset += 4;
2440                         }
2441
2442                         /*
2443                          * There's no protocol reply, so don't
2444                          * try to dissect it.
2445                          */
2446                         dissect_rpc = FALSE;
2447                         break;
2448
2449                 default:
2450                         /*
2451                          * This isn't a valid reply state, so we have
2452                          * no clue what's going on; don't try to dissect
2453                          * the protocol reply.
2454                          */
2455                         dissect_rpc = FALSE;
2456                         break;
2457                 }
2458                 break; /* end of RPC reply */
2459
2460         default:
2461                 /*
2462                  * The switch statement at the top returned if
2463                  * this was neither an RPC call nor a reply.
2464                  */
2465                 DISSECTOR_ASSERT_NOT_REACHED();
2466         }
2467
2468         /* now we know, that RPC was shorter */
2469         if (rpc_item) {
2470                 if (offset < 0)
2471                         THROW(ReportedBoundsError);
2472                 tvb_ensure_bytes_exist(tvb, offset, 0);
2473                 proto_item_set_end(rpc_item, tvb, offset);
2474         }
2475
2476         if (!dissect_rpc) {
2477                 /*
2478                  * There's no RPC call or reply here; just dissect
2479                  * whatever's left as data.
2480                  */
2481                 call_dissector(data_handle,
2482                     tvb_new_subset(tvb, offset, -1, -1), pinfo, rpc_tree);
2483                 return TRUE;
2484         }
2485
2486         /* we must queue this packet to the tap system before we actually
2487            call the subdissectors since short packets (i.e. nfs read reply)
2488            will cause an exception and execution would never reach the call
2489            to tap_queue_packet() in that case
2490         */
2491         tap_queue_packet(rpc_tap, pinfo, rpc_call);
2492
2493         /* create here the program specific sub-tree */
2494         if (tree && (flavor != FLAVOR_AUTHGSSAPI_MSG)) {
2495                 pitem = proto_tree_add_item(tree, proto_id, tvb, offset, -1,
2496                     FALSE);
2497                 if (pitem) {
2498                         ptree = proto_item_add_subtree(pitem, ett);
2499                 }
2500
2501                 if (ptree) {
2502                         proto_item *tmp_item;
2503
2504                         tmp_item=proto_tree_add_uint(ptree,
2505                                 hf_rpc_programversion, tvb, 0, 0, vers);
2506                         PROTO_ITEM_SET_GENERATED(tmp_item);
2507                         if (rpc_prog && (rpc_prog->procedure_hfs->len > vers) )
2508                                 procedure_hf = g_array_index(rpc_prog->procedure_hfs, int, vers);
2509                         else {
2510                                 /*
2511                                  * No such element in the GArray.
2512                                  */
2513                                 procedure_hf = 0;
2514                         }
2515                         if (procedure_hf != 0 && procedure_hf != -1) {
2516                                 tmp_item=proto_tree_add_uint(ptree,
2517                                         procedure_hf, tvb, 0, 0, proc);
2518                                 PROTO_ITEM_SET_GENERATED(tmp_item);
2519                         } else {
2520                                 tmp_item=proto_tree_add_uint_format(ptree,
2521                                         hf_rpc_procedure, tvb, 0, 0, proc,
2522                                         "Procedure: %s (%u)", procname, proc);
2523                                 PROTO_ITEM_SET_GENERATED(tmp_item);
2524                         }
2525                 }
2526         }
2527
2528         /* proto==0 if this is an unknown program */
2529         if( (proto==0) || !proto_is_protocol_enabled(proto)){
2530                 dissect_function = NULL;
2531         }
2532
2533         /*
2534          * Don't call any subdissector if we have no more date to dissect.
2535          */
2536         if (tvb_length_remaining(tvb, offset) == 0) {
2537                 return TRUE;
2538         }
2539
2540         /*
2541          * Handle RPCSEC_GSS and AUTH_GSSAPI specially.
2542          */
2543         switch (flavor) {
2544
2545         case FLAVOR_UNKNOWN:
2546                 /*
2547                  * We don't know the authentication flavor, so we can't
2548                  * dissect the payload.
2549                  */
2550                 proto_tree_add_text(ptree, tvb, offset, -1,
2551                     "Unknown authentication flavor - cannot dissect");
2552                 return TRUE;
2553
2554         case FLAVOR_NOT_GSSAPI:
2555                 /*
2556                  * It's not GSS-API authentication.  Just dissect the
2557                  * payload.
2558                  */
2559                 offset = call_dissect_function(tvb, pinfo, ptree, offset,
2560                                 dissect_function, progname);
2561                 break;
2562
2563         case FLAVOR_GSSAPI_NO_INFO:
2564                 /*
2565                  * It's GSS-API authentication, but we don't have the
2566                  * procedure and service information, so we can't dissect
2567                  * the payload.
2568                  */
2569                 proto_tree_add_text(ptree, tvb, offset, -1,
2570                     "GSS-API authentication, but procedure and service unknown - cannot dissect");
2571                 return TRUE;
2572
2573         case FLAVOR_GSSAPI:
2574                 /*
2575                  * It's GSS-API authentication, and we have the procedure
2576                  * and service information; process the GSS-API stuff,
2577                  * and process the payload if there is any.
2578                  */
2579                 switch (gss_proc) {
2580
2581                 case RPCSEC_GSS_INIT:
2582                 case RPCSEC_GSS_CONTINUE_INIT:
2583                         if (msg_type == RPC_CALL) {
2584                                 offset = dissect_rpc_authgss_initarg(tvb,
2585                                         ptree, offset, pinfo);
2586                         }
2587                         else {
2588                                 offset = dissect_rpc_authgss_initres(tvb,
2589                                         ptree, offset, pinfo);
2590                         }
2591                         break;
2592
2593                 case RPCSEC_GSS_DATA:
2594                         if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2595                                 offset = call_dissect_function(tvb,
2596                                                 pinfo, ptree, offset,
2597                                                 dissect_function,
2598                                                 progname);
2599                         }
2600                         else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2601                                 offset = dissect_rpc_authgss_integ_data(tvb,
2602                                                 pinfo, ptree, offset,
2603                                                 dissect_function,
2604                                                 progname);
2605                         }
2606                         else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2607                                 offset = dissect_rpc_authgss_priv_data(tvb,
2608                                                 ptree, offset);
2609                         }
2610                         break;
2611
2612                 default:
2613                         break;
2614                 }
2615                 break;
2616
2617         case FLAVOR_AUTHGSSAPI_MSG:
2618                 /*
2619                  * This is an AUTH_GSSAPI message.  It contains data
2620                  * only for the authentication procedure and not for the
2621                  * application level RPC procedure.  Reset the column
2622                  * protocol and info fields to indicate that this is
2623                  * an RPC auth level message, then process the args.
2624                  */
2625                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2626                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
2627                 }
2628                 if (check_col(pinfo->cinfo, COL_INFO)) {
2629                         col_clear(pinfo->cinfo, COL_INFO);
2630                         col_append_fstr(pinfo->cinfo, COL_INFO,
2631                             "%s %s XID 0x%x",
2632                             val_to_str(gss_proc, rpc_authgssapi_proc, "Unknown (%d)"),
2633                             msg_type_name, xid);
2634                 }
2635
2636                 switch (gss_proc) {
2637
2638                 case AUTH_GSSAPI_INIT:
2639                 case AUTH_GSSAPI_CONTINUE_INIT:
2640                 case AUTH_GSSAPI_MSG:
2641                         if (msg_type == RPC_CALL) {
2642                             offset = dissect_rpc_authgssapi_initarg(tvb,
2643                                 rpc_tree, offset, pinfo);
2644                         } else {
2645                             offset = dissect_rpc_authgssapi_initres(tvb,
2646                                 rpc_tree, offset, pinfo);
2647                         }
2648                         break;
2649
2650                 case AUTH_GSSAPI_DESTROY:
2651                         offset = dissect_rpc_data(tvb, rpc_tree,
2652                             hf_rpc_authgss_data, offset);
2653                         break;
2654
2655                 case AUTH_GSSAPI_EXIT:
2656                         break;
2657                 }
2658
2659                 /* Adjust the length to account for the auth message. */
2660                 if (rpc_item) {
2661                         proto_item_set_end(rpc_item, tvb, offset);
2662                 }
2663                 break;
2664
2665         case FLAVOR_AUTHGSSAPI:
2666                 /*
2667                  * An RPC with AUTH_GSSAPI authentication.  The data
2668                  * portion is always private, so don't call the dissector.
2669                  */
2670                 offset = dissect_auth_gssapi_data(tvb, ptree, offset);
2671                 break;
2672         }
2673
2674         if (tvb_length_remaining(tvb, offset) > 0) {
2675           /*
2676            * dissect any remaining bytes (incomplete dissection) as pure
2677            * data in the ptree
2678            */
2679
2680           call_dissector(data_handle,
2681               tvb_new_subset(tvb, offset, -1, -1), pinfo, ptree);
2682         }
2683
2684         /* XXX this should really loop over all fhandles registred for the frame */
2685         if(nfs_fhandle_reqrep_matching){
2686                 switch (msg_type) {
2687                 case RPC_CALL:
2688                         if(rpc_call && rpc_call->rep_num){
2689                                 dissect_fhandle_hidden(pinfo,
2690                                                 ptree, rpc_call->rep_num);
2691                         }
2692                         break;
2693                 case RPC_REPLY:
2694                         if(rpc_call && rpc_call->req_num){
2695                                 dissect_fhandle_hidden(pinfo,
2696                                                 ptree, rpc_call->req_num);
2697                         }
2698                         break;
2699                 }
2700         }
2701
2702         return TRUE;
2703 }
2704
2705 static gboolean
2706 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2707 {
2708         return dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2709             TRUE);
2710 }
2711
2712 static void
2713 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2714 {
2715         if (!dissect_rpc_message(tvb, pinfo, tree, NULL, NULL, FALSE, 0,
2716             TRUE)) {
2717                 if (tvb_length(tvb) != 0)
2718                         dissect_rpc_continuation(tvb, pinfo, tree);
2719         }
2720 }
2721
2722
2723 /* Defragmentation of RPC-over-TCP records */
2724 /* table to hold defragmented RPC records */
2725 static GHashTable *rpc_fragment_table = NULL;
2726
2727 static GHashTable *rpc_reassembly_table = NULL;
2728
2729 typedef struct _rpc_fragment_key {
2730         guint32 conv_id;
2731         guint32 seq;
2732         guint32 offset;
2733         guint32 port;
2734         /* xxx */
2735         guint32 start_seq;
2736 } rpc_fragment_key;
2737
2738 static guint
2739 rpc_fragment_hash(gconstpointer k)
2740 {
2741         const rpc_fragment_key *key = (const rpc_fragment_key *)k;
2742
2743         return key->conv_id + key->seq;
2744 }
2745
2746 static gint
2747 rpc_fragment_equal(gconstpointer k1, gconstpointer k2)
2748 {
2749         const rpc_fragment_key *key1 = (const rpc_fragment_key *)k1;
2750         const rpc_fragment_key *key2 = (const rpc_fragment_key *)k2;
2751
2752         return key1->conv_id == key2->conv_id &&
2753             key1->seq == key2->seq && key1->port == key2->port;
2754 }
2755
2756 static void
2757 show_rpc_fragheader(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2758 {
2759         proto_item *hdr_item;
2760         proto_tree *hdr_tree;
2761         guint32 fraglen;
2762
2763         if (tree) {
2764                 fraglen = rpc_rm & RPC_RM_FRAGLEN;
2765
2766                 hdr_item = proto_tree_add_text(tree, tvb, 0, 4,
2767                     "Fragment header: %s%u %s",
2768                     (rpc_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
2769                     fraglen, plurality(fraglen, "byte", "bytes"));
2770                 hdr_tree = proto_item_add_subtree(hdr_item, ett_rpc_fraghdr);
2771
2772                 proto_tree_add_boolean(hdr_tree, hf_rpc_lastfrag, tvb, 0, 4,
2773                     rpc_rm);
2774                 proto_tree_add_uint(hdr_tree, hf_rpc_fraglen, tvb, 0, 4,
2775                     rpc_rm);
2776         }
2777 }
2778
2779 static void
2780 show_rpc_fragment(tvbuff_t *tvb, proto_tree *tree, guint32 rpc_rm)
2781 {
2782         if (tree) {
2783                 /*
2784                  * Show the fragment header and the data for the fragment.
2785                  */
2786                 show_rpc_fragheader(tvb, tree, rpc_rm);
2787                 proto_tree_add_text(tree, tvb, 4, -1, "Fragment Data");
2788         }
2789 }
2790
2791 static void
2792 make_frag_tree(tvbuff_t *tvb, proto_tree *tree, int proto, gint ett,
2793     guint32 rpc_rm)
2794 {
2795         proto_item *frag_item;
2796         proto_tree *frag_tree;
2797
2798         if (tree == NULL)
2799                 return;         /* nothing to do */
2800
2801         frag_item = proto_tree_add_protocol_format(tree, proto, tvb, 0, -1,
2802             "%s Fragment", proto_get_protocol_name(proto));
2803         frag_tree = proto_item_add_subtree(frag_item, ett);
2804         show_rpc_fragment(tvb, frag_tree, rpc_rm);
2805 }
2806
2807 void
2808 show_rpc_fraginfo(tvbuff_t *tvb, tvbuff_t *frag_tvb, proto_tree *tree,
2809     guint32 rpc_rm, fragment_data *ipfd_head, packet_info *pinfo)
2810 {
2811     proto_item *frag_tree_item;
2812
2813         if (tree == NULL)
2814                 return;         /* don't do any work */
2815
2816         if (tvb != frag_tvb) {
2817                 /*
2818                  * This message was not all in one fragment,
2819                  * so show the fragment header *and* the data
2820                  * for the fragment (which is the last fragment),
2821                  * and a tree with information about all fragments.
2822                  */
2823                 show_rpc_fragment(frag_tvb, tree, rpc_rm);
2824
2825                 /*
2826                  * Show a tree with information about all fragments.
2827                  */
2828                 show_fragment_tree(ipfd_head, &rpc_frag_items, tree, pinfo, tvb, &frag_tree_item);
2829         } else {
2830                 /*
2831                  * This message was all in one fragment, so just show
2832                  * the fragment header.
2833                  */
2834                 show_rpc_fragheader(tvb, tree, rpc_rm);
2835         }
2836 }
2837
2838 static gboolean
2839 call_message_dissector(tvbuff_t *tvb, tvbuff_t *rec_tvb, packet_info *pinfo,
2840     proto_tree *tree, tvbuff_t *frag_tvb, rec_dissector_t dissector,
2841     fragment_data *ipfd_head, guint32 rpc_rm, gboolean first_pdu)
2842 {
2843         const char *saved_proto;
2844         volatile gboolean rpc_succeeded;
2845
2846         /*
2847          * Catch the ReportedBoundsError exception; if
2848          * this particular message happens to get a
2849          * ReportedBoundsError exception, that doesn't
2850          * mean that we should stop dissecting RPC
2851          * messages within this frame or chunk of
2852          * reassembled data.
2853          *
2854          * If it gets a BoundsError, we can stop, as there's
2855          * nothing more to see, so we just re-throw it.
2856          */
2857         saved_proto = pinfo->current_proto;
2858         rpc_succeeded = FALSE;
2859         TRY {
2860                 rpc_succeeded = (*dissector)(rec_tvb, pinfo, tree,
2861                     frag_tvb, ipfd_head, TRUE, rpc_rm, first_pdu);
2862         }
2863         CATCH(BoundsError) {
2864                 RETHROW;
2865         }
2866         CATCH(ReportedBoundsError) {
2867                 show_reported_bounds_error(tvb, pinfo, tree);
2868                 pinfo->current_proto = saved_proto;
2869
2870                 /*
2871                  * We treat this as a "successful" dissection of
2872                  * an RPC packet, as "dissect_rpc_message()"
2873                  * *did* decide it was an RPC packet, throwing
2874                  * an exception while dissecting it as such.
2875                  */
2876                 rpc_succeeded = TRUE;
2877         }
2878         ENDTRY;
2879         return rpc_succeeded;
2880 }
2881
2882 int
2883 dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
2884     proto_tree *tree, rec_dissector_t dissector, gboolean is_heur,
2885     int proto, int ett, gboolean defragment, gboolean first_pdu)
2886 {
2887         struct tcpinfo *tcpinfo;
2888         guint32 seq;
2889         guint32 rpc_rm;
2890         volatile guint32 len;
2891         gint32 seglen;
2892         gint tvb_len, tvb_reported_len;
2893         tvbuff_t *frag_tvb;
2894         gboolean rpc_succeeded;
2895         gboolean save_fragmented;
2896         rpc_fragment_key old_rfk, *rfk, *new_rfk;
2897         conversation_t *conversation;
2898         fragment_data *ipfd_head;
2899         tvbuff_t *rec_tvb;
2900
2901         if (pinfo == NULL || pinfo->private_data == NULL) {
2902                 return 0;
2903         }
2904         tcpinfo = pinfo->private_data;
2905
2906         if (tcpinfo == NULL) {
2907                 return 0;
2908         }
2909         seq = tcpinfo->seq + offset;
2910
2911         /*
2912          * Get the record mark.
2913          */
2914         if (!tvb_bytes_exist(tvb, offset, 4)) {
2915                 /*
2916                  * XXX - we should somehow arrange to handle
2917                  * a record mark split across TCP segments.
2918                  */
2919                 return 0;       /* not enough to tell if it's valid */
2920         }
2921         rpc_rm = tvb_get_ntohl(tvb, offset);
2922
2923         len = rpc_rm & RPC_RM_FRAGLEN;
2924
2925         /*
2926          * Do TCP desegmentation, if enabled.
2927          *
2928          * reject fragments bigger than this preference setting.
2929          * This is arbitrary, but should at least prevent
2930          * some crashes from either packets with really
2931          * large RPC-over-TCP fragments or from stuff that's
2932          * not really valid for this protocol.
2933          */
2934         if (len > max_rpc_tcp_pdu_size)
2935                 return 0;       /* pretend it's not valid */
2936         if (rpc_desegment) {
2937                 seglen = tvb_length_remaining(tvb, offset + 4);
2938
2939                 if ((gint)len > seglen && pinfo->can_desegment) {
2940                         /*
2941                          * This frame doesn't have all of the
2942                          * data for this message, but we can do
2943                          * reassembly on it.
2944                          *
2945                          * If this is a heuristic dissector, just
2946                          * return 0 - we don't want to try to get
2947                          * more data, as that's too likely to cause
2948                          * us to misidentify this as valid.
2949                          *
2950                          * XXX - this means that we won't
2951                          * recognize the first fragment of a
2952                          * multi-fragment RPC operation unless
2953                          * we've already identified this
2954                          * conversation as being an RPC
2955                          * conversation (and thus aren't running
2956                          * heuristically) - that would be a problem
2957                          * if, for example, the first segment were
2958                          * the beginning of a large NFS WRITE.
2959                          *
2960                          * If this isn't a heuristic dissector,
2961                          * we've already identified this conversation
2962                          * as containing data for this protocol, as we
2963                          * saw valid data in previous frames.  Try to
2964                          * get more data.
2965                          */
2966                         if (is_heur)
2967                                 return 0;       /* not valid */
2968                         else {
2969                                 pinfo->desegment_offset = offset;
2970                                 pinfo->desegment_len = len - seglen;
2971                                 return -((gint32) pinfo->desegment_len);
2972                         }
2973                 }
2974         }
2975         len += 4;       /* include record mark */
2976         tvb_len = tvb_length_remaining(tvb, offset);
2977         tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2978         if (tvb_len > (gint)len)
2979                 tvb_len = len;
2980         if (tvb_reported_len > (gint)len)
2981                 tvb_reported_len = len;
2982         frag_tvb = tvb_new_subset(tvb, offset, tvb_len,
2983             tvb_reported_len);
2984
2985         /*
2986          * If we're not defragmenting, just hand this to the
2987          * disssector.
2988          */
2989         if (!defragment) {
2990                 /*
2991                  * This is the first fragment we've seen, and it's also
2992                  * the last fragment; that means the record wasn't
2993                  * fragmented.  Hand the dissector the tvbuff for the
2994                  * fragment as the tvbuff for the record.
2995                  */
2996                 rec_tvb = frag_tvb;
2997                 ipfd_head = NULL;
2998
2999                 /*
3000                  * Mark this as fragmented, so if somebody throws an
3001                  * exception, we don't report it as a malformed frame.
3002                  */
3003                 save_fragmented = pinfo->fragmented;
3004                 pinfo->fragmented = TRUE;
3005                 rpc_succeeded = call_message_dissector(tvb, rec_tvb, pinfo,
3006                     tree, frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu);
3007                 pinfo->fragmented = save_fragmented;
3008                 if (!rpc_succeeded)
3009                         return 0;       /* not RPC */
3010                 return len;
3011         }
3012
3013         /*
3014          * First, we check to see if this fragment is part of a record
3015          * that we're in the process of defragmenting.
3016          *
3017          * The key is the conversation ID for the conversation to which
3018          * the packet belongs and the current sequence number.
3019          * We must first find the conversation and, if we don't find
3020          * one, create it.  We know this is running over TCP, so the
3021          * conversation should not wildcard either address or port.
3022          */
3023         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
3024             pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
3025         if (conversation == NULL) {
3026                 /*
3027                  * It's not part of any conversation - create a new one.
3028                  */
3029                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
3030                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
3031         }
3032         old_rfk.conv_id = conversation->index;
3033         old_rfk.seq = seq;
3034         old_rfk.port = pinfo->srcport;
3035         rfk = g_hash_table_lookup(rpc_reassembly_table, &old_rfk);
3036
3037         if (rfk == NULL) {
3038                 /*
3039                  * This fragment was not found in our table, so it doesn't
3040                  * contain a continuation of a higher-level PDU.
3041                  * Is it the last fragment?
3042                  */
3043                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
3044                         /*
3045                          * This isn't the last fragment, so we don't
3046                          * have the complete record.
3047                          *
3048                          * It's the first fragment we've seen, so if
3049                          * it's truly the first fragment of the record,
3050                          * and it has enough data, the dissector can at
3051                          * least check whether it looks like a valid
3052                          * message, as it contains the start of the
3053                          * message.
3054                          *
3055                          * The dissector should not dissect anything
3056                          * if the "last fragment" flag isn't set in
3057                          * the record marker, so it shouldn't throw
3058                          * an exception.
3059                          */
3060                         if (!(*dissector)(frag_tvb, pinfo, tree, frag_tvb,
3061                             NULL, TRUE, rpc_rm, first_pdu))
3062                                 return 0;       /* not valid */
3063
3064                         /*
3065                          * OK, now start defragmentation with that
3066                          * fragment.  Add this fragment, and set up
3067                          * next packet/sequence number as well.
3068                          *
3069                          * We must remember this fragment.
3070                          */
3071
3072                         rfk = se_alloc(sizeof(rpc_fragment_key));
3073                         rfk->conv_id = conversation->index;
3074                         rfk->seq = seq;
3075                         rfk->port = pinfo->srcport;
3076                         rfk->offset = 0;
3077                         rfk->start_seq = seq;
3078                         g_hash_table_insert(rpc_reassembly_table, rfk, rfk);
3079
3080                         /*
3081                          * Start defragmentation.
3082                          */
3083                         ipfd_head = fragment_add_multiple_ok(tvb, offset + 4,
3084                             pinfo, rfk->start_seq, rpc_fragment_table,
3085                             rfk->offset, len - 4, TRUE);
3086
3087                         /*
3088                          * Make sure that defragmentation isn't complete;
3089                          * it shouldn't be, as this is the first fragment
3090                          * we've seen, and the "last fragment" bit wasn't
3091                          * set on it.
3092                          */
3093                         if (ipfd_head == NULL) {
3094                                 new_rfk = se_alloc(sizeof(rpc_fragment_key));
3095                                 new_rfk->conv_id = rfk->conv_id;
3096                                 new_rfk->seq = seq + len;
3097                                 new_rfk->port = pinfo->srcport;
3098                                 new_rfk->offset = rfk->offset + len - 4;
3099                                 new_rfk->start_seq = rfk->start_seq;
3100                                 g_hash_table_insert(rpc_reassembly_table, new_rfk,
3101                                         new_rfk);
3102
3103                                 /*
3104                                  * This is part of a fragmented record,
3105                                  * but it's not the first part.
3106                                  * Show it as a record marker plus data, under
3107                                  * a top-level tree for this protocol.
3108                                  */
3109                                 make_frag_tree(frag_tvb, tree, proto, ett,rpc_rm);
3110
3111                                 /*
3112                                  * No more processing need be done, as we don't
3113                                  * have a complete record.
3114                                  */
3115                                 return len;
3116                         } else {
3117                                 /* oddly, we have a first fragment, not marked as last,
3118                                  * but which the defragmenter thinks is complete.
3119                                  * So rather than creating a fragment reassembly tree,
3120                                  * we simply throw away the partial fragment structure
3121                                  * and fall though to our "sole fragment" processing below.
3122                                  */
3123                         }
3124                 }
3125
3126                 /*
3127                  * This is the first fragment we've seen, and it's also
3128                  * the last fragment; that means the record wasn't
3129                  * fragmented.  Hand the dissector the tvbuff for the
3130                  * fragment as the tvbuff for the record.
3131                  */
3132                 rec_tvb = frag_tvb;
3133                 ipfd_head = NULL;
3134         } else {
3135                 /*
3136                  * OK, this fragment was found, which means it continues
3137                  * a record.  This means we must defragment it.
3138                  * Add it to the defragmentation lists.
3139                  */
3140                 ipfd_head = fragment_add_multiple_ok(tvb, offset + 4, pinfo,
3141                     rfk->start_seq, rpc_fragment_table,
3142                     rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
3143
3144                 if (ipfd_head == NULL) {
3145                         /*
3146                          * fragment_add_multiple_ok() returned NULL.
3147                          * This means that defragmentation is not
3148                          * completed yet.
3149                          *
3150                          * We must add an entry to the hash table with
3151                          * the sequence number following this fragment
3152                          * as the starting sequence number, so that when
3153                          * we see that fragment we'll find that entry.
3154                          *
3155                          * XXX - as TCP stream data is not currently
3156                          * guaranteed to be provided in order to dissectors,
3157                          * RPC fragments aren't guaranteed to be provided
3158                          * in order, either.
3159                          */
3160                         new_rfk = se_alloc(sizeof(rpc_fragment_key));
3161                         new_rfk->conv_id = rfk->conv_id;
3162                         new_rfk->seq = seq + len;
3163                         new_rfk->port = pinfo->srcport;
3164                         new_rfk->offset = rfk->offset + len - 4;
3165                         new_rfk->start_seq = rfk->start_seq;
3166                         g_hash_table_insert(rpc_reassembly_table, new_rfk,
3167                             new_rfk);
3168
3169                         /*
3170                          * This is part of a fragmented record,
3171                          * but it's not the first part.
3172                          * Show it as a record marker plus data, under
3173                          * a top-level tree for this protocol,
3174                          * but don't hand it to the dissector
3175                          */
3176                         make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3177
3178                         /*
3179                          * No more processing need be done, as we don't
3180                          * have a complete record.
3181                          */
3182                         return len;
3183                 }
3184
3185                 /*
3186                  * It's completely defragmented.
3187                  *
3188                  * We only call subdissector for the last fragment.
3189                  * XXX - this assumes in-order delivery of RPC
3190                  * fragments, which requires in-order delivery of TCP
3191                  * segments.
3192                  */
3193                 if (!(rpc_rm & RPC_RM_LASTFRAG)) {
3194                         /*
3195                          * Well, it's defragmented, but this isn't
3196                          * the last fragment; this probably means
3197                          * this isn't the first pass, so we don't
3198                          * need to start defragmentation.
3199                          *
3200                          * This is part of a fragmented record,
3201                          * but it's not the first part.
3202                          * Show it as a record marker plus data, under
3203                          * a top-level tree for this protocol,
3204                          * but don't show it to the dissector.
3205                          */
3206                         make_frag_tree(frag_tvb, tree, proto, ett, rpc_rm);
3207
3208                         /*
3209                          * No more processing need be done, as we
3210                          * only disssect the data with the last
3211                          * fragment.
3212                          */
3213                         return len;
3214                 }
3215
3216                 /*
3217                  * OK, this is the last segment.
3218                  * Create a tvbuff for the defragmented
3219                  * record.
3220                  */
3221
3222                 /*
3223                  * Create a new TVB structure for
3224                  * defragmented data.
3225                  */
3226                 rec_tvb = tvb_new_child_real_data(tvb, ipfd_head->data,
3227                     ipfd_head->datalen, ipfd_head->datalen);
3228
3229                 /*
3230                  * Add defragmented data to the data source list.
3231                  */
3232                 add_new_data_source(pinfo, rec_tvb, "Defragmented");
3233         }
3234
3235         /*
3236          * We have something to hand to the RPC message
3237          * dissector.
3238          */
3239         if (!call_message_dissector(tvb, rec_tvb, pinfo, tree,
3240             frag_tvb, dissector, ipfd_head, rpc_rm, first_pdu))
3241                 return 0;       /* not RPC */
3242         return len;
3243 }  /* end of dissect_rpc_fragment() */
3244
3245 /**
3246  * Scans tvb, starting at given offset, to see if we can find
3247  * what looks like a valid RPC-over-TCP reply header.
3248  *
3249  * @param tvb Buffer to inspect for RPC reply header.
3250  * @param offset Offset to begin search of tvb at.
3251  *
3252  * @return -1 if no reply header found, else offset to start of header
3253  *         (i.e., to the RPC record mark field).
3254  */
3255
3256 static int
3257 find_rpc_over_tcp_reply_start(tvbuff_t *tvb, int offset)
3258 {
3259
3260 /*
3261  * Looking for partial header sequence.  From beginning of
3262  * stream-style header, including "record mark", full ONC-RPC
3263  * looks like:
3264  *    BE int32    record mark (rfc 1831 sec. 10)
3265  *    ?  int32    XID (rfc 1831 sec. 8)
3266  *    BE int32    msg_type (ibid sec. 8, call = 0, reply = 1)
3267  *
3268  * -------------------------------------------------------------
3269  * Then reply-specific fields are
3270  *    BE int32    reply_stat (ibid, accept = 0, deny = 1)
3271  *
3272  * Then, assuming accepted,
3273  *   opaque_auth
3274  *    BE int32    auth_flavor (ibid, none = 0)
3275  *    BE int32    ? auth_len (ibid, none = 0)
3276  *
3277  *    BE int32    accept_stat (ibid, success = 0, errs are 1..5 in rpc v2)
3278  *
3279  * -------------------------------------------------------------
3280  * Or, call-specific fields are
3281  *    BE int32    rpc_vers (rfc 1831 sec 8, always == 2)
3282  *    BE int32    prog (NFS == 000186A3)
3283  *    BE int32    prog_ver (NFS v2/3 == 2 or 3)
3284  *    BE int32    proc_id (NFS, <= 256 ???)
3285  *   opaque_auth
3286  *    ...
3287  */
3288
3289 /* Initially, we search only for something matching the template
3290  * of a successful reply with no auth verifier.
3291  * Our first qualification test is search for a string of zero bytes,
3292  * corresponding the four guint32 values
3293  *    reply_stat
3294  *    auth_flavor
3295  *    auth_len
3296  *    accept_stat
3297  *
3298  * If this string of zeros matches, then we go back and check the
3299  * preceding msg_type and record_mark fields.
3300  */
3301
3302 const gint     cbZeroTail = 4 * 4;     /* four guint32s of zeros */
3303 const gint     ibPatternStart = 3 * 4;    /* offset of zero fill from reply start */
3304 const guint8 * pbWholeBuf;    /* all of tvb, from offset onwards */
3305 const int      NoMatch = -1;
3306
3307 gint     ibSearchStart;       /* offset of search start, in case of false hits. */
3308
3309 const    guint8 * pbBuf;
3310
3311 gint     cbInBuf;       /* bytes in tvb, from offset onwards */
3312
3313 guint32  ulMsgType;
3314 guint32  ulRecMark;
3315
3316 int      i;
3317
3318
3319         cbInBuf = tvb_reported_length_remaining(tvb, offset);
3320
3321         /* start search at first possible location */
3322         ibSearchStart = ibPatternStart;
3323
3324         if (cbInBuf < (cbZeroTail + ibSearchStart)) {
3325                 /* nothing to search, so claim no RPC */
3326                 return (NoMatch);
3327         }
3328
3329         pbWholeBuf = tvb_get_ptr(tvb, offset, cbInBuf);
3330         if (pbWholeBuf == NULL) {
3331                 /* probably never take this, as get_ptr seems to assert */
3332                 return (NoMatch);
3333         }
3334
3335         while ((cbInBuf - ibSearchStart) > cbZeroTail) {
3336                 /* First test for long tail of zeros, starting at the back.
3337                  * A failure lets us skip the maximum possible buffer amount.
3338                  */
3339                 pbBuf = pbWholeBuf + ibSearchStart + cbZeroTail - 1;
3340                 for (i = cbZeroTail; i > 0;  i --)
3341                         {
3342                         if (*pbBuf != 0)
3343                                 {
3344                                 /* match failure.  Since we need N contiguous zeros,
3345                                  * we can increment next match start so zero testing
3346                                  * begins right after this failure spot.
3347                                  */
3348                                 ibSearchStart += i;
3349                                 pbBuf = NULL;
3350                                 break;
3351                                 }
3352
3353                         pbBuf --;
3354                         }
3355
3356                 if (pbBuf == NULL) {
3357                         continue;
3358                 }
3359
3360                 /* got a match in zero-fill region, verify reply ID and
3361                  * record mark fields */
3362                 ulMsgType = pntohl (pbWholeBuf + ibSearchStart - 4);
3363                 ulRecMark = pntohl (pbWholeBuf + ibSearchStart - ibPatternStart);
3364
3365                 if ((ulMsgType == RPC_REPLY) &&
3366                          ((ulRecMark & ~0x80000000) <= (unsigned) max_rpc_tcp_pdu_size)) {
3367                         /* looks ok, try dissect */
3368                         return (offset + ibSearchStart - ibPatternStart);
3369                 }
3370
3371                 /* no match yet, nor egregious miss either.  Inch along to next try */
3372                 ibSearchStart ++;
3373         }
3374
3375         return (NoMatch);
3376
3377 }  /* end of find_rpc_over_tcp_reply_start() */
3378
3379 /**
3380  * Scans tvb for what looks like a valid RPC call / reply header.
3381  * If found, calls standard dissect_rpc_fragment() logic to digest
3382  * the (hopefully valid) fragment.
3383  *
3384  * With any luck, one invocation of this will be sufficient to get
3385  * us back in alignment with the stream, and no further calls to
3386  * this routine will be needed for a given conversation.  As if.  :-)
3387  *
3388  * Can return:
3389  *       Same as dissect_rpc_fragment().  Will return zero (no frame)
3390  *       if no valid RPC header is found.
3391  */
3392
3393 static int
3394 find_and_dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
3395                                                           proto_tree *tree, rec_dissector_t dissector,
3396                                                           gboolean is_heur,
3397                                                           int proto, int ett, gboolean defragment)
3398 {
3399
3400         int   offReply;
3401         int   len;
3402
3403
3404         offReply = find_rpc_over_tcp_reply_start(tvb, offset);
3405         if (offReply < 0) {
3406                 /* could search for request, but not needed (or testable) thus far */
3407                 return (0);    /* claim no RPC */
3408         }
3409
3410         len = dissect_rpc_fragment(tvb, offReply,
3411                                                            pinfo, tree,
3412                                                            dissector, is_heur, proto, ett,
3413                                                            defragment,
3414                                                            TRUE /* force first-pdu state */);
3415
3416         /* misses are reported as-is */
3417         if (len == 0)
3418                 {
3419                 return (0);
3420                 }
3421
3422         /* returning a non-zero length, correct it to reflect the extra offset
3423          * we found necessary
3424          */
3425         if (len > 0) {
3426                 len += offReply - offset;
3427         }
3428         else {
3429                 /* negative length seems to only be used as a flag,
3430                  * don't mess it up until found necessary
3431                  */
3432 /*      len -= offReply - offset; */
3433         }
3434
3435         return (len);
3436
3437 }  /* end of find_and_dissect_rpc_fragment */
3438
3439
3440 /*
3441  * Can return:
3442  *
3443  *      NEED_MORE_DATA, if we don't have enough data to dissect anything;
3444  *
3445  *      IS_RPC, if we dissected at least one message in its entirety
3446  *      as RPC;
3447  *
3448  *      IS_NOT_RPC, if we found no RPC message.
3449  */
3450 typedef enum {
3451         NEED_MORE_DATA,
3452         IS_RPC,
3453         IS_NOT_RPC
3454 } rpc_tcp_return_t;
3455
3456 static rpc_tcp_return_t
3457 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3458     gboolean is_heur)
3459 {
3460         int offset = 0;
3461         gboolean saw_rpc = FALSE;
3462         gboolean first_pdu = TRUE;
3463         int len;
3464
3465         while (tvb_reported_length_remaining(tvb, offset) != 0) {
3466                 /*
3467                  * Process this fragment.
3468                  */
3469                 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
3470                     dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
3471                     rpc_defragment, first_pdu);
3472
3473                 if ((len == 0) && first_pdu && rpc_find_fragment_start) {
3474                         /*
3475                          * Try discarding some leading bytes from tvb, on assumption
3476                          * that we are looking at the middle of a stream-based transfer
3477                          */
3478                         len = find_and_dissect_rpc_fragment(tvb, offset, pinfo, tree,
3479                                  dissect_rpc_message, is_heur, proto_rpc, ett_rpc,
3480                                  rpc_defragment);
3481                 }
3482
3483                 first_pdu = FALSE;
3484                 if (len < 0) {
3485                         /*
3486                          * We need more data from the TCP stream for
3487                          * this fragment.
3488                          */
3489                         return NEED_MORE_DATA;
3490                 }
3491                 if (len == 0) {
3492                         /*
3493                          * It's not RPC.  Stop processing.
3494                          */
3495                         break;
3496                 }
3497
3498                 /* PDU tracking
3499                   If the length indicates that the PDU continues beyond
3500                   the end of this tvb, then tell TCP about it so that it
3501                   knows where the next PDU starts.
3502                   This is to help TCP detect when PDUs are not aligned to
3503                   segment boundaries and allow it to find RPC headers
3504                   that starts in the middle of a TCP segment.
3505                 */
3506                 if(!pinfo->fd->flags.visited){
3507                         if(len>tvb_reported_length_remaining(tvb, offset)){
3508                                 pinfo->want_pdu_tracking=2;
3509                                 pinfo->bytes_until_next_pdu=len-tvb_reported_length_remaining(tvb, offset);
3510                         }
3511                 }
3512                 offset += len;
3513                 saw_rpc = TRUE;
3514         }
3515         return saw_rpc ? IS_RPC : IS_NOT_RPC;
3516 }
3517
3518 static gboolean
3519 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3520 {
3521         switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
3522
3523         case IS_RPC:
3524                 return TRUE;
3525
3526         case IS_NOT_RPC:
3527                 return FALSE;
3528
3529         default:
3530                 /* "Can't happen" */
3531                 DISSECTOR_ASSERT_NOT_REACHED();
3532                 return FALSE;
3533         }
3534 }
3535
3536 static void
3537 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3538 {
3539         if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
3540                 dissect_rpc_continuation(tvb, pinfo, tree);
3541 }
3542
3543 /* Discard any state we've saved. */
3544 static void
3545 rpc_init_protocol(void)
3546 {
3547         if (rpc_reassembly_table != NULL) {
3548                 g_hash_table_destroy(rpc_reassembly_table);
3549                 rpc_reassembly_table = NULL;
3550         }
3551
3552         rpc_reassembly_table = g_hash_table_new(rpc_fragment_hash,
3553             rpc_fragment_equal);
3554
3555         fragment_table_init(&rpc_fragment_table);
3556 }
3557
3558 /* will be called once from register.c at startup time */
3559 void
3560 proto_register_rpc(void)
3561 {
3562         static hf_register_info hf[] = {
3563                 { &hf_rpc_reqframe, {
3564                         "Request Frame", "rpc.reqframe", FT_FRAMENUM, BASE_NONE,
3565                         NULL, 0, "Request Frame", HFILL }},
3566                 { &hf_rpc_repframe, {
3567                         "Reply Frame", "rpc.repframe", FT_FRAMENUM, BASE_NONE,
3568                         NULL, 0, "Reply Frame", HFILL }},
3569                 { &hf_rpc_lastfrag, {
3570                         "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, 32,
3571                         TFS(&tfs_yes_no), RPC_RM_LASTFRAG, "Last Fragment", HFILL }},
3572                 { &hf_rpc_fraglen, {
3573                         "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
3574                         NULL, RPC_RM_FRAGLEN, "Fragment Length", HFILL }},
3575                 { &hf_rpc_xid, {
3576                         "XID", "rpc.xid", FT_UINT32, BASE_HEX,
3577                         NULL, 0, "XID", HFILL }},
3578                 { &hf_rpc_msgtype, {
3579                         "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
3580                         VALS(rpc_msg_type), 0, "Message Type", HFILL }},
3581                 { &hf_rpc_state_reply, {
3582                         "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
3583                         VALS(rpc_reply_state), 0, "Reply State", HFILL }},
3584                 { &hf_rpc_state_accept, {
3585                         "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
3586                         VALS(rpc_accept_state), 0, "Accept State", HFILL }},
3587                 { &hf_rpc_state_reject, {
3588                         "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
3589                         VALS(rpc_reject_state), 0, "Reject State", HFILL }},
3590                 { &hf_rpc_state_auth, {
3591                         "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
3592                         VALS(rpc_auth_state), 0, "Auth State", HFILL }},
3593                 { &hf_rpc_version, {
3594                         "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
3595                         NULL, 0, "RPC Version", HFILL }},
3596                 { &hf_rpc_version_min, {
3597                         "RPC Version (Minimum)", "rpc.version.min", FT_UINT32,
3598                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3599                 { &hf_rpc_version_max, {
3600                         "RPC Version (Maximum)", "rpc.version.max", FT_UINT32,
3601                         BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
3602                 { &hf_rpc_program, {
3603                         "Program", "rpc.program", FT_UINT32, BASE_DEC,
3604                         NULL, 0, "Program", HFILL }},
3605                 { &hf_rpc_programversion, {
3606                         "Program Version", "rpc.programversion", FT_UINT32,
3607                         BASE_DEC, NULL, 0, "Program Version", HFILL }},
3608                 { &hf_rpc_programversion_min, {
3609                         "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32,
3610                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
3611                 { &hf_rpc_programversion_max, {
3612                         "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32,
3613                         BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
3614                 { &hf_rpc_procedure, {
3615                         "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
3616                         NULL, 0, "Procedure", HFILL }},
3617                 { &hf_rpc_auth_flavor, {
3618                         "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
3619                         VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
3620                 { &hf_rpc_auth_length, {
3621                         "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
3622                         NULL, 0, "Length", HFILL }},
3623                 { &hf_rpc_auth_stamp, {
3624                         "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
3625                         NULL, 0, "Stamp", HFILL }},
3626                 { &hf_rpc_auth_uid, {
3627                         "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
3628                         NULL, 0, "UID", HFILL }},
3629                 { &hf_rpc_auth_gid, {
3630                         "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
3631                         NULL, 0, "GID", HFILL }},
3632                 { &hf_rpc_authgss_v, {
3633                         "GSS Version", "rpc.authgss.version", FT_UINT32,
3634                         BASE_DEC, NULL, 0, "GSS Version", HFILL }},
3635                 { &hf_rpc_authgss_proc, {
3636                         "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
3637                         BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
3638                 { &hf_rpc_authgss_seq, {
3639                         "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
3640                         BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
3641                 { &hf_rpc_authgss_svc, {
3642                         "GSS Service", "rpc.authgss.service", FT_UINT32,
3643                         BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
3644                 { &hf_rpc_authgss_ctx, {
3645                         "GSS Context", "rpc.authgss.context", FT_BYTES,
3646                         BASE_HEX, NULL, 0, "GSS Context", HFILL }},
3647                 { &hf_rpc_authgss_major, {
3648                         "GSS Major Status", "rpc.authgss.major", FT_UINT32,
3649                         BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
3650                 { &hf_rpc_authgss_minor, {
3651                         "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
3652                         BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
3653                 { &hf_rpc_authgss_window, {
3654                         "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
3655                         BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
3656                 { &hf_rpc_authgss_token_length, {
3657                         "GSS Token Length", "rpc.authgss.token_length", FT_UINT32,
3658                         BASE_DEC, NULL, 0, "GSS Token Length", HFILL }},
3659                 { &hf_rpc_authgss_data_length, {
3660                         "Length", "rpc.authgss.data.length", FT_UINT32,
3661                         BASE_DEC, NULL, 0, "Length", HFILL }},
3662                 { &hf_rpc_authgss_data, {
3663                         "GSS Data", "rpc.authgss.data", FT_BYTES,
3664                         BASE_HEX, NULL, 0, "GSS Data", HFILL }},
3665                 { &hf_rpc_authgss_checksum, {
3666                         "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
3667                         BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
3668                 { &hf_rpc_authgss_token, {
3669                         "GSS Token", "rpc.authgss.token", FT_BYTES,
3670                         BASE_HEX, NULL, 0, "GSS Token", HFILL }},
3671                 { &hf_rpc_authgssapi_v, {
3672                         "AUTH_GSSAPI Version", "rpc.authgssapi.version",
3673                         FT_UINT32, BASE_DEC, NULL, 0, "AUTH_GSSAPI Version",
3674                         HFILL }},
3675                 { &hf_rpc_authgssapi_msg, {
3676                         "AUTH_GSSAPI Message", "rpc.authgssapi.message",
3677                         FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, "AUTH_GSSAPI Message",
3678                         HFILL }},
3679                 { &hf_rpc_authgssapi_msgv, {
3680                         "Msg Version", "rpc.authgssapi.msgversion",
3681                         FT_UINT32, BASE_DEC, NULL, 0, "Msg Version",
3682                         HFILL }},
3683                 { &hf_rpc_authgssapi_handle, {
3684                         "Client Handle", "rpc.authgssapi.handle",
3685                         FT_BYTES, BASE_HEX, NULL, 0, "Client Handle", HFILL }},
3686                 { &hf_rpc_authgssapi_isn, {
3687                         "Signed ISN", "rpc.authgssapi.isn",
3688                         FT_BYTES, BASE_HEX, NULL, 0, "Signed ISN", HFILL }},
3689                 { &hf_rpc_authdes_namekind, {
3690                         "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
3691                         VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
3692                 { &hf_rpc_authdes_netname, {
3693                         "Netname", "rpc.authdes.netname", FT_STRING,
3694                         BASE_DEC, NULL, 0, "Netname", HFILL }},
3695                 { &hf_rpc_authdes_convkey, {
3696                         "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
3697                         BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
3698                 { &hf_rpc_authdes_window, {
3699                         "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
3700                         BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
3701                 { &hf_rpc_authdes_nickname, {
3702                         "Nickname", "rpc.authdes.nickname", FT_UINT32,
3703                         BASE_HEX, NULL, 0, "Nickname", HFILL }},
3704                 { &hf_rpc_authdes_timestamp, {
3705                         "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
3706                         BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
3707                 { &hf_rpc_authdes_windowverf, {
3708                         "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
3709                         BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
3710                 { &hf_rpc_authdes_timeverf, {
3711                         "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
3712                         BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
3713                 { &hf_rpc_auth_machinename, {
3714                         "Machine Name", "rpc.auth.machinename", FT_STRING,
3715                         BASE_DEC, NULL, 0, "Machine Name", HFILL }},
3716                 { &hf_rpc_dup, {
3717                         "Duplicate Call/Reply", "rpc.dup", FT_NONE, BASE_NONE,
3718                         NULL, 0, "Duplicate Call/Reply", HFILL }},
3719                 { &hf_rpc_call_dup, {
3720                         "Duplicate to the call in", "rpc.call.dup", FT_FRAMENUM, BASE_DEC,
3721                         NULL, 0, "This is a duplicate to the call in frame", HFILL }},
3722                 { &hf_rpc_reply_dup, {
3723                         "Duplicate to the reply in", "rpc.reply.dup", FT_FRAMENUM, BASE_DEC,
3724                         NULL, 0, "This is a duplicate to the reply in frame", HFILL }},
3725                 { &hf_rpc_value_follows, {
3726                         "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
3727                         TFS(&tfs_yes_no), 0, "Value Follows", HFILL }},
3728                 { &hf_rpc_array_len, {
3729                         "num", "rpc.array.len", FT_UINT32, BASE_DEC,
3730                         NULL, 0, "Length of RPC array", HFILL }},
3731
3732                 { &hf_rpc_time, {
3733                         "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
3734                         NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
3735
3736                 { &hf_rpc_fragment_overlap,
3737                 { "Fragment overlap",   "rpc.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3738                         "Fragment overlaps with other fragments", HFILL }},
3739
3740                 { &hf_rpc_fragment_overlap_conflict,
3741                 { "Conflicting data in fragment overlap",       "rpc.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3742                         "Overlapping fragments contained conflicting data", HFILL }},
3743
3744                 { &hf_rpc_fragment_multiple_tails,
3745                 { "Multiple tail fragments found",      "rpc.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3746                         "Several tails were found when defragmenting the packet", HFILL }},
3747
3748                 { &hf_rpc_fragment_too_long_fragment,
3749                 { "Fragment too long",  "rpc.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3750                         "Fragment contained data past end of packet", HFILL }},
3751
3752                 { &hf_rpc_fragment_error,
3753                 { "Defragmentation error", "rpc.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3754                         "Defragmentation error due to illegal fragments", HFILL }},
3755
3756                 { &hf_rpc_fragment,
3757                 { "RPC Fragment", "rpc.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3758                         "RPC Fragment", HFILL }},
3759
3760                 { &hf_rpc_fragments,
3761                 { "RPC Fragments", "rpc.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
3762                         "RPC Fragments", HFILL }},
3763         };
3764         static gint *ett[] = {
3765                 &ett_rpc,
3766                 &ett_rpc_fragments,
3767                 &ett_rpc_fragment,
3768                 &ett_rpc_fraghdr,
3769                 &ett_rpc_string,
3770                 &ett_rpc_cred,
3771                 &ett_rpc_verf,
3772                 &ett_rpc_gids,
3773                 &ett_rpc_gss_token,
3774                 &ett_rpc_gss_data,
3775                 &ett_rpc_array,
3776                 &ett_rpc_authgssapi_msg,
3777                 &ett_rpc_unknown_program,
3778         };
3779         module_t *rpc_module;
3780
3781         proto_rpc = proto_register_protocol("Remote Procedure Call",
3782             "RPC", "rpc");
3783         /* this is a dummy dissector for all those unknown rpc programs */
3784         proto_register_field_array(proto_rpc, hf, array_length(hf));
3785         proto_register_subtree_array(ett, array_length(ett));
3786         register_init_routine(&rpc_init_protocol);
3787
3788         rpc_module = prefs_register_protocol(proto_rpc, NULL);
3789         prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
3790             "Reassemble RPC over TCP messages\nspanning multiple TCP segments",
3791             "Whether the RPC dissector should reassemble messages spanning multiple TCP segments."
3792             " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3793                 &rpc_desegment);
3794         prefs_register_bool_preference(rpc_module, "defragment_rpc_over_tcp",
3795                 "Reassemble fragmented RPC-over-TCP messages",
3796                 "Whether the RPC dissector should defragment RPC-over-TCP messages.",
3797                 &rpc_defragment);
3798
3799         prefs_register_uint_preference(rpc_module, "max_tcp_pdu_size", "Maximum size of a RPC-over-TCP PDU",
3800                 "Set the maximum size of RPCoverTCP PDUs. "
3801                 " If the size field of the record marker is larger "
3802                 "than this value it will not be considered a valid RPC PDU.",
3803                  10, &max_rpc_tcp_pdu_size);
3804
3805         prefs_register_bool_preference(rpc_module, "dissect_unknown_programs",
3806                 "Dissect unknown RPC program numbers",
3807                 "Whether the RPC dissector should attempt to dissect RPC PDUs containing programs that are not known to Wireshark. This will make the heuristics significantly weaker and elevate the risk for falsely identifying and misdissecting packets significantly.",
3808                 &rpc_dissect_unknown_programs);
3809
3810         prefs_register_bool_preference(rpc_module, "find_fragment_start",
3811                 "Attempt to locate start-of-fragment in partial RPC-over-TCP captures",
3812                 "Whether the RPC dissector should attempt to locate RPC PDU boundaries when initial fragment alignment is not known.  This may cause false positives, or slow operation.",
3813                 &rpc_find_fragment_start);
3814
3815         register_dissector("rpc", dissect_rpc, proto_rpc);
3816         register_dissector("rpc-tcp", dissect_rpc_tcp, proto_rpc);
3817         rpc_tap = register_tap("rpc");
3818
3819         /*
3820          * Init the hash tables.  Dissectors for RPC protocols must
3821          * have a "handoff registration" routine that registers the
3822          * protocol with RPC; they must not do it in their protocol
3823          * registration routine, as their protocol registration
3824          * routine might be called before this routine is called and
3825          * thus might be called before the hash tables are initialized,
3826          * but it's guaranteed that all protocol registration routines
3827          * will be called before any handoff registration routines
3828          * are called.
3829          */
3830         rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
3831         rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
3832 }
3833
3834 void
3835 proto_reg_handoff_rpc(void)
3836 {
3837         /* tcp/udp port 111 is used by portmapper which is an onc-rpc service.
3838            we register onc-rpc on this port so that we can choose RPC in
3839            the list offered by DecodeAs, and so that traffic to or from
3840            port 111 from or to a higher-numbered port is dissected as RPC
3841            even if there's a dissector registered on the other port (it's
3842            probably RPC traffic from some randomly-chosen port that happens
3843            to match some port for which we have a dissector)
3844         */
3845         rpc_tcp_handle = find_dissector("rpc-tcp");
3846         dissector_add("tcp.port", 111, rpc_tcp_handle);
3847         rpc_handle = find_dissector("rpc");
3848         dissector_add("udp.port", 111, rpc_handle);
3849
3850         heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
3851         heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
3852         gssapi_handle = find_dissector("gssapi");
3853         data_handle = find_dissector("data");
3854 }
3855
3856 /*
3857  * Editor modelines
3858  *
3859  * Local Variables:
3860  * c-basic-offset: 8
3861  * tab-width: 8
3862  * indent-tabs-mode: t
3863  * End:
3864  *
3865  * ex: set shiftwidth=8 tabstop=8 noexpandtab
3866  * :indentSize=8:tabSize=8:noTabs=false:
3867  */
3868