10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23*410Skcpoon * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*410Skcpoon * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <sys/errno.h>
310Sstevel@tonic-gate #include <sys/tiuser.h>
320Sstevel@tonic-gate #include <setjmp.h>
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include <rpc/types.h>
350Sstevel@tonic-gate #include <rpc/xdr.h>
360Sstevel@tonic-gate #include <rpc/auth.h>
370Sstevel@tonic-gate #include <rpc/clnt.h>
380Sstevel@tonic-gate #include <rpc/rpc_msg.h>
390Sstevel@tonic-gate #include <rpc/rpcsec_gss.h>
400Sstevel@tonic-gate #include <string.h>
410Sstevel@tonic-gate #include "snoop.h"
420Sstevel@tonic-gate
430Sstevel@tonic-gate extern jmp_buf xdr_err;
440Sstevel@tonic-gate
450Sstevel@tonic-gate struct cache_struct *find_xid();
460Sstevel@tonic-gate char *nameof_prog(int prog);
47*410Skcpoon static void print_rpc_gss_init_arg(int, struct cache_struct *);
48*410Skcpoon static void print_rpc_gss_init_res(int);
490Sstevel@tonic-gate
500Sstevel@tonic-gate char *
rpcsec_gss_proc_to_string(unsigned int proc)510Sstevel@tonic-gate rpcsec_gss_proc_to_string(unsigned int proc)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate switch (proc) {
540Sstevel@tonic-gate case RPCSEC_GSS_DATA: return "RPCSEC_GSS_DATA"; break;
550Sstevel@tonic-gate case RPCSEC_GSS_INIT: return "RPCSEC_GSS_INIT"; break;
560Sstevel@tonic-gate case RPCSEC_GSS_CONTINUE_INIT:
570Sstevel@tonic-gate return ("RPCSEC_GSS_CONTINUE_INIT");
580Sstevel@tonic-gate case RPCSEC_GSS_DESTROY:
590Sstevel@tonic-gate return ("RPCSEC_GSS_DESTROY");
600Sstevel@tonic-gate default: return ("unknown");
610Sstevel@tonic-gate
620Sstevel@tonic-gate }
630Sstevel@tonic-gate }
640Sstevel@tonic-gate
650Sstevel@tonic-gate
660Sstevel@tonic-gate char *
rpcsec_gss_service_to_string(rpc_gss_service_t service)670Sstevel@tonic-gate rpcsec_gss_service_to_string(rpc_gss_service_t service)
680Sstevel@tonic-gate {
690Sstevel@tonic-gate switch (service) {
700Sstevel@tonic-gate case rpc_gss_svc_none: return "none"; break;
710Sstevel@tonic-gate case rpc_gss_svc_integrity: return "integrity"; break;
720Sstevel@tonic-gate case rpc_gss_svc_privacy: return "privacy"; break;
730Sstevel@tonic-gate default: return "unknown"; break;
740Sstevel@tonic-gate
750Sstevel@tonic-gate }
760Sstevel@tonic-gate }
770Sstevel@tonic-gate
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate * Print detailed RPCSEC_GSS cred data.
800Sstevel@tonic-gate */
810Sstevel@tonic-gate void
print_rpcsec_gss_cred(int xid,int authlen)820Sstevel@tonic-gate print_rpcsec_gss_cred(int xid, int authlen)
830Sstevel@tonic-gate {
840Sstevel@tonic-gate unsigned int seq_num;
850Sstevel@tonic-gate unsigned int handle_len;
860Sstevel@tonic-gate unsigned int rpcsec_gss_ver;
870Sstevel@tonic-gate rpc_gss_service_t rpcsec_gss_service;
880Sstevel@tonic-gate unsigned int rpcsec_gss_proc;
890Sstevel@tonic-gate char *handle, *line;
900Sstevel@tonic-gate struct cache_struct *x;
910Sstevel@tonic-gate int pos;
920Sstevel@tonic-gate
930Sstevel@tonic-gate pos = getxdr_pos();
940Sstevel@tonic-gate rpcsec_gss_ver = getxdr_u_long();
950Sstevel@tonic-gate
960Sstevel@tonic-gate /* see if we know this version or not */
970Sstevel@tonic-gate
980Sstevel@tonic-gate if (rpcsec_gss_ver != 1) {
990Sstevel@tonic-gate (void) showxdr_hex(authlen, "[%s]");
1000Sstevel@tonic-gate return;
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate rpcsec_gss_proc = getxdr_u_long();
1040Sstevel@tonic-gate seq_num = getxdr_u_long();
1050Sstevel@tonic-gate rpcsec_gss_service = getxdr_enum();
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()),
1080Sstevel@tonic-gate " version = %u", rpcsec_gss_ver);
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()),
1110Sstevel@tonic-gate " gss control procedure = %u (%s)",
1120Sstevel@tonic-gate rpcsec_gss_proc,
1130Sstevel@tonic-gate rpcsec_gss_proc_to_string(rpcsec_gss_proc));
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()),
1160Sstevel@tonic-gate " sequence num = %u", seq_num);
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()),
1190Sstevel@tonic-gate " service = %d (%s)", rpcsec_gss_service,
1200Sstevel@tonic-gate rpcsec_gss_service_to_string(rpcsec_gss_service));
1210Sstevel@tonic-gate pos = getxdr_pos();
1220Sstevel@tonic-gate handle_len = getxdr_u_long();
1230Sstevel@tonic-gate handle = getxdr_hex(handle_len);
1240Sstevel@tonic-gate line = get_line(pos, getxdr_pos());
1250Sstevel@tonic-gate sprintf(line, " handle: length = %d, data = [%s]",
1260Sstevel@tonic-gate handle_len, handle);
1270Sstevel@tonic-gate x = find_xid(xid);
1280Sstevel@tonic-gate if (x) {
1290Sstevel@tonic-gate x->xid_gss_proc = rpcsec_gss_proc;
1300Sstevel@tonic-gate x->xid_gss_service = rpcsec_gss_service;
1310Sstevel@tonic-gate }
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate /*
1350Sstevel@tonic-gate * Based on different RPCSEC_GSS services supported, maybe a
1360Sstevel@tonic-gate * special handling is needed before printing the arguments.
1370Sstevel@tonic-gate *
1380Sstevel@tonic-gate * For integrity service : print the sequence number.
1390Sstevel@tonic-gate * For privacy service : do not print the arguments.
1400Sstevel@tonic-gate */
1410Sstevel@tonic-gate int
rpcsec_gss_pre_proto(int type,int flags,int xid,int prog,int vers,int proc)1420Sstevel@tonic-gate rpcsec_gss_pre_proto(int type, int flags, int xid,
1430Sstevel@tonic-gate int prog, int vers, int proc)
1440Sstevel@tonic-gate {
1450Sstevel@tonic-gate int seq;
1460Sstevel@tonic-gate struct cache_struct *x;
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate if (! (x = find_xid(xid)))
1490Sstevel@tonic-gate return (0);
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate switch (x->xid_gss_service) {
1520Sstevel@tonic-gate case rpc_gss_svc_default:
1530Sstevel@tonic-gate case rpc_gss_svc_none:
1540Sstevel@tonic-gate break; /* standard call args */
1550Sstevel@tonic-gate case rpc_gss_svc_integrity:
1560Sstevel@tonic-gate /* length of rpc_gss_data_t encoded in the databody_integ */
1570Sstevel@tonic-gate getxdr_u_long();
1580Sstevel@tonic-gate /* read the seq number */
1590Sstevel@tonic-gate seq = getxdr_u_long();
1600Sstevel@tonic-gate if (flags & F_ALLSUM) {
1610Sstevel@tonic-gate (void) sprintf(get_sum_line(), "%s %c seq_num = %u",
1620Sstevel@tonic-gate "RPC RPCSEC_GSS", type == CALL ? 'C' : 'R',
1630Sstevel@tonic-gate seq);
1640Sstevel@tonic-gate } else if (flags & F_DTAIL) {
1650Sstevel@tonic-gate sprintf(get_line(0, 0),
1660Sstevel@tonic-gate "RPCSEC_GSS data seq_num = %u", seq);
1670Sstevel@tonic-gate show_space();
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate /* call args follow */
1700Sstevel@tonic-gate break;
1710Sstevel@tonic-gate case rpc_gss_svc_privacy: {
1720Sstevel@tonic-gate char *progname = nameof_prog(prog);
1730Sstevel@tonic-gate char prognum[32];
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate if (*progname == '?') {
1760Sstevel@tonic-gate sprintf(prognum, "%d", prog);
1770Sstevel@tonic-gate progname = prognum;
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate if (flags & F_SUM || flags & F_ALLSUM) {
1810Sstevel@tonic-gate (void) sprintf(get_sum_line(),
1820Sstevel@tonic-gate "%s %c %s ver(%d) proc(%d) (data encrypted) ",
1830Sstevel@tonic-gate "RPC RPCSEC_GSS", type == CALL ? 'C' : 'R',
1840Sstevel@tonic-gate progname, vers, proc);
1850Sstevel@tonic-gate } else if (flags & F_DTAIL) {
1860Sstevel@tonic-gate unsigned int args_len;
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate args_len = getxdr_u_long();
1890Sstevel@tonic-gate sprintf(get_line(0, 0),
1900Sstevel@tonic-gate "RPCSEC_GSS %s ver(%d) proc(%d)",
1910Sstevel@tonic-gate progname, vers, proc);
1920Sstevel@tonic-gate sprintf(get_line(0, 0),
1930Sstevel@tonic-gate "(%s args encrypted, len = %d bytes)",
1940Sstevel@tonic-gate type == CALL ? "CALL" : "REPLY", args_len);
1950Sstevel@tonic-gate show_space();
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate }
1980Sstevel@tonic-gate return (1);
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate default:
2010Sstevel@tonic-gate break;
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate return (0);
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate /*
2070Sstevel@tonic-gate * Based on different RPCSEC_GSS services supported, maybe a
2080Sstevel@tonic-gate * special handling is needed after printing the arguments.
2090Sstevel@tonic-gate *
2100Sstevel@tonic-gate * For integrity service : print the checksum.
2110Sstevel@tonic-gate */
2120Sstevel@tonic-gate void
rpcsec_gss_post_proto(int flags,int xid)2130Sstevel@tonic-gate rpcsec_gss_post_proto(int flags, int xid)
2140Sstevel@tonic-gate {
2150Sstevel@tonic-gate char *line;
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate struct cache_struct *x;
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate if (! (x = find_xid(xid)))
2200Sstevel@tonic-gate return;
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate switch (x->xid_gss_service) {
2230Sstevel@tonic-gate case rpc_gss_svc_default:
2240Sstevel@tonic-gate case rpc_gss_svc_none:
2250Sstevel@tonic-gate case rpc_gss_svc_privacy:
2260Sstevel@tonic-gate /* nothing left */
2270Sstevel@tonic-gate break;
2280Sstevel@tonic-gate case rpc_gss_svc_integrity:
2290Sstevel@tonic-gate if (flags & F_ALLSUM) {
2300Sstevel@tonic-gate line = get_sum_line();
2310Sstevel@tonic-gate sprintf(line, "RPC RPCSEC_GSS C (checksum)");
2320Sstevel@tonic-gate } else if (flags & F_DTAIL) {
2330Sstevel@tonic-gate unsigned int checksum_len;
2340Sstevel@tonic-gate char *checksum;
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate show_header("RPC: ", "RPCSEC_GSS", 0);
2370Sstevel@tonic-gate show_space();
2380Sstevel@tonic-gate checksum_len = getxdr_u_long();
2390Sstevel@tonic-gate checksum = getxdr_hex(checksum_len);
2400Sstevel@tonic-gate sprintf(get_line(0, 0),
2410Sstevel@tonic-gate "checksum: len = %d", checksum_len);
2420Sstevel@tonic-gate sprintf(get_line(0, 0), "[%s]", checksum);
2430Sstevel@tonic-gate show_trailer();
2440Sstevel@tonic-gate }
2450Sstevel@tonic-gate break;
2460Sstevel@tonic-gate default:
2470Sstevel@tonic-gate break;
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate /*
2520Sstevel@tonic-gate * Print RPCSEC_GSS control procedures protocol data,
2530Sstevel@tonic-gate * No-op for RPCSEC_GSS_DATA.
2540Sstevel@tonic-gate */
2550Sstevel@tonic-gate int
rpcsec_gss_control_proc(int type,int flags,int xid)2560Sstevel@tonic-gate rpcsec_gss_control_proc(int type, int flags, int xid)
2570Sstevel@tonic-gate {
2580Sstevel@tonic-gate int seq;
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate struct cache_struct *x;
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate if (! (x = find_xid(xid)))
2630Sstevel@tonic-gate return (0);
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate if (x->xid_gss_proc != RPCSEC_GSS_DATA) {
2660Sstevel@tonic-gate if (flags & F_SUM) {
2670Sstevel@tonic-gate if (type == CALL) {
2680Sstevel@tonic-gate (void) sprintf(get_sum_line(), "%s %c %u (%s)",
2690Sstevel@tonic-gate "RPC RPCSEC_GSS",
2700Sstevel@tonic-gate type == CALL ? 'C' : 'R',
2710Sstevel@tonic-gate x->xid_gss_proc,
2720Sstevel@tonic-gate rpcsec_gss_proc_to_string(x->xid_gss_proc));
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate } else if (flags & F_DTAIL) {
2750Sstevel@tonic-gate if (x->xid_gss_proc == RPCSEC_GSS_INIT ||
2760Sstevel@tonic-gate x->xid_gss_proc == RPCSEC_GSS_CONTINUE_INIT) {
2770Sstevel@tonic-gate if (type == CALL) {
2780Sstevel@tonic-gate print_rpc_gss_init_arg(flags, x);
2790Sstevel@tonic-gate } else {
2800Sstevel@tonic-gate print_rpc_gss_init_res(flags);
2810Sstevel@tonic-gate }
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate return (1);
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate return (0);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate /*
2910Sstevel@tonic-gate * Skip the header RPCSEC_GSS cred data and
2920Sstevel@tonic-gate * put service and control type in the xid cache.
2930Sstevel@tonic-gate */
294*410Skcpoon void
extract_rpcsec_gss_cred_info(int xid)2950Sstevel@tonic-gate extract_rpcsec_gss_cred_info(int xid)
2960Sstevel@tonic-gate {
2970Sstevel@tonic-gate unsigned int seq_num;
2980Sstevel@tonic-gate unsigned int handle_len;
2990Sstevel@tonic-gate unsigned int flavor_len;
3000Sstevel@tonic-gate unsigned int rpcsec_gss_ver;
3010Sstevel@tonic-gate rpc_gss_service_t rpcsec_gss_service;
3020Sstevel@tonic-gate unsigned int rpcsec_gss_proc;
3030Sstevel@tonic-gate struct cache_struct *x;
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate flavor_len = getxdr_u_long();
3060Sstevel@tonic-gate rpcsec_gss_ver = getxdr_u_long();
3070Sstevel@tonic-gate /* see if we know this version or not */
3080Sstevel@tonic-gate if (rpcsec_gss_ver != 1) {
3090Sstevel@tonic-gate longjmp(xdr_err, 1);
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate rpcsec_gss_proc = getxdr_u_long();
3120Sstevel@tonic-gate seq_num = getxdr_u_long();
3130Sstevel@tonic-gate rpcsec_gss_service = getxdr_enum();
3140Sstevel@tonic-gate /* skip the handle */
3150Sstevel@tonic-gate xdr_skip(RNDUP(getxdr_u_long()));
3160Sstevel@tonic-gate
3170Sstevel@tonic-gate if (x = find_xid(xid)) {
3180Sstevel@tonic-gate x->xid_gss_service = rpcsec_gss_service;
3190Sstevel@tonic-gate x->xid_gss_proc = rpcsec_gss_proc;
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate }
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate /*
3250Sstevel@tonic-gate * Print the argument data for the RPCSEC_GSS_INIT control procedure.
3260Sstevel@tonic-gate */
327*410Skcpoon static void
print_rpc_gss_init_arg(int flags,struct cache_struct * x)328*410Skcpoon print_rpc_gss_init_arg(int flags, struct cache_struct *x)
3290Sstevel@tonic-gate {
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate char *token, *line;
3320Sstevel@tonic-gate unsigned int token_len;
3330Sstevel@tonic-gate int pos;
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate /*
3360Sstevel@tonic-gate * see if we need to print out the rpc_gss_init_arg structure
3370Sstevel@tonic-gate * or not.
3380Sstevel@tonic-gate */
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate if (x->xid_gss_proc != RPCSEC_GSS_INIT &&
3410Sstevel@tonic-gate x->xid_gss_proc != RPCSEC_GSS_CONTINUE_INIT) {
3420Sstevel@tonic-gate return;
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate /* print it */
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()),
3480Sstevel@tonic-gate "RPCSEC_GSS_INIT args:");
3490Sstevel@tonic-gate
3500Sstevel@tonic-gate pos = getxdr_pos();
3510Sstevel@tonic-gate token_len = getxdr_u_long();
3520Sstevel@tonic-gate token = getxdr_hex(token_len);
3530Sstevel@tonic-gate line = get_line(pos, getxdr_pos());
3540Sstevel@tonic-gate sprintf(line, " gss token: length = %d, data = [%d bytes]",
3550Sstevel@tonic-gate token_len, token_len);
3560Sstevel@tonic-gate
3570Sstevel@tonic-gate show_trailer();
3580Sstevel@tonic-gate }
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate /*
3610Sstevel@tonic-gate * Print the results data for the RPCSEC_GSS_INIT control procedure.
3620Sstevel@tonic-gate */
363*410Skcpoon void
print_rpc_gss_init_res(int flags)3640Sstevel@tonic-gate print_rpc_gss_init_res(int flags)
3650Sstevel@tonic-gate {
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate char *handle, *token, *line;
3680Sstevel@tonic-gate unsigned int token_len, handle_len;
3690Sstevel@tonic-gate unsigned int major, minor, seq_window;
3700Sstevel@tonic-gate
3710Sstevel@tonic-gate int pos;
3720Sstevel@tonic-gate struct cache_struct *x;
3730Sstevel@tonic-gate
3740Sstevel@tonic-gate /* print it */
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), "RPCSEC_GSS_INIT result:");
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate pos = getxdr_pos();
3790Sstevel@tonic-gate handle_len = getxdr_u_long();
3800Sstevel@tonic-gate handle = getxdr_hex(handle_len);
3810Sstevel@tonic-gate line = get_line(pos, getxdr_pos());
3820Sstevel@tonic-gate sprintf(line, " handle: length = %d, data = [%s]",
3830Sstevel@tonic-gate handle_len, handle);
3840Sstevel@tonic-gate pos = getxdr_pos();
3850Sstevel@tonic-gate major = getxdr_u_long();
3860Sstevel@tonic-gate minor = getxdr_u_long();
3870Sstevel@tonic-gate seq_window = getxdr_u_long();
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()),
3900Sstevel@tonic-gate " gss_major status = %u", major);
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()),
3930Sstevel@tonic-gate " gss_minor status = %u", minor);
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()),
3960Sstevel@tonic-gate " sequence window = %u", seq_window);
3970Sstevel@tonic-gate pos = getxdr_pos();
3980Sstevel@tonic-gate token_len = getxdr_u_long();
3990Sstevel@tonic-gate token = getxdr_hex(token_len);
4000Sstevel@tonic-gate line = get_line(pos, getxdr_pos());
4010Sstevel@tonic-gate sprintf(line, " gss token: length = %d, data = [%d bytes]",
4020Sstevel@tonic-gate token_len, token_len);
4030Sstevel@tonic-gate show_trailer();
4040Sstevel@tonic-gate }
405