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