2 * Routines for rpc dissection
3 * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-smb.c
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include <epan/packet.h>
35 #include <epan/exceptions.h>
36 #include <wsutil/pint.h>
37 #include <epan/conversation.h>
38 #include <epan/wmem/wmem.h>
39 #include <epan/prefs.h>
40 #include <epan/reassemble.h>
42 #include <epan/strutil.h>
43 #include <epan/garrayfix.h>
44 #include <epan/show_exception.h>
46 #include "packet-rpc.h"
47 #include "packet-tcp.h"
48 #include "packet-nfs.h"
53 * RFC 1831, "RPC: Remote Procedure Call Protocol Specification
56 * RFC 1832, "XDR: External Data Representation Standard";
58 * RFC 2203, "RPCSEC_GSS Protocol Specification".
62 * RFC 2695, "Authentication Mechanisms for ONC RPC"
64 * although we don't currently dissect AUTH_DES or AUTH_KERB.
66 * RFC 5531, "Appendix C: Current Number Assignments" defines AUTH_RSA.
67 * AUTH_RSA is not implemented for any known RPC-protocols. The Gluster
68 * protocols (ab)use AUTH_RSA for their own AUTH-flavor. AUTH_RSA is
69 * therefore dissected as the inofficial AUTH_GLUSTER.
72 /* desegmentation of RPC over TCP */
73 static gboolean rpc_desegment
= TRUE
;
75 /* defragmentation of fragmented RPC over TCP records */
76 static gboolean rpc_defragment
= TRUE
;
78 /* try to dissect RPC packets for programs that are not known
79 * (proprietary ones) by wireshark.
81 static gboolean rpc_dissect_unknown_programs
= FALSE
;
83 /* try to find RPC fragment start if normal decode fails
84 * (good when starting decode of mid-stream capture)
86 static gboolean rpc_find_fragment_start
= FALSE
;
88 static int rpc_tap
= -1;
90 static dissector_handle_t spnego_krb5_wrap_handle
= NULL
;
92 static const value_string rpc_msg_type
[] = {
94 { RPC_REPLY
, "Reply" },
98 static const value_string rpc_reply_state
[] = {
99 { MSG_ACCEPTED
, "accepted" },
100 { MSG_DENIED
, "denied" },
104 const value_string rpc_auth_flavor
[] = {
105 { AUTH_NULL
, "AUTH_NULL" },
106 { AUTH_UNIX
, "AUTH_UNIX" },
107 { AUTH_SHORT
, "AUTH_SHORT" },
108 { AUTH_DES
, "AUTH_DES" },
109 { AUTH_RSA
, "AUTH_RSA/Gluster" },
110 { RPCSEC_GSS
, "RPCSEC_GSS" },
111 { AUTH_GSSAPI
, "AUTH_GSSAPI" },
112 { RPCSEC_GSS_KRB5
, "RPCSEC_GSS_KRB5" },
113 { RPCSEC_GSS_KRB5I
, "RPCSEC_GSS_KRB5I" },
114 { RPCSEC_GSS_KRB5P
, "RPCSEC_GSS_KRB5P" },
115 { RPCSEC_GSS_LIPKEY
, "RPCSEC_GSS_LIPKEY" },
116 { RPCSEC_GSS_LIPKEY_I
, "RPCSEC_GSS_LIPKEY_I" },
117 { RPCSEC_GSS_LIPKEY_P
, "RPCSEC_GSS_LIPKEY_P" },
118 { RPCSEC_GSS_SPKM3
, "RPCSEC_GSS_SPKM3" },
119 { RPCSEC_GSS_SPKM3I
, "RPCSEC_GSS_SPKM3I" },
120 { RPCSEC_GSS_SPKM3P
, "RPCSEC_GSS_SPKM3P" },
121 { AUTH_GLUSTERFS
, "AUTH_GLUSTERFS" },
125 static const value_string rpc_authgss_proc
[] = {
126 { RPCSEC_GSS_DATA
, "RPCSEC_GSS_DATA" },
127 { RPCSEC_GSS_INIT
, "RPCSEC_GSS_INIT" },
128 { RPCSEC_GSS_CONTINUE_INIT
, "RPCSEC_GSS_CONTINUE_INIT" },
129 { RPCSEC_GSS_DESTROY
, "RPCSEC_GSS_DESTROY" },
133 static const value_string rpc_authgssapi_proc
[] = {
134 { AUTH_GSSAPI_EXIT
, "AUTH_GSSAPI_EXIT" },
135 { AUTH_GSSAPI_INIT
, "AUTH_GSSAPI_INIT" },
136 { AUTH_GSSAPI_CONTINUE_INIT
, "AUTH_GSSAPI_CONTINUE_INIT" },
137 { AUTH_GSSAPI_MSG
, "AUTH_GSSAPI_MSG" },
138 { AUTH_GSSAPI_DESTROY
, "AUTH_GSSAPI_DESTROY" },
142 const value_string rpc_authgss_svc
[] = {
143 { RPCSEC_GSS_SVC_NONE
, "rpcsec_gss_svc_none" },
144 { RPCSEC_GSS_SVC_INTEGRITY
, "rpcsec_gss_svc_integrity" },
145 { RPCSEC_GSS_SVC_PRIVACY
, "rpcsec_gss_svc_privacy" },
149 static const value_string rpc_accept_state
[] = {
150 { SUCCESS
, "RPC executed successfully" },
151 { PROG_UNAVAIL
, "remote hasn't exported program" },
152 { PROG_MISMATCH
, "remote can't support version #" },
153 { PROC_UNAVAIL
, "program can't support procedure" },
154 { GARBAGE_ARGS
, "procedure can't decode params" },
155 { SYSTEM_ERROR
, "system errors like memory allocation failure" },
159 static const value_string rpc_reject_state
[] = {
160 { RPC_MISMATCH
, "RPC_MISMATCH" },
161 { AUTH_ERROR
, "AUTH_ERROR" },
165 static const value_string rpc_auth_state
[] = {
166 { AUTH_BADCRED
, "bad credential (seal broken)" },
167 { AUTH_REJECTEDCRED
, "client must begin new session" },
168 { AUTH_BADVERF
, "bad verifier (seal broken)" },
169 { AUTH_REJECTEDVERF
, "verifier expired or replayed" },
170 { AUTH_TOOWEAK
, "rejected for security reasons" },
171 { RPCSEC_GSSCREDPROB
, "GSS credential problem" },
172 { RPCSEC_GSSCTXPROB
, "GSS context problem" },
176 static const value_string rpc_authdes_namekind
[] = {
177 { AUTHDES_NAMEKIND_FULLNAME
, "ADN_FULLNAME" },
178 { AUTHDES_NAMEKIND_NICKNAME
, "ADN_NICKNAME" },
182 /* the protocol number */
183 static int proto_rpc
= -1;
184 static int hf_rpc_reqframe
= -1;
185 static int hf_rpc_repframe
= -1;
186 static int hf_rpc_lastfrag
= -1;
187 static int hf_rpc_fraglen
= -1;
188 static int hf_rpc_xid
= -1;
189 static int hf_rpc_msgtype
= -1;
190 static int hf_rpc_version
= -1;
191 static int hf_rpc_version_min
= -1;
192 static int hf_rpc_version_max
= -1;
193 static int hf_rpc_program
= -1;
194 static int hf_rpc_programversion
= -1;
195 static int hf_rpc_programversion_min
= -1;
196 static int hf_rpc_programversion_max
= -1;
197 static int hf_rpc_procedure
= -1;
198 static int hf_rpc_auth_flavor
= -1;
199 static int hf_rpc_auth_length
= -1;
200 static int hf_rpc_auth_machinename
= -1;
201 static int hf_rpc_auth_stamp
= -1;
202 static int hf_rpc_auth_lk_owner
= -1;
203 static int hf_rpc_auth_pid
= -1;
204 static int hf_rpc_auth_uid
= -1;
205 static int hf_rpc_auth_gid
= -1;
206 static int hf_rpc_authgss_v
= -1;
207 static int hf_rpc_authgss_proc
= -1;
208 static int hf_rpc_authgss_seq
= -1;
209 static int hf_rpc_authgss_svc
= -1;
210 static int hf_rpc_authgss_ctx
= -1;
211 static int hf_rpc_authgss_ctx_create_frame
= -1;
212 static int hf_rpc_authgss_ctx_destroy_frame
= -1;
213 static int hf_rpc_authgss_ctx_len
= -1;
214 static int hf_rpc_authgss_major
= -1;
215 static int hf_rpc_authgss_minor
= -1;
216 static int hf_rpc_authgss_window
= -1;
217 static int hf_rpc_authgss_token_length
= -1;
218 static int hf_rpc_authgss_data_length
= -1;
219 static int hf_rpc_authgss_data
= -1;
220 static int hf_rpc_authgss_token
= -1;
221 static int hf_rpc_authgss_checksum
= -1;
222 static int hf_rpc_authgssapi_v
= -1;
223 static int hf_rpc_authgssapi_msg
= -1;
224 static int hf_rpc_authgssapi_msgv
= -1;
225 static int hf_rpc_authgssapi_handle
= -1;
226 static int hf_rpc_authgssapi_isn
= -1;
227 static int hf_rpc_authdes_namekind
= -1;
228 static int hf_rpc_authdes_netname
= -1;
229 static int hf_rpc_authdes_convkey
= -1;
230 static int hf_rpc_authdes_window
= -1;
231 static int hf_rpc_authdes_nickname
= -1;
232 static int hf_rpc_authdes_timestamp
= -1;
233 static int hf_rpc_authdes_windowverf
= -1;
234 static int hf_rpc_authdes_timeverf
= -1;
235 static int hf_rpc_state_accept
= -1;
236 static int hf_rpc_state_reply
= -1;
237 static int hf_rpc_state_reject
= -1;
238 static int hf_rpc_state_auth
= -1;
239 static int hf_rpc_dup
= -1;
240 static int hf_rpc_call_dup
= -1;
241 static int hf_rpc_reply_dup
= -1;
242 static int hf_rpc_value_follows
= -1;
243 static int hf_rpc_array_len
= -1;
244 static int hf_rpc_time
= -1;
245 static int hf_rpc_fragments
= -1;
246 static int hf_rpc_fragment
= -1;
247 static int hf_rpc_fragment_overlap
= -1;
248 static int hf_rpc_fragment_overlap_conflict
= -1;
249 static int hf_rpc_fragment_multiple_tails
= -1;
250 static int hf_rpc_fragment_too_long_fragment
= -1;
251 static int hf_rpc_fragment_error
= -1;
252 static int hf_rpc_fragment_count
= -1;
253 static int hf_rpc_reassembled_length
= -1;
255 static gint ett_rpc
= -1;
256 static gint ett_rpc_unknown_program
= -1;
257 static gint ett_rpc_fragments
= -1;
258 static gint ett_rpc_fragment
= -1;
259 static gint ett_rpc_fraghdr
= -1;
260 static gint ett_rpc_string
= -1;
261 static gint ett_rpc_cred
= -1;
262 static gint ett_rpc_verf
= -1;
263 static gint ett_rpc_gids
= -1;
264 static gint ett_rpc_gss_token
= -1;
265 static gint ett_rpc_gss_data
= -1;
266 static gint ett_rpc_array
= -1;
267 static gint ett_rpc_authgssapi_msg
= -1;
268 static gint ett_gss_context
= -1;
269 static gint ett_gss_wrap
= -1;
271 static dissector_handle_t rpc_tcp_handle
;
272 static dissector_handle_t rpc_handle
;
273 static dissector_handle_t gssapi_handle
;
274 static dissector_handle_t data_handle
;
276 static guint max_rpc_tcp_pdu_size
= 4 * 1024 * 1024;
278 static const fragment_items rpc_frag_items
= {
283 &hf_rpc_fragment_overlap
,
284 &hf_rpc_fragment_overlap_conflict
,
285 &hf_rpc_fragment_multiple_tails
,
286 &hf_rpc_fragment_too_long_fragment
,
287 &hf_rpc_fragment_error
,
288 &hf_rpc_fragment_count
,
290 &hf_rpc_reassembled_length
,
291 /* Reassembled data field */
296 /* Hash table with info on RPC program numbers */
297 GHashTable
*rpc_progs
= NULL
;
299 /* Hash table with info on RPC procedure numbers */
300 GHashTable
*rpc_procs
= NULL
;
302 typedef gboolean (*rec_dissector_t
)(tvbuff_t
*, packet_info
*, proto_tree
*,
303 tvbuff_t
*, fragment_head
*, gboolean
, guint32
, gboolean
);
305 static void dissect_rpc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
306 static void show_rpc_fraginfo(tvbuff_t
*tvb
, tvbuff_t
*frag_tvb
, proto_tree
*tree
,
307 guint32 rpc_rm
, fragment_head
*ipfd_head
, packet_info
*pinfo
);
309 /***********************************/
310 /* Hash array with procedure names */
311 /***********************************/
315 rpc_proc_equal(gconstpointer k1
, gconstpointer k2
)
317 const rpc_proc_info_key
* key1
= (const rpc_proc_info_key
*) k1
;
318 const rpc_proc_info_key
* key2
= (const rpc_proc_info_key
*) k2
;
320 return ((key1
->prog
== key2
->prog
&&
321 key1
->vers
== key2
->vers
&&
322 key1
->proc
== key2
->proc
) ?
326 /* calculate a hash key */
328 rpc_proc_hash(gconstpointer k
)
330 const rpc_proc_info_key
* key
= (const rpc_proc_info_key
*) k
;
332 return (key
->prog
^ (key
->vers
<<16) ^ (key
->proc
<<24));
336 /* insert some entries */
338 rpc_init_proc_table(guint prog
, guint vers
, const vsff
*proc_table
,
341 rpc_prog_info_key rpc_prog_key
;
342 rpc_prog_info_value
*rpc_prog
;
346 * Add the operation number hfinfo value for this version of the
349 rpc_prog_key
.prog
= prog
;
350 rpc_prog
= (rpc_prog_info_value
*)g_hash_table_lookup(rpc_progs
, &rpc_prog_key
);
351 DISSECTOR_ASSERT(rpc_prog
!= NULL
);
352 rpc_prog
->procedure_hfs
= g_array_set_size(rpc_prog
->procedure_hfs
,
354 g_array_insert_val(rpc_prog
->procedure_hfs
, vers
, procedure_hf
);
356 for (proc
= proc_table
; proc
->strptr
!=NULL
; proc
++) {
357 rpc_proc_info_key
*key
;
358 rpc_proc_info_value
*value
;
360 key
= (rpc_proc_info_key
*) g_malloc(sizeof(rpc_proc_info_key
));
363 key
->proc
= proc
->value
;
365 value
= (rpc_proc_info_value
*) g_malloc(sizeof(rpc_proc_info_value
));
366 value
->name
= proc
->strptr
;
367 value
->dissect_call
= proc
->dissect_call
;
368 value
->dissect_reply
= proc
->dissect_reply
;
370 g_hash_table_insert(rpc_procs
,key
,value
);
375 /* return the name associated with a previously registered procedure. */
377 rpc_proc_name(guint32 prog
, guint32 vers
, guint32 proc
)
379 rpc_proc_info_key key
;
380 rpc_proc_info_value
*value
;
387 if ((value
= (rpc_proc_info_value
*)g_hash_table_lookup(rpc_procs
,&key
)) != NULL
)
388 procname
= (char *)value
->name
;
390 /* happens only with strange program versions or
391 non-existing dissectors */
392 procname
= wmem_strdup_printf(wmem_packet_scope(), "proc-%u", key
.proc
);
397 /*----------------------------------------*/
398 /* end of Hash array with procedure names */
399 /*----------------------------------------*/
402 /*********************************/
403 /* Hash array with program names */
404 /*********************************/
408 rpc_prog_equal(gconstpointer k1
, gconstpointer k2
)
410 const rpc_prog_info_key
* key1
= (const rpc_prog_info_key
*) k1
;
411 const rpc_prog_info_key
* key2
= (const rpc_prog_info_key
*) k2
;
413 return ((key1
->prog
== key2
->prog
) ?
418 /* calculate a hash key */
420 rpc_prog_hash(gconstpointer k
)
422 const rpc_prog_info_key
* key
= (const rpc_prog_info_key
*) k
;
429 rpc_init_prog(int proto
, guint32 prog
, int ett
)
431 rpc_prog_info_key
*key
;
432 rpc_prog_info_value
*value
;
434 key
= (rpc_prog_info_key
*) g_malloc(sizeof(rpc_prog_info_key
));
437 value
= (rpc_prog_info_value
*) g_malloc(sizeof(rpc_prog_info_value
));
438 value
->proto
= find_protocol_by_id(proto
);
439 value
->proto_id
= proto
;
441 value
->progname
= proto_get_protocol_short_name(value
->proto
);
442 value
->procedure_hfs
= g_array_new(FALSE
, TRUE
, sizeof (int));
444 g_hash_table_insert(rpc_progs
,key
,value
);
449 /* return the hf_field associated with a previously registered program.
452 rpc_prog_hf(guint32 prog
, guint32 vers
)
454 rpc_prog_info_key rpc_prog_key
;
455 rpc_prog_info_value
*rpc_prog
;
457 rpc_prog_key
.prog
= prog
;
458 if ((rpc_prog
= (rpc_prog_info_value
*)g_hash_table_lookup(rpc_progs
,&rpc_prog_key
))) {
459 return g_array_index(rpc_prog
->procedure_hfs
, int, vers
);
464 /* return the name associated with a previously registered program. This
465 should probably eventually be expanded to use the rpc YP/NIS map
466 so that it can give names for programs not handled by wireshark */
468 rpc_prog_name(guint32 prog
)
470 const char *progname
= NULL
;
471 rpc_prog_info_key rpc_prog_key
;
472 rpc_prog_info_value
*rpc_prog
;
474 rpc_prog_key
.prog
= prog
;
475 if ((rpc_prog
= (rpc_prog_info_value
*)g_hash_table_lookup(rpc_progs
,&rpc_prog_key
)) == NULL
) {
476 progname
= "Unknown";
479 progname
= rpc_prog
->progname
;
485 /*--------------------------------------*/
486 /* end of Hash array with program names */
487 /*--------------------------------------*/
489 /* One of these structures are created for each conversation that contains
490 * RPC and contains the state we need to maintain for the conversation.
492 typedef struct _rpc_conv_info_t
{
497 /* we can not hang this off the conversation structure above since the context
498 will be reused across all tcp connections between the client and the server.
499 a global tree for all contexts should still be unlikely to have collissions
502 wmem_tree_t
*authgss_contexts
= NULL
;
505 rpc_roundup(unsigned int a
)
507 unsigned int mod
= a
% 4;
509 ret
= a
+ ((mod
)? 4-mod
: 0);
510 /* Check for overflow */
512 THROW(ReportedBoundsError
);
518 dissect_rpc_bool(tvbuff_t
*tvb
, proto_tree
*tree
,
519 int hfindex
, int offset
)
521 proto_tree_add_item(tree
, hfindex
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
527 dissect_rpc_uint32(tvbuff_t
*tvb
, proto_tree
*tree
,
528 int hfindex
, int offset
)
530 proto_tree_add_item(tree
, hfindex
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
536 dissect_rpc_uint64(tvbuff_t
*tvb
, proto_tree
*tree
,
537 int hfindex
, int offset
)
539 header_field_info
*hfinfo
;
541 hfinfo
= proto_registrar_get_nth(hfindex
);
542 DISSECTOR_ASSERT(hfinfo
->type
== FT_UINT64
);
543 proto_tree_add_item(tree
, hfindex
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
549 * We want to make this function available outside this file and
550 * allow callers to pass a dissection function for the opaque data
553 dissect_rpc_opaque_data(tvbuff_t
*tvb
, int offset
,
557 gboolean fixed_length
, guint32 length
,
558 gboolean string_data
, const char **string_buffer_ret
,
559 dissect_function_t
*dissect_it
)
562 proto_item
*string_item
= NULL
;
563 proto_tree
*string_tree
= NULL
;
565 guint32 string_length
;
566 guint32 string_length_full
;
567 guint32 string_length_packet
;
568 guint32 string_length_captured
;
569 guint32 string_length_copy
;
573 guint32 fill_length_packet
;
574 guint32 fill_length_captured
;
575 guint32 fill_length_copy
;
578 /* int string_item_offset; */
580 char *string_buffer
= NULL
;
581 const char *string_buffer_print
= NULL
;
584 string_length
= length
;
585 data_offset
= offset
;
588 string_length
= tvb_get_ntohl(tvb
,offset
);
589 data_offset
= offset
+ 4;
591 string_length_captured
= tvb_length_remaining(tvb
, data_offset
);
592 string_length_packet
= tvb_reported_length_remaining(tvb
, data_offset
);
593 string_length_full
= rpc_roundup(string_length
);
594 if (string_length_captured
< string_length
) {
595 /* truncated string */
596 string_length_copy
= string_length_captured
;
599 fill_length_copy
= 0;
600 if (string_length_packet
< string_length
)
601 exception
= ReportedBoundsError
;
603 exception
= BoundsError
;
606 /* full string data */
607 string_length_copy
= string_length
;
608 fill_length
= string_length_full
- string_length
;
609 fill_length_captured
= tvb_length_remaining(tvb
,
610 data_offset
+ string_length
);
611 fill_length_packet
= tvb_reported_length_remaining(tvb
,
612 data_offset
+ string_length
);
613 if (fill_length_captured
< fill_length
) {
614 /* truncated fill bytes */
615 fill_length_copy
= fill_length_packet
;
617 if (fill_length_packet
< fill_length
)
618 exception
= ReportedBoundsError
;
620 exception
= BoundsError
;
623 /* full fill bytes */
624 fill_length_copy
= fill_length
;
630 * If we were passed a dissection routine, make a TVB of the data
631 * and call the dissection routine
635 tvbuff_t
*opaque_tvb
;
637 opaque_tvb
= tvb_new_subset(tvb
, data_offset
, string_length_copy
,
640 return (*dissect_it
)(opaque_tvb
, offset
, pinfo
, tree
, NULL
);
645 string_buffer
= tvb_get_string(wmem_packet_scope(), tvb
, data_offset
, string_length_copy
);
647 string_buffer
= (char *)tvb_memcpy(tvb
, wmem_alloc(wmem_packet_scope(), string_length_copy
+1), data_offset
, string_length_copy
);
649 string_buffer
[string_length_copy
] = '\0';
650 /* calculate a nice printable string */
652 if (string_length
!= string_length_copy
) {
656 formatted
= format_text(string_buffer
, strlen(string_buffer
));
657 /* copy over the data and append <TRUNCATED> */
658 string_buffer_print
=wmem_strdup_printf(wmem_packet_scope(), "%s%s", formatted
, RPC_STRING_TRUNCATED
);
660 string_buffer_print
=RPC_STRING_DATA RPC_STRING_TRUNCATED
;
664 string_buffer_print
=
665 wmem_strdup(wmem_packet_scope(), format_text(string_buffer
, strlen(string_buffer
)));
667 string_buffer_print
=RPC_STRING_DATA
;
671 string_buffer_print
=RPC_STRING_EMPTY
;
675 /* string_item_offset = offset; */
676 string_item
= proto_tree_add_text(tree
, tvb
,offset
, -1,
677 "%s: %s", proto_registrar_get_name(hfindex
),
678 string_buffer_print
);
679 string_tree
= proto_item_add_subtree(string_item
,
684 proto_tree_add_text(string_tree
, tvb
,offset
,4,
685 "length: %u", string_length
);
691 proto_tree_add_string_format(string_tree
,
692 hfindex
, tvb
, offset
, string_length_copy
,
694 "contents: %s", string_buffer_print
);
696 proto_tree_add_bytes_format(string_tree
,
697 hfindex
, tvb
, offset
, string_length_copy
,
699 "contents: %s", string_buffer_print
);
703 offset
+= string_length_copy
;
707 if (fill_truncated
) {
708 proto_tree_add_text(string_tree
, tvb
,
709 offset
,fill_length_copy
,
710 "fill bytes: opaque data<TRUNCATED>");
713 proto_tree_add_text(string_tree
, tvb
,
714 offset
,fill_length_copy
,
715 "fill bytes: opaque data");
718 offset
+= fill_length_copy
;
722 proto_item_set_end(string_item
, tvb
, offset
);
724 if (string_buffer_ret
!= NULL
)
725 *string_buffer_ret
= string_buffer_print
;
728 * If the data was truncated, throw the appropriate exception,
729 * so that dissection stops and the frame is properly marked.
738 dissect_rpc_string(tvbuff_t
*tvb
, proto_tree
*tree
,
739 int hfindex
, int offset
, const char **string_buffer_ret
)
741 offset
= dissect_rpc_opaque_data(tvb
, offset
, tree
, NULL
,
742 hfindex
, FALSE
, 0, TRUE
, string_buffer_ret
, NULL
);
748 dissect_rpc_data(tvbuff_t
*tvb
, proto_tree
*tree
,
749 int hfindex
, int offset
)
751 offset
= dissect_rpc_opaque_data(tvb
, offset
, tree
, NULL
,
752 hfindex
, FALSE
, 0, FALSE
, NULL
, NULL
);
758 dissect_rpc_bytes(tvbuff_t
*tvb
, proto_tree
*tree
,
759 int hfindex
, int offset
, guint32 length
,
760 gboolean string_data
, const char **string_buffer_ret
)
762 offset
= dissect_rpc_opaque_data(tvb
, offset
, tree
, NULL
,
763 hfindex
, TRUE
, length
, string_data
, string_buffer_ret
, NULL
);
769 dissect_rpc_list(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
770 int offset
, dissect_function_t
*rpc_list_dissector
)
772 guint32 value_follows
;
775 value_follows
= tvb_get_ntohl(tvb
, offset
);
776 proto_tree_add_boolean(tree
,hf_rpc_value_follows
, tvb
,
777 offset
, 4, value_follows
);
779 if (value_follows
== 1) {
780 offset
= rpc_list_dissector(tvb
, offset
, pinfo
, tree
, NULL
);
791 dissect_rpc_array(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
792 int offset
, dissect_function_t
*rpc_array_dissector
,
795 proto_item
* lock_item
;
796 proto_tree
* lock_tree
;
799 num
= tvb_get_ntohl(tvb
, offset
);
801 lock_item
= proto_tree_add_item(tree
, hfindex
, tvb
, offset
, -1, ENC_NA
);
803 lock_tree
= proto_item_add_subtree(lock_item
, ett_rpc_array
);
806 proto_tree_add_text(lock_tree
, tvb
, offset
, 4, "no values");
809 proto_item_set_end(lock_item
, tvb
, offset
);
814 offset
= dissect_rpc_uint32(tvb
, lock_tree
,
815 hf_rpc_array_len
, offset
);
818 offset
= rpc_array_dissector(tvb
, offset
, pinfo
, lock_tree
, NULL
);
821 proto_item_set_end(lock_item
, tvb
, offset
);
826 dissect_rpc_authunix_groups(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
)
831 proto_item
*gitem
= NULL
;
832 proto_tree
*gtree
= NULL
;
834 gids_count
= tvb_get_ntohl(tvb
,offset
);
836 gitem
= proto_tree_add_text(tree
, tvb
, offset
,
837 4+gids_count
*4, "Auxiliary GIDs (%d)", gids_count
);
838 gtree
= proto_item_add_subtree(gitem
, ett_rpc_gids
);
842 /* first, open with [ */
843 if (tree
&& gids_count
> 0)
844 proto_item_append_text(gitem
, " [");
846 for (gids_i
= 0 ; gids_i
< gids_count
; gids_i
++) {
847 gids_entry
= tvb_get_ntohl(tvb
,offset
);
849 proto_tree_add_uint(gtree
, hf_rpc_auth_gid
, tvb
,
850 offset
, 4, gids_entry
);
853 /* add at most 16 GIDs to the text */
854 if (tree
&& gids_i
< 16) {
856 proto_item_append_text(gitem
, ", ");
858 proto_item_append_text(gitem
, "%d", gids_entry
);
859 } else if (tree
&& gids_i
== 16) {
860 proto_item_append_text(gitem
, "...");
865 /* finally, close with ] */
866 if (tree
&& gids_count
> 0)
867 proto_item_append_text(gitem
, "]");
873 dissect_rpc_authunix_cred(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
)
879 stamp
= tvb_get_ntohl(tvb
,offset
);
880 proto_tree_add_uint(tree
, hf_rpc_auth_stamp
, tvb
,
884 offset
= dissect_rpc_string(tvb
, tree
,
885 hf_rpc_auth_machinename
, offset
, NULL
);
887 uid
= tvb_get_ntohl(tvb
,offset
);
888 proto_tree_add_uint(tree
, hf_rpc_auth_uid
, tvb
,
892 gid
= tvb_get_ntohl(tvb
,offset
);
893 proto_tree_add_uint(tree
, hf_rpc_auth_gid
, tvb
,
897 offset
= dissect_rpc_authunix_groups(tvb
, tree
, offset
);
902 typedef struct _gssauth_context_info_t
{
903 guint32 create_frame
;
904 guint32 destroy_frame
;
905 } gssauth_context_info_t
;
909 dissect_rpc_authgss_context(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
,
910 packet_info
*pinfo
, rpc_conv_info_t
*rpc_conv_info _U_
,
911 gboolean is_create
, gboolean is_destroy
)
913 proto_item
*context_item
;
914 proto_tree
*context_tree
;
915 int old_offset
= offset
;
917 guint32 context_length
;
918 gssauth_context_info_t
*context_info
;
919 wmem_tree_key_t tkey
[2];
920 guint32 key
[4] = {0,0,0,0};
922 context_item
= proto_tree_add_text(tree
, tvb
, offset
, -1,
925 context_tree
= proto_item_add_subtree(context_item
,
928 context_length
= tvb_get_ntohl(tvb
, offset
);
929 proto_tree_add_item(context_tree
, hf_rpc_authgss_ctx_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
932 context_offset
= offset
;
933 proto_tree_add_item(context_tree
, hf_rpc_authgss_ctx
, tvb
, offset
, context_length
, ENC_NA
);
934 offset
+= context_length
;
936 offset
= (offset
+ 3) & 0xffffffc;
938 if (context_length
> 16) {
939 /* we only track contexts up to 16 bytes in size */
943 tvb_memcpy(tvb
, key
, context_offset
, context_length
);
945 tkey
[0].key
= &key
[0];
949 context_info
= (gssauth_context_info_t
*)wmem_tree_lookup32_array(authgss_contexts
, &tkey
[0]);
950 if(context_info
== NULL
) {
951 tvb_memcpy(tvb
, key
, context_offset
, context_length
);
953 tkey
[0].key
= &key
[0];
957 context_info
= wmem_new(wmem_file_scope(), gssauth_context_info_t
);
958 context_info
->create_frame
= 0;
959 context_info
->destroy_frame
= 0;
960 wmem_tree_insert32_array(authgss_contexts
, &tkey
[0], context_info
);
963 context_info
->create_frame
= pinfo
->fd
->num
;
966 context_info
->destroy_frame
= pinfo
->fd
->num
;
969 if (context_info
->create_frame
) {
971 it
= proto_tree_add_uint(context_tree
, hf_rpc_authgss_ctx_create_frame
, tvb
, 0, 0, context_info
->create_frame
);
972 PROTO_ITEM_SET_GENERATED(it
);
975 if (context_info
->destroy_frame
) {
977 it
= proto_tree_add_uint(context_tree
, hf_rpc_authgss_ctx_destroy_frame
, tvb
, 0, 0, context_info
->destroy_frame
);
978 PROTO_ITEM_SET_GENERATED(it
);
981 proto_item_set_len(context_item
, offset
- old_offset
);
987 dissect_rpc_authgss_cred(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
,
988 packet_info
*pinfo
, rpc_conv_info_t
*rpc_conv_info
)
995 agc_v
= tvb_get_ntohl(tvb
, offset
);
996 proto_tree_add_uint(tree
, hf_rpc_authgss_v
,
997 tvb
, offset
, 4, agc_v
);
1000 agc_proc
= tvb_get_ntohl(tvb
, offset
);
1001 proto_tree_add_uint(tree
, hf_rpc_authgss_proc
,
1002 tvb
, offset
, 4, agc_proc
);
1005 agc_seq
= tvb_get_ntohl(tvb
, offset
);
1006 proto_tree_add_uint(tree
, hf_rpc_authgss_seq
,
1007 tvb
, offset
, 4, agc_seq
);
1010 agc_svc
= tvb_get_ntohl(tvb
, offset
);
1011 proto_tree_add_uint(tree
, hf_rpc_authgss_svc
,
1012 tvb
, offset
, 4, agc_svc
);
1015 offset
= dissect_rpc_authgss_context(tree
, tvb
, offset
, pinfo
, rpc_conv_info
, FALSE
, agc_proc
== RPCSEC_GSS_DESTROY
? TRUE
: FALSE
);
1021 dissect_rpc_authdes_desblock(tvbuff_t
*tvb
, proto_tree
*tree
,
1022 int hfindex
, int offset
)
1027 value_high
= tvb_get_ntohl(tvb
, offset
);
1028 value_low
= tvb_get_ntohl(tvb
, offset
+ 4);
1031 proto_tree_add_text(tree
, tvb
, offset
, 8,
1032 "%s: 0x%x%08x", proto_registrar_get_name(hfindex
), value_high
,
1040 dissect_rpc_authdes_cred(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
)
1046 adc_namekind
= tvb_get_ntohl(tvb
, offset
);
1047 proto_tree_add_uint(tree
, hf_rpc_authdes_namekind
,
1048 tvb
, offset
, 4, adc_namekind
);
1051 switch(adc_namekind
)
1053 case AUTHDES_NAMEKIND_FULLNAME
:
1054 offset
= dissect_rpc_string(tvb
, tree
,
1055 hf_rpc_authdes_netname
, offset
, NULL
);
1056 offset
= dissect_rpc_authdes_desblock(tvb
, tree
,
1057 hf_rpc_authdes_convkey
, offset
);
1058 window
= tvb_get_ntohl(tvb
, offset
);
1059 proto_tree_add_uint(tree
, hf_rpc_authdes_window
, tvb
, offset
, 4,
1064 case AUTHDES_NAMEKIND_NICKNAME
:
1065 nickname
= tvb_get_ntohl(tvb
, offset
);
1066 proto_tree_add_uint(tree
, hf_rpc_authdes_nickname
, tvb
, offset
, 4,
1076 dissect_rpc_authgluster_cred(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
)
1078 proto_tree_add_item(tree
, hf_rpc_auth_lk_owner
, tvb
, offset
,
1082 offset
= dissect_rpc_uint32(tvb
, tree
, hf_rpc_auth_pid
, offset
);
1083 offset
= dissect_rpc_uint32(tvb
, tree
, hf_rpc_auth_uid
, offset
);
1084 offset
= dissect_rpc_uint32(tvb
, tree
, hf_rpc_auth_gid
, offset
);
1085 offset
= dissect_rpc_authunix_groups(tvb
, tree
, offset
);
1091 dissect_rpc_authglusterfs_v2_cred(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
)
1095 offset
= dissect_rpc_uint32(tvb
, tree
, hf_rpc_auth_pid
, offset
);
1096 offset
= dissect_rpc_uint32(tvb
, tree
, hf_rpc_auth_uid
, offset
);
1097 offset
= dissect_rpc_uint32(tvb
, tree
, hf_rpc_auth_gid
, offset
);
1098 offset
= dissect_rpc_authunix_groups(tvb
, tree
, offset
);
1100 len
= tvb_get_ntohl(tvb
, offset
);
1103 proto_tree_add_item(tree
, hf_rpc_auth_lk_owner
, tvb
, offset
,
1111 dissect_rpc_authgssapi_cred(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
)
1116 agc_v
= tvb_get_ntohl(tvb
, offset
);
1117 proto_tree_add_uint(tree
, hf_rpc_authgssapi_v
,
1118 tvb
, offset
, 4, agc_v
);
1121 agc_msg
= tvb_get_ntohl(tvb
, offset
);
1122 proto_tree_add_boolean(tree
, hf_rpc_authgssapi_msg
,
1123 tvb
, offset
, 4, agc_msg
);
1126 offset
= dissect_rpc_data(tvb
, tree
, hf_rpc_authgssapi_handle
,
1133 dissect_rpc_cred(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
,
1134 packet_info
*pinfo
, rpc_conv_info_t
*rpc_conv_info
)
1142 flavor
= tvb_get_ntohl(tvb
,offset
);
1143 length
= tvb_get_ntohl(tvb
,offset
+4);
1144 length
= rpc_roundup(length
);
1147 citem
= proto_tree_add_text(tree
, tvb
, offset
,
1148 8+length
, "Credentials");
1149 ctree
= proto_item_add_subtree(citem
, ett_rpc_cred
);
1150 proto_tree_add_uint(ctree
, hf_rpc_auth_flavor
, tvb
,
1152 proto_tree_add_uint(ctree
, hf_rpc_auth_length
, tvb
,
1153 offset
+4, 4, length
);
1157 dissect_rpc_authunix_cred(tvb
, ctree
, offset
+8);
1165 dissect_rpc_authdes_cred(tvb
, ctree
, offset
+8);
1169 /* AUTH_RSA is (ab)used by Gluster */
1170 dissect_rpc_authgluster_cred(tvb
, ctree
, offset
+8);
1174 dissect_rpc_authgss_cred(tvb
, ctree
, offset
+8, pinfo
, rpc_conv_info
);
1177 case AUTH_GLUSTERFS
:
1178 dissect_rpc_authglusterfs_v2_cred(tvb
, ctree
, offset
+8);
1182 dissect_rpc_authgssapi_cred(tvb
, ctree
, offset
+8);
1187 proto_tree_add_text(ctree
, tvb
, offset
+8,
1188 length
,"opaque data");
1192 offset
+= 8 + length
;
1198 * XDR opaque object, the contents of which are interpreted as a GSS-API
1202 dissect_rpc_authgss_token(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
,
1203 packet_info
*pinfo
, int hfindex
)
1205 guint32 opaque_length
, rounded_length
;
1206 gint len_consumed
, length
, reported_length
;
1210 proto_tree
*gtree
= NULL
;
1212 opaque_length
= tvb_get_ntohl(tvb
, offset
);
1213 rounded_length
= rpc_roundup(opaque_length
);
1215 gitem
= proto_tree_add_item(tree
, hfindex
, tvb
, offset
, 4+rounded_length
, ENC_NA
);
1216 gtree
= proto_item_add_subtree(gitem
, ett_rpc_gss_token
);
1217 proto_tree_add_uint(gtree
, hf_rpc_authgss_token_length
,
1218 tvb
, offset
, 4, opaque_length
);
1221 if (opaque_length
!= 0) {
1222 length
= tvb_length_remaining(tvb
, offset
);
1223 reported_length
= tvb_reported_length_remaining(tvb
, offset
);
1224 DISSECTOR_ASSERT(length
>= 0);
1225 DISSECTOR_ASSERT(reported_length
>= 0);
1226 if (length
> reported_length
)
1227 length
= reported_length
;
1228 if ((guint32
)length
> opaque_length
)
1229 length
= opaque_length
;
1230 if ((guint32
)reported_length
> opaque_length
)
1231 reported_length
= opaque_length
;
1232 new_tvb
= tvb_new_subset(tvb
, offset
, length
, reported_length
);
1233 len_consumed
= call_dissector(gssapi_handle
, new_tvb
, pinfo
, gtree
);
1234 offset
+= len_consumed
;
1236 offset
= rpc_roundup(offset
);
1240 /* AUTH_DES verifiers are asymmetrical, so we need to know what type of
1241 * verifier we're decoding (CALL or REPLY).
1244 dissect_rpc_verf(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
, int msg_type
,
1253 flavor
= tvb_get_ntohl(tvb
,offset
);
1254 length
= tvb_get_ntohl(tvb
,offset
+4);
1255 length
= rpc_roundup(length
);
1258 vitem
= proto_tree_add_text(tree
, tvb
, offset
,
1259 8+length
, "Verifier");
1260 vtree
= proto_item_add_subtree(vitem
, ett_rpc_verf
);
1261 proto_tree_add_uint(vtree
, hf_rpc_auth_flavor
, tvb
,
1266 proto_tree_add_uint(vtree
, hf_rpc_auth_length
, tvb
,
1267 offset
+4, 4, length
);
1268 dissect_rpc_authunix_cred(tvb
, vtree
, offset
+8);
1271 proto_tree_add_uint(vtree
, hf_rpc_auth_length
, tvb
,
1272 offset
+4, 4, length
);
1274 if (msg_type
== RPC_CALL
)
1278 dissect_rpc_authdes_desblock(tvb
, vtree
,
1279 hf_rpc_authdes_timestamp
, offset
+8);
1280 window
= tvb_get_ntohl(tvb
, offset
+16);
1281 proto_tree_add_uint(vtree
, hf_rpc_authdes_windowverf
, tvb
,
1282 offset
+16, 4, window
);
1286 /* must be an RPC_REPLY */
1289 dissect_rpc_authdes_desblock(tvb
, vtree
,
1290 hf_rpc_authdes_timeverf
, offset
+8);
1291 nickname
= tvb_get_ntohl(tvb
, offset
+16);
1292 proto_tree_add_uint(vtree
, hf_rpc_authdes_nickname
, tvb
,
1293 offset
+16, 4, nickname
);
1297 dissect_rpc_authgss_token(tvb
, vtree
, offset
+4, pinfo
, hf_rpc_authgss_token
);
1300 proto_tree_add_uint(vtree
, hf_rpc_auth_length
, tvb
,
1301 offset
+4, 4, length
);
1303 proto_tree_add_text(vtree
, tvb
, offset
+8,
1304 length
, "opaque data");
1308 offset
+= 8 + length
;
1314 dissect_rpc_authgss_initarg(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
,
1317 return dissect_rpc_authgss_token(tvb
, tree
, offset
, pinfo
, hf_rpc_authgss_token
);
1321 dissect_rpc_authgss_initres(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
,
1322 packet_info
*pinfo
, rpc_conv_info_t
*rpc_conv_info
)
1324 int major
, minor
, window
;
1326 offset
= dissect_rpc_authgss_context(tree
, tvb
, offset
, pinfo
, rpc_conv_info
, TRUE
, FALSE
);
1328 major
= tvb_get_ntohl(tvb
,offset
);
1329 proto_tree_add_uint(tree
, hf_rpc_authgss_major
, tvb
,
1333 minor
= tvb_get_ntohl(tvb
,offset
);
1334 proto_tree_add_uint(tree
, hf_rpc_authgss_minor
, tvb
,
1338 window
= tvb_get_ntohl(tvb
,offset
);
1339 proto_tree_add_uint(tree
, hf_rpc_authgss_window
, tvb
,
1343 offset
= dissect_rpc_authgss_token(tvb
, tree
, offset
, pinfo
, hf_rpc_authgss_token
);
1349 dissect_rpc_authgssapi_initarg(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
,
1354 proto_tree
*mtree
= NULL
;
1357 mitem
= proto_tree_add_text(tree
, tvb
, offset
, -1,
1359 mtree
= proto_item_add_subtree(mitem
, ett_rpc_authgssapi_msg
);
1361 version
= tvb_get_ntohl(tvb
, offset
);
1363 proto_tree_add_uint(mtree
, hf_rpc_authgssapi_msgv
, tvb
,
1364 offset
, 4, version
);
1368 offset
= dissect_rpc_authgss_token(tvb
, mtree
, offset
, pinfo
, hf_rpc_authgss_token
);
1374 dissect_rpc_authgssapi_initres(tvbuff_t
* tvb
, proto_tree
* tree
, int offset
,
1380 proto_tree
*mtree
= NULL
;
1383 mitem
= proto_tree_add_text(tree
, tvb
, offset
, -1,
1385 mtree
= proto_item_add_subtree(mitem
, ett_rpc_authgssapi_msg
);
1388 version
= tvb_get_ntohl(tvb
,offset
);
1390 proto_tree_add_uint(mtree
, hf_rpc_authgssapi_msgv
, tvb
,
1391 offset
, 4, version
);
1395 offset
= dissect_rpc_data(tvb
, mtree
, hf_rpc_authgssapi_handle
,
1398 major
= tvb_get_ntohl(tvb
,offset
);
1400 proto_tree_add_uint(mtree
, hf_rpc_authgss_major
, tvb
,
1405 minor
= tvb_get_ntohl(tvb
,offset
);
1407 proto_tree_add_uint(mtree
, hf_rpc_authgss_minor
, tvb
,
1412 offset
= dissect_rpc_authgss_token(tvb
, mtree
, offset
, pinfo
, hf_rpc_authgss_token
);
1414 offset
= dissect_rpc_data(tvb
, mtree
, hf_rpc_authgssapi_isn
, offset
);
1420 dissect_auth_gssapi_data(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
1422 offset
= dissect_rpc_data(tvb
, tree
, hf_rpc_authgss_data
,
1428 call_dissect_function(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1429 int offset
, dissect_function_t
* dissect_function
, const char *progname
,
1430 rpc_call_info_value
*rpc_call
)
1432 const char *saved_proto
;
1434 tvb_ensure_length_remaining(tvb
, offset
);
1435 if (dissect_function
!= NULL
) {
1436 /* set the current protocol name */
1437 saved_proto
= pinfo
->current_proto
;
1438 if (progname
!= NULL
)
1439 pinfo
->current_proto
= progname
;
1441 /* call the dissector for the next level */
1442 offset
= dissect_function(tvb
, offset
, pinfo
, tree
, rpc_call
);
1444 /* restore the protocol name */
1445 pinfo
->current_proto
= saved_proto
;
1453 dissect_rpc_authgss_integ_data(tvbuff_t
*tvb
, packet_info
*pinfo
,
1454 proto_tree
*tree
, int offset
,
1455 dissect_function_t
* dissect_function
,
1456 const char *progname
, rpc_call_info_value
*rpc_call
)
1458 guint32 length
, rounded_length
, seq
;
1461 proto_tree
*gtree
= NULL
;
1463 length
= tvb_get_ntohl(tvb
, offset
);
1464 rounded_length
= rpc_roundup(length
);
1465 seq
= tvb_get_ntohl(tvb
, offset
+4);
1467 gitem
= proto_tree_add_text(tree
, tvb
, offset
,
1468 4+rounded_length
, "GSS Data");
1469 gtree
= proto_item_add_subtree(gitem
, ett_rpc_gss_data
);
1470 proto_tree_add_uint(gtree
, hf_rpc_authgss_data_length
,
1471 tvb
, offset
, 4, length
);
1472 proto_tree_add_uint(gtree
, hf_rpc_authgss_seq
,
1473 tvb
, offset
+4, 4, seq
);
1476 if (dissect_function
!= NULL
) {
1478 call_dissect_function(tvb
, pinfo
, gtree
, offset
,
1479 dissect_function
, progname
, rpc_call
);
1481 offset
+= rounded_length
- 4;
1482 offset
= dissect_rpc_authgss_token(tvb
, tree
, offset
, pinfo
, hf_rpc_authgss_checksum
);
1488 dissect_rpc_authgss_priv_data(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
1489 packet_info
*pinfo _U_
)
1492 /* int return_offset; */
1494 length
= tvb_get_ntohl(tvb
, offset
);
1495 proto_tree_add_uint(tree
, hf_rpc_authgss_data_length
,
1496 tvb
, offset
, 4, length
);
1499 proto_tree_add_item(tree
, hf_rpc_authgss_data
, tvb
, offset
, length
,
1503 /* cant decrypt if we dont have SPNEGO */
1504 if (!spnego_krb5_wrap_handle
) {
1509 /* return_offset = */ call_dissector(spnego_krb5_wrap_handle
,
1510 tvb_new_subset_remaining(tvb
, offset
),
1513 if (!pinfo
->gssapi_decrypted_tvb
) {
1514 /* failed to decrypt the data */
1524 * Dissect the arguments to an indirect call; used by the portmapper/RPCBIND
1525 * dissector for the CALLIT procedure.
1527 * Record these in the same table as the direct calls
1528 * so we can find it when dissecting an indirect call reply.
1529 * (There should not be collissions between xid between direct and
1533 dissect_rpc_indir_call(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1534 int offset
, int args_id
, guint32 prog
, guint32 vers
, guint32 proc
)
1536 conversation_t
* conversation
;
1537 static address null_address
= { AT_NONE
, -1, 0, NULL
};
1538 rpc_proc_info_key key
;
1539 rpc_proc_info_value
*value
;
1540 rpc_call_info_value
*rpc_call
;
1541 dissect_function_t
*dissect_function
= NULL
;
1542 rpc_conv_info_t
*rpc_conv_info
=NULL
;
1548 if ((value
= (rpc_proc_info_value
*)g_hash_table_lookup(rpc_procs
,&key
)) != NULL
) {
1549 dissect_function
= value
->dissect_call
;
1551 /* Keep track of the address whence the call came, and the
1552 port to which the call is being sent, so that we can
1553 match up calls with replies.
1555 If the transport is connection-oriented (we check, for
1556 now, only for "pinfo->ptype" of PT_TCP), we also take
1557 into account the port from which the call was sent
1558 and the address to which the call was sent, because
1559 the addresses and ports of the two endpoints should be
1560 the same for all calls and replies. (XXX - what if
1561 the connection is broken and re-established?)
1563 If the transport is connectionless, we don't worry
1564 about the address to which the call was sent and from
1565 which the reply was sent, because there's no
1566 guarantee that the reply will come from the address
1567 to which the call was sent. We also don't worry about
1568 the port *from* which the call was sent and *to* which
1569 the reply was sent, because some clients (*cough* OS X
1570 NFS client *cough) might send retransmissions from a
1571 different port from the original request. */
1572 if (pinfo
->ptype
== PT_TCP
) {
1573 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
,
1574 &pinfo
->dst
, pinfo
->ptype
, pinfo
->srcport
,
1575 pinfo
->destport
, 0);
1578 * XXX - you currently still have to pass a non-null
1579 * pointer for the second address argument even
1580 * if you use NO_ADDR_B.
1582 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
,
1583 &null_address
, pinfo
->ptype
, pinfo
->destport
,
1584 0, NO_ADDR_B
|NO_PORT_B
);
1586 if (conversation
== NULL
) {
1587 /* It's not part of any conversation - create a new
1590 XXX - this should never happen, as we should've
1591 created a conversation for it in the RPC
1593 if (pinfo
->ptype
== PT_TCP
) {
1594 conversation
= conversation_new(pinfo
->fd
->num
, &pinfo
->src
,
1595 &pinfo
->dst
, pinfo
->ptype
, pinfo
->srcport
,
1596 pinfo
->destport
, 0);
1598 conversation
= conversation_new(pinfo
->fd
->num
, &pinfo
->src
,
1599 &null_address
, pinfo
->ptype
, pinfo
->destport
,
1600 0, NO_ADDR2
|NO_PORT2
);
1604 * Do we already have a state structure for this conv
1606 rpc_conv_info
= (rpc_conv_info_t
*)conversation_get_proto_data(conversation
, proto_rpc
);
1607 if (!rpc_conv_info
) {
1608 /* No. Attach that information to the conversation, and add
1609 * it to the list of information structures.
1611 rpc_conv_info
= wmem_new(wmem_file_scope(), rpc_conv_info_t
);
1612 rpc_conv_info
->xids
=wmem_tree_new(wmem_file_scope());
1614 conversation_add_proto_data(conversation
, proto_rpc
, rpc_conv_info
);
1617 /* Make the dissector for this conversation the non-heuristic
1619 conversation_set_dissector(conversation
,
1620 (pinfo
->ptype
== PT_TCP
) ? rpc_tcp_handle
: rpc_handle
);
1622 /* Dissectors for RPC procedure calls and replies shouldn't
1623 create new tvbuffs, and we don't create one ourselves,
1624 so we should have been handed the tvbuff for this RPC call;
1625 as such, the XID is at offset 0 in this tvbuff. */
1626 /* look up the request */
1627 xid
= tvb_get_ntohl(tvb
, offset
);
1628 rpc_call
= (rpc_call_info_value
*)wmem_tree_lookup32(rpc_conv_info
->xids
, xid
);
1629 if (rpc_call
== NULL
) {
1630 /* We didn't find it; create a new entry.
1631 Prepare the value data.
1632 Not all of it is needed for handling indirect
1633 calls, so we set a bunch of items to 0. */
1634 rpc_call
= wmem_new(wmem_file_scope(), rpc_call_info_value
);
1635 rpc_call
->req_num
= 0;
1636 rpc_call
->rep_num
= 0;
1637 rpc_call
->prog
= prog
;
1638 rpc_call
->vers
= vers
;
1639 rpc_call
->proc
= proc
;
1640 rpc_call
->private_data
= NULL
;
1643 * XXX - what about RPCSEC_GSS?
1644 * Do we have to worry about it?
1646 rpc_call
->flavor
= FLAVOR_NOT_GSSAPI
;
1647 rpc_call
->gss_proc
= 0;
1648 rpc_call
->gss_svc
= 0;
1649 rpc_call
->proc_info
= value
;
1651 wmem_tree_insert32(rpc_conv_info
->xids
, xid
, (void *)rpc_call
);
1655 /* We don't know the procedure.
1656 Happens only with strange program versions or
1657 non-existing dissectors.
1658 Just show the arguments as opaque data. */
1659 offset
= dissect_rpc_data(tvb
, tree
, args_id
,
1666 proto_tree_add_text(tree
, tvb
, offset
, 4,
1667 "Argument length: %u",
1668 tvb_get_ntohl(tvb
, offset
));
1672 /* Dissect the arguments */
1673 offset
= call_dissect_function(tvb
, pinfo
, tree
, offset
,
1674 dissect_function
, NULL
, rpc_call
);
1679 * Dissect the results in an indirect reply; used by the portmapper/RPCBIND
1683 dissect_rpc_indir_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1684 int offset
, int result_id
, int prog_id
, int vers_id
, int proc_id
)
1686 conversation_t
* conversation
;
1687 static address null_address
= { AT_NONE
, -1, 0, NULL
};
1688 rpc_call_info_value
*rpc_call
;
1689 char *procname
=NULL
;
1690 dissect_function_t
*dissect_function
= NULL
;
1691 rpc_conv_info_t
*rpc_conv_info
=NULL
;
1694 /* Look for the matching call in the xid table.
1695 A reply must match a call that we've seen, and the
1696 reply must be sent to the same address that the call came
1697 from, and must come from the port to which the call was sent.
1699 If the transport is connection-oriented (we check, for
1700 now, only for "pinfo->ptype" of PT_TCP), we take
1701 into account the port from which the call was sent
1702 and the address to which the call was sent, because
1703 the addresses and ports of the two endpoints should be
1704 the same for all calls and replies.
1706 If the transport is connectionless, we don't worry
1707 about the address to which the call was sent and from
1708 which the reply was sent, because there's no
1709 guarantee that the reply will come from the address
1710 to which the call was sent. We also don't worry about
1711 the port *from* which the call was sent and *to* which
1712 the reply was sent, because some clients (*cough* OS X
1713 NFS client *cough) might send retransmissions from a
1714 different port from the original request. */
1715 if (pinfo
->ptype
== PT_TCP
) {
1716 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
1717 pinfo
->ptype
, pinfo
->srcport
, pinfo
->destport
, 0);
1720 * XXX - you currently still have to pass a non-null
1721 * pointer for the second address argument even
1722 * if you use NO_ADDR_B.
1724 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->dst
, &null_address
,
1725 pinfo
->ptype
, pinfo
->srcport
, 0, NO_ADDR_B
|NO_PORT_B
);
1727 if (conversation
== NULL
) {
1728 /* We haven't seen an RPC call for that conversation,
1729 so we can't check for a reply to that call.
1730 Just show the reply stuff as opaque data. */
1731 offset
= dissect_rpc_data(tvb
, tree
, result_id
,
1736 * Do we already have a state structure for this conv
1738 rpc_conv_info
= (rpc_conv_info_t
*)conversation_get_proto_data(conversation
, proto_rpc
);
1739 if (!rpc_conv_info
) {
1740 /* No. Attach that information to the conversation, and add
1741 * it to the list of information structures.
1743 rpc_conv_info
= wmem_new(wmem_file_scope(), rpc_conv_info_t
);
1744 rpc_conv_info
->xids
=wmem_tree_new(wmem_file_scope());
1745 conversation_add_proto_data(conversation
, proto_rpc
, rpc_conv_info
);
1748 /* The XIDs of the call and reply must match. */
1749 xid
= tvb_get_ntohl(tvb
, 0);
1750 rpc_call
= (rpc_call_info_value
*)wmem_tree_lookup32(rpc_conv_info
->xids
, xid
);
1751 if (rpc_call
== NULL
) {
1752 /* The XID doesn't match a call from that
1753 conversation, so it's probably not an RPC reply.
1754 Just show the reply stuff as opaque data. */
1755 offset
= dissect_rpc_data(tvb
, tree
, result_id
,
1760 if (rpc_call
->proc_info
!= NULL
) {
1761 dissect_function
= rpc_call
->proc_info
->dissect_reply
;
1762 if (rpc_call
->proc_info
->name
!= NULL
) {
1763 procname
= (char *)rpc_call
->proc_info
->name
;
1766 procname
=wmem_strdup_printf(wmem_packet_scope(), "proc-%u", rpc_call
->proc
);
1771 dissect_function
= NULL
;
1773 procname
=wmem_strdup_printf(wmem_packet_scope(), "proc-%u", rpc_call
->proc
);
1778 proto_item
*tmp_item
;
1780 /* Put the program, version, and procedure into the tree. */
1781 tmp_item
=proto_tree_add_uint_format(tree
, prog_id
, tvb
,
1782 0, 0, rpc_call
->prog
, "Program: %s (%u)",
1783 rpc_prog_name(rpc_call
->prog
), rpc_call
->prog
);
1784 PROTO_ITEM_SET_GENERATED(tmp_item
);
1786 tmp_item
=proto_tree_add_uint(tree
, vers_id
, tvb
, 0, 0, rpc_call
->vers
);
1787 PROTO_ITEM_SET_GENERATED(tmp_item
);
1789 tmp_item
=proto_tree_add_uint_format(tree
, proc_id
, tvb
,
1790 0, 0, rpc_call
->proc
, "Procedure: %s (%u)",
1791 procname
, rpc_call
->proc
);
1792 PROTO_ITEM_SET_GENERATED(tmp_item
);
1795 if (dissect_function
== NULL
) {
1796 /* We don't know how to dissect the reply procedure.
1797 Just show the reply stuff as opaque data. */
1798 offset
= dissect_rpc_data(tvb
, tree
, result_id
,
1803 /* Put the length of the reply value into the tree. */
1804 proto_tree_add_text(tree
, tvb
, offset
, 4, "Argument length: %u",
1805 tvb_get_ntohl(tvb
, offset
));
1808 /* Dissect the return value */
1809 offset
= call_dissect_function(tvb
, pinfo
, tree
, offset
,
1810 dissect_function
, NULL
, rpc_call
);
1815 * Just mark this as a continuation of an earlier packet.
1818 dissect_rpc_continuation(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1820 proto_item
*rpc_item
;
1821 proto_tree
*rpc_tree
;
1823 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RPC");
1824 col_set_str(pinfo
->cinfo
, COL_INFO
, "Continuation");
1827 rpc_item
= proto_tree_add_item(tree
, proto_rpc
, tvb
, 0, -1,
1829 rpc_tree
= proto_item_add_subtree(rpc_item
, ett_rpc
);
1830 proto_tree_add_text(rpc_tree
, tvb
, 0, -1, "Continuation data");
1836 * Produce a dummy RPC program entry for the given RPC program key
1837 * and version values.
1841 make_fake_rpc_prog_if_needed (rpc_prog_info_key
*prpc_prog_key
, guint prog_ver
)
1843 /* sanity check: no one uses versions > 10 */
1848 if(g_hash_table_lookup(rpc_progs
, prpc_prog_key
) == NULL
) {
1849 /* ok this is not a known rpc program so we
1850 * will have to fake it.
1852 int proto_rpc_unknown_program
;
1853 char *NAME
, *Name
, *name
;
1854 static const vsff unknown_proc
[] = {
1855 { 0,"NULL",NULL
,NULL
},
1856 { 0,NULL
,NULL
,NULL
}
1859 NAME
= g_strdup_printf("Unknown RPC Program:%d",prpc_prog_key
->prog
);
1860 Name
= g_strdup_printf("RPC:%d",prpc_prog_key
->prog
);
1861 name
= g_strdup_printf("rpc%d",prpc_prog_key
->prog
);
1862 proto_rpc_unknown_program
= proto_register_protocol(NAME
, Name
, name
);
1864 rpc_init_prog(proto_rpc_unknown_program
, prpc_prog_key
->prog
, ett_rpc_unknown_program
);
1865 rpc_init_proc_table(prpc_prog_key
->prog
, prog_ver
, unknown_proc
, hf_rpc_procedure
);
1871 dissect_rpc_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1872 tvbuff_t
*frag_tvb
, fragment_head
*ipfd_head
, gboolean is_tcp
,
1873 guint32 rpc_rm
, gboolean first_pdu
)
1876 rpc_call_info_value
*rpc_call
= NULL
;
1877 rpc_prog_info_value
*rpc_prog
= NULL
;
1878 rpc_prog_info_key rpc_prog_key
;
1881 unsigned int rpcvers
;
1882 unsigned int prog
= 0;
1883 unsigned int vers
= 0;
1884 unsigned int proc
= 0;
1885 flavor_t flavor
= FLAVOR_UNKNOWN
;
1886 unsigned int gss_proc
= 0;
1887 unsigned int gss_svc
= 0;
1888 protocol_t
*proto
= NULL
;
1893 unsigned int reply_state
;
1894 unsigned int accept_state
;
1895 unsigned int reject_state
;
1897 const char *msg_type_name
= NULL
;
1898 const char *progname
= NULL
;
1899 char *procname
= NULL
;
1901 unsigned int vers_low
;
1902 unsigned int vers_high
;
1904 unsigned int auth_state
;
1906 proto_item
*rpc_item
= NULL
;
1907 proto_tree
*rpc_tree
= NULL
;
1909 proto_item
*pitem
= NULL
;
1910 proto_tree
*ptree
= NULL
;
1911 int offset
= (is_tcp
&& tvb
== frag_tvb
) ? 4 : 0;
1913 rpc_proc_info_key key
;
1914 rpc_proc_info_value
*value
= NULL
;
1915 conversation_t
* conversation
;
1916 static address null_address
= { AT_NONE
, -1, 0, NULL
};
1919 dissect_function_t
*dissect_function
= NULL
;
1920 gboolean dissect_rpc_flag
= TRUE
;
1922 rpc_conv_info_t
*rpc_conv_info
=NULL
;
1926 * Check to see whether this looks like an RPC call or reply.
1928 if (!tvb_bytes_exist(tvb
, offset
, 8)) {
1929 /* Captured data in packet isn't enough to let us tell. */
1933 /* both directions need at least this */
1934 msg_type
= tvb_get_ntohl(tvb
, offset
+ 4);
1939 /* check for RPC call */
1940 if (!tvb_bytes_exist(tvb
, offset
, 16)) {
1941 /* Captured data in packet isn't enough to let us
1946 /* XID can be anything, so dont check it.
1947 We already have the message type.
1948 Check whether an RPC version number of 2 is in the
1949 location where it would be, and that an RPC program
1950 number we know about is in the location where it would be.
1952 XXX - Sun's snoop appears to recognize as RPC even calls
1953 to stuff it doesn't dissect; does it just look for a 2
1954 at that location, which seems far to weak a heuristic
1955 (too many false positives), or does it have some additional
1958 We could conceivably check for any of the program numbers
1961 ftp://ftp.tau.ac.il/pub/users/eilon/rpc/rpc
1963 and report it as RPC (but not dissect the payload if
1964 we don't have a subdissector) if it matches. */
1965 rpc_prog_key
.prog
= tvb_get_ntohl(tvb
, offset
+ 12);
1967 /* we only dissect version 2 */
1968 if (tvb_get_ntohl(tvb
, offset
+ 8) != 2 ){
1971 /* let the user be able to weaken the heuristics if he need
1972 * to look at proprietary protocols not known
1975 if(rpc_dissect_unknown_programs
){
1978 /* if the user has specified that he wants to try to
1979 * dissect even completely unknown RPC program numbers
1980 * then let him do that.
1981 * In this case we only check that the program number
1982 * is neither 0 nor -1 which is better than nothing.
1984 if(rpc_prog_key
.prog
==0 || rpc_prog_key
.prog
==0xffffffff){
1987 version
=tvb_get_ntohl(tvb
, offset
+16);
1988 make_fake_rpc_prog_if_needed (&rpc_prog_key
, version
);
1990 if( (rpc_prog
= (rpc_prog_info_value
*)g_hash_table_lookup(rpc_progs
, &rpc_prog_key
)) == NULL
) {
1991 /* They're not, so it's probably not an RPC call. */
1997 /* Check for RPC reply. A reply must match a call that
1998 we've seen, and the reply must be sent to the same
1999 address that the call came from, and must come from
2000 the port to which the call was sent.
2002 If the transport is connection-oriented (we check, for
2003 now, only for "pinfo->ptype" of PT_TCP), we take
2004 into account the port from which the call was sent
2005 and the address to which the call was sent, because
2006 the addresses and ports of the two endpoints should be
2007 the same for all calls and replies.
2009 If the transport is connectionless, we don't worry
2010 about the address to which the call was sent and from
2011 which the reply was sent, because there's no
2012 guarantee that the reply will come from the address
2013 to which the call was sent. We also don't worry about
2014 the port *from* which the call was sent and *to* which
2015 the reply was sent, because some clients (*cough* OS X
2016 NFS client *cough) might send retransmissions from a
2017 different port from the original request. */
2018 if (pinfo
->ptype
== PT_TCP
) {
2019 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
,
2020 &pinfo
->dst
, pinfo
->ptype
, pinfo
->srcport
,
2021 pinfo
->destport
, 0);
2024 * XXX - you currently still have to pass a non-null
2025 * pointer for the second address argument even
2026 * if you use NO_ADDR_B.
2028 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->dst
,
2029 &null_address
, pinfo
->ptype
, pinfo
->srcport
,
2030 0, NO_ADDR_B
|NO_PORT_B
);
2032 if (conversation
== NULL
) {
2033 /* We haven't seen an RPC call for that conversation,
2034 so we can't check for a reply to that call. */
2038 * Do we already have a state structure for this conv
2040 rpc_conv_info
= (rpc_conv_info_t
*)conversation_get_proto_data(conversation
, proto_rpc
);
2041 if (!rpc_conv_info
) {
2042 /* No. Attach that information to the conversation, and add
2043 * it to the list of information structures.
2045 rpc_conv_info
= wmem_new(wmem_file_scope(), rpc_conv_info_t
);
2046 rpc_conv_info
->xids
=wmem_tree_new(wmem_file_scope());
2048 conversation_add_proto_data(conversation
, proto_rpc
, rpc_conv_info
);
2051 /* The XIDs of the call and reply must match. */
2052 xid
= tvb_get_ntohl(tvb
, offset
);
2053 rpc_call
= (rpc_call_info_value
*)wmem_tree_lookup32(rpc_conv_info
->xids
, xid
);
2054 if (rpc_call
== NULL
) {
2055 /* The XID doesn't match a call from that
2056 conversation, so it's probably not an RPC reply. */
2058 /* unless we're permitted to scan for embedded records
2059 * and this is a connection-oriented transport, give up */
2060 if ((! rpc_find_fragment_start
) || (pinfo
->ptype
!= PT_TCP
)) {
2064 /* in parse-partials, so define a dummy conversation for this reply */
2065 rpc_call
= wmem_new(wmem_file_scope(), rpc_call_info_value
);
2066 rpc_call
->req_num
= 0;
2067 rpc_call
->rep_num
= pinfo
->fd
->num
;
2071 rpc_call
->private_data
= NULL
;
2072 rpc_call
->xid
= xid
;
2073 rpc_call
->flavor
= FLAVOR_NOT_GSSAPI
; /* total punt */
2074 rpc_call
->gss_proc
= 0;
2075 rpc_call
->gss_svc
= 0;
2076 rpc_call
->proc_info
= value
;
2077 rpc_call
->req_time
= pinfo
->fd
->abs_ts
;
2080 wmem_tree_insert32(rpc_conv_info
->xids
, xid
, (void *)rpc_call
);
2082 /* and fake up a matching program */
2083 rpc_prog_key
.prog
= rpc_call
->prog
;
2086 /* pass rpc_info to subdissectors */
2087 rpc_call
->request
=FALSE
;
2091 /* The putative message type field contains neither
2092 RPC_CALL nor RPC_REPLY, so it's not an RPC call or
2099 * This is RPC-over-TCP; check if this is the last
2102 if (!(rpc_rm
& RPC_RM_LASTFRAG
)) {
2104 * This isn't the last fragment.
2105 * If we're doing reassembly, just return
2106 * TRUE to indicate that this looks like
2107 * the beginning of an RPC message,
2108 * and let them do fragment reassembly.
2115 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RPC");
2117 rpc_item
= proto_tree_add_item(tree
, proto_rpc
, tvb
, 0, -1,
2119 rpc_tree
= proto_item_add_subtree(rpc_item
, ett_rpc
);
2122 show_rpc_fraginfo(tvb
, frag_tvb
, rpc_tree
, rpc_rm
,
2126 xid
= tvb_get_ntohl(tvb
, offset
);
2127 proto_tree_add_item(rpc_tree
,hf_rpc_xid
, tvb
,
2128 offset
, 4, ENC_BIG_ENDIAN
);
2130 msg_type_name
= val_to_str(msg_type
,rpc_msg_type
,"%u");
2132 proto_tree_add_uint(rpc_tree
, hf_rpc_msgtype
, tvb
,
2133 offset
+4, 4, msg_type
);
2134 proto_item_append_text(rpc_item
, ", Type:%s XID:0x%08x", msg_type_name
, xid
);
2142 /* we know already the proto-entry, the ETT-const,
2144 proto
= rpc_prog
->proto
;
2145 proto_id
= rpc_prog
->proto_id
;
2146 ett
= rpc_prog
->ett
;
2147 progname
= rpc_prog
->progname
;
2149 rpcvers
= tvb_get_ntohl(tvb
, offset
);
2151 proto_tree_add_uint(rpc_tree
,
2152 hf_rpc_version
, tvb
, offset
, 4, rpcvers
);
2155 prog
= tvb_get_ntohl(tvb
, offset
+ 4);
2158 proto_tree_add_uint_format_value(rpc_tree
,
2159 hf_rpc_program
, tvb
, offset
+4, 4, prog
,
2160 "%s (%u)", progname
, prog
);
2163 /* Set the protocol name to the underlying
2165 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, progname
);
2167 vers
= tvb_get_ntohl(tvb
, offset
+8);
2169 proto_tree_add_uint(rpc_tree
,
2170 hf_rpc_programversion
, tvb
, offset
+8, 4, vers
);
2173 proc
= tvb_get_ntohl(tvb
, offset
+12);
2179 if ((value
= (rpc_proc_info_value
*)g_hash_table_lookup(rpc_procs
,&key
)) != NULL
) {
2180 dissect_function
= value
->dissect_call
;
2181 procname
= (char *)value
->name
;
2184 /* happens only with strange program versions or
2185 non-existing dissectors */
2187 dissect_function
= NULL
;
2189 procname
=wmem_strdup_printf(wmem_packet_scope(), "proc-%u", proc
);
2192 /* Check for RPCSEC_GSS and AUTH_GSSAPI */
2193 if (tvb_bytes_exist(tvb
, offset
+16, 4)) {
2194 switch (tvb_get_ntohl(tvb
, offset
+16)) {
2198 * It's GSS-API authentication...
2200 if (tvb_bytes_exist(tvb
, offset
+28, 8)) {
2202 * ...and we have the procedure
2203 * and service information for it.
2205 flavor
= FLAVOR_GSSAPI
;
2206 gss_proc
= tvb_get_ntohl(tvb
, offset
+28);
2207 gss_svc
= tvb_get_ntohl(tvb
, offset
+36);
2210 * ...but the procedure and service
2211 * information isn't available.
2213 flavor
= FLAVOR_GSSAPI_NO_INFO
;
2219 * AUTH_GSSAPI flavor. If auth_msg is TRUE,
2220 * then this is an AUTH_GSSAPI message and
2221 * not an application level message.
2223 if (tvb_bytes_exist(tvb
, offset
+28, 4)) {
2224 if (tvb_get_ntohl(tvb
, offset
+28)) {
2225 flavor
= FLAVOR_AUTHGSSAPI_MSG
;
2228 val_to_str(gss_proc
,
2229 rpc_authgssapi_proc
, "Unknown (%d)");
2231 flavor
= FLAVOR_AUTHGSSAPI
;
2238 * It's not GSS-API authentication.
2240 flavor
= FLAVOR_NOT_GSSAPI
;
2246 proto_tree_add_uint_format_value(rpc_tree
,
2247 hf_rpc_procedure
, tvb
, offset
+12, 4, proc
,
2248 "%s (%u)", procname
, proc
);
2251 /* Print the program version, procedure name, and message type (call or reply). */
2253 col_clear(pinfo
->cinfo
, COL_INFO
);
2255 col_append_str(pinfo
->cinfo
, COL_INFO
, " ; ");
2256 /* Special case for NFSv4 - if the type is COMPOUND, do not print the procedure name */
2257 if (vers
==4 && prog
==NFS_PROGRAM
&& !strcmp(procname
, "COMPOUND"))
2258 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"V%u %s", vers
,
2261 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"V%u %s %s",
2262 vers
, procname
, msg_type_name
);
2264 /* Keep track of the address whence the call came, and the
2265 port to which the call is being sent, so that we can
2266 match up calls with replies.
2268 If the transport is connection-oriented (we check, for
2269 now, only for "pinfo->ptype" of PT_TCP), we also take
2270 into account the port from which the call was sent
2271 and the address to which the call was sent, because
2272 the addresses and ports of the two endpoints should be
2273 the same for all calls and replies. (XXX - what if
2274 the connection is broken and re-established?)
2276 If the transport is connectionless, we don't worry
2277 about the address to which the call was sent and from
2278 which the reply was sent, because there's no
2279 guarantee that the reply will come from the address
2280 to which the call was sent. We also don't worry about
2281 the port *from* which the call was sent and *to* which
2282 the reply was sent, because some clients (*cough* OS X
2283 NFS client *cough) might send retransmissions from a
2284 different port from the original request. */
2285 if (pinfo
->ptype
== PT_TCP
) {
2286 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
,
2287 &pinfo
->dst
, pinfo
->ptype
, pinfo
->srcport
,
2288 pinfo
->destport
, 0);
2291 * XXX - you currently still have to pass a non-null
2292 * pointer for the second address argument even
2293 * if you use NO_ADDR_B.
2295 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
,
2296 &null_address
, pinfo
->ptype
, pinfo
->destport
,
2297 0, NO_ADDR_B
|NO_PORT_B
);
2299 if (conversation
== NULL
) {
2300 /* It's not part of any conversation - create a new
2302 if (pinfo
->ptype
== PT_TCP
) {
2303 conversation
= conversation_new(pinfo
->fd
->num
, &pinfo
->src
,
2304 &pinfo
->dst
, pinfo
->ptype
, pinfo
->srcport
,
2305 pinfo
->destport
, 0);
2307 conversation
= conversation_new(pinfo
->fd
->num
, &pinfo
->src
,
2308 &null_address
, pinfo
->ptype
, pinfo
->destport
,
2309 0, NO_ADDR2
|NO_PORT2
);
2313 * Do we already have a state structure for this conv
2315 rpc_conv_info
= (rpc_conv_info_t
*)conversation_get_proto_data(conversation
, proto_rpc
);
2316 if (!rpc_conv_info
) {
2317 /* No. Attach that information to the conversation, and add
2318 * it to the list of information structures.
2320 rpc_conv_info
= wmem_new(wmem_file_scope(), rpc_conv_info_t
);
2321 rpc_conv_info
->xids
=wmem_tree_new(wmem_file_scope());
2322 conversation_add_proto_data(conversation
, proto_rpc
, rpc_conv_info
);
2326 /* Make the dissector for this conversation the non-heuristic
2328 conversation_set_dissector(conversation
,
2329 (pinfo
->ptype
== PT_TCP
) ? rpc_tcp_handle
: rpc_handle
);
2331 /* look up the request */
2332 rpc_call
= (rpc_call_info_value
*)wmem_tree_lookup32(rpc_conv_info
->xids
, xid
);
2334 /* We've seen a request with this XID, with the same
2335 source and destination, before - but was it
2337 if (pinfo
->fd
->num
!= rpc_call
->req_num
) {
2338 /* No, so it's a duplicate request.
2340 col_prepend_fstr(pinfo
->cinfo
, COL_INFO
,
2341 "[RPC retransmission of #%d]",
2343 proto_tree_add_item(rpc_tree
, hf_rpc_dup
, tvb
,
2345 proto_tree_add_uint(rpc_tree
, hf_rpc_call_dup
,
2346 tvb
, 0,0, rpc_call
->req_num
);
2348 if(rpc_call
->rep_num
){
2349 col_append_fstr(pinfo
->cinfo
, COL_INFO
," (Reply In %d)", rpc_call
->rep_num
);
2352 /* Prepare the value data.
2353 "req_num" and "rep_num" are frame numbers;
2354 frame numbers are 1-origin, so we use 0
2355 to mean "we don't yet know in which frame
2356 the reply for this call appears". */
2357 rpc_call
= wmem_new(wmem_file_scope(), rpc_call_info_value
);
2358 rpc_call
->req_num
= pinfo
->fd
->num
;
2359 rpc_call
->rep_num
= 0;
2360 rpc_call
->prog
= prog
;
2361 rpc_call
->vers
= vers
;
2362 rpc_call
->proc
= proc
;
2363 rpc_call
->private_data
= NULL
;
2364 rpc_call
->xid
= xid
;
2365 rpc_call
->flavor
= flavor
;
2366 rpc_call
->gss_proc
= gss_proc
;
2367 rpc_call
->gss_svc
= gss_svc
;
2368 rpc_call
->proc_info
= value
;
2369 rpc_call
->req_time
= pinfo
->fd
->abs_ts
;
2372 wmem_tree_insert32(rpc_conv_info
->xids
, xid
, (void *)rpc_call
);
2375 if(rpc_call
->rep_num
){
2376 proto_item
*tmp_item
;
2378 tmp_item
=proto_tree_add_uint_format(rpc_tree
, hf_rpc_reqframe
,
2379 tvb
, 0, 0, rpc_call
->rep_num
,
2380 "The reply to this request is in frame %u",
2382 PROTO_ITEM_SET_GENERATED(tmp_item
);
2387 offset
= dissect_rpc_cred(tvb
, rpc_tree
, offset
, pinfo
, rpc_conv_info
);
2388 /* pass rpc_info to subdissectors */
2389 rpc_call
->request
=TRUE
;
2391 if (gss_proc
== RPCSEC_GSS_DESTROY
) {
2392 /* there is no verifier for GSS destroy packets */
2396 offset
= dissect_rpc_verf(tvb
, rpc_tree
, offset
, msg_type
, pinfo
);
2398 /* go to the next dissector */
2400 break; /* end of RPC call */
2403 /* we know already the type from the calling routine,
2404 and we already have "rpc_call" set above. */
2405 prog
= rpc_call
->prog
;
2406 vers
= rpc_call
->vers
;
2407 proc
= rpc_call
->proc
;
2408 flavor
= rpc_call
->flavor
;
2409 gss_proc
= rpc_call
->gss_proc
;
2410 gss_svc
= rpc_call
->gss_svc
;
2412 if (rpc_call
->proc_info
!= NULL
) {
2413 dissect_function
= rpc_call
->proc_info
->dissect_reply
;
2414 if (rpc_call
->proc_info
->name
!= NULL
) {
2415 procname
= (char *)rpc_call
->proc_info
->name
;
2418 procname
=wmem_strdup_printf(wmem_packet_scope(), "proc-%u", proc
);
2423 dissect_function
= NULL
;
2425 procname
=wmem_strdup_printf(wmem_packet_scope(), "proc-%u", proc
);
2429 * If this is an AUTH_GSSAPI message, then the RPC procedure
2430 * is not an application procedure, but rather an auth level
2431 * procedure, so it would be misleading to print the RPC
2432 * procname. Replace the RPC procname with the corresponding
2433 * AUTH_GSSAPI procname.
2435 if (flavor
== FLAVOR_AUTHGSSAPI_MSG
) {
2436 procname
= (char *)val_to_str_const(gss_proc
, rpc_authgssapi_proc
, "(null)");
2439 rpc_prog_key
.prog
= prog
;
2440 if ((rpc_prog
= (rpc_prog_info_value
*)g_hash_table_lookup(rpc_progs
,&rpc_prog_key
)) == NULL
) {
2444 progname
= "Unknown";
2447 proto
= rpc_prog
->proto
;
2448 proto_id
= rpc_prog
->proto_id
;
2449 ett
= rpc_prog
->ett
;
2450 progname
= rpc_prog
->progname
;
2452 /* Set the protocol name to the underlying
2454 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, progname
);
2457 /* Print the program version, procedure name, and message type (call or reply). */
2459 col_clear(pinfo
->cinfo
, COL_INFO
);
2461 col_append_str(pinfo
->cinfo
, COL_INFO
, " ; ");
2462 /* Special case for NFSv4 - if the type is COMPOUND, do not print the procedure name */
2463 if (vers
==4 && prog
==NFS_PROGRAM
&& !strcmp(procname
, "COMPOUND"))
2464 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"V%u %s",
2465 vers
, msg_type_name
);
2467 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"V%u %s %s",
2468 vers
, procname
, msg_type_name
);
2471 proto_item
*tmp_item
;
2472 tmp_item
=proto_tree_add_uint_format_value(rpc_tree
,
2473 hf_rpc_program
, tvb
, 0, 0, prog
,
2474 "%s (%u)", progname
, prog
);
2475 PROTO_ITEM_SET_GENERATED(tmp_item
);
2476 tmp_item
=proto_tree_add_uint(rpc_tree
,
2477 hf_rpc_programversion
, tvb
, 0, 0, vers
);
2478 PROTO_ITEM_SET_GENERATED(tmp_item
);
2479 tmp_item
=proto_tree_add_uint_format_value(rpc_tree
,
2480 hf_rpc_procedure
, tvb
, 0, 0, proc
,
2481 "%s (%u)", procname
, proc
);
2482 PROTO_ITEM_SET_GENERATED(tmp_item
);
2485 reply_state
= tvb_get_ntohl(tvb
,offset
);
2487 proto_tree_add_uint(rpc_tree
, hf_rpc_state_reply
, tvb
,
2488 offset
, 4, reply_state
);
2492 /* Indicate the frame to which this is a reply. */
2493 if(rpc_call
&& rpc_call
->req_num
){
2494 proto_item
*tmp_item
;
2496 tmp_item
=proto_tree_add_uint_format(rpc_tree
, hf_rpc_repframe
,
2497 tvb
, 0, 0, rpc_call
->req_num
,
2498 "This is a reply to a request in frame %u",
2500 PROTO_ITEM_SET_GENERATED(tmp_item
);
2502 nstime_delta(&ns
, &pinfo
->fd
->abs_ts
, &rpc_call
->req_time
);
2503 tmp_item
=proto_tree_add_time(rpc_tree
, hf_rpc_time
, tvb
, offset
, 0,
2505 PROTO_ITEM_SET_GENERATED(tmp_item
);
2507 col_append_fstr(pinfo
->cinfo
, COL_INFO
," (Call In %d)", rpc_call
->req_num
);
2511 if ((!rpc_call
) || (rpc_call
->rep_num
== 0)) {
2512 /* We have not yet seen a reply to that call, so
2513 this must be the first reply; remember its
2515 rpc_call
->rep_num
= pinfo
->fd
->num
;
2517 /* We have seen a reply to this call - but was it
2519 if (rpc_call
->rep_num
!= pinfo
->fd
->num
) {
2520 proto_item
*tmp_item
;
2522 /* No, so it's a duplicate reply.
2524 col_prepend_fstr(pinfo
->cinfo
, COL_INFO
,
2525 "[RPC duplicate of #%d]", rpc_call
->rep_num
);
2526 tmp_item
=proto_tree_add_item(rpc_tree
,
2527 hf_rpc_dup
, tvb
, 0,0, ENC_NA
);
2528 PROTO_ITEM_SET_GENERATED(tmp_item
);
2530 tmp_item
=proto_tree_add_uint(rpc_tree
,
2531 hf_rpc_reply_dup
, tvb
, 0,0, rpc_call
->rep_num
);
2532 PROTO_ITEM_SET_GENERATED(tmp_item
);
2536 switch (reply_state
) {
2539 offset
= dissect_rpc_verf(tvb
, rpc_tree
, offset
, msg_type
, pinfo
);
2540 accept_state
= tvb_get_ntohl(tvb
,offset
);
2542 proto_tree_add_uint(rpc_tree
, hf_rpc_state_accept
, tvb
,
2543 offset
, 4, accept_state
);
2546 switch (accept_state
) {
2549 /* go to the next dissector */
2553 vers_low
= tvb_get_ntohl(tvb
,offset
);
2554 vers_high
= tvb_get_ntohl(tvb
,offset
+4);
2556 proto_tree_add_uint(rpc_tree
,
2557 hf_rpc_programversion_min
,
2558 tvb
, offset
, 4, vers_low
);
2559 proto_tree_add_uint(rpc_tree
,
2560 hf_rpc_programversion_max
,
2561 tvb
, offset
+4, 4, vers_high
);
2566 * There's no protocol reply, so don't
2567 * try to dissect it.
2569 dissect_rpc_flag
= FALSE
;
2574 * There's no protocol reply, so don't
2575 * try to dissect it.
2577 dissect_rpc_flag
= FALSE
;
2583 reject_state
= tvb_get_ntohl(tvb
,offset
);
2585 proto_tree_add_uint(rpc_tree
,
2586 hf_rpc_state_reject
, tvb
, offset
, 4,
2591 if (reject_state
==RPC_MISMATCH
) {
2592 vers_low
= tvb_get_ntohl(tvb
,offset
);
2593 vers_high
= tvb_get_ntohl(tvb
,offset
+4);
2595 proto_tree_add_uint(rpc_tree
,
2597 tvb
, offset
, 4, vers_low
);
2598 proto_tree_add_uint(rpc_tree
,
2600 tvb
, offset
+4, 4, vers_high
);
2603 } else if (reject_state
==AUTH_ERROR
) {
2604 auth_state
= tvb_get_ntohl(tvb
,offset
);
2606 proto_tree_add_uint(rpc_tree
,
2607 hf_rpc_state_auth
, tvb
, offset
, 4,
2614 * There's no protocol reply, so don't
2615 * try to dissect it.
2617 dissect_rpc_flag
= FALSE
;
2622 * This isn't a valid reply state, so we have
2623 * no clue what's going on; don't try to dissect
2624 * the protocol reply.
2626 dissect_rpc_flag
= FALSE
;
2629 break; /* end of RPC reply */
2633 * The switch statement at the top returned if
2634 * this was neither an RPC call nor a reply.
2636 DISSECTOR_ASSERT_NOT_REACHED();
2639 /* now we know, that RPC was shorter */
2642 THROW(ReportedBoundsError
);
2643 tvb_ensure_bytes_exist(tvb
, offset
, 0);
2644 proto_item_set_end(rpc_item
, tvb
, offset
);
2647 if (!dissect_rpc_flag
) {
2649 * There's no RPC call or reply here; just dissect
2650 * whatever's left as data.
2652 call_dissector(data_handle
,
2653 tvb_new_subset_remaining(tvb
, offset
), pinfo
, rpc_tree
);
2657 /* we must queue this packet to the tap system before we actually
2658 call the subdissectors since short packets (i.e. nfs read reply)
2659 will cause an exception and execution would never reach the call
2660 to tap_queue_packet() in that case
2662 tap_queue_packet(rpc_tap
, pinfo
, rpc_call
);
2665 /* If this is encrypted data we have to try to decrypt the data first before we
2667 * the reason for this is because if we can decrypt the data we must create the
2668 * item/tree for the next protocol using the decrypted tdb and not the current
2671 pinfo
->decrypt_gssapi_tvb
=DECRYPT_GSSAPI_NORMAL
;
2672 pinfo
->gssapi_wrap_tvb
=NULL
;
2673 pinfo
->gssapi_encrypted_tvb
=NULL
;
2674 pinfo
->gssapi_decrypted_tvb
=NULL
;
2675 if (flavor
== FLAVOR_GSSAPI
&& gss_proc
== RPCSEC_GSS_DATA
&& gss_svc
== RPCSEC_GSS_SVC_PRIVACY
) {
2676 proto_item
*gss_item
;
2677 proto_tree
*gss_tree
;
2679 gss_item
= proto_tree_add_text(tree
, tvb
, offset
, -1, "GSS-Wrap");
2680 gss_tree
= proto_item_add_subtree(gss_item
, ett_gss_wrap
);
2682 offset
= dissect_rpc_authgss_priv_data(tvb
, gss_tree
, offset
, pinfo
);
2683 if (pinfo
->gssapi_decrypted_tvb
) {
2684 proto_tree_add_item(gss_tree
, hf_rpc_authgss_seq
, pinfo
->gssapi_decrypted_tvb
, 0, 4, ENC_BIG_ENDIAN
);
2686 /* Switcheroo to the new tvb that contains the decrypted payload */
2687 tvb
= pinfo
->gssapi_decrypted_tvb
;
2693 /* create here the program specific sub-tree */
2694 if (tree
&& (flavor
!= FLAVOR_AUTHGSSAPI_MSG
)) {
2695 proto_item
*tmp_item
;
2697 pitem
= proto_tree_add_item(tree
, proto_id
, tvb
, offset
, -1, ENC_NA
);
2698 ptree
= proto_item_add_subtree(pitem
, ett
);
2700 tmp_item
=proto_tree_add_uint(ptree
,
2701 hf_rpc_programversion
, tvb
, 0, 0, vers
);
2702 PROTO_ITEM_SET_GENERATED(tmp_item
);
2703 if (rpc_prog
&& (rpc_prog
->procedure_hfs
->len
> vers
) )
2704 procedure_hf
= g_array_index(rpc_prog
->procedure_hfs
, int, vers
);
2707 * No such element in the GArray.
2711 if (procedure_hf
!= 0 && procedure_hf
!= -1) {
2712 tmp_item
=proto_tree_add_uint(ptree
,
2713 procedure_hf
, tvb
, 0, 0, proc
);
2714 PROTO_ITEM_SET_GENERATED(tmp_item
);
2716 tmp_item
=proto_tree_add_uint_format_value(ptree
,
2717 hf_rpc_procedure
, tvb
, 0, 0, proc
,
2718 "%s (%u)", procname
, proc
);
2719 PROTO_ITEM_SET_GENERATED(tmp_item
);
2723 /* proto==0 if this is an unknown program */
2724 if( (proto
==0) || !proto_is_protocol_enabled(proto
)){
2725 dissect_function
= NULL
;
2729 * Don't call any subdissector if we have no more date to dissect.
2731 if (tvb_length_remaining(tvb
, offset
) == 0) {
2736 * Handle RPCSEC_GSS and AUTH_GSSAPI specially.
2740 case FLAVOR_UNKNOWN
:
2742 * We don't know the authentication flavor, so we can't
2743 * dissect the payload.
2745 proto_tree_add_text(ptree
, tvb
, offset
, -1,
2746 "Unknown authentication flavor - cannot dissect");
2749 case FLAVOR_NOT_GSSAPI
:
2751 * It's not GSS-API authentication. Just dissect the
2754 offset
= call_dissect_function(tvb
, pinfo
, ptree
, offset
,
2755 dissect_function
, progname
, rpc_call
);
2758 case FLAVOR_GSSAPI_NO_INFO
:
2760 * It's GSS-API authentication, but we don't have the
2761 * procedure and service information, so we can't dissect
2764 proto_tree_add_text(ptree
, tvb
, offset
, -1,
2765 "GSS-API authentication, but procedure and service unknown - cannot dissect");
2770 * It's GSS-API authentication, and we have the procedure
2771 * and service information; process the GSS-API stuff,
2772 * and process the payload if there is any.
2776 case RPCSEC_GSS_INIT
:
2777 case RPCSEC_GSS_CONTINUE_INIT
:
2778 if (msg_type
== RPC_CALL
) {
2779 offset
= dissect_rpc_authgss_initarg(tvb
,
2780 ptree
, offset
, pinfo
);
2783 offset
= dissect_rpc_authgss_initres(tvb
,
2784 ptree
, offset
, pinfo
, rpc_conv_info
);
2788 case RPCSEC_GSS_DATA
:
2789 if (gss_svc
== RPCSEC_GSS_SVC_NONE
) {
2790 offset
= call_dissect_function(tvb
,
2791 pinfo
, ptree
, offset
,
2793 progname
, rpc_call
);
2795 else if (gss_svc
== RPCSEC_GSS_SVC_INTEGRITY
) {
2796 offset
= dissect_rpc_authgss_integ_data(tvb
,
2797 pinfo
, ptree
, offset
,
2799 progname
, rpc_call
);
2801 else if (gss_svc
== RPCSEC_GSS_SVC_PRIVACY
) {
2802 if (pinfo
->gssapi_decrypted_tvb
) {
2803 call_dissect_function(
2804 pinfo
->gssapi_decrypted_tvb
,
2807 progname
, rpc_call
);
2808 offset
= tvb_length(pinfo
->gssapi_decrypted_tvb
);
2818 case FLAVOR_AUTHGSSAPI_MSG
:
2820 * This is an AUTH_GSSAPI message. It contains data
2821 * only for the authentication procedure and not for the
2822 * application level RPC procedure. Reset the column
2823 * protocol and info fields to indicate that this is
2824 * an RPC auth level message, then process the args.
2826 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RPC");
2827 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
2829 val_to_str(gss_proc
, rpc_authgssapi_proc
, "Unknown (%d)"),
2830 msg_type_name
, xid
);
2834 case AUTH_GSSAPI_INIT
:
2835 case AUTH_GSSAPI_CONTINUE_INIT
:
2836 case AUTH_GSSAPI_MSG
:
2837 if (msg_type
== RPC_CALL
) {
2838 offset
= dissect_rpc_authgssapi_initarg(tvb
,
2839 rpc_tree
, offset
, pinfo
);
2841 offset
= dissect_rpc_authgssapi_initres(tvb
,
2842 rpc_tree
, offset
, pinfo
);
2846 case AUTH_GSSAPI_DESTROY
:
2847 offset
= dissect_rpc_data(tvb
, rpc_tree
,
2848 hf_rpc_authgss_data
, offset
);
2851 case AUTH_GSSAPI_EXIT
:
2855 /* Adjust the length to account for the auth message. */
2857 proto_item_set_end(rpc_item
, tvb
, offset
);
2861 case FLAVOR_AUTHGSSAPI
:
2863 * An RPC with AUTH_GSSAPI authentication. The data
2864 * portion is always private, so don't call the dissector.
2866 offset
= dissect_auth_gssapi_data(tvb
, ptree
, offset
);
2870 if (tvb_length_remaining(tvb
, offset
) > 0) {
2872 * dissect any remaining bytes (incomplete dissection) as pure
2876 call_dissector(data_handle
,
2877 tvb_new_subset_remaining(tvb
, offset
), pinfo
, ptree
);
2880 /* XXX this should really loop over all fhandles registred for the frame */
2881 if(nfs_fhandle_reqrep_matching
){
2884 if(rpc_call
&& rpc_call
->rep_num
){
2885 dissect_fhandle_hidden(pinfo
,
2886 ptree
, rpc_call
->rep_num
);
2890 if(rpc_call
&& rpc_call
->req_num
){
2891 dissect_fhandle_hidden(pinfo
,
2892 ptree
, rpc_call
->req_num
);
2902 dissect_rpc_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
2904 return dissect_rpc_message(tvb
, pinfo
, tree
, NULL
, NULL
, FALSE
, 0,
2909 dissect_rpc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
2911 if (!dissect_rpc_message(tvb
, pinfo
, tree
, NULL
, NULL
, FALSE
, 0,
2913 if (tvb_length(tvb
) != 0)
2914 dissect_rpc_continuation(tvb
, pinfo
, tree
);
2919 /* Defragmentation of RPC-over-TCP records */
2920 /* table to hold defragmented RPC records */
2921 static reassembly_table rpc_fragment_table
;
2924 * XXX - can we eliminate this by defining our own key-handling functions
2925 * for rpc_fragment_table? (Note that those functions must look at
2926 * not only the addresses of the endpoints, but the ports of the endpoints,
2927 * so that they don't try to combine fragments from different TCP
2930 static GHashTable
*rpc_reassembly_table
= NULL
;
2932 typedef struct _rpc_fragment_key
{
2942 rpc_fragment_hash(gconstpointer k
)
2944 const rpc_fragment_key
*key
= (const rpc_fragment_key
*)k
;
2946 return key
->conv_id
+ key
->seq
;
2950 rpc_fragment_equal(gconstpointer k1
, gconstpointer k2
)
2952 const rpc_fragment_key
*key1
= (const rpc_fragment_key
*)k1
;
2953 const rpc_fragment_key
*key2
= (const rpc_fragment_key
*)k2
;
2955 return key1
->conv_id
== key2
->conv_id
&&
2956 key1
->seq
== key2
->seq
&& key1
->port
== key2
->port
;
2960 show_rpc_fragheader(tvbuff_t
*tvb
, proto_tree
*tree
, guint32 rpc_rm
)
2962 proto_item
*hdr_item
;
2963 proto_tree
*hdr_tree
;
2967 fraglen
= rpc_rm
& RPC_RM_FRAGLEN
;
2969 hdr_item
= proto_tree_add_text(tree
, tvb
, 0, 4,
2970 "Fragment header: %s%u %s",
2971 (rpc_rm
& RPC_RM_LASTFRAG
) ? "Last fragment, " : "",
2972 fraglen
, plurality(fraglen
, "byte", "bytes"));
2973 hdr_tree
= proto_item_add_subtree(hdr_item
, ett_rpc_fraghdr
);
2975 proto_tree_add_boolean(hdr_tree
, hf_rpc_lastfrag
, tvb
, 0, 4,
2977 proto_tree_add_uint(hdr_tree
, hf_rpc_fraglen
, tvb
, 0, 4,
2983 show_rpc_fragment(tvbuff_t
*tvb
, proto_tree
*tree
, guint32 rpc_rm
)
2987 * Show the fragment header and the data for the fragment.
2989 show_rpc_fragheader(tvb
, tree
, rpc_rm
);
2990 proto_tree_add_text(tree
, tvb
, 4, -1, "Fragment Data");
2995 make_frag_tree(tvbuff_t
*tvb
, proto_tree
*tree
, int proto
, gint ett
,
2998 proto_item
*frag_item
;
2999 proto_tree
*frag_tree
;
3002 return; /* nothing to do */
3004 frag_item
= proto_tree_add_protocol_format(tree
, proto
, tvb
, 0, -1,
3005 "%s Fragment", proto_get_protocol_name(proto
));
3006 frag_tree
= proto_item_add_subtree(frag_item
, ett
);
3007 show_rpc_fragment(tvb
, frag_tree
, rpc_rm
);
3011 show_rpc_fraginfo(tvbuff_t
*tvb
, tvbuff_t
*frag_tvb
, proto_tree
*tree
,
3012 guint32 rpc_rm
, fragment_head
*ipfd_head
, packet_info
*pinfo
)
3014 proto_item
*frag_tree_item
;
3017 return; /* don't do any work */
3019 if (tvb
!= frag_tvb
) {
3021 * This message was not all in one fragment,
3022 * so show the fragment header *and* the data
3023 * for the fragment (which is the last fragment),
3024 * and a tree with information about all fragments.
3026 show_rpc_fragment(frag_tvb
, tree
, rpc_rm
);
3029 * Show a tree with information about all fragments.
3031 show_fragment_tree(ipfd_head
, &rpc_frag_items
, tree
, pinfo
, tvb
, &frag_tree_item
);
3034 * This message was all in one fragment, so just show
3035 * the fragment header.
3037 show_rpc_fragheader(tvb
, tree
, rpc_rm
);
3042 call_message_dissector(tvbuff_t
*tvb
, tvbuff_t
*rec_tvb
, packet_info
*pinfo
,
3043 proto_tree
*tree
, tvbuff_t
*frag_tvb
, rec_dissector_t dissector
,
3044 fragment_head
*ipfd_head
, guint32 rpc_rm
, gboolean first_pdu
)
3046 const char *saved_proto
;
3047 volatile gboolean rpc_succeeded
;
3050 saved_proto
= pinfo
->current_proto
;
3051 rpc_succeeded
= FALSE
;
3052 pd_save
= pinfo
->private_data
;
3054 rpc_succeeded
= (*dissector
)(rec_tvb
, pinfo
, tree
,
3055 frag_tvb
, ipfd_head
, TRUE
, rpc_rm
, first_pdu
);
3057 CATCH_NONFATAL_ERRORS
{
3059 * Somebody threw an exception that means that there
3060 * was a problem dissecting the payload; that means
3061 * that a dissector was found, so we don't need to
3062 * dissect the payload as data or update the protocol
3065 * Just show the exception and then continue dissecting.
3067 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
3068 pinfo
->current_proto
= saved_proto
;
3070 /* Restore the private_data structure in case one of the
3071 * called dissectors modified it (and, due to the exception,
3072 * was unable to restore it).
3074 pinfo
->private_data
= pd_save
;
3077 * We treat this as a "successful" dissection of
3078 * an RPC packet, as "dissect_rpc_message()"
3079 * *did* decide it was an RPC packet, throwing
3080 * an exception while dissecting it as such.
3082 rpc_succeeded
= TRUE
;
3085 return rpc_succeeded
;
3089 dissect_rpc_fragment(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
3090 proto_tree
*tree
, rec_dissector_t dissector
, gboolean is_heur
,
3091 int proto
, int ett
, gboolean defragment
, gboolean first_pdu
, struct tcpinfo
*tcpinfo
)
3095 volatile guint32 len
;
3097 gint tvb_len
, tvb_reported_len
;
3099 gboolean rpc_succeeded
;
3100 gboolean save_fragmented
;
3101 rpc_fragment_key old_rfk
, *rfk
, *new_rfk
;
3102 conversation_t
*conversation
;
3103 fragment_head
*ipfd_head
;
3106 if (pinfo
== NULL
|| tcpinfo
== NULL
) {
3110 seq
= tcpinfo
->seq
+ offset
;
3113 * Get the record mark.
3115 if (!tvb_bytes_exist(tvb
, offset
, 4)) {
3117 * XXX - we should somehow arrange to handle
3118 * a record mark split across TCP segments.
3120 return 0; /* not enough to tell if it's valid */
3122 rpc_rm
= tvb_get_ntohl(tvb
, offset
);
3124 len
= rpc_rm
& RPC_RM_FRAGLEN
;
3127 * Do TCP desegmentation, if enabled.
3129 * reject fragments bigger than this preference setting.
3130 * This is arbitrary, but should at least prevent
3131 * some crashes from either packets with really
3132 * large RPC-over-TCP fragments or from stuff that's
3133 * not really valid for this protocol.
3135 if (len
> max_rpc_tcp_pdu_size
)
3136 return 0; /* pretend it's not valid */
3137 if (rpc_desegment
) {
3138 seglen
= tvb_length_remaining(tvb
, offset
+ 4);
3140 if ((gint
)len
> seglen
&& pinfo
->can_desegment
) {
3142 * This frame doesn't have all of the
3143 * data for this message, but we can do
3146 * If this is a heuristic dissector, just
3147 * return 0 - we don't want to try to get
3148 * more data, as that's too likely to cause
3149 * us to misidentify this as valid.
3151 * XXX - this means that we won't
3152 * recognize the first fragment of a
3153 * multi-fragment RPC operation unless
3154 * we've already identified this
3155 * conversation as being an RPC
3156 * conversation (and thus aren't running
3157 * heuristically) - that would be a problem
3158 * if, for example, the first segment were
3159 * the beginning of a large NFS WRITE.
3161 * If this isn't a heuristic dissector,
3162 * we've already identified this conversation
3163 * as containing data for this protocol, as we
3164 * saw valid data in previous frames. Try to
3168 return 0; /* not valid */
3170 pinfo
->desegment_offset
= offset
;
3171 pinfo
->desegment_len
= len
- seglen
;
3172 return -((gint32
) pinfo
->desegment_len
);
3176 len
+= 4; /* include record mark */
3177 tvb_len
= tvb_length_remaining(tvb
, offset
);
3178 tvb_reported_len
= tvb_reported_length_remaining(tvb
, offset
);
3179 if (tvb_len
> (gint
)len
)
3181 if (tvb_reported_len
> (gint
)len
)
3182 tvb_reported_len
= len
;
3183 frag_tvb
= tvb_new_subset(tvb
, offset
, tvb_len
,
3187 * If we're not defragmenting, just hand this to the
3192 * This is the first fragment we've seen, and it's also
3193 * the last fragment; that means the record wasn't
3194 * fragmented. Hand the dissector the tvbuff for the
3195 * fragment as the tvbuff for the record.
3201 * Mark this as fragmented, so if somebody throws an
3202 * exception, we don't report it as a malformed frame.
3204 save_fragmented
= pinfo
->fragmented
;
3205 pinfo
->fragmented
= TRUE
;
3206 rpc_succeeded
= call_message_dissector(tvb
, rec_tvb
, pinfo
,
3207 tree
, frag_tvb
, dissector
, ipfd_head
, rpc_rm
, first_pdu
);
3208 pinfo
->fragmented
= save_fragmented
;
3210 return 0; /* not RPC */
3215 * First, we check to see if this fragment is part of a record
3216 * that we're in the process of defragmenting.
3218 * The key is the conversation ID for the conversation to which
3219 * the packet belongs and the current sequence number.
3220 * We must first find the conversation and, if we don't find
3221 * one, create it. We know this is running over TCP, so the
3222 * conversation should not wildcard either address or port.
3224 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
3225 pinfo
->ptype
, pinfo
->srcport
, pinfo
->destport
, 0);
3226 if (conversation
== NULL
) {
3228 * It's not part of any conversation - create a new one.
3230 conversation
= conversation_new(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
3231 pinfo
->ptype
, pinfo
->srcport
, pinfo
->destport
, 0);
3233 old_rfk
.conv_id
= conversation
->index
;
3235 old_rfk
.port
= pinfo
->srcport
;
3236 rfk
= (rpc_fragment_key
*)g_hash_table_lookup(rpc_reassembly_table
, &old_rfk
);
3240 * This fragment was not found in our table, so it doesn't
3241 * contain a continuation of a higher-level PDU.
3242 * Is it the last fragment?
3244 if (!(rpc_rm
& RPC_RM_LASTFRAG
)) {
3246 * This isn't the last fragment, so we don't
3247 * have the complete record.
3249 * It's the first fragment we've seen, so if
3250 * it's truly the first fragment of the record,
3251 * and it has enough data, the dissector can at
3252 * least check whether it looks like a valid
3253 * message, as it contains the start of the
3256 * The dissector should not dissect anything
3257 * if the "last fragment" flag isn't set in
3258 * the record marker, so it shouldn't throw
3261 if (!(*dissector
)(frag_tvb
, pinfo
, tree
, frag_tvb
,
3262 NULL
, TRUE
, rpc_rm
, first_pdu
))
3263 return 0; /* not valid */
3266 * OK, now start defragmentation with that
3267 * fragment. Add this fragment, and set up
3268 * next packet/sequence number as well.
3270 * We must remember this fragment.
3273 rfk
= wmem_new(wmem_file_scope(), rpc_fragment_key
);
3274 rfk
->conv_id
= conversation
->index
;
3276 rfk
->port
= pinfo
->srcport
;
3278 rfk
->start_seq
= seq
;
3279 g_hash_table_insert(rpc_reassembly_table
, rfk
, rfk
);
3282 * Start defragmentation.
3284 ipfd_head
= fragment_add_multiple_ok(&rpc_fragment_table
,
3286 pinfo
, rfk
->start_seq
, NULL
,
3287 rfk
->offset
, len
- 4, TRUE
);
3290 * Make sure that defragmentation isn't complete;
3291 * it shouldn't be, as this is the first fragment
3292 * we've seen, and the "last fragment" bit wasn't
3295 if (ipfd_head
== NULL
) {
3296 new_rfk
= wmem_new(wmem_file_scope(), rpc_fragment_key
);
3297 new_rfk
->conv_id
= rfk
->conv_id
;
3298 new_rfk
->seq
= seq
+ len
;
3299 new_rfk
->port
= pinfo
->srcport
;
3300 new_rfk
->offset
= rfk
->offset
+ len
- 4;
3301 new_rfk
->start_seq
= rfk
->start_seq
;
3302 g_hash_table_insert(rpc_reassembly_table
, new_rfk
,
3306 * This is part of a fragmented record,
3307 * but it's not the first part.
3308 * Show it as a record marker plus data, under
3309 * a top-level tree for this protocol.
3311 make_frag_tree(frag_tvb
, tree
, proto
, ett
,rpc_rm
);
3314 * No more processing need be done, as we don't
3315 * have a complete record.
3319 /* oddly, we have a first fragment, not marked as last,
3320 * but which the defragmenter thinks is complete.
3321 * So rather than creating a fragment reassembly tree,
3322 * we simply throw away the partial fragment structure
3323 * and fall though to our "sole fragment" processing below.
3329 * This is the first fragment we've seen, and it's also
3330 * the last fragment; that means the record wasn't
3331 * fragmented. Hand the dissector the tvbuff for the
3332 * fragment as the tvbuff for the record.
3338 * OK, this fragment was found, which means it continues
3339 * a record. This means we must defragment it.
3340 * Add it to the defragmentation lists.
3342 ipfd_head
= fragment_add_multiple_ok(&rpc_fragment_table
,
3343 tvb
, offset
+ 4, pinfo
, rfk
->start_seq
, NULL
,
3344 rfk
->offset
, len
- 4, !(rpc_rm
& RPC_RM_LASTFRAG
));
3346 if (ipfd_head
== NULL
) {
3348 * fragment_add_multiple_ok() returned NULL.
3349 * This means that defragmentation is not
3352 * We must add an entry to the hash table with
3353 * the sequence number following this fragment
3354 * as the starting sequence number, so that when
3355 * we see that fragment we'll find that entry.
3357 * XXX - as TCP stream data is not currently
3358 * guaranteed to be provided in order to dissectors,
3359 * RPC fragments aren't guaranteed to be provided
3362 new_rfk
= wmem_new(wmem_file_scope(), rpc_fragment_key
);
3363 new_rfk
->conv_id
= rfk
->conv_id
;
3364 new_rfk
->seq
= seq
+ len
;
3365 new_rfk
->port
= pinfo
->srcport
;
3366 new_rfk
->offset
= rfk
->offset
+ len
- 4;
3367 new_rfk
->start_seq
= rfk
->start_seq
;
3368 g_hash_table_insert(rpc_reassembly_table
, new_rfk
,
3372 * This is part of a fragmented record,
3373 * but it's not the first part.
3374 * Show it as a record marker plus data, under
3375 * a top-level tree for this protocol,
3376 * but don't hand it to the dissector
3378 make_frag_tree(frag_tvb
, tree
, proto
, ett
, rpc_rm
);
3381 * No more processing need be done, as we don't
3382 * have a complete record.
3388 * It's completely defragmented.
3390 * We only call subdissector for the last fragment.
3391 * XXX - this assumes in-order delivery of RPC
3392 * fragments, which requires in-order delivery of TCP
3395 if (!(rpc_rm
& RPC_RM_LASTFRAG
)) {
3397 * Well, it's defragmented, but this isn't
3398 * the last fragment; this probably means
3399 * this isn't the first pass, so we don't
3400 * need to start defragmentation.
3402 * This is part of a fragmented record,
3403 * but it's not the first part.
3404 * Show it as a record marker plus data, under
3405 * a top-level tree for this protocol,
3406 * but don't show it to the dissector.
3408 make_frag_tree(frag_tvb
, tree
, proto
, ett
, rpc_rm
);
3411 * No more processing need be done, as we
3412 * only disssect the data with the last
3419 * OK, this is the last segment.
3420 * Create a tvbuff for the defragmented
3425 * Create a new TVB structure for
3426 * defragmented data.
3428 rec_tvb
= tvb_new_chain(tvb
, ipfd_head
->tvb_data
);
3431 * Add defragmented data to the data source list.
3433 add_new_data_source(pinfo
, rec_tvb
, "Defragmented");
3437 * We have something to hand to the RPC message
3440 if (!call_message_dissector(tvb
, rec_tvb
, pinfo
, tree
,
3441 frag_tvb
, dissector
, ipfd_head
, rpc_rm
, first_pdu
))
3442 return 0; /* not RPC */
3444 } /* end of dissect_rpc_fragment() */
3447 * Scans tvb, starting at given offset, to see if we can find
3448 * what looks like a valid RPC-over-TCP reply header.
3450 * @param tvb Buffer to inspect for RPC reply header.
3451 * @param offset Offset to begin search of tvb at.
3453 * @return -1 if no reply header found, else offset to start of header
3454 * (i.e., to the RPC record mark field).
3458 find_rpc_over_tcp_reply_start(tvbuff_t
*tvb
, int offset
)
3462 * Looking for partial header sequence. From beginning of
3463 * stream-style header, including "record mark", full ONC-RPC
3465 * BE int32 record mark (rfc 1831 sec. 10)
3466 * ? int32 XID (rfc 1831 sec. 8)
3467 * BE int32 msg_type (ibid sec. 8, call = 0, reply = 1)
3469 * -------------------------------------------------------------
3470 * Then reply-specific fields are
3471 * BE int32 reply_stat (ibid, accept = 0, deny = 1)
3473 * Then, assuming accepted,
3475 * BE int32 auth_flavor (ibid, none = 0)
3476 * BE int32 ? auth_len (ibid, none = 0)
3478 * BE int32 accept_stat (ibid, success = 0, errs are 1..5 in rpc v2)
3480 * -------------------------------------------------------------
3481 * Or, call-specific fields are
3482 * BE int32 rpc_vers (rfc 1831 sec 8, always == 2)
3483 * BE int32 prog (NFS == 000186A3)
3484 * BE int32 prog_ver (NFS v2/3 == 2 or 3)
3485 * BE int32 proc_id (NFS, <= 256 ???)
3490 /* Initially, we search only for something matching the template
3491 * of a successful reply with no auth verifier.
3492 * Our first qualification test is search for a string of zero bytes,
3493 * corresponding the four guint32 values
3499 * If this string of zeros matches, then we go back and check the
3500 * preceding msg_type and record_mark fields.
3503 const gint cbZeroTail
= 4 * 4; /* four guint32s of zeros */
3504 const gint ibPatternStart
= 3 * 4; /* offset of zero fill from reply start */
3505 const guint8
* pbWholeBuf
; /* all of tvb, from offset onwards */
3506 const int NoMatch
= -1;
3508 gint ibSearchStart
; /* offset of search start, in case of false hits. */
3510 const guint8
* pbBuf
;
3512 gint cbInBuf
; /* bytes in tvb, from offset onwards */
3520 cbInBuf
= tvb_reported_length_remaining(tvb
, offset
);
3522 /* start search at first possible location */
3523 ibSearchStart
= ibPatternStart
;
3525 if (cbInBuf
< (cbZeroTail
+ ibSearchStart
)) {
3526 /* nothing to search, so claim no RPC */
3530 pbWholeBuf
= tvb_get_ptr(tvb
, offset
, cbInBuf
);
3531 if (pbWholeBuf
== NULL
) {
3532 /* probably never take this, as get_ptr seems to assert */
3536 while ((cbInBuf
- ibSearchStart
) > cbZeroTail
) {
3537 /* First test for long tail of zeros, starting at the back.
3538 * A failure lets us skip the maximum possible buffer amount.
3540 pbBuf
= pbWholeBuf
+ ibSearchStart
+ cbZeroTail
- 1;
3541 for (i
= cbZeroTail
; i
> 0; i
--)
3545 /* match failure. Since we need N contiguous zeros,
3546 * we can increment next match start so zero testing
3547 * begins right after this failure spot.
3557 if (pbBuf
== NULL
) {
3561 /* got a match in zero-fill region, verify reply ID and
3562 * record mark fields */
3563 ulMsgType
= pntohl (pbWholeBuf
+ ibSearchStart
- 4);
3564 ulRecMark
= pntohl (pbWholeBuf
+ ibSearchStart
- ibPatternStart
);
3566 if ((ulMsgType
== RPC_REPLY
) &&
3567 ((ulRecMark
& ~0x80000000) <= (unsigned) max_rpc_tcp_pdu_size
)) {
3568 /* looks ok, try dissect */
3569 return (offset
+ ibSearchStart
- ibPatternStart
);
3572 /* no match yet, nor egregious miss either. Inch along to next try */
3578 } /* end of find_rpc_over_tcp_reply_start() */
3581 * Scans tvb for what looks like a valid RPC call / reply header.
3582 * If found, calls standard dissect_rpc_fragment() logic to digest
3583 * the (hopefully valid) fragment.
3585 * With any luck, one invocation of this will be sufficient to get
3586 * us back in alignment with the stream, and no further calls to
3587 * this routine will be needed for a given conversation. As if. :-)
3590 * Same as dissect_rpc_fragment(). Will return zero (no frame)
3591 * if no valid RPC header is found.
3595 find_and_dissect_rpc_fragment(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
3596 proto_tree
*tree
, rec_dissector_t dissector
,
3598 int proto
, int ett
, gboolean defragment
, struct tcpinfo
* tcpinfo
)
3604 offReply
= find_rpc_over_tcp_reply_start(tvb
, offset
);
3606 /* could search for request, but not needed (or testable) thus far */
3607 return (0); /* claim no RPC */
3610 len
= dissect_rpc_fragment(tvb
, offReply
,
3612 dissector
, is_heur
, proto
, ett
,
3614 TRUE
/* force first-pdu state */, tcpinfo
);
3616 /* misses are reported as-is */
3622 /* returning a non-zero length, correct it to reflect the extra offset
3623 * we found necessary
3626 len
+= offReply
- offset
;
3629 /* negative length seems to only be used as a flag,
3630 * don't mess it up until found necessary
3632 /* len -= offReply - offset; */
3637 } /* end of find_and_dissect_rpc_fragment */
3643 * NEED_MORE_DATA, if we don't have enough data to dissect anything;
3645 * IS_RPC, if we dissected at least one message in its entirety
3648 * IS_NOT_RPC, if we found no RPC message.
3656 static rpc_tcp_return_t
3657 dissect_rpc_tcp_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
3658 gboolean is_heur
, struct tcpinfo
* tcpinfo
)
3661 gboolean saw_rpc
= FALSE
;
3662 gboolean first_pdu
= TRUE
;
3665 while (tvb_reported_length_remaining(tvb
, offset
) != 0) {
3667 * Process this fragment.
3669 len
= dissect_rpc_fragment(tvb
, offset
, pinfo
, tree
,
3670 dissect_rpc_message
, is_heur
, proto_rpc
, ett_rpc
,
3671 rpc_defragment
, first_pdu
, tcpinfo
);
3673 if ((len
== 0) && first_pdu
&& rpc_find_fragment_start
) {
3675 * Try discarding some leading bytes from tvb, on assumption
3676 * that we are looking at the middle of a stream-based transfer
3678 len
= find_and_dissect_rpc_fragment(tvb
, offset
, pinfo
, tree
,
3679 dissect_rpc_message
, is_heur
, proto_rpc
, ett_rpc
,
3680 rpc_defragment
, tcpinfo
);
3686 * We need more data from the TCP stream for
3689 return NEED_MORE_DATA
;
3693 * It's not RPC. Stop processing.
3698 /* Set a fence so whatever the subdissector put in the
3699 * Info column stays there. This is useful when the
3700 * subdissector clears the column (which it might have to do
3701 * if it runs over some other protocol too) and there are
3702 * multiple PDUs in one frame.
3704 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3707 If the length indicates that the PDU continues beyond
3708 the end of this tvb, then tell TCP about it so that it
3709 knows where the next PDU starts.
3710 This is to help TCP detect when PDUs are not aligned to
3711 segment boundaries and allow it to find RPC headers
3712 that starts in the middle of a TCP segment.
3714 if(!pinfo
->fd
->flags
.visited
){
3715 if(len
>tvb_reported_length_remaining(tvb
, offset
)){
3716 pinfo
->want_pdu_tracking
=2;
3717 pinfo
->bytes_until_next_pdu
=len
-tvb_reported_length_remaining(tvb
, offset
);
3723 return saw_rpc
? IS_RPC
: IS_NOT_RPC
;
3727 dissect_rpc_tcp_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
3729 struct tcpinfo
* tcpinfo
= (struct tcpinfo
*)data
;
3731 switch (dissect_rpc_tcp_common(tvb
, pinfo
, tree
, TRUE
, tcpinfo
)) {
3740 /* "Can't happen" */
3741 DISSECTOR_ASSERT_NOT_REACHED();
3747 dissect_rpc_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
3749 struct tcpinfo
* tcpinfo
= (struct tcpinfo
*)data
;
3751 if (dissect_rpc_tcp_common(tvb
, pinfo
, tree
, FALSE
, tcpinfo
) == IS_NOT_RPC
)
3752 dissect_rpc_continuation(tvb
, pinfo
, tree
);
3754 return tvb_length(tvb
);
3757 /* Discard any state we've saved. */
3759 rpc_init_protocol(void)
3761 if (rpc_reassembly_table
!= NULL
) {
3762 g_hash_table_destroy(rpc_reassembly_table
);
3763 rpc_reassembly_table
= NULL
;
3766 rpc_reassembly_table
= g_hash_table_new(rpc_fragment_hash
,
3767 rpc_fragment_equal
);
3769 reassembly_table_init(&rpc_fragment_table
,
3770 &addresses_ports_reassembly_table_functions
);
3773 /* will be called once from register.c at startup time */
3775 proto_register_rpc(void)
3777 static hf_register_info hf
[] = {
3778 { &hf_rpc_reqframe
, {
3779 "Request Frame", "rpc.reqframe", FT_FRAMENUM
, BASE_NONE
,
3780 NULL
, 0, NULL
, HFILL
}},
3781 { &hf_rpc_repframe
, {
3782 "Reply Frame", "rpc.repframe", FT_FRAMENUM
, BASE_NONE
,
3783 NULL
, 0, NULL
, HFILL
}},
3784 { &hf_rpc_lastfrag
, {
3785 "Last Fragment", "rpc.lastfrag", FT_BOOLEAN
, 32,
3786 TFS(&tfs_yes_no
), RPC_RM_LASTFRAG
, NULL
, HFILL
}},
3787 { &hf_rpc_fraglen
, {
3788 "Fragment Length", "rpc.fraglen", FT_UINT32
, BASE_DEC
,
3789 NULL
, RPC_RM_FRAGLEN
, NULL
, HFILL
}},
3791 "XID", "rpc.xid", FT_UINT32
, BASE_HEX_DEC
,
3792 NULL
, 0, NULL
, HFILL
}},
3793 { &hf_rpc_msgtype
, {
3794 "Message Type", "rpc.msgtyp", FT_UINT32
, BASE_DEC
,
3795 VALS(rpc_msg_type
), 0, NULL
, HFILL
}},
3796 { &hf_rpc_state_reply
, {
3797 "Reply State", "rpc.replystat", FT_UINT32
, BASE_DEC
,
3798 VALS(rpc_reply_state
), 0, NULL
, HFILL
}},
3799 { &hf_rpc_state_accept
, {
3800 "Accept State", "rpc.state_accept", FT_UINT32
, BASE_DEC
,
3801 VALS(rpc_accept_state
), 0, NULL
, HFILL
}},
3802 { &hf_rpc_state_reject
, {
3803 "Reject State", "rpc.state_reject", FT_UINT32
, BASE_DEC
,
3804 VALS(rpc_reject_state
), 0, NULL
, HFILL
}},
3805 { &hf_rpc_state_auth
, {
3806 "Auth State", "rpc.state_auth", FT_UINT32
, BASE_DEC
,
3807 VALS(rpc_auth_state
), 0, NULL
, HFILL
}},
3808 { &hf_rpc_version
, {
3809 "RPC Version", "rpc.version", FT_UINT32
, BASE_DEC
,
3810 NULL
, 0, NULL
, HFILL
}},
3811 { &hf_rpc_version_min
, {
3812 "RPC Version (Minimum)", "rpc.version.min", FT_UINT32
,
3813 BASE_DEC
, NULL
, 0, "Program Version (Minimum)", HFILL
}},
3814 { &hf_rpc_version_max
, {
3815 "RPC Version (Maximum)", "rpc.version.max", FT_UINT32
,
3816 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3817 { &hf_rpc_program
, {
3818 "Program", "rpc.program", FT_UINT32
, BASE_DEC
,
3819 NULL
, 0, NULL
, HFILL
}},
3820 { &hf_rpc_programversion
, {
3821 "Program Version", "rpc.programversion", FT_UINT32
,
3822 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3823 { &hf_rpc_programversion_min
, {
3824 "Program Version (Minimum)", "rpc.programversion.min", FT_UINT32
,
3825 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3826 { &hf_rpc_programversion_max
, {
3827 "Program Version (Maximum)", "rpc.programversion.max", FT_UINT32
,
3828 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3829 { &hf_rpc_procedure
, {
3830 "Procedure", "rpc.procedure", FT_UINT32
, BASE_DEC
,
3831 NULL
, 0, NULL
, HFILL
}},
3832 { &hf_rpc_auth_flavor
, {
3833 "Flavor", "rpc.auth.flavor", FT_UINT32
, BASE_DEC
,
3834 VALS(rpc_auth_flavor
), 0, NULL
, HFILL
}},
3835 { &hf_rpc_auth_length
, {
3836 "Length", "rpc.auth.length", FT_UINT32
, BASE_DEC
,
3837 NULL
, 0, NULL
, HFILL
}},
3838 { &hf_rpc_auth_stamp
, {
3839 "Stamp", "rpc.auth.stamp", FT_UINT32
, BASE_HEX
,
3840 NULL
, 0, NULL
, HFILL
}},
3841 { &hf_rpc_auth_lk_owner
, {
3842 "Lock Owner", "rpc.auth.lk_owner", FT_BYTES
, BASE_NONE
,
3843 NULL
, 0, NULL
, HFILL
}},
3844 { &hf_rpc_auth_pid
, {
3845 "PID", "rpc.auth.pid", FT_UINT32
, BASE_DEC
,
3846 NULL
, 0, NULL
, HFILL
}},
3847 { &hf_rpc_auth_uid
, {
3848 "UID", "rpc.auth.uid", FT_UINT32
, BASE_DEC
,
3849 NULL
, 0, NULL
, HFILL
}},
3850 { &hf_rpc_auth_gid
, {
3851 "GID", "rpc.auth.gid", FT_UINT32
, BASE_DEC
,
3852 NULL
, 0, NULL
, HFILL
}},
3853 { &hf_rpc_authgss_v
, {
3854 "GSS Version", "rpc.authgss.version", FT_UINT32
,
3855 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3856 { &hf_rpc_authgss_proc
, {
3857 "GSS Procedure", "rpc.authgss.procedure", FT_UINT32
,
3858 BASE_DEC
, VALS(rpc_authgss_proc
), 0, NULL
, HFILL
}},
3859 { &hf_rpc_authgss_seq
, {
3860 "GSS Sequence Number", "rpc.authgss.seqnum", FT_UINT32
,
3861 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3862 { &hf_rpc_authgss_svc
, {
3863 "GSS Service", "rpc.authgss.service", FT_UINT32
,
3864 BASE_DEC
, VALS(rpc_authgss_svc
), 0, NULL
, HFILL
}},
3865 { &hf_rpc_authgss_ctx
, {
3866 "GSS Context", "rpc.authgss.context", FT_BYTES
,
3867 BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3868 { &hf_rpc_authgss_ctx_create_frame
, {
3869 "Created in frame", "rpc.authgss.context.created_frame", FT_FRAMENUM
,
3870 BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3871 { &hf_rpc_authgss_ctx_destroy_frame
, {
3872 "Destroyed in frame", "rpc.authgss.context.destroyed_frame", FT_FRAMENUM
,
3873 BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3874 { &hf_rpc_authgss_ctx_len
, {
3875 "GSS Context Length", "rpc.authgss.context.length", FT_UINT32
,
3876 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3877 { &hf_rpc_authgss_major
, {
3878 "GSS Major Status", "rpc.authgss.major", FT_UINT32
,
3879 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3880 { &hf_rpc_authgss_minor
, {
3881 "GSS Minor Status", "rpc.authgss.minor", FT_UINT32
,
3882 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3883 { &hf_rpc_authgss_window
, {
3884 "GSS Sequence Window", "rpc.authgss.window", FT_UINT32
,
3885 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3886 { &hf_rpc_authgss_token_length
, {
3887 "GSS Token Length", "rpc.authgss.token_length", FT_UINT32
,
3888 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3889 { &hf_rpc_authgss_data_length
, {
3890 "Length", "rpc.authgss.data.length", FT_UINT32
,
3891 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
3892 { &hf_rpc_authgss_data
, {
3893 "GSS Data", "rpc.authgss.data", FT_BYTES
,
3894 BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3895 { &hf_rpc_authgss_checksum
, {
3896 "GSS Checksum", "rpc.authgss.checksum", FT_BYTES
,
3897 BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3898 { &hf_rpc_authgss_token
, {
3899 "GSS Token", "rpc.authgss.token", FT_BYTES
,
3900 BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3901 { &hf_rpc_authgssapi_v
, {
3902 "AUTH_GSSAPI Version", "rpc.authgssapi.version",
3903 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
,
3905 { &hf_rpc_authgssapi_msg
, {
3906 "AUTH_GSSAPI Message", "rpc.authgssapi.message",
3907 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0, NULL
,
3909 { &hf_rpc_authgssapi_msgv
, {
3910 "Msg Version", "rpc.authgssapi.msgversion",
3911 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
,
3913 { &hf_rpc_authgssapi_handle
, {
3914 "Client Handle", "rpc.authgssapi.handle",
3915 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3916 { &hf_rpc_authgssapi_isn
, {
3917 "Signed ISN", "rpc.authgssapi.isn",
3918 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3919 { &hf_rpc_authdes_namekind
, {
3920 "Namekind", "rpc.authdes.namekind", FT_UINT32
, BASE_DEC
,
3921 VALS(rpc_authdes_namekind
), 0, NULL
, HFILL
}},
3922 { &hf_rpc_authdes_netname
, {
3923 "Netname", "rpc.authdes.netname", FT_STRING
,
3924 BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3925 { &hf_rpc_authdes_convkey
, {
3926 "Conversation Key (encrypted)", "rpc.authdes.convkey", FT_UINT32
,
3927 BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
3928 { &hf_rpc_authdes_window
, {
3929 "Window (encrypted)", "rpc.authdes.window", FT_UINT32
,
3930 BASE_HEX
, NULL
, 0, "Windows (encrypted)", HFILL
}},
3931 { &hf_rpc_authdes_nickname
, {
3932 "Nickname", "rpc.authdes.nickname", FT_UINT32
,
3933 BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
3934 { &hf_rpc_authdes_timestamp
, {
3935 "Timestamp (encrypted)", "rpc.authdes.timestamp", FT_UINT32
,
3936 BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
3937 { &hf_rpc_authdes_windowverf
, {
3938 "Window verifier (encrypted)", "rpc.authdes.windowverf", FT_UINT32
,
3939 BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
3940 { &hf_rpc_authdes_timeverf
, {
3941 "Timestamp verifier (encrypted)", "rpc.authdes.timeverf", FT_UINT32
,
3942 BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
3943 { &hf_rpc_auth_machinename
, {
3944 "Machine Name", "rpc.auth.machinename", FT_STRING
,
3945 BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
3947 "Duplicate Call/Reply", "rpc.dup", FT_NONE
, BASE_NONE
,
3948 NULL
, 0, NULL
, HFILL
}},
3949 { &hf_rpc_call_dup
, {
3950 "Duplicate to the call in", "rpc.call.dup", FT_FRAMENUM
, BASE_NONE
,
3951 NULL
, 0, "This is a duplicate to the call in frame", HFILL
}},
3952 { &hf_rpc_reply_dup
, {
3953 "Duplicate to the reply in", "rpc.reply.dup", FT_FRAMENUM
, BASE_NONE
,
3954 NULL
, 0, "This is a duplicate to the reply in frame", HFILL
}},
3955 { &hf_rpc_value_follows
, {
3956 "Value Follows", "rpc.value_follows", FT_BOOLEAN
, BASE_NONE
,
3957 TFS(&tfs_yes_no
), 0x0, NULL
, HFILL
}},
3958 { &hf_rpc_array_len
, {
3959 "num", "rpc.array.len", FT_UINT32
, BASE_DEC
,
3960 NULL
, 0, "Length of RPC array", HFILL
}},
3963 "Time from request", "rpc.time", FT_RELATIVE_TIME
, BASE_NONE
,
3964 NULL
, 0, "Time between Request and Reply for ONC-RPC calls", HFILL
}},
3966 { &hf_rpc_fragment_overlap
,
3967 { "Fragment overlap", "rpc.fragment.overlap", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
3968 "Fragment overlaps with other fragments", HFILL
}},
3970 { &hf_rpc_fragment_overlap_conflict
,
3971 { "Conflicting data in fragment overlap", "rpc.fragment.overlap.conflict", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
3972 "Overlapping fragments contained conflicting data", HFILL
}},
3974 { &hf_rpc_fragment_multiple_tails
,
3975 { "Multiple tail fragments found", "rpc.fragment.multipletails", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
3976 "Several tails were found when defragmenting the packet", HFILL
}},
3978 { &hf_rpc_fragment_too_long_fragment
,
3979 { "Fragment too long", "rpc.fragment.toolongfragment", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
3980 "Fragment contained data past end of packet", HFILL
}},
3982 { &hf_rpc_fragment_error
,
3983 { "Defragmentation error", "rpc.fragment.error", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
3984 "Defragmentation error due to illegal fragments", HFILL
}},
3986 { &hf_rpc_fragment_count
,
3987 { "Fragment count", "rpc.fragment.count", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3991 { "RPC Fragment", "rpc.fragment", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
3994 { &hf_rpc_fragments
,
3995 { "RPC Fragments", "rpc.fragments", FT_NONE
, BASE_NONE
, NULL
, 0x0,
3998 { &hf_rpc_reassembled_length
,
3999 { "Reassembled RPC length", "rpc.reassembled.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4000 "The total length of the reassembled payload", HFILL
}},
4003 static gint
*ett
[] = {
4015 &ett_rpc_authgssapi_msg
,
4016 &ett_rpc_unknown_program
,
4020 module_t
*rpc_module
;
4022 proto_rpc
= proto_register_protocol("Remote Procedure Call",
4024 /* this is a dummy dissector for all those unknown rpc programs */
4025 proto_register_field_array(proto_rpc
, hf
, array_length(hf
));
4026 proto_register_subtree_array(ett
, array_length(ett
));
4027 register_init_routine(&rpc_init_protocol
);
4029 rpc_module
= prefs_register_protocol(proto_rpc
, NULL
);
4030 prefs_register_bool_preference(rpc_module
, "desegment_rpc_over_tcp",
4031 "Reassemble RPC over TCP messages\nspanning multiple TCP segments",
4032 "Whether the RPC dissector should reassemble messages spanning multiple TCP segments."
4033 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
4035 prefs_register_bool_preference(rpc_module
, "defragment_rpc_over_tcp",
4036 "Reassemble fragmented RPC-over-TCP messages",
4037 "Whether the RPC dissector should defragment RPC-over-TCP messages.",
4040 prefs_register_uint_preference(rpc_module
, "max_tcp_pdu_size", "Maximum size of a RPC-over-TCP PDU",
4041 "Set the maximum size of RPCoverTCP PDUs. "
4042 " If the size field of the record marker is larger "
4043 "than this value it will not be considered a valid RPC PDU.",
4044 10, &max_rpc_tcp_pdu_size
);
4046 prefs_register_bool_preference(rpc_module
, "dissect_unknown_programs",
4047 "Dissect unknown RPC program numbers",
4048 "Whether the RPC dissector should attempt to dissect RPC PDUs containing programs that are not known to Wireshark. This will make the heuristics significantly weaker and elevate the risk for falsely identifying and misdissecting packets significantly.",
4049 &rpc_dissect_unknown_programs
);
4051 prefs_register_bool_preference(rpc_module
, "find_fragment_start",
4052 "Attempt to locate start-of-fragment in partial RPC-over-TCP captures",
4053 "Whether the RPC dissector should attempt to locate RPC PDU boundaries when initial fragment alignment is not known. This may cause false positives, or slow operation.",
4054 &rpc_find_fragment_start
);
4056 register_dissector("rpc", dissect_rpc
, proto_rpc
);
4057 new_register_dissector("rpc-tcp", dissect_rpc_tcp
, proto_rpc
);
4058 rpc_tap
= register_tap("rpc");
4061 * Init the hash tables. Dissectors for RPC protocols must
4062 * have a "handoff registration" routine that registers the
4063 * protocol with RPC; they must not do it in their protocol
4064 * registration routine, as their protocol registration
4065 * routine might be called before this routine is called and
4066 * thus might be called before the hash tables are initialized,
4067 * but it's guaranteed that all protocol registration routines
4068 * will be called before any handoff registration routines
4071 rpc_progs
= g_hash_table_new(rpc_prog_hash
, rpc_prog_equal
);
4072 rpc_procs
= g_hash_table_new(rpc_proc_hash
, rpc_proc_equal
);
4074 authgss_contexts
=wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4078 proto_reg_handoff_rpc(void)
4080 /* tcp/udp port 111 is used by portmapper which is an onc-rpc service.
4081 we register onc-rpc on this port so that we can choose RPC in
4082 the list offered by DecodeAs, and so that traffic to or from
4083 port 111 from or to a higher-numbered port is dissected as RPC
4084 even if there's a dissector registered on the other port (it's
4085 probably RPC traffic from some randomly-chosen port that happens
4086 to match some port for which we have a dissector)
4088 rpc_tcp_handle
= find_dissector("rpc-tcp");
4089 dissector_add_uint("tcp.port", 111, rpc_tcp_handle
);
4090 rpc_handle
= find_dissector("rpc");
4091 dissector_add_uint("udp.port", 111, rpc_handle
);
4093 heur_dissector_add("tcp", dissect_rpc_tcp_heur
, proto_rpc
);
4094 heur_dissector_add("udp", dissect_rpc_heur
, proto_rpc
);
4095 gssapi_handle
= find_dissector("gssapi");
4096 spnego_krb5_wrap_handle
= find_dissector("spnego-krb5-wrap");
4097 data_handle
= find_dissector("data");
4106 * indent-tabs-mode: t
4109 * ex: set shiftwidth=8 tabstop=8 noexpandtab:
4110 * :indentSize=8:tabSize=8:noTabs=false: