Collapse the two entries for Mark Burton into one.
[obnox/wireshark/wip.git] / packet-rpc.c
1 /* packet-rpc.c
2  * Routines for rpc dissection
3  * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
4  * 
5  * $Id: packet-rpc.c,v 1.81 2002/01/12 10:24:47 guy Exp $
6  * 
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
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 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35
36 #include <glib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include "packet.h"
41 #include "conversation.h"
42 #include "packet-rpc.h"
43 #include "packet-frame.h"
44 #include "prefs.h"
45
46 /*
47  * See:
48  *
49  *      RFC 1831, "RPC: Remote Procedure Call Protocol Specification
50  *      Version 2";
51  *
52  *      RFC 1832, "XDR: External Data Representation Standard";
53  *
54  *      RFC 2203, "RPCSEC_GSS Protocol Specification".
55  *
56  * See also
57  *
58  *      RFC 2695, "Authentication Mechanisms for ONC RPC"
59  *
60  *      although we don't currently dissect AUTH_DES or AUTH_KERB.
61  */
62
63 #define RPC_RM_FRAGLEN  0x7fffffffL
64
65 /* desegmentation of RPC over TCP */
66 static gboolean rpc_desegment = TRUE;
67
68 static struct true_false_string yesno = { "Yes", "No" };
69
70
71 static const value_string rpc_msg_type[] = {
72         { RPC_CALL, "Call" },
73         { RPC_REPLY, "Reply" },
74         { 0, NULL }
75 };
76
77 static const value_string rpc_reply_state[] = {
78         { MSG_ACCEPTED, "accepted" },
79         { MSG_DENIED, "denied" },
80         { 0, NULL }
81 };
82
83 const value_string rpc_auth_flavor[] = {
84         { AUTH_NULL, "AUTH_NULL" },
85         { AUTH_UNIX, "AUTH_UNIX" },
86         { AUTH_SHORT, "AUTH_SHORT" },
87         { AUTH_DES, "AUTH_DES" },
88         { RPCSEC_GSS, "RPCSEC_GSS" },
89         { 0, NULL }
90 };
91
92 static const value_string rpc_authgss_proc[] = {
93         { RPCSEC_GSS_DATA, "RPCSEC_GSS_DATA" },
94         { RPCSEC_GSS_INIT, "RPCSEC_GSS_INIT" },
95         { RPCSEC_GSS_CONTINUE_INIT, "RPCSEC_GSS_CONTINUE_INIT" },
96         { RPCSEC_GSS_DESTROY, "RPCSEC_GSS_DESTROY" },
97         { 0, NULL }
98 };
99
100 value_string rpc_authgss_svc[] = {
101         { RPCSEC_GSS_SVC_NONE, "rpcsec_gss_svc_none" },
102         { RPCSEC_GSS_SVC_INTEGRITY, "rpcsec_gss_svc_integrity" },
103         { RPCSEC_GSS_SVC_PRIVACY, "rpcsec_gss_svc_privacy" },
104         { 0, NULL }
105 };
106
107 static const value_string rpc_accept_state[] = {
108         { SUCCESS, "RPC executed successfully" },
109         { PROG_UNAVAIL, "remote hasn't exported program" },
110         { PROG_MISMATCH, "remote can't support version #" },
111         { PROC_UNAVAIL, "program can't support procedure" },
112         { GARBAGE_ARGS, "procedure can't decode params" },
113         { 0, NULL }
114 };
115
116 static const value_string rpc_reject_state[] = {
117         { RPC_MISMATCH, "RPC_MISMATCH" },
118         { AUTH_ERROR, "AUTH_ERROR" },
119         { 0, NULL }
120 };
121
122 static const value_string rpc_auth_state[] = {
123         { AUTH_BADCRED, "bad credential (seal broken)" },
124         { AUTH_REJECTEDCRED, "client must begin new session" },
125         { AUTH_BADVERF, "bad verifier (seal broken)" },
126         { AUTH_REJECTEDVERF, "verifier expired or replayed" },
127         { AUTH_TOOWEAK, "rejected for security reasons" },
128         { RPCSEC_GSSCREDPROB, "GSS credential problem" },
129         { RPCSEC_GSSCTXPROB, "GSS context problem" },
130         { 0, NULL }
131 };
132
133 static const value_string rpc_authdes_namekind[] = {
134         { AUTHDES_NAMEKIND_FULLNAME, "ADN_FULLNAME" },
135         { AUTHDES_NAMEKIND_NICKNAME, "ADN_NICKNAME" },
136         { 0, NULL }
137 };
138
139 /* the protocol number */
140 static int proto_rpc = -1;
141 static int hf_rpc_lastfrag = -1;
142 static int hf_rpc_fraglen = -1;
143 static int hf_rpc_xid = -1;
144 static int hf_rpc_msgtype = -1;
145 static int hf_rpc_version = -1;
146 static int hf_rpc_version_min = -1;
147 static int hf_rpc_version_max = -1;
148 static int hf_rpc_program = -1;
149 static int hf_rpc_programversion = -1;
150 static int hf_rpc_programversion_min = -1;
151 static int hf_rpc_programversion_max = -1;
152 static int hf_rpc_procedure = -1;
153 static int hf_rpc_auth_flavor = -1;
154 static int hf_rpc_auth_length = -1;
155 static int hf_rpc_auth_machinename = -1;
156 static int hf_rpc_auth_stamp = -1;
157 static int hf_rpc_auth_uid = -1;
158 static int hf_rpc_auth_gid = -1;
159 static int hf_rpc_authgss_v = -1;
160 static int hf_rpc_authgss_proc = -1;
161 static int hf_rpc_authgss_seq = -1;
162 static int hf_rpc_authgss_svc = -1;
163 static int hf_rpc_authgss_ctx = -1;
164 static int hf_rpc_authgss_major = -1;
165 static int hf_rpc_authgss_minor = -1;
166 static int hf_rpc_authgss_window = -1;
167 static int hf_rpc_authgss_token = -1;
168 static int hf_rpc_authgss_data_length = -1;
169 static int hf_rpc_authgss_data = -1;
170 static int hf_rpc_authgss_checksum = -1;
171 static int hf_rpc_authdes_namekind = -1;
172 static int hf_rpc_authdes_netname = -1;
173 static int hf_rpc_authdes_convkey = -1;
174 static int hf_rpc_authdes_window = -1;
175 static int hf_rpc_authdes_nickname = -1;
176 static int hf_rpc_authdes_timestamp = -1;
177 static int hf_rpc_authdes_windowverf = -1;
178 static int hf_rpc_authdes_timeverf = -1;
179 static int hf_rpc_state_accept = -1;
180 static int hf_rpc_state_reply = -1;
181 static int hf_rpc_state_reject = -1;
182 static int hf_rpc_state_auth = -1;
183 static int hf_rpc_dup = -1;
184 static int hf_rpc_call_dup = -1;
185 static int hf_rpc_reply_dup = -1;
186 static int hf_rpc_value_follows = -1;
187 static int hf_rpc_array_len = -1;
188 static int hf_rpc_time = -1;
189
190 static gint ett_rpc = -1;
191 static gint ett_rpc_string = -1;
192 static gint ett_rpc_cred = -1;
193 static gint ett_rpc_verf = -1;
194 static gint ett_rpc_gids = -1;
195 static gint ett_rpc_gss_data = -1;
196 static gint ett_rpc_array = -1;
197
198 static dissector_handle_t rpc_tcp_handle;
199 static dissector_handle_t rpc_handle;
200 static dissector_handle_t data_handle;
201
202 /* Hash table with info on RPC program numbers */
203 static GHashTable *rpc_progs;
204
205 /* Hash table with info on RPC procedure numbers */
206 static GHashTable *rpc_procs;
207
208 typedef struct _rpc_proc_info_key {
209         guint32 prog;
210         guint32 vers;
211         guint32 proc;
212 } rpc_proc_info_key;
213
214 typedef struct _rpc_proc_info_value {
215         gchar           *name;
216         dissect_function_t *dissect_call;
217         dissect_function_t *dissect_reply;
218 } rpc_proc_info_value;
219
220 typedef struct _rpc_prog_info_key {
221         guint32 prog;
222 } rpc_prog_info_key;
223
224 typedef struct _rpc_prog_info_value {
225         int proto;
226         int ett;
227         char* progname;
228 } rpc_prog_info_value;
229
230 static void dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
231 static void dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
232
233 /***********************************/
234 /* Hash array with procedure names */
235 /***********************************/
236
237 /* compare 2 keys */
238 gint
239 rpc_proc_equal(gconstpointer k1, gconstpointer k2)
240 {
241         rpc_proc_info_key* key1 = (rpc_proc_info_key*) k1;
242         rpc_proc_info_key* key2 = (rpc_proc_info_key*) k2;
243
244         return ((key1->prog == key2->prog && 
245                 key1->vers == key2->vers &&
246                 key1->proc == key2->proc) ?
247         TRUE : FALSE);
248 }
249
250 /* calculate a hash key */
251 guint
252 rpc_proc_hash(gconstpointer k)
253 {
254         rpc_proc_info_key* key = (rpc_proc_info_key*) k;
255
256         return (key->prog ^ (key->vers<<16) ^ (key->proc<<24));
257 }
258
259
260 /* insert some entries */
261 void
262 rpc_init_proc_table(guint prog, guint vers, const vsff *proc_table)
263 {
264         const vsff *proc;
265
266         for (proc = proc_table ; proc->strptr!=NULL; proc++) {
267                 rpc_proc_info_key *key;
268                 rpc_proc_info_value *value;
269
270                 key = (rpc_proc_info_key *) g_malloc(sizeof(rpc_proc_info_key));
271                 key->prog = prog;
272                 key->vers = vers;
273                 key->proc = proc->value;
274
275                 value = (rpc_proc_info_value *) g_malloc(sizeof(rpc_proc_info_value));
276                 value->name = proc->strptr;
277                 value->dissect_call = proc->dissect_call;
278                 value->dissect_reply = proc->dissect_reply;
279
280                 g_hash_table_insert(rpc_procs,key,value);
281         }
282 }
283
284 /*      return the name associated with a previously registered procedure. */
285 char *rpc_proc_name(guint32 prog, guint32 vers, guint32 proc)
286 {
287         rpc_proc_info_key key;
288         rpc_proc_info_value *value;
289         char *procname;
290         static char procname_static[20];
291
292         key.prog = prog;
293         key.vers = vers;
294         key.proc = proc;
295
296         if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL)
297                 procname = value->name;
298         else {
299                 /* happens only with strange program versions or
300                    non-existing dissectors */
301                 sprintf(procname_static, "proc-%u", key.proc);
302                 procname = procname_static;
303         }
304         return procname;
305 }
306
307 /*----------------------------------------*/
308 /* end of Hash array with procedure names */
309 /*----------------------------------------*/
310
311
312 /*********************************/
313 /* Hash array with program names */
314 /*********************************/
315
316 /* compare 2 keys */
317 gint
318 rpc_prog_equal(gconstpointer k1, gconstpointer k2)
319 {
320         rpc_prog_info_key* key1 = (rpc_prog_info_key*) k1;
321         rpc_prog_info_key* key2 = (rpc_prog_info_key*) k2;
322
323         return ((key1->prog == key2->prog) ?
324         TRUE : FALSE);
325 }
326
327
328 /* calculate a hash key */
329 guint
330 rpc_prog_hash(gconstpointer k)
331 {
332         rpc_prog_info_key* key = (rpc_prog_info_key*) k;
333
334         return (key->prog);
335 }
336
337
338 void
339 rpc_init_prog(int proto, guint32 prog, int ett)
340 {
341         rpc_prog_info_key *key;
342         rpc_prog_info_value *value;
343
344         key = (rpc_prog_info_key *) g_malloc(sizeof(rpc_prog_info_key));
345         key->prog = prog;
346
347         value = (rpc_prog_info_value *) g_malloc(sizeof(rpc_prog_info_value));
348         value->proto = proto;
349         value->ett = ett;
350         value->progname = proto_get_protocol_short_name(proto);
351
352         g_hash_table_insert(rpc_progs,key,value);
353 }
354
355 /*      return the name associated with a previously registered program. This
356         should probably eventually be expanded to use the rpc YP/NIS map
357         so that it can give names for programs not handled by ethereal */
358 char *rpc_prog_name(guint32 prog)
359 {
360         char *progname = NULL;
361         rpc_prog_info_key       rpc_prog_key;
362         rpc_prog_info_value     *rpc_prog;
363
364         rpc_prog_key.prog = prog;
365         if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
366                 progname = "Unknown";
367         }
368         else {
369                 progname = rpc_prog->progname;
370         }
371         return progname;
372 }
373
374
375 /*--------------------------------------*/
376 /* end of Hash array with program names */
377 /*--------------------------------------*/
378
379 typedef struct _rpc_call_info_key {
380         guint32 xid;
381         conversation_t *conversation;
382 } rpc_call_info_key;
383
384 static GMemChunk *rpc_call_info_key_chunk;
385
386 static GMemChunk *rpc_call_info_value_chunk;
387
388 static GHashTable *rpc_calls;
389
390 static GHashTable *rpc_indir_calls;
391
392 /* compare 2 keys */
393 gint
394 rpc_call_equal(gconstpointer k1, gconstpointer k2)
395 {
396         rpc_call_info_key* key1 = (rpc_call_info_key*) k1;
397         rpc_call_info_key* key2 = (rpc_call_info_key*) k2;
398
399         return (key1->xid == key2->xid &&
400             key1->conversation == key2->conversation);
401 }
402
403
404 /* calculate a hash key */
405 guint
406 rpc_call_hash(gconstpointer k)
407 {
408         rpc_call_info_key* key = (rpc_call_info_key*) k;
409
410         return key->xid + (guint32)(key->conversation);
411 }
412
413
414 unsigned int
415 rpc_roundup(unsigned int a)
416 {
417         unsigned int mod = a % 4;
418         return a + ((mod)? 4-mod : 0);
419 }
420
421
422 int
423 dissect_rpc_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
424 int hfindex, int offset)
425 {
426         if (tree)
427                 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
428         return offset + 4;
429 }
430
431
432 int
433 dissect_rpc_uint32(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
434 int hfindex, int offset)
435 {
436         if (tree)
437                 proto_tree_add_item(tree, hfindex, tvb, offset, 4, FALSE);
438         return offset + 4;
439 }
440
441
442 int
443 dissect_rpc_uint64(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
444 int hfindex, int offset)
445 {
446         header_field_info       *hfinfo;
447
448         hfinfo = proto_registrar_get_nth(hfindex);
449         g_assert(hfinfo->type == FT_UINT64);
450         if (tree)
451                 proto_tree_add_item(tree, hfindex, tvb, offset, 8, FALSE);
452
453         return offset + 8;
454 }
455
456
457 static int
458 dissect_rpc_opaque_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
459     proto_tree *tree, int hfindex, gboolean string_data,
460     char **string_buffer_ret)
461 {
462         proto_item *string_item = NULL;
463         proto_tree *string_tree = NULL;
464         int old_offset = offset;
465
466         int length_truncated = 0;
467
468         int string_truncated = 0;
469         guint32 string_length = 0;
470         guint32 string_length_full;
471         guint32 string_length_packet;
472         guint32 string_length_copy = 0;
473
474         int fill_truncated = 0;
475         guint32 fill_length  = 0;
476         guint32 fill_length_packet  = 0;
477         guint32 fill_length_copy  = 0;
478
479         char *string_buffer = NULL;
480         char *string_buffer_print = NULL;
481
482         string_length = tvb_get_ntohl(tvb,offset+0);
483         string_length_full = rpc_roundup(string_length);
484         /* XXX - just let the tvbuff stuff throw an exception? */
485         string_length_packet = tvb_length_remaining(tvb, offset + 4);
486         if (string_length_packet < string_length) {
487                 /* truncated string */
488                 string_truncated = 1;
489                 string_length_copy = string_length_packet;
490                 fill_truncated = 2;
491                 fill_length = 0;
492                 fill_length_packet = 0;
493                 fill_length_copy = 0;
494         }
495         else {
496                 /* full string data */
497                 string_truncated = 0;
498                 string_length_copy = string_length;
499                 fill_length = string_length_full - string_length;
500                 /* XXX - just let the tvbuff stuff throw an exception? */
501                 fill_length_packet = tvb_length_remaining(tvb,
502                     offset + 4 + string_length);
503                 if (fill_length_packet < fill_length) {
504                         /* truncated fill bytes */
505                         fill_length_copy = fill_length_packet;
506                         fill_truncated = 1;
507                 }
508                 else {
509                         /* full fill bytes */
510                         fill_length_copy = fill_length;
511                         fill_truncated = 0;
512                 }
513         }
514         string_buffer = (char*)g_malloc(string_length_copy + 
515                         (string_data ? 1 : 0));
516         tvb_memcpy(tvb,string_buffer,offset+4,string_length_copy);
517         if (string_data)
518                 string_buffer[string_length_copy] = '\0';
519
520         /* calculate a nice printable string */
521         if (string_length) {
522                 if (string_length != string_length_copy) {
523                         if (string_data) {
524                                 /* alloc maximum data area */
525                                 string_buffer_print = (char*)g_malloc(string_length_copy + 12 + 1);
526                                 /* copy over the data */
527                                 memcpy(string_buffer_print,string_buffer,string_length_copy);
528                                 /* append a 0 byte for sure printing */
529                                 string_buffer_print[string_length_copy] = '\0';
530                                 /* append <TRUNCATED> */
531                                 /* This way, we get the TRUNCATED even
532                                    in the case of totally wrong packets,
533                                    where \0 are inside the string.
534                                    TRUNCATED will appear at the
535                                    first \0 or at the end (where we 
536                                    put the securing \0).
537                                 */
538                                 strcat(string_buffer_print,"<TRUNCATED>");
539                         }
540                         else {
541                                 string_buffer_print = g_strdup("<DATA><TRUNCATED>");
542                         }
543                 }
544                 else {
545                         if (string_data) {
546                                 string_buffer_print = g_strdup(string_buffer);
547                         }
548                         else {
549                                 string_buffer_print = g_strdup("<DATA>");
550                         }
551                 }
552         }
553         else {
554                 string_buffer_print = g_strdup("<EMPTY>");
555         }
556
557         if (tree) {
558                 string_item = proto_tree_add_text(tree, tvb,offset+0, tvb_length_remaining(tvb, offset),
559                         "%s: %s", proto_registrar_get_name(hfindex), string_buffer_print);
560                 if (string_data) {
561                         proto_tree_add_string_hidden(tree, hfindex, tvb, offset+4,
562                                 string_length_copy, string_buffer);
563                 }
564                 if (string_item) {
565                         string_tree = proto_item_add_subtree(string_item, ett_rpc_string);
566                 }
567         }
568         if (length_truncated) {
569                 if (string_tree)
570                         proto_tree_add_text(string_tree, tvb,
571                                 offset, tvb_length_remaining(tvb, offset),
572                                 "length: <TRUNCATED>");
573                 offset = tvb_length(tvb);
574         } else {
575                 if (string_tree)
576                         proto_tree_add_text(string_tree, tvb,offset+0,4,
577                                 "length: %u", string_length);
578                 offset += 4;
579
580                 if (string_tree) {
581                         if (string_data) {
582                                 proto_tree_add_string_format(string_tree,
583                                     hfindex, tvb, offset, string_length_copy,
584                                         string_buffer_print, 
585                                         "contents: %s", string_buffer_print);
586                         } else {
587                                 proto_tree_add_bytes_format(string_tree,
588                                     hfindex, tvb, offset, string_length_copy,
589                                         string_buffer_print, 
590                                         "contents: %s", string_buffer_print);
591                         }
592                 }
593                 offset += string_length_copy;
594                 if (fill_length) {
595                         if (string_tree) {
596                                 if (fill_truncated) {
597                                         proto_tree_add_text(string_tree, tvb,
598                                         offset,fill_length_copy,
599                                         "fill bytes: opaque data<TRUNCATED>");
600                                 }
601                                 else {
602                                         proto_tree_add_text(string_tree, tvb,
603                                         offset,fill_length_copy,
604                                         "fill bytes: opaque data");
605                                 }
606                         }
607                         offset += fill_length_copy;
608                 }
609         }
610         
611         if (string_item) {
612                 proto_item_set_len(string_item, offset - old_offset);
613         }
614
615         if (string_buffer       != NULL) g_free (string_buffer      );
616         if (string_buffer_print != NULL) {
617                 if (string_buffer_ret != NULL)
618                         *string_buffer_ret = string_buffer_print;
619                 else
620                         g_free (string_buffer_print);
621         }
622         return offset;
623 }
624
625
626 int
627 dissect_rpc_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
628     int hfindex, int offset, char **string_buffer_ret)
629 {
630         offset = dissect_rpc_opaque_data(tvb, offset, pinfo, tree,
631             hfindex, TRUE, string_buffer_ret);
632         return offset;
633 }
634
635
636 int
637 dissect_rpc_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
638     int hfindex, int offset)
639 {
640         offset = dissect_rpc_opaque_data(tvb, offset, pinfo, tree, hfindex,
641             FALSE, NULL);
642
643         return offset;
644 }
645
646
647 int
648 dissect_rpc_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
649         int offset, dissect_function_t *rpc_list_dissector)
650 {
651         guint32 value_follows;
652
653         while (1) {
654                 value_follows = tvb_get_ntohl(tvb, offset+0);
655                 proto_tree_add_boolean(tree,hf_rpc_value_follows, tvb,
656                         offset+0, 4, value_follows);
657                 offset += 4;
658                 if (value_follows == 1) {
659                         offset = rpc_list_dissector(tvb, offset, pinfo, tree);
660                 }
661                 else {
662                         break;
663                 }
664         }
665
666         return offset;
667 }
668
669 int
670 dissect_rpc_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
671         int offset, dissect_function_t *rpc_array_dissector,
672         int hfindex)
673 {
674         proto_item* lock_item;
675         proto_tree* lock_tree;
676         guint32 num;
677         int old_offset = offset;
678
679         num = tvb_get_ntohl(tvb, offset);
680
681         if( num == 0 ){
682                 proto_tree_add_none_format(tree, hfindex, tvb, offset, 4,
683                         "no values");
684                 offset += 4;
685
686                 return offset;
687         }
688
689         lock_item = proto_tree_add_item(tree, hfindex, tvb, offset,
690                         0, FALSE);
691
692         lock_tree = proto_item_add_subtree(lock_item, ett_rpc_array);   
693
694         offset = dissect_rpc_uint32(tvb, pinfo, lock_tree,
695                         hf_rpc_array_len, offset);
696
697         while (num--) {
698                 offset = rpc_array_dissector(tvb, offset, pinfo, lock_tree);
699         }
700
701         proto_item_set_len(lock_item, offset-old_offset);
702         return offset;
703 }
704
705 static int
706 dissect_rpc_authunix_cred(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
707 {
708         guint stamp;
709         guint uid;
710         guint gid;
711         guint gids_count;
712         guint gids_i;
713         guint gids_entry;
714         proto_item *gitem;
715         proto_tree *gtree = NULL;
716
717         stamp = tvb_get_ntohl(tvb,offset+0);
718         if (tree)
719                 proto_tree_add_uint(tree, hf_rpc_auth_stamp, tvb,
720                         offset+0, 4, stamp);
721         offset += 4;
722
723         offset = dissect_rpc_string(tvb, pinfo, tree,
724                         hf_rpc_auth_machinename, offset, NULL);
725
726         uid = tvb_get_ntohl(tvb,offset+0);
727         if (tree)
728                 proto_tree_add_uint(tree, hf_rpc_auth_uid, tvb,
729                         offset+0, 4, uid);
730         offset += 4;
731
732         gid = tvb_get_ntohl(tvb,offset+0);
733         if (tree)
734                 proto_tree_add_uint(tree, hf_rpc_auth_gid, tvb,
735                         offset+0, 4, gid);
736         offset += 4;
737
738         gids_count = tvb_get_ntohl(tvb,offset+0);
739         if (tree) {
740                 gitem = proto_tree_add_text(tree, tvb,
741                         offset, 4+gids_count*4, "Auxiliary GIDs");
742                 gtree = proto_item_add_subtree(gitem, ett_rpc_gids);
743         }
744         offset += 4;
745         
746         for (gids_i = 0 ; gids_i < gids_count ; gids_i++) {
747                 gids_entry = tvb_get_ntohl(tvb,offset+0);
748                 if (gtree)
749                 proto_tree_add_uint(gtree, hf_rpc_auth_gid, tvb,
750                         offset, 4, gids_entry);
751                 offset+=4;
752         }
753         /* how can I NOW change the gitem to print a list with
754                 the first 16 gids? */
755
756         return offset;
757 }
758
759 static int
760 dissect_rpc_authgss_cred(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
761 {
762         guint agc_v;
763         guint agc_proc;
764         guint agc_seq;
765         guint agc_svc;
766
767         agc_v = tvb_get_ntohl(tvb, offset+0);
768         if (tree)
769                 proto_tree_add_uint(tree, hf_rpc_authgss_v,
770                                     tvb, offset+0, 4, agc_v);
771         offset += 4;
772         
773         agc_proc = tvb_get_ntohl(tvb, offset+0);
774         if (tree)
775                 proto_tree_add_uint(tree, hf_rpc_authgss_proc,
776                                     tvb, offset+0, 4, agc_proc);
777         offset += 4;
778         
779         agc_seq = tvb_get_ntohl(tvb, offset+0);
780         if (tree)
781                 proto_tree_add_uint(tree, hf_rpc_authgss_seq,
782                                     tvb, offset+0, 4, agc_seq);
783         offset += 4;
784         
785         agc_svc = tvb_get_ntohl(tvb, offset+0);
786         if (tree)
787                 proto_tree_add_uint(tree, hf_rpc_authgss_svc,
788                                     tvb, offset+0, 4, agc_svc);
789         offset += 4;
790         
791         offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_ctx,
792                         offset);
793         
794         return offset;
795 }
796
797 int
798 dissect_rpc_authdes_desblock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
799 int hfindex, int offset)
800 {
801         guint32 value_low;
802         guint32 value_high;
803
804         value_high = tvb_get_ntohl(tvb, offset + 0);
805         value_low  = tvb_get_ntohl(tvb, offset + 4);
806
807         if (tree) {
808                 proto_tree_add_text(tree, tvb, offset, 8,
809                         "%s: 0x%x%08x", proto_registrar_get_name(hfindex), value_high, 
810                         value_low);
811         }
812
813         return offset + 8;
814 }
815
816 static int
817 dissect_rpc_authdes_cred(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
818 {
819         guint adc_namekind;
820         guint window = 0;
821         guint nickname = 0;
822
823         adc_namekind = tvb_get_ntohl(tvb, offset+0);
824         if (tree)
825                 proto_tree_add_uint(tree, hf_rpc_authdes_namekind,
826                                     tvb, offset+0, 4, adc_namekind);
827         offset += 4;
828
829         switch(adc_namekind)
830         {
831         case AUTHDES_NAMEKIND_FULLNAME:
832                 offset = dissect_rpc_string(tvb, pinfo, tree, 
833                         hf_rpc_authdes_netname, offset, NULL);
834                 offset = dissect_rpc_authdes_desblock(tvb, pinfo, tree,
835                         hf_rpc_authdes_convkey, offset);
836                 window = tvb_get_ntohl(tvb, offset+0);
837                 proto_tree_add_uint(tree, hf_rpc_authdes_window, tvb, offset+0, 4,
838                         window);
839                 offset += 4;
840                 break;
841
842         case AUTHDES_NAMEKIND_NICKNAME:
843                 nickname = tvb_get_ntohl(tvb, offset+0);
844                 proto_tree_add_uint(tree, hf_rpc_authdes_nickname, tvb, offset+0, 4,
845                         window);
846                 offset += 4;
847                 break;
848         }
849
850         return offset;
851 }
852
853 static int
854 dissect_rpc_cred(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
855 {
856         guint flavor;
857         guint length;
858
859         proto_item *citem;
860         proto_tree *ctree;
861
862         flavor = tvb_get_ntohl(tvb,offset+0);
863         length = tvb_get_ntohl(tvb,offset+4);
864         length = rpc_roundup(length);
865
866         if (tree) {
867                 citem = proto_tree_add_text(tree, tvb, offset,
868                                             8+length, "Credentials");
869                 ctree = proto_item_add_subtree(citem, ett_rpc_cred);
870                 proto_tree_add_uint(ctree, hf_rpc_auth_flavor, tvb,
871                                     offset+0, 4, flavor);
872                 proto_tree_add_uint(ctree, hf_rpc_auth_length, tvb,
873                                     offset+4, 4, length);
874
875                 switch (flavor) {
876                 case AUTH_UNIX:
877                         dissect_rpc_authunix_cred(tvb, pinfo, ctree, offset+8);
878                         break;
879                 /*
880                 case AUTH_SHORT:
881
882                 break;
883                 */
884                 case AUTH_DES:
885                         dissect_rpc_authdes_cred(tvb, pinfo, ctree, offset+8);
886                         break;
887                         
888                 case RPCSEC_GSS:
889                         dissect_rpc_authgss_cred(tvb, pinfo, ctree, offset+8);
890                         break;
891                 default:
892                         if (length)
893                                 proto_tree_add_text(ctree, tvb, offset+8,
894                                                     length,"opaque data");
895                 break;
896                 }
897         }
898         offset += 8 + length;
899
900         return offset;
901 }
902
903 /* AUTH_DES verifiers are asymmetrical, so we need to know what type of
904  * verifier we're decoding (CALL or REPLY).
905  */
906 static int
907 dissect_rpc_verf(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset, int msg_type)
908 {
909         guint flavor;
910         guint length;
911         
912         proto_item *vitem;
913         proto_tree *vtree;
914
915         flavor = tvb_get_ntohl(tvb,offset+0);
916         length = tvb_get_ntohl(tvb,offset+4);
917         length = rpc_roundup(length);
918
919         if (tree) {
920                 vitem = proto_tree_add_text(tree, tvb, offset,
921                                             8+length, "Verifier");
922                 vtree = proto_item_add_subtree(vitem, ett_rpc_verf);
923                 proto_tree_add_uint(vtree, hf_rpc_auth_flavor, tvb,
924                                     offset+0, 4, flavor);
925
926                 switch (flavor) {
927                 case AUTH_UNIX:
928                         proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
929                                             offset+4, 4, length);
930                         dissect_rpc_authunix_cred(tvb, pinfo, vtree, offset+8);
931                         break;
932                 case AUTH_DES:
933                         proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
934                                 offset+4, 4, length);
935
936                         if (msg_type == RPC_CALL)
937                         {
938                                 guint window;
939
940                                 dissect_rpc_authdes_desblock(tvb, pinfo, vtree,
941                                         hf_rpc_authdes_timestamp, offset+8);
942                                 window = tvb_get_ntohl(tvb, offset+16);
943                                 proto_tree_add_uint(vtree, hf_rpc_authdes_windowverf, tvb, 
944                                         offset+16, 4, window);
945                         }
946                         else
947                         {
948                                 /* must be an RPC_REPLY */
949                                 guint nickname;
950
951                                 dissect_rpc_authdes_desblock(tvb, pinfo, vtree,
952                                         hf_rpc_authdes_timeverf, offset+8);
953                                 nickname = tvb_get_ntohl(tvb, offset+16);
954                                 proto_tree_add_uint(vtree, hf_rpc_authdes_nickname, tvb, 
955                                         offset+16, 4, nickname);
956                         }
957                         break;
958                 case RPCSEC_GSS:
959                         dissect_rpc_data(tvb, pinfo, vtree,
960                                 hf_rpc_authgss_checksum, offset+4);
961                         break;
962                 default:
963                         proto_tree_add_uint(vtree, hf_rpc_auth_length, tvb,
964                                             offset+4, 4, length);
965                         if (length)
966                                 proto_tree_add_text(vtree, tvb, offset+8,
967                                                     length, "opaque data");
968                         break;
969                 }
970         }
971         offset += 8 + length;
972
973         return offset;
974 }
975
976 static int
977 dissect_rpc_authgss_initarg(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
978 {
979         offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_token,
980                         offset);
981         return offset;
982 }
983
984 static int
985 dissect_rpc_authgss_initres(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
986 {
987         int major, minor, window;
988         
989         offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_ctx,
990                         offset);
991         
992         major = tvb_get_ntohl(tvb,offset+0);
993         if (tree)
994                 proto_tree_add_uint(tree, hf_rpc_authgss_major, tvb,
995                                     offset+0, 4, major);
996         offset += 4;
997
998         minor = tvb_get_ntohl(tvb,offset+0);
999         if (tree)
1000                 proto_tree_add_uint(tree, hf_rpc_authgss_minor, tvb,
1001                                     offset+0, 4, minor);
1002         offset += 4;
1003
1004         window = tvb_get_ntohl(tvb,offset+0);
1005         if (tree)
1006                 proto_tree_add_uint(tree, hf_rpc_authgss_window, tvb,
1007                                     offset+0, 4, window);
1008         offset += 4;
1009
1010         offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_token,
1011                         offset);
1012
1013         return offset;
1014 }
1015
1016
1017 static int
1018 call_dissect_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1019         int offset, dissect_function_t* dissect_function, const char *progname)
1020 {
1021         const char *saved_proto;
1022
1023         if (dissect_function != NULL) {
1024                 /* set the current protocol name */
1025                 saved_proto = pinfo->current_proto;
1026                 if (progname != NULL)
1027                         pinfo->current_proto = progname;
1028
1029                 /* call the dissector for the next level */
1030                 offset = dissect_function(tvb, offset, pinfo, tree);
1031
1032                 /* restore the protocol name */
1033                 pinfo->current_proto = saved_proto;
1034         }
1035
1036         return offset;
1037 }
1038
1039
1040 static int
1041 dissect_rpc_authgss_integ_data(tvbuff_t *tvb, packet_info *pinfo,
1042         proto_tree *tree, int offset,
1043         dissect_function_t* dissect_function,
1044         const char *progname)
1045 {
1046         guint32 length, seq;
1047         
1048         proto_item *gitem;
1049         proto_tree *gtree = NULL;
1050
1051         length = tvb_get_ntohl(tvb, offset+0);
1052         length = rpc_roundup(length);
1053         seq = tvb_get_ntohl(tvb, offset+4);
1054
1055         if (tree) {
1056                 gitem = proto_tree_add_text(tree, tvb, offset,
1057                                             4+length, "GSS Data");
1058                 gtree = proto_item_add_subtree(gitem, ett_rpc_gss_data);
1059                 proto_tree_add_uint(gtree, hf_rpc_authgss_data_length,
1060                                     tvb, offset+0, 4, length);
1061                 proto_tree_add_uint(gtree, hf_rpc_authgss_seq,
1062                                     tvb, offset+4, 4, seq);
1063         }
1064         offset += 8;
1065
1066         if (dissect_function != NULL) {
1067                 /* offset = */
1068                 call_dissect_function(tvb, pinfo, gtree, offset,
1069                                       dissect_function, progname);
1070         }
1071         offset += length - 4;
1072         offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_checksum,
1073                         offset);
1074         return offset;
1075 }
1076
1077
1078 static int
1079 dissect_rpc_authgss_priv_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1080 {
1081         offset = dissect_rpc_data(tvb, pinfo, tree, hf_rpc_authgss_data,
1082                         offset);
1083         return offset;
1084 }
1085
1086 /*
1087  * Dissect the arguments to an indirect call; used by the portmapper/RPCBIND
1088  * dissector.
1089  *
1090  * Record this call in a hash table, similar to the hash table for
1091  * direct calls, so we can find it when dissecting an indirect call reply.
1092  */
1093 int
1094 dissect_rpc_indir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1095     int offset, int args_id, guint32 prog, guint32 vers, guint32 proc)
1096 {
1097         conversation_t* conversation;
1098         static address null_address = { AT_NONE, 0, NULL };
1099         rpc_proc_info_key key;
1100         rpc_proc_info_value *value;
1101         rpc_call_info_value *rpc_call;
1102         rpc_call_info_key rpc_call_key;
1103         rpc_call_info_key *new_rpc_call_key;
1104         dissect_function_t *dissect_function = NULL;
1105
1106         key.prog = prog;
1107         key.vers = vers;
1108         key.proc = proc;
1109         if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1110                 dissect_function = value->dissect_call;
1111
1112                 /* Keep track of the address and port whence the call came,
1113                    and the port to which the call is being sent, so that
1114                    we can match up calls with replies.
1115
1116                    If the transport is connection-oriented (we check, for
1117                    now, only for "pinfo->ptype" of PT_TCP), we take
1118                    into account the address from which the call was sent
1119                    and the address to which the call was sent, because
1120                    the addresses of the two endpoints should be the same
1121                    for all calls and replies.
1122
1123                    If the transport is connectionless, we don't worry
1124                    about the address to which the call was sent and from
1125                    which the reply was sent, because there's no
1126                    guarantee that the reply will come from the address
1127                    to which the call was sent. */
1128                 if (pinfo->ptype == PT_TCP) {
1129                         conversation = find_conversation(&pinfo->src,
1130                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1131                             pinfo->destport, 0);
1132                 } else {
1133                         /*
1134                          * XXX - can we just use NO_ADDR_B?  Unfortunately,
1135                          * you currently still have to pass a non-null
1136                          * pointer for the second address argument even
1137                          * if you do that.
1138                          */
1139                         conversation = find_conversation(&pinfo->src,
1140                             &null_address, pinfo->ptype, pinfo->srcport,
1141                             pinfo->destport, 0);
1142                 }
1143                 if (conversation == NULL) {
1144                         /* It's not part of any conversation - create a new
1145                            one.
1146
1147                            XXX - this should never happen, as we should've
1148                            created a conversation for it in the RPC
1149                            dissector. */
1150                         if (pinfo->ptype == PT_TCP) {
1151                                 conversation = conversation_new(&pinfo->src,
1152                                     &pinfo->dst, pinfo->ptype, pinfo->srcport,
1153                                     pinfo->destport, 0);
1154                         } else {
1155                                 conversation = conversation_new(&pinfo->src,
1156                                     &null_address, pinfo->ptype, pinfo->srcport,
1157                                     pinfo->destport, 0);
1158                         }
1159                 }
1160
1161                 /* Make the dissector for this conversation the non-heuristic
1162                    RPC dissector. */
1163                 conversation_set_dissector(conversation,
1164                     (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1165
1166                 /* Prepare the key data.
1167
1168                    Dissectors for RPC procedure calls and replies shouldn't
1169                    create new tvbuffs, and we don't create one ourselves,
1170                    so we should have been handed the tvbuff for this RPC call;
1171                    as such, the XID is at offset 0 in this tvbuff. */
1172                 rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1173                 rpc_call_key.conversation = conversation;
1174
1175                 /* look up the request */
1176                 rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1177                 if (rpc_call == NULL) {
1178                         /* We didn't find it; create a new entry.
1179                            Prepare the value data.
1180                            Not all of it is needed for handling indirect
1181                            calls, so we set a bunch of items to 0. */
1182                         new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1183                         *new_rpc_call_key = rpc_call_key;
1184                         rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1185                         rpc_call->req_num = 0;
1186                         rpc_call->rep_num = 0;
1187                         rpc_call->prog = prog;
1188                         rpc_call->vers = vers;
1189                         rpc_call->proc = proc;
1190
1191                         /*
1192                          * XXX - what about RPCSEC_GSS?
1193                          * Do we have to worry about it?
1194                          */
1195                         rpc_call->flavor = FLAVOR_NOT_GSSAPI;
1196                         rpc_call->gss_proc = 0;
1197                         rpc_call->gss_svc = 0;
1198                         rpc_call->proc_info = value;
1199                         /* store it */
1200                         g_hash_table_insert(rpc_indir_calls, new_rpc_call_key,
1201                             rpc_call);
1202                 }
1203         }
1204         else {
1205                 /* We don't know the procedure.
1206                    Happens only with strange program versions or
1207                    non-existing dissectors.
1208                    Just show the arguments as opaque data. */
1209                 offset = dissect_rpc_data(tvb, pinfo, tree, args_id,
1210                     offset);
1211                 return offset;
1212         }
1213
1214         if ( tree )
1215         {
1216                 proto_tree_add_text(tree, tvb, offset, 4,
1217                         "Argument length: %u",
1218                         tvb_get_ntohl(tvb, offset));
1219         }
1220         offset += 4;
1221
1222         /* Dissect the arguments */
1223         offset = call_dissect_function(tvb, pinfo, tree, offset,
1224                         dissect_function, NULL);
1225         return offset;
1226 }
1227
1228 /*
1229  * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1230  * dissector.
1231  */
1232 int
1233 dissect_rpc_indir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1234     int offset, int result_id, int prog_id, int vers_id, int proc_id)
1235 {
1236         conversation_t* conversation;
1237         static address null_address = { AT_NONE, 0, NULL };
1238         rpc_call_info_key rpc_call_key;
1239         rpc_call_info_value *rpc_call;
1240         char *procname = NULL;
1241         char procname_static[20];
1242         dissect_function_t *dissect_function = NULL;
1243
1244         /* Look for the matching call in the hash table of indirect
1245            calls.  A reply must match a call that we've seen, and the
1246            reply must be sent to the same port and address that the
1247            call came from, and must come from the port to which the
1248            call was sent.
1249
1250            If the transport is connection-oriented (we check, for
1251            now, only for "pinfo->ptype" of PT_TCP), we take
1252            into account the address from which the call was sent
1253            and the address to which the call was sent, because
1254            the addresses of the two endpoints should be the same
1255            for all calls and replies.
1256
1257            If the transport is connectionless, we don't worry
1258            about the address to which the call was sent and from
1259            which the reply was sent, because there's no
1260            guarantee that the reply will come from the address
1261            to which the call was sent. */
1262         if (pinfo->ptype == PT_TCP) {
1263                 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1264                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1265         } else {
1266                 /*
1267                  * XXX - can we just use NO_ADDR_B?  Unfortunately,
1268                  * you currently still have to pass a non-null
1269                  * pointer for the second address argument even
1270                  * if you do that.
1271                  */
1272                 conversation = find_conversation(&null_address, &pinfo->dst,
1273                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1274         }
1275         if (conversation == NULL) {
1276                 /* We haven't seen an RPC call for that conversation,
1277                    so we can't check for a reply to that call.
1278                    Just show the reply stuff as opaque data. */
1279                 offset = dissect_rpc_data(tvb, pinfo, tree, result_id,
1280                     offset);
1281                 return offset;
1282         }
1283
1284         /* The XIDs of the call and reply must match. */
1285         rpc_call_key.xid = tvb_get_ntohl(tvb, 0);
1286         rpc_call_key.conversation = conversation;
1287         rpc_call = g_hash_table_lookup(rpc_indir_calls, &rpc_call_key);
1288         if (rpc_call == NULL) {
1289                 /* The XID doesn't match a call from that
1290                    conversation, so it's probably not an RPC reply.
1291                    Just show the reply stuff as opaque data. */
1292                 offset = dissect_rpc_data(tvb, pinfo, tree, result_id,
1293                     offset);
1294                 return offset;
1295         }
1296
1297         if (rpc_call->proc_info != NULL) {
1298                 dissect_function = rpc_call->proc_info->dissect_reply;
1299                 if (rpc_call->proc_info->name != NULL) {
1300                         procname = rpc_call->proc_info->name;
1301                 }
1302                 else {
1303                         sprintf(procname_static, "proc-%u", rpc_call->proc);
1304                         procname = procname_static;
1305                 }
1306         }
1307         else {
1308 #if 0
1309                 dissect_function = NULL;
1310 #endif
1311                 sprintf(procname_static, "proc-%u", rpc_call->proc);
1312                 procname = procname_static;
1313         }
1314
1315         if ( tree )
1316         {
1317                 /* Put the program, version, and procedure into the tree. */
1318                 proto_tree_add_uint_format(tree, prog_id, tvb,
1319                         0, 0, rpc_call->prog, "Program: %s (%u)",
1320                         rpc_prog_name(rpc_call->prog), rpc_call->prog);
1321                 proto_tree_add_uint(tree, vers_id, tvb, 0, 0, rpc_call->vers);
1322                 proto_tree_add_uint_format(tree, proc_id, tvb,
1323                         0, 0, rpc_call->proc, "Procedure: %s (%u)",
1324                         procname, rpc_call->proc);
1325         }
1326
1327         if (dissect_function == NULL) {
1328                 /* We don't know how to dissect the reply procedure.
1329                    Just show the reply stuff as opaque data. */
1330                 offset = dissect_rpc_data(tvb, pinfo, tree, result_id,
1331                     offset);
1332                 return offset;
1333         }
1334
1335         if (tree) {
1336                 /* Put the length of the reply value into the tree. */
1337                 proto_tree_add_text(tree, tvb, offset, 4,
1338                         "Argument length: %u",
1339                         tvb_get_ntohl(tvb, offset));
1340         }
1341         offset += 4;
1342
1343         /* Dissect the return value */
1344         offset = call_dissect_function(tvb, pinfo, tree, offset,
1345                         dissect_function, NULL);
1346         return offset;
1347 }
1348
1349 /*
1350  * Just mark this as a continuation of an earlier packet.
1351  */
1352 static void
1353 dissect_rpc_continuation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1354 {
1355         proto_item *rpc_item;
1356         proto_tree *rpc_tree;
1357
1358         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1359                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1360         if (check_col(pinfo->cinfo, COL_INFO))
1361                 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1362
1363         if (tree) {
1364                 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0,
1365                                 tvb_length(tvb), FALSE);
1366                 rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1367                 proto_tree_add_text(rpc_tree, tvb, 0, tvb_length(tvb),
1368                     "Continuation data");
1369         }
1370 }
1371
1372 static gboolean
1373 dissect_rpc_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
1374     proto_tree *tree, gboolean use_rm, guint32 rpc_rm)
1375 {
1376         guint32 msg_type;
1377         rpc_call_info_key rpc_call_key;
1378         rpc_call_info_value *rpc_call = NULL;
1379         rpc_prog_info_value *rpc_prog = NULL;
1380         rpc_prog_info_key rpc_prog_key;
1381
1382         unsigned int xid;
1383         unsigned int rpcvers;
1384         unsigned int prog = 0;
1385         unsigned int vers = 0;
1386         unsigned int proc = 0;
1387         flavor_t flavor = FLAVOR_UNKNOWN;
1388         unsigned int gss_proc = 0;
1389         unsigned int gss_svc = 0;
1390         int     proto = 0;
1391         int     ett = 0;
1392
1393         unsigned int reply_state;
1394         unsigned int accept_state;
1395         unsigned int reject_state;
1396
1397         char *msg_type_name = NULL;
1398         char *progname = NULL;
1399         char *procname = NULL;
1400         static char procname_static[20];
1401
1402         unsigned int vers_low;
1403         unsigned int vers_high;
1404
1405         unsigned int auth_state;
1406
1407         proto_item *rpc_item=NULL;
1408         proto_tree *rpc_tree = NULL;
1409
1410         proto_item *pitem=NULL;
1411         proto_tree *ptree = NULL;
1412         int offset_old = offset;
1413
1414         rpc_call_info_key       *new_rpc_call_key;
1415         rpc_proc_info_key       key;
1416         rpc_proc_info_value     *value = NULL;
1417         conversation_t* conversation;
1418         static address null_address = { AT_NONE, 0, NULL };
1419         nstime_t ns;
1420
1421         dissect_function_t *dissect_function = NULL;
1422
1423         /*
1424          * Check to see whether this looks like an RPC call or reply.
1425          */
1426         if (!tvb_bytes_exist(tvb, offset, 8)) {
1427                 /* Captured data in packet isn't enough to let us tell. */
1428                 return FALSE;
1429         }
1430
1431         /* both directions need at least this */
1432         msg_type = tvb_get_ntohl(tvb, offset + 4);
1433
1434         switch (msg_type) {
1435
1436         case RPC_CALL:
1437                 /* check for RPC call */
1438                 if (!tvb_bytes_exist(tvb, offset, 16)) {
1439                         /* Captured data in packet isn't enough to let us
1440                            tell. */
1441                         return FALSE;
1442                 }
1443
1444                 /* XID can be anything, we don't check it.
1445                    We already have the message type.
1446                    Check whether an RPC version number of 2 is in the
1447                    location where it would be, and that an RPC program
1448                    number we know about is in the location where it would be. */
1449                 rpc_prog_key.prog = tvb_get_ntohl(tvb, offset + 12);
1450                 if (tvb_get_ntohl(tvb, offset + 8) != 2 ||
1451                     ((rpc_prog = g_hash_table_lookup(rpc_progs, &rpc_prog_key))
1452                        == NULL)) {
1453                         /* They're not, so it's probably not an RPC call. */
1454                         return FALSE;
1455                 }
1456                 break;
1457
1458         case RPC_REPLY:
1459                 /* Check for RPC reply.  A reply must match a call that
1460                    we've seen, and the reply must be sent to the same
1461                    port and address that the call came from, and must
1462                    come from the port to which the call was sent.
1463
1464                    If the transport is connection-oriented (we check, for
1465                    now, only for "pinfo->ptype" of PT_TCP), we take
1466                    into account the address from which the call was sent
1467                    and the address to which the call was sent, because
1468                    the addresses of the two endpoints should be the same
1469                    for all calls and replies.
1470
1471                    If the transport is connectionless, we don't worry
1472                    about the address to which the call was sent and from
1473                    which the reply was sent, because there's no
1474                    guarantee that the reply will come from the address
1475                    to which the call was sent. */
1476                 if (pinfo->ptype == PT_TCP) {
1477                         conversation = find_conversation(&pinfo->src,
1478                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1479                             pinfo->destport, 0);
1480                 } else {
1481                         /*
1482                          * XXX - can we just use NO_ADDR_B?  Unfortunately,
1483                          * you currently still have to pass a non-null
1484                          * pointer for the second address argument even
1485                          * if you do that.
1486                          */
1487                         conversation = find_conversation(&null_address,
1488                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1489                             pinfo->destport, 0);
1490                 }
1491                 if (conversation == NULL) {
1492                         /* We haven't seen an RPC call for that conversation,
1493                            so we can't check for a reply to that call. */
1494                         return FALSE;
1495                 }
1496
1497                 /* The XIDs of the call and reply must match. */
1498                 rpc_call_key.xid = tvb_get_ntohl(tvb, offset + 0);
1499                 rpc_call_key.conversation = conversation;
1500                 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1501                 if (rpc_call == NULL) {
1502                         /* The XID doesn't match a call from that
1503                            conversation, so it's probably not an RPC reply. */
1504                         return FALSE;
1505                 }
1506                 /* pass rpc_info to subdissectors */
1507                 rpc_call->request=FALSE;
1508                 pinfo->private_data=rpc_call;
1509                 break;
1510
1511         default:
1512                 /* The putative message type field contains neither
1513                    RPC_CALL nor RPC_REPLY, so it's not an RPC call or
1514                    reply. */
1515                 return FALSE;
1516         }
1517
1518         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1519                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPC");
1520         if (check_col(pinfo->cinfo, COL_INFO))
1521                 col_clear(pinfo->cinfo, COL_INFO);
1522
1523         if (tree) {
1524                 rpc_item = proto_tree_add_item(tree, proto_rpc, tvb, 0,
1525                                 tvb_length(tvb), FALSE);
1526                 if (rpc_item) {
1527                         rpc_tree = proto_item_add_subtree(rpc_item, ett_rpc);
1528                 }
1529         }
1530
1531         if (use_rm && rpc_tree) {
1532                 proto_tree_add_boolean(rpc_tree,hf_rpc_lastfrag, tvb,
1533                         offset-4, 4, (rpc_rm >> 31) & 0x1);
1534                 proto_tree_add_uint(rpc_tree,hf_rpc_fraglen, tvb,
1535                         offset-4, 4, rpc_rm & RPC_RM_FRAGLEN);
1536         }
1537
1538         xid      = tvb_get_ntohl(tvb, offset + 0);
1539         if (rpc_tree) {
1540                 proto_tree_add_uint_format(rpc_tree,hf_rpc_xid, tvb,
1541                         offset+0, 4, xid, "XID: 0x%x (%u)", xid, xid);
1542         }
1543
1544         msg_type_name = val_to_str(msg_type,rpc_msg_type,"%u");
1545         if (rpc_tree) {
1546                 proto_tree_add_uint(rpc_tree, hf_rpc_msgtype, tvb,
1547                         offset+4, 4, msg_type);
1548         }
1549
1550         offset += 8;
1551
1552         switch (msg_type) {
1553
1554         case RPC_CALL:
1555                 /* we know already the proto-entry, the ETT-const,
1556                    and "rpc_prog" */
1557                 proto = rpc_prog->proto;
1558                 ett = rpc_prog->ett;
1559                 progname = rpc_prog->progname;
1560
1561                 rpcvers = tvb_get_ntohl(tvb, offset + 0);
1562                 if (rpc_tree) {
1563                         proto_tree_add_uint(rpc_tree,
1564                                 hf_rpc_version, tvb, offset+0, 4, rpcvers);
1565                 }
1566
1567                 prog = tvb_get_ntohl(tvb, offset + 4);
1568                 
1569                 if (rpc_tree) {
1570                         proto_tree_add_uint_format(rpc_tree,
1571                                 hf_rpc_program, tvb, offset+4, 4, prog,
1572                                 "Program: %s (%u)", progname, prog);
1573                 }
1574                 
1575                 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1576                         /* Set the protocol name to the underlying
1577                            program name. */
1578                         col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1579                 }
1580
1581                 vers = tvb_get_ntohl(tvb, offset+8);
1582                 if (rpc_tree) {
1583                         proto_tree_add_uint(rpc_tree,
1584                                 hf_rpc_programversion, tvb, offset+8, 4, vers);
1585                 }
1586
1587                 proc = tvb_get_ntohl(tvb, offset+12);
1588
1589                 key.prog = prog;
1590                 key.vers = vers;
1591                 key.proc = proc;
1592
1593                 if ((value = g_hash_table_lookup(rpc_procs,&key)) != NULL) {
1594                         dissect_function = value->dissect_call;
1595                         procname = value->name;
1596                 }
1597                 else {
1598                         /* happens only with strange program versions or
1599                            non-existing dissectors */
1600 #if 0
1601                         dissect_function = NULL;
1602 #endif
1603                         sprintf(procname_static, "proc-%u", proc);
1604                         procname = procname_static;
1605                 }
1606                 
1607                 if (rpc_tree) {
1608                         proto_tree_add_uint_format(rpc_tree,
1609                                 hf_rpc_procedure, tvb, offset+12, 4, proc,
1610                                 "Procedure: %s (%u)", procname, proc);
1611                 }
1612
1613                 if (check_col(pinfo->cinfo, COL_INFO)) {
1614                         col_add_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s XID 0x%x",
1615                                 vers,
1616                                 procname,
1617                                 msg_type_name,
1618                                 xid);
1619                 }
1620
1621                 /* Check for RPCSEC_GSS */
1622                 if (tvb_bytes_exist(tvb, offset+16, 4)) {
1623                         switch (tvb_get_ntohl(tvb, offset+16)) {
1624
1625                         case RPCSEC_GSS:
1626                                 /*
1627                                  * It's GSS-API authentication...
1628                                  */
1629                                 if (tvb_bytes_exist(tvb, offset+28, 8)) {
1630                                         /*
1631                                          * ...and we have the procedure
1632                                          * and service information for it.
1633                                          */
1634                                         flavor = FLAVOR_GSSAPI;
1635                                         gss_proc = tvb_get_ntohl(tvb, offset+28);
1636                                         gss_svc = tvb_get_ntohl(tvb, offset+36);
1637                                 } else {
1638                                         /*
1639                                          * ...but the procedure and service
1640                                          * information isn't available.
1641                                          */
1642                                         flavor = FLAVOR_GSSAPI_NO_INFO;
1643                                 }
1644                                 break;
1645
1646                         default:
1647                                 /*
1648                                  * It's not GSS-API authentication.
1649                                  */
1650                                 flavor = FLAVOR_NOT_GSSAPI;
1651                                 break;
1652                         }
1653                 }
1654
1655                 /* Keep track of the address and port whence the call came,
1656                    and the port to which the call is being sent, so that
1657                    we can match up calls with replies.
1658
1659                    If the transport is connection-oriented (we check, for
1660                    now, only for "pinfo->ptype" of PT_TCP), we take
1661                    into account the address from which the call was sent
1662                    and the address to which the call was sent, because
1663                    the addresses of the two endpoints should be the same
1664                    for all calls and replies.
1665
1666                    If the transport is connectionless, we don't worry
1667                    about the address to which the call was sent and from
1668                    which the reply was sent, because there's no
1669                    guarantee that the reply will come from the address
1670                    to which the call was sent. */
1671                 if (pinfo->ptype == PT_TCP) {
1672                         conversation = find_conversation(&pinfo->src,
1673                             &pinfo->dst, pinfo->ptype, pinfo->srcport,
1674                             pinfo->destport, 0);
1675                 } else {
1676                         /*
1677                          * XXX - can we just use NO_ADDR_B?  Unfortunately,
1678                          * you currently still have to pass a non-null
1679                          * pointer for the second address argument even
1680                          * if you do that.
1681                          */
1682                         conversation = find_conversation(&pinfo->src,
1683                             &null_address, pinfo->ptype, pinfo->srcport,
1684                             pinfo->destport, 0);
1685                 }
1686                 if (conversation == NULL) {
1687                         /* It's not part of any conversation - create a new
1688                            one. */
1689                         if (pinfo->ptype == PT_TCP) {
1690                                 conversation = conversation_new(&pinfo->src,
1691                                     &pinfo->dst, pinfo->ptype, pinfo->srcport,
1692                                     pinfo->destport, 0);
1693                         } else {
1694                                 conversation = conversation_new(&pinfo->src,
1695                                     &null_address, pinfo->ptype, pinfo->srcport,
1696                                     pinfo->destport, 0);
1697                         }
1698                 }
1699
1700                 /* Make the dissector for this conversation the non-heuristic
1701                    RPC dissector. */
1702                 conversation_set_dissector(conversation,
1703                     (pinfo->ptype == PT_TCP) ? rpc_tcp_handle : rpc_handle);
1704
1705                 /* prepare the key data */
1706                 rpc_call_key.xid = xid;
1707                 rpc_call_key.conversation = conversation;
1708
1709                 /* look up the request */
1710                 rpc_call = g_hash_table_lookup(rpc_calls, &rpc_call_key);
1711                 if (rpc_call != NULL) {
1712                         /* We've seen a request with this XID, with the same
1713                            source and destination, before - but was it
1714                            *this* request? */
1715                         if (pinfo->fd->num != rpc_call->req_num) {
1716                                 /* No, so it's a duplicate request.
1717                                    Mark it as such. */
1718                                 if (check_col(pinfo->cinfo, COL_INFO)) {
1719                                         col_append_fstr(pinfo->cinfo, COL_INFO,
1720                                                 " dup XID 0x%x", xid);
1721                                         if (rpc_tree) {
1722                                                 proto_tree_add_uint_hidden(rpc_tree,
1723                                                         hf_rpc_dup, tvb, 0,0, xid);
1724                                                 proto_tree_add_uint_hidden(rpc_tree,
1725                                                         hf_rpc_call_dup, tvb, 0,0, xid);
1726                                         }
1727                                 }
1728                         }
1729                 }
1730                 else {
1731                         /* Prepare the value data.
1732                            "req_num" and "rep_num" are frame numbers;
1733                            frame numbers are 1-origin, so we use 0
1734                            to mean "we don't yet know in which frame
1735                            the reply for this call appears". */
1736                         new_rpc_call_key = g_mem_chunk_alloc(rpc_call_info_key_chunk);
1737                         *new_rpc_call_key = rpc_call_key;
1738                         rpc_call = g_mem_chunk_alloc(rpc_call_info_value_chunk);
1739                         rpc_call->req_num = pinfo->fd->num;
1740                         rpc_call->rep_num = 0;
1741                         rpc_call->prog = prog;
1742                         rpc_call->vers = vers;
1743                         rpc_call->proc = proc;
1744                         rpc_call->xid = xid;
1745                         rpc_call->flavor = flavor;
1746                         rpc_call->gss_proc = gss_proc;
1747                         rpc_call->gss_svc = gss_svc;
1748                         rpc_call->proc_info = value;
1749                         rpc_call->req_time.secs=pinfo->fd->abs_secs;
1750                         rpc_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
1751
1752                         /* store it */
1753                         g_hash_table_insert(rpc_calls, new_rpc_call_key,
1754                             rpc_call);
1755                 }
1756
1757                 offset += 16;
1758
1759                 offset = dissect_rpc_cred(tvb, pinfo, rpc_tree, offset);
1760                 offset = dissect_rpc_verf(tvb, pinfo, rpc_tree, offset, msg_type);
1761
1762                 /* pass rpc_info to subdissectors */
1763                 rpc_call->request=TRUE;
1764                 pinfo->private_data=rpc_call;
1765
1766                 /* go to the next dissector */
1767
1768                 break;  /* end of RPC call */
1769
1770         case RPC_REPLY:
1771                 /* we know already the type from the calling routine,
1772                    and we already have "rpc_call" set above. */
1773                 prog = rpc_call->prog;
1774                 vers = rpc_call->vers;
1775                 proc = rpc_call->proc;
1776                 flavor = rpc_call->flavor;
1777                 gss_proc = rpc_call->gss_proc;
1778                 gss_svc = rpc_call->gss_svc;
1779
1780                 /* Indicate the frame to which this is a reply. */
1781                 proto_tree_add_text(rpc_tree, tvb, 0, 0,
1782                     "This is a reply to a request in frame %u",
1783                     rpc_call->req_num);
1784                 ns.secs= pinfo->fd->abs_secs-rpc_call->req_time.secs;
1785                 ns.nsecs=pinfo->fd->abs_usecs*1000-rpc_call->req_time.nsecs;
1786                 if(ns.nsecs<0){
1787                         ns.nsecs+=1000000000;
1788                         ns.secs--;
1789                 }
1790                 proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0,
1791                                 &ns);
1792
1793
1794
1795                 if (rpc_call->proc_info != NULL) {
1796                         dissect_function = rpc_call->proc_info->dissect_reply;
1797                         if (rpc_call->proc_info->name != NULL) {
1798                                 procname = rpc_call->proc_info->name;
1799                         }
1800                         else {
1801                                 sprintf(procname_static, "proc-%u", proc);
1802                                 procname = procname_static;
1803                         }
1804                 }
1805                 else {
1806 #if 0
1807                         dissect_function = NULL;
1808 #endif
1809                         sprintf(procname_static, "proc-%u", proc);
1810                         procname = procname_static;
1811                 }
1812
1813                 rpc_prog_key.prog = prog;
1814                 if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) {
1815                         proto = 0;
1816                         ett = 0;
1817                         progname = "Unknown";
1818                 }
1819                 else {
1820                         proto = rpc_prog->proto;
1821                         ett = rpc_prog->ett;
1822                         progname = rpc_prog->progname;
1823
1824                         if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1825                                 /* Set the protocol name to the underlying
1826                                    program name. */
1827                                 col_set_str(pinfo->cinfo, COL_PROTOCOL, progname);
1828                         }
1829                 }
1830
1831                 if (check_col(pinfo->cinfo, COL_INFO)) {
1832                         col_add_fstr(pinfo->cinfo, COL_INFO,"V%u %s %s XID 0x%x",
1833                                 vers,
1834                                 procname,
1835                                 msg_type_name,
1836                                 xid);
1837                 }
1838
1839                 if (rpc_tree) {
1840                         proto_tree_add_uint_format(rpc_tree,
1841                                 hf_rpc_program, tvb, 0, 0, prog,
1842                                 "Program: %s (%u)", progname, prog);
1843                         proto_tree_add_uint(rpc_tree,
1844                                 hf_rpc_programversion, tvb, 0, 0, vers);
1845                         proto_tree_add_uint_format(rpc_tree,
1846                                 hf_rpc_procedure, tvb, 0, 0, proc,
1847                                 "Procedure: %s (%u)", procname, proc);
1848                 }
1849
1850                 if (rpc_call->rep_num == 0) {
1851                         /* We have not yet seen a reply to that call, so
1852                            this must be the first reply; remember its
1853                            frame number. */
1854                         rpc_call->rep_num = pinfo->fd->num;
1855                 } else {
1856                         /* We have seen a reply to this call - but was it
1857                            *this* reply? */
1858                         if (rpc_call->rep_num != pinfo->fd->num) {
1859                                 /* No, so it's a duplicate reply.
1860                                    Mark it as such. */
1861                                 if (check_col(pinfo->cinfo, COL_INFO)) {
1862                                         col_append_fstr(pinfo->cinfo, COL_INFO,
1863                                                 " dup XID 0x%x", xid);
1864                                         if (rpc_tree) {
1865                                                 proto_tree_add_uint_hidden(rpc_tree,
1866                                                         hf_rpc_dup, tvb, 0,0, xid);
1867                                                 proto_tree_add_uint_hidden(rpc_tree,
1868                                                         hf_rpc_reply_dup, tvb, 0,0, xid);
1869                                         }
1870                                 }
1871                         }
1872                 }
1873
1874                 reply_state = tvb_get_ntohl(tvb,offset+0);
1875                 if (rpc_tree) {
1876                         proto_tree_add_uint(rpc_tree, hf_rpc_state_reply, tvb,
1877                                 offset+0, 4, reply_state);
1878                 }
1879                 offset += 4;
1880
1881                 if (reply_state == MSG_ACCEPTED) {
1882                         offset = dissect_rpc_verf(tvb, pinfo, rpc_tree, offset, msg_type);
1883                         accept_state = tvb_get_ntohl(tvb,offset+0);
1884                         if (rpc_tree) {
1885                                 proto_tree_add_uint(rpc_tree, hf_rpc_state_accept, tvb,
1886                                         offset+0, 4, accept_state);
1887                         }
1888                         offset += 4;
1889                         switch (accept_state) {
1890
1891                         case SUCCESS:
1892                                 /* go to the next dissector */
1893                                 break;
1894
1895                         case PROG_MISMATCH:
1896                                 vers_low = tvb_get_ntohl(tvb,offset+0);
1897                                 vers_high = tvb_get_ntohl(tvb,offset+4);
1898                                 if (rpc_tree) {
1899                                         proto_tree_add_uint(rpc_tree,
1900                                                 hf_rpc_programversion_min,
1901                                                 tvb, offset+0, 4, vers_low);
1902                                         proto_tree_add_uint(rpc_tree,
1903                                                 hf_rpc_programversion_max,
1904                                                 tvb, offset+4, 4, vers_high);
1905                                 }
1906                                 offset += 8;
1907                                 break;
1908
1909                         default:
1910                                 /* void */
1911                                 break;
1912                         }
1913                 } else if (reply_state == MSG_DENIED) {
1914                         reject_state = tvb_get_ntohl(tvb,offset+0);
1915                         if (rpc_tree) {
1916                                 proto_tree_add_uint(rpc_tree,
1917                                         hf_rpc_state_reject, tvb, offset+0, 4,
1918                                         reject_state);
1919                         }
1920                         offset += 4;
1921
1922                         if (reject_state==RPC_MISMATCH) {
1923                                 vers_low = tvb_get_ntohl(tvb,offset+0);
1924                                 vers_high = tvb_get_ntohl(tvb,offset+4);
1925                                 if (rpc_tree) {
1926                                         proto_tree_add_uint(rpc_tree,
1927                                                 hf_rpc_version_min,
1928                                                 tvb, offset+0, 4, vers_low);
1929                                         proto_tree_add_uint(rpc_tree,
1930                                                 hf_rpc_version_max,
1931                                                 tvb, offset+4, 4, vers_high);
1932                                 }
1933                                 offset += 8;
1934                         } else if (reject_state==AUTH_ERROR) {
1935                                 auth_state = tvb_get_ntohl(tvb,offset+0);
1936                                 if (rpc_tree) {
1937                                         proto_tree_add_uint(rpc_tree,
1938                                                 hf_rpc_state_auth, tvb, offset+0, 4,
1939                                                 auth_state);
1940                                 }
1941                                 offset += 4;
1942                         }
1943                 } 
1944                 break; /* end of RPC reply */
1945
1946         default:
1947                 /*
1948                  * The switch statement at the top returned if
1949                  * this was neither an RPC call nor a reply.
1950                  */
1951                 g_assert_not_reached();
1952         }
1953
1954         /* now we know, that RPC was shorter */
1955         if (rpc_item) {
1956                 proto_item_set_len(rpc_item, offset - offset_old);
1957         }
1958
1959         /* create here the program specific sub-tree */
1960         if (tree) {
1961                 pitem = proto_tree_add_item(tree, proto, tvb,
1962                                 offset, tvb_length(tvb) - offset, FALSE);
1963                 if (pitem) {
1964                         ptree = proto_item_add_subtree(pitem, ett);
1965                 }
1966
1967                 if (ptree) {
1968                         proto_tree_add_uint(ptree,
1969                                 hf_rpc_programversion, tvb, 0, 0, vers);
1970                         proto_tree_add_uint_format(ptree,
1971                                 hf_rpc_procedure, tvb, 0, 0, proc,
1972                                 "Procedure: %s (%u)", procname, proc);
1973                 }
1974         }
1975
1976         if (!proto_is_protocol_enabled(proto))
1977                 dissect_function = NULL;
1978
1979         /*
1980          * Handle RPCSEC_GSS specially.
1981          */
1982         switch (flavor) {
1983
1984         case FLAVOR_UNKNOWN:
1985                 /*
1986                  * We don't know the authentication flavor, so we can't
1987                  * dissect the payload.
1988                  */
1989                 proto_tree_add_text(ptree, tvb, offset, tvb_length_remaining(tvb, offset),
1990                     "Unknown authentication flavor - cannot dissect");
1991                 return TRUE;
1992
1993         case FLAVOR_NOT_GSSAPI:
1994                 /*
1995                  * It's not GSS-API authentication.  Just dissect the
1996                  * payload.
1997                  */
1998                 offset = call_dissect_function(tvb, pinfo, ptree, offset,
1999                                 dissect_function, progname);
2000                 break;
2001
2002         case FLAVOR_GSSAPI_NO_INFO:
2003                 /*
2004                  * It's GSS-API authentication, but we don't have the
2005                  * procedure and service information, so we can't dissect
2006                  * the payload.
2007                  */
2008                 proto_tree_add_text(ptree, tvb, offset, tvb_length_remaining(tvb, offset),
2009                     "GSS-API authentication, but procedure and service unknown - cannot dissect");
2010                 return TRUE;
2011
2012         case FLAVOR_GSSAPI:
2013                 /*
2014                  * It's GSS-API authentication, and we have the procedure
2015                  * and service information; process the GSS-API stuff,
2016                  * and process the payload if there is any.
2017                  */
2018                 switch (gss_proc) {
2019
2020                 case RPCSEC_GSS_INIT:
2021                 case RPCSEC_GSS_CONTINUE_INIT:
2022                         if (msg_type == RPC_CALL) {
2023                                 offset = dissect_rpc_authgss_initarg(tvb,
2024                                         pinfo, ptree, offset);
2025                         }
2026                         else {
2027                                 offset = dissect_rpc_authgss_initres(tvb,
2028                                         pinfo, ptree, offset);
2029                         }
2030                         break;
2031
2032                 case RPCSEC_GSS_DATA:
2033                         if (gss_svc == RPCSEC_GSS_SVC_NONE) {
2034                                 offset = call_dissect_function(tvb, 
2035                                                 pinfo, ptree, offset,
2036                                                 dissect_function,
2037                                                 progname);
2038                         }
2039                         else if (gss_svc == RPCSEC_GSS_SVC_INTEGRITY) {
2040                                 offset = dissect_rpc_authgss_integ_data(tvb,
2041                                                 pinfo, ptree, offset,
2042                                                 dissect_function,
2043                                                 progname);
2044                         }
2045                         else if (gss_svc == RPCSEC_GSS_SVC_PRIVACY) {
2046                                 offset = dissect_rpc_authgss_priv_data(tvb,
2047                                                 pinfo, ptree, offset);
2048                         }
2049                         break;
2050
2051                 default:
2052                         break;
2053                 }
2054         }
2055
2056         /* dissect any remaining bytes (incomplete dissection) as pure data in
2057            the ptree */
2058         call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, ptree);
2059
2060         return TRUE;
2061 }
2062
2063 static gboolean
2064 dissect_rpc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2065 {
2066         return dissect_rpc_message(tvb, 0, pinfo, tree, FALSE, 0);
2067 }
2068
2069 static void
2070 dissect_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2071 {
2072         if (!dissect_rpc_message(tvb, 0, pinfo, tree, FALSE, 0))
2073                 dissect_rpc_continuation(tvb, pinfo, tree);
2074 }
2075
2076 /*
2077  * Can return:
2078  *
2079  *      NEED_MORE_DATA, if we don't have enough data to dissect anything;
2080  *
2081  *      IS_RPC, if we dissected at least one message in its entirety
2082  *      as RPC;
2083  *
2084  *      IS_NOT_RPC, if we found no RPC message.
2085  */
2086 typedef enum {
2087         NEED_MORE_DATA,
2088         IS_RPC,
2089         IS_NOT_RPC
2090 } rpc_tcp_return_t;
2091
2092 static rpc_tcp_return_t
2093 dissect_rpc_tcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2094     gboolean is_heur)
2095 {
2096         volatile int offset = 0;
2097         guint32 rpc_rm;
2098         volatile gboolean saw_rpc = FALSE;
2099         volatile gint32 len;
2100         gint32 seglen;
2101         gint tvb_len, tvb_reported_len;
2102         tvbuff_t *msg_tvb;
2103         const char *saved_proto;
2104         volatile gboolean rpc_succeeded;
2105
2106         while (tvb_reported_length_remaining(tvb, offset) != 0) {
2107                 /*
2108                  * XXX - we need to handle records that don't have the "last
2109                  * fragment" bit set, and reassemble fragments.
2110                  */
2111
2112                 /* the first 4 bytes are special in "record marking mode" */
2113                 if (!tvb_bytes_exist(tvb, offset, 4)) {
2114                         /*
2115                          * XXX - we should somehow arrange to handle
2116                          * a record mark split across TCP segments.
2117                          */
2118                         return saw_rpc ? IS_RPC : IS_NOT_RPC;
2119                 }
2120                 rpc_rm = tvb_get_ntohl(tvb, offset);
2121
2122                 len = rpc_rm&RPC_RM_FRAGLEN;
2123
2124                 /*
2125                  * XXX - reject fragments bigger than 2 megabytes.
2126                  * This is arbitrary, but should at least prevent
2127                  * some crashes from either packets with really
2128                  * large RPC-over-TCP fragments or from stuff that's
2129                  * not really RPC.
2130                  */
2131                 if (len > 2*1024*1024)
2132                         return saw_rpc ? IS_RPC : IS_NOT_RPC;
2133                 if (rpc_desegment) {
2134                         seglen = tvb_length_remaining(tvb, offset + 4);
2135
2136                         if (len > seglen && pinfo->can_desegment) {
2137                                 /*
2138                                  * This frame doesn't have all of the
2139                                  * data for this message, but we can do
2140                                  * reassembly on it.
2141                                  *
2142                                  * If this is a heuristic dissector, just
2143                                  * return IS_NOT_RPC - we don't want to try
2144                                  * to get more data, as that's too likely
2145                                  * to cause us to misidentify this as
2146                                  * RPC.
2147                                  *
2148                                  * If this isn't a heuristic dissector,
2149                                  * we've already identified this conversation
2150                                  * as containing RPC data, as we saw RPC
2151                                  * data in previous frames.  Try to get
2152                                  * more data.
2153                                  */
2154                                 if (is_heur)
2155                                         return IS_NOT_RPC;
2156                                 else {
2157                                         pinfo->desegment_offset = offset;
2158                                         pinfo->desegment_len = len - seglen;
2159                                         return NEED_MORE_DATA;
2160                                 }
2161                         }
2162                 }
2163                 len += 4;       /* include record mark */
2164                 tvb_len = tvb_length_remaining(tvb, offset);
2165                 tvb_reported_len = tvb_reported_length_remaining(tvb, offset);
2166                 if (tvb_len > len)
2167                         tvb_len = len;
2168                 if (tvb_reported_len > len)
2169                         tvb_reported_len = len;
2170                 msg_tvb = tvb_new_subset(tvb, offset, tvb_len,
2171                     tvb_reported_len);
2172
2173                 /*
2174                  * Catch the ReportedBoundsError exception; if this
2175                  * particular message happens to get a ReportedBoundsError
2176                  * exception, that doesn't mean that we should stop
2177                  * dissecting RPC messages within this frame or chunk
2178                  * of reassembled data.
2179                  *
2180                  * If it gets a BoundsError, we can stop, as there's
2181                  * nothing more to see, so we just re-throw it.
2182                  */
2183                 saved_proto = pinfo->current_proto;
2184                 rpc_succeeded = FALSE;
2185                 TRY {
2186                         rpc_succeeded = dissect_rpc_message(msg_tvb, 4,
2187                             pinfo, tree, TRUE, rpc_rm);
2188                 }
2189                 CATCH(BoundsError) {
2190                         RETHROW;
2191                 }
2192                 CATCH(ReportedBoundsError) {
2193                         if (check_col(pinfo->cinfo, COL_INFO)) {
2194                                 col_append_str(pinfo->cinfo, COL_INFO,
2195                                     "[Malformed Packet]");
2196                         }
2197                         proto_tree_add_protocol_format(tree, proto_malformed,
2198                             tvb, 0, 0, "[Malformed Packet: %s]",
2199                             pinfo->current_proto );
2200                         pinfo->current_proto = saved_proto;
2201
2202                         /*
2203                          * We treat this as a "successful" dissection of
2204                          * an RPC packet, as "dissect_rpc_message()"
2205                          * *did* decide it was an RPC packet, throwing
2206                          * an exception while dissecting it as such.
2207                          */
2208                         rpc_succeeded = TRUE;
2209                 }
2210                 ENDTRY;
2211                 if (!rpc_succeeded)
2212                         break;
2213                 offset += len;
2214                 saw_rpc = TRUE;
2215         }
2216         return saw_rpc ? IS_RPC : IS_NOT_RPC;
2217 }
2218
2219 static gboolean
2220 dissect_rpc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2221 {
2222         switch (dissect_rpc_tcp_common(tvb, pinfo, tree, TRUE)) {
2223
2224         case IS_RPC:
2225                 return TRUE;
2226
2227         case IS_NOT_RPC:
2228                 return FALSE;
2229
2230         default:
2231                 /* "Can't happen" */
2232                 g_assert_not_reached();
2233                 return FALSE;
2234         }
2235 }
2236
2237 static void
2238 dissect_rpc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2239 {
2240         if (dissect_rpc_tcp_common(tvb, pinfo, tree, FALSE) == IS_NOT_RPC)
2241                 dissect_rpc_continuation(tvb, pinfo, tree);
2242 }
2243
2244 /* Discard any state we've saved. */
2245 static void
2246 rpc_init_protocol(void)
2247 {
2248         if (rpc_calls != NULL)
2249                 g_hash_table_destroy(rpc_calls);
2250         if (rpc_indir_calls != NULL)
2251                 g_hash_table_destroy(rpc_indir_calls);
2252         if (rpc_call_info_key_chunk != NULL)
2253                 g_mem_chunk_destroy(rpc_call_info_key_chunk);
2254         if (rpc_call_info_value_chunk != NULL)
2255                 g_mem_chunk_destroy(rpc_call_info_value_chunk);
2256
2257         rpc_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
2258         rpc_indir_calls = g_hash_table_new(rpc_call_hash, rpc_call_equal);
2259         rpc_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
2260             sizeof(rpc_call_info_key),
2261             200 * sizeof(rpc_call_info_key),
2262             G_ALLOC_ONLY);
2263         rpc_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
2264             sizeof(rpc_call_info_value),
2265             200 * sizeof(rpc_call_info_value),
2266             G_ALLOC_ONLY);
2267 }
2268
2269 /* will be called once from register.c at startup time */
2270 void
2271 proto_register_rpc(void)
2272 {
2273         static hf_register_info hf[] = {
2274                 { &hf_rpc_lastfrag, {
2275                         "Last Fragment", "rpc.lastfrag", FT_BOOLEAN, BASE_NONE,
2276                         &yesno, 0, "Last Fragment", HFILL }},
2277                 { &hf_rpc_fraglen, {
2278                         "Fragment Length", "rpc.fraglen", FT_UINT32, BASE_DEC,
2279                         NULL, 0, "Fragment Length", HFILL }},
2280                 { &hf_rpc_xid, {
2281                         "XID", "rpc.xid", FT_UINT32, BASE_HEX,
2282                         NULL, 0, "XID", HFILL }},
2283                 { &hf_rpc_msgtype, {
2284                         "Message Type", "rpc.msgtyp", FT_UINT32, BASE_DEC,
2285                         VALS(rpc_msg_type), 0, "Message Type", HFILL }},
2286                 { &hf_rpc_state_reply, {
2287                         "Reply State", "rpc.replystat", FT_UINT32, BASE_DEC,
2288                         VALS(rpc_reply_state), 0, "Reply State", HFILL }},
2289                 { &hf_rpc_state_accept, {
2290                         "Accept State", "rpc.state_accept", FT_UINT32, BASE_DEC,
2291                         VALS(rpc_accept_state), 0, "Accept State", HFILL }},
2292                 { &hf_rpc_state_reject, {
2293                         "Reject State", "rpc.state_reject", FT_UINT32, BASE_DEC,
2294                         VALS(rpc_reject_state), 0, "Reject State", HFILL }},
2295                 { &hf_rpc_state_auth, {
2296                         "Auth State", "rpc.state_auth", FT_UINT32, BASE_DEC,
2297                         VALS(rpc_auth_state), 0, "Auth State", HFILL }},
2298                 { &hf_rpc_version, {
2299                         "RPC Version", "rpc.version", FT_UINT32, BASE_DEC,
2300                         NULL, 0, "RPC Version", HFILL }},
2301                 { &hf_rpc_version_min, {
2302                         "RPC Version (Minimum)", "rpc.version.min", FT_UINT32, 
2303                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
2304                 { &hf_rpc_version_max, {
2305                         "RPC Version (Maximum)", "rpc.version.max", FT_UINT32, 
2306                         BASE_DEC, NULL, 0, "RPC Version (Maximum)", HFILL }},
2307                 { &hf_rpc_program, {
2308                         "Program", "rpc.program", FT_UINT32, BASE_DEC,
2309                         NULL, 0, "Program", HFILL }},
2310                 { &hf_rpc_programversion, {
2311                         "Program Version", "rpc.programversion", FT_UINT32, 
2312                         BASE_DEC, NULL, 0, "Program Version", HFILL }},
2313                 { &hf_rpc_programversion_min, {
2314                         "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32, 
2315                         BASE_DEC, NULL, 0, "Program Version (Minimum)", HFILL }},
2316                 { &hf_rpc_programversion_max, {
2317                         "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32, 
2318                         BASE_DEC, NULL, 0, "Program Version (Maximum)", HFILL }},
2319                 { &hf_rpc_procedure, {
2320                         "Procedure", "rpc.procedure", FT_UINT32, BASE_DEC,
2321                         NULL, 0, "Procedure", HFILL }},
2322                 { &hf_rpc_auth_flavor, {
2323                         "Flavor", "rpc.auth.flavor", FT_UINT32, BASE_DEC,
2324                         VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
2325                 { &hf_rpc_auth_length, {
2326                         "Length", "rpc.auth.length", FT_UINT32, BASE_DEC,
2327                         NULL, 0, "Length", HFILL }},
2328                 { &hf_rpc_auth_stamp, {
2329                         "Stamp", "rpc.auth.stamp", FT_UINT32, BASE_HEX,
2330                         NULL, 0, "Stamp", HFILL }},
2331                 { &hf_rpc_auth_uid, {
2332                         "UID", "rpc.auth.uid", FT_UINT32, BASE_DEC,
2333                         NULL, 0, "UID", HFILL }},
2334                 { &hf_rpc_auth_gid, {
2335                         "GID", "rpc.auth.gid", FT_UINT32, BASE_DEC,
2336                         NULL, 0, "GID", HFILL }},
2337                 { &hf_rpc_authgss_v, {
2338                         "GSS Version", "rpc.authgss.version", FT_UINT32,
2339                         BASE_DEC, NULL, 0, "GSS Version", HFILL }},
2340                 { &hf_rpc_authgss_proc, {
2341                         "GSS Procedure", "rpc.authgss.procedure", FT_UINT32,
2342                         BASE_DEC, VALS(rpc_authgss_proc), 0, "GSS Procedure", HFILL }},
2343                 { &hf_rpc_authgss_seq, {
2344                         "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32,
2345                         BASE_DEC, NULL, 0, "GSS Sequence Number", HFILL }},
2346                 { &hf_rpc_authgss_svc, {
2347                         "GSS Service", "rpc.authgss.service", FT_UINT32,
2348                         BASE_DEC, VALS(rpc_authgss_svc), 0, "GSS Service", HFILL }},
2349                 { &hf_rpc_authgss_ctx, {
2350                         "GSS Context", "rpc.authgss.context", FT_BYTES,
2351                         BASE_HEX, NULL, 0, "GSS Context", HFILL }},
2352                 { &hf_rpc_authgss_major, {
2353                         "GSS Major Status", "rpc.authgss.major", FT_UINT32,
2354                         BASE_DEC, NULL, 0, "GSS Major Status", HFILL }},
2355                 { &hf_rpc_authgss_minor, {
2356                         "GSS Minor Status", "rpc.authgss.minor", FT_UINT32,
2357                         BASE_DEC, NULL, 0, "GSS Minor Status", HFILL }},
2358                 { &hf_rpc_authgss_window, {
2359                         "GSS Sequence Window", "rpc.authgss.window", FT_UINT32,
2360                         BASE_DEC, NULL, 0, "GSS Sequence Window", HFILL }},
2361                 { &hf_rpc_authgss_token, {
2362                         "GSS Token", "rpc.authgss.token", FT_BYTES,
2363                         BASE_HEX, NULL, 0, "GSS Token", HFILL }},
2364                 { &hf_rpc_authgss_data_length, {
2365                         "Length", "rpc.authgss.data.length", FT_UINT32,
2366                         BASE_DEC, NULL, 0, "Length", HFILL }},
2367                 { &hf_rpc_authgss_data, {
2368                         "GSS Data", "rpc.authgss.data", FT_BYTES,
2369                         BASE_HEX, NULL, 0, "GSS Data", HFILL }},
2370                 { &hf_rpc_authgss_checksum, {
2371                         "GSS Checksum", "rpc.authgss.checksum", FT_BYTES,
2372                         BASE_HEX, NULL, 0, "GSS Checksum", HFILL }},
2373                 { &hf_rpc_authdes_namekind, {
2374                         "Namekind", "rpc.authdes.namekind", FT_UINT32, BASE_DEC,
2375                         VALS(rpc_authdes_namekind), 0, "Namekind", HFILL }},
2376                 { &hf_rpc_authdes_netname, {
2377                         "Netname", "rpc.authdes.netname", FT_STRING,
2378                         BASE_DEC, NULL, 0, "Netname", HFILL }},
2379                 { &hf_rpc_authdes_convkey, {
2380                         "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32,
2381                         BASE_HEX, NULL, 0, "Conversation Key (encrypted)", HFILL }},
2382                 { &hf_rpc_authdes_window, {
2383                         "Window (encrypted)", "rpc.authdes.window", FT_UINT32,
2384                         BASE_HEX, NULL, 0, "Windows (encrypted)", HFILL }},
2385                 { &hf_rpc_authdes_nickname, {
2386                         "Nickname", "rpc.authdes.nickname", FT_UINT32, 
2387                         BASE_HEX, NULL, 0, "Nickname", HFILL }},
2388                 { &hf_rpc_authdes_timestamp, {
2389                         "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32,
2390                         BASE_HEX, NULL, 0, "Timestamp (encrypted)", HFILL }},
2391                 { &hf_rpc_authdes_windowverf, {
2392                         "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32,
2393                         BASE_HEX, NULL, 0, "Window verifier (encrypted)", HFILL }},
2394                 { &hf_rpc_authdes_timeverf, {
2395                         "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32,
2396                         BASE_HEX, NULL, 0, "Timestamp verifier (encrypted)", HFILL }},
2397                 { &hf_rpc_auth_machinename, {
2398                         "Machine Name", "rpc.auth.machinename", FT_STRING, 
2399                         BASE_DEC, NULL, 0, "Machine Name", HFILL }},
2400                 { &hf_rpc_dup, {
2401                         "Duplicate Transaction", "rpc.dup", FT_UINT32, BASE_DEC,
2402                         NULL, 0, "Duplicate Transaction", HFILL }},
2403                 { &hf_rpc_call_dup, {
2404                         "Duplicate Call", "rpc.call.dup", FT_UINT32, BASE_DEC,
2405                         NULL, 0, "Duplicate Call", HFILL }},
2406                 { &hf_rpc_reply_dup, {
2407                         "Duplicate Reply", "rpc.reply.dup", FT_UINT32, BASE_DEC,
2408                         NULL, 0, "Duplicate Reply", HFILL }},
2409                 { &hf_rpc_value_follows, {
2410                         "Value Follows", "rpc.value_follows", FT_BOOLEAN, BASE_NONE,
2411                         &yesno, 0, "Value Follows", HFILL }},
2412                 { &hf_rpc_array_len, {
2413                         "num", "rpc.array.len", FT_UINT32, BASE_DEC,
2414                         NULL, 0, "Length of RPC array", HFILL }},
2415
2416                 { &hf_rpc_time, {
2417                         "Time from request", "rpc.time", FT_RELATIVE_TIME, BASE_NONE,
2418                         NULL, 0, "Time between Request and Reply for ONC-RPC calls", HFILL }},
2419
2420         };
2421         static gint *ett[] = {
2422                 &ett_rpc,
2423                 &ett_rpc_string,
2424                 &ett_rpc_cred,
2425                 &ett_rpc_verf,
2426                 &ett_rpc_gids,
2427                 &ett_rpc_gss_data,
2428                 &ett_rpc_array,
2429         };
2430         module_t *rpc_module;
2431
2432         proto_rpc = proto_register_protocol("Remote Procedure Call",
2433             "RPC", "rpc");
2434         proto_register_field_array(proto_rpc, hf, array_length(hf));
2435         proto_register_subtree_array(ett, array_length(ett));
2436         register_init_routine(&rpc_init_protocol);
2437         rpc_tcp_handle = create_dissector_handle(dissect_rpc_tcp, proto_rpc);
2438         rpc_handle = create_dissector_handle(dissect_rpc, proto_rpc);
2439         rpc_module = prefs_register_protocol(proto_rpc, NULL);
2440         prefs_register_bool_preference(rpc_module, "desegment_rpc_over_tcp",
2441                 "Desegment all RPC over TCP commands",
2442                 "Whether the RPC dissector should desegment all RPC over TCP commands",
2443                 &rpc_desegment);
2444
2445         /*
2446          * Init the hash tables.  Dissectors for RPC protocols must
2447          * have a "handoff registration" routine that registers the
2448          * protocol with RPC; they must not do it in their protocol
2449          * registration routine, as their protocol registration
2450          * routine might be called before this routine is called and
2451          * thus might be called before the hash tables are initialized,
2452          * but it's guaranteed that all protocol registration routines
2453          * will be called before any handoff registration routines
2454          * are called.
2455          */
2456         rpc_progs = g_hash_table_new(rpc_prog_hash, rpc_prog_equal);
2457         rpc_procs = g_hash_table_new(rpc_proc_hash, rpc_proc_equal);
2458 }
2459
2460 void
2461 proto_reg_handoff_rpc(void)
2462 {
2463         heur_dissector_add("tcp", dissect_rpc_tcp_heur, proto_rpc);
2464         heur_dissector_add("udp", dissect_rpc_heur, proto_rpc);
2465         data_handle = find_dissector("data");
2466 }