Home | History | Annotate | Download | only in snoop
      1     0    stevel /*
      2     0    stevel  * CDDL HEADER START
      3     0    stevel  *
      4     0    stevel  * The contents of this file are subject to the terms of the
      5  6631  ss150715  * Common Development and Distribution License (the "License").
      6  6631  ss150715  * You may not use this file except in compliance with the License.
      7     0    stevel  *
      8     0    stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0    stevel  * or http://www.opensolaris.org/os/licensing.
     10     0    stevel  * See the License for the specific language governing permissions
     11     0    stevel  * and limitations under the License.
     12     0    stevel  *
     13     0    stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0    stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0    stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0    stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0    stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0    stevel  *
     19     0    stevel  * CDDL HEADER END
     20     0    stevel  */
     21     0    stevel /*
     22  6631  ss150715  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23     0    stevel  * Use is subject to license terms.
     24     0    stevel  */
     25     0    stevel 
     26     0    stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27     0    stevel 
     28     0    stevel #include <stdio.h>
     29     0    stevel #include <stdlib.h>
     30     0    stevel #include <ctype.h>
     31     0    stevel #include <string.h>
     32     0    stevel #include <fcntl.h>
     33     0    stevel #include <string.h>
     34     0    stevel #include <sys/types.h>
     35     0    stevel #include <time.h>
     36     0    stevel #include <sys/time.h>
     37     0    stevel #include <sys/bufmod.h>
     38     0    stevel #include <setjmp.h>
     39     0    stevel #include <varargs.h>
     40     0    stevel #include <sys/socket.h>
     41     0    stevel #include <net/if.h>
     42     0    stevel #include <netinet/in_systm.h>
     43     0    stevel #include <netinet/in.h>
     44     0    stevel #include <netinet/ip.h>
     45     0    stevel #include <netinet/if_ether.h>
     46     0    stevel #include <rpc/types.h>
     47     0    stevel #include <rpc/xdr.h>
     48     0    stevel #include <inttypes.h>
     49     0    stevel 
     50     0    stevel #include "snoop.h"
     51     0    stevel 
     52     0    stevel char *dlc_header;
     53     0    stevel char *src_name, *dst_name;
     54     0    stevel int pi_frame;
     55     0    stevel int pi_time_hour;
     56     0    stevel int pi_time_min;
     57     0    stevel int pi_time_sec;
     58     0    stevel int pi_time_usec;
     59     0    stevel 
     60     0    stevel #ifndef MIN
     61     0    stevel #define	MIN(a, b) ((a) < (b) ? (a) : (b))
     62     0    stevel #endif
     63     0    stevel 
     64     0    stevel static void hexdump(char *, int);
     65     0    stevel 
     66     0    stevel /*
     67     0    stevel  * This routine invokes the packet interpreters
     68     0    stevel  * on a packet.  There's some messing around
     69     0    stevel  * setting up a few packet-externals before
     70     0    stevel  * starting with the ethernet interpreter.
     71     0    stevel  * Yes, we assume here that all packets will
     72     0    stevel  * be ethernet packets.
     73     0    stevel  */
     74     0    stevel void
     75     0    stevel process_pkt(struct sb_hdr *hdrp, char *pktp, int num, int flags)
     76     0    stevel {
     77     0    stevel 	int drops, pktlen;
     78     0    stevel 	struct timeval *tvp;
     79     0    stevel 	struct tm *tm;
     80     0    stevel 	extern int x_offset;
     81     0    stevel 	extern int x_length;
     82     0    stevel 	int offset, length;
     83     0    stevel 	static struct timeval ptv;
     84     0    stevel 
     85     0    stevel 	if (hdrp == NULL)
     86     0    stevel 		return;
     87     0    stevel 
     88     0    stevel 	tvp = &hdrp->sbh_timestamp;
     89     0    stevel 	if (ptv.tv_sec == 0)
     90     0    stevel 		ptv = *tvp;
     91     0    stevel 	drops  = hdrp->sbh_drops;
     92     0    stevel 	pktlen = hdrp->sbh_msglen;
     93     0    stevel 	if (pktlen <= 0)
     94     0    stevel 		return;
     95     0    stevel 
     96     0    stevel 	/* set up externals */
     97     0    stevel 	dlc_header = pktp;
     98     0    stevel 	pi_frame = num;
     99     0    stevel 	tm = localtime(&tvp->tv_sec);
    100     0    stevel 	pi_time_hour = tm->tm_hour;
    101     0    stevel 	pi_time_min  = tm->tm_min;
    102     0    stevel 	pi_time_sec  = tm->tm_sec;
    103     0    stevel 	pi_time_usec = tvp->tv_usec;
    104     0    stevel 
    105     0    stevel 	src_name = "?";
    106     0    stevel 	dst_name = "*";
    107     0    stevel 
    108     0    stevel 	click(hdrp->sbh_origlen);
    109     0    stevel 
    110     0    stevel 	(*interface->interpreter)(flags, dlc_header, hdrp->sbh_msglen,
    111     0    stevel 	    hdrp->sbh_origlen);
    112     0    stevel 
    113     0    stevel 	show_pktinfo(flags, num, src_name, dst_name, &ptv, tvp, drops,
    114     0    stevel 	    hdrp->sbh_origlen);
    115     0    stevel 
    116     0    stevel 	if (x_offset >= 0) {
    117     0    stevel 		offset = MIN(x_offset, hdrp->sbh_msglen);
    118     0    stevel 		offset -= (offset % 2);  /* round down */
    119     0    stevel 		length = MIN(hdrp->sbh_msglen - offset, x_length);
    120     0    stevel 
    121     0    stevel 		hexdump(dlc_header + offset, length);
    122     0    stevel 	}
    123     0    stevel 
    124     0    stevel 	ptv = *tvp;
    125     0    stevel }
    126     0    stevel 
    127     0    stevel 
    128     0    stevel /*
    129     0    stevel  * *************************************************************
    130     0    stevel  * The following routines constitute a library
    131     0    stevel  * used by the packet interpreters to facilitate
    132     0    stevel  * the display of packet data.  This library
    133     0    stevel  * of routines helps provide a consistent
    134     0    stevel  * "look and feel".
    135     0    stevel  */
    136     0    stevel 
    137     0    stevel 
    138     0    stevel /*
    139     0    stevel  * Display the value of a flag bit in
    140     0    stevel  * a byte together with some text that
    141     0    stevel  * corresponds to its value - whether
    142     0    stevel  * true or false.
    143     0    stevel  */
    144     0    stevel char *
    145     0    stevel getflag(int val, int mask, char *s_true, char *s_false)
    146     0    stevel {
    147     0    stevel 	static char buff[80];
    148     0    stevel 	char *p;
    149     0    stevel 	int set;
    150     0    stevel 
    151     0    stevel 	(void) strcpy(buff, ".... .... = ");
    152     0    stevel 	if (s_false == NULL)
    153     0    stevel 		s_false = s_true;
    154     0    stevel 
    155     0    stevel 	for (p = &buff[8]; p >= buff; p--) {
    156     0    stevel 		if (*p == ' ')
    157     0    stevel 			p--;
    158     0    stevel 		if (mask & 0x1) {
    159     0    stevel 			set = val & mask & 0x1;
    160     0    stevel 			*p = set ? '1':'0';
    161     0    stevel 			(void) strcat(buff, set ? s_true: s_false);
    162     0    stevel 			break;
    163     0    stevel 		}
    164     0    stevel 		mask >>= 1;
    165     0    stevel 		val  >>= 1;
    166     0    stevel 	}
    167     0    stevel 	return (buff);
    168     0    stevel }
    169     0    stevel 
    170     0    stevel XDR xdrm;
    171     0    stevel jmp_buf xdr_err;
    172     0    stevel int xdr_totlen;
    173     0    stevel char *prot_prefix;
    174     0    stevel char *prot_nest_prefix = "";
    175     0    stevel char *prot_title;
    176     0    stevel 
    177     0    stevel void
    178     0    stevel show_header(char *pref, char *str, int len)
    179     0    stevel {
    180     0    stevel 	prot_prefix = pref;
    181     0    stevel 	prot_title = str;
    182     0    stevel 	(void) sprintf(get_detail_line(0, len), "%s%s----- %s -----",
    183     0    stevel 	    prot_nest_prefix, pref, str);
    184     0    stevel }
    185     0    stevel 
    186     0    stevel void
    187     0    stevel xdr_init(char *addr, int len)
    188     0    stevel {
    189     0    stevel 	xdr_totlen = len;
    190     0    stevel 	xdrmem_create(&xdrm, addr, len, XDR_DECODE);
    191     0    stevel }
    192     0    stevel 
    193     0    stevel char *
    194     0    stevel get_line(int begin, int end)
    195     0    stevel {
    196     0    stevel 	char *line;
    197     0    stevel 
    198     0    stevel 	line = get_detail_line(begin, end);
    199     0    stevel 	(void) strcpy(line, prot_nest_prefix);
    200     0    stevel 	(void) strcat(line, prot_prefix);
    201     0    stevel 	return (line + strlen(line));
    202     0    stevel }
    203     0    stevel 
    204     0    stevel int
    205     0    stevel get_line_remain(void)
    206     0    stevel {
    207     0    stevel 	return (MAXLINE - strlen(prot_nest_prefix) - strlen(prot_prefix));
    208     0    stevel }
    209     0    stevel 
    210     0    stevel void
    211     0    stevel show_line(char *str)
    212     0    stevel {
    213     0    stevel 	(void) strcpy(get_line(0, 0), str);
    214     0    stevel }
    215     0    stevel 
    216     0    stevel char
    217     0    stevel getxdr_char()
    218     0    stevel {
    219     0    stevel 	char s;
    220     0    stevel 
    221     0    stevel 	if (xdr_char(&xdrm, &s))
    222     0    stevel 		return (s);
    223     0    stevel 	longjmp(xdr_err, 1);
    224     0    stevel 	/* NOTREACHED */
    225     0    stevel }
    226     0    stevel 
    227     0    stevel char
    228     0    stevel showxdr_char(char *fmt)
    229     0    stevel {
    230     0    stevel 	int pos; char val;
    231     0    stevel 
    232     0    stevel 	pos = getxdr_pos();
    233     0    stevel 	val = getxdr_char();
    234     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, val);
    235     0    stevel 	return (val);
    236     0    stevel }
    237     0    stevel 
    238     0    stevel uchar_t
    239     0    stevel getxdr_u_char()
    240     0    stevel {
    241     0    stevel 	uchar_t s;
    242     0    stevel 
    243     0    stevel 	if (xdr_u_char(&xdrm, &s))
    244     0    stevel 		return (s);
    245     0    stevel 	longjmp(xdr_err, 1);
    246     0    stevel 	/* NOTREACHED */
    247     0    stevel }
    248     0    stevel 
    249     0    stevel uchar_t
    250     0    stevel showxdr_u_char(char *fmt)
    251     0    stevel {
    252     0    stevel 	int pos;
    253     0    stevel 	uchar_t val;
    254     0    stevel 
    255     0    stevel 	pos = getxdr_pos();
    256     0    stevel 	val = getxdr_u_char();
    257     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, val);
    258     0    stevel 	return (val);
    259     0    stevel }
    260     0    stevel 
    261     0    stevel short
    262     0    stevel getxdr_short()
    263     0    stevel {
    264     0    stevel 	short s;
    265     0    stevel 
    266     0    stevel 	if (xdr_short(&xdrm, &s))
    267     0    stevel 		return (s);
    268     0    stevel 	longjmp(xdr_err, 1);
    269     0    stevel 	/* NOTREACHED */
    270     0    stevel }
    271     0    stevel 
    272     0    stevel short
    273     0    stevel showxdr_short(char *fmt)
    274     0    stevel {
    275     0    stevel 	int pos; short val;
    276     0    stevel 
    277     0    stevel 	pos = getxdr_pos();
    278     0    stevel 	val = getxdr_short();
    279     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, val);
    280     0    stevel 	return (val);
    281     0    stevel }
    282     0    stevel 
    283     0    stevel ushort_t
    284     0    stevel getxdr_u_short()
    285     0    stevel {
    286     0    stevel 	ushort_t s;
    287     0    stevel 
    288     0    stevel 	if (xdr_u_short(&xdrm, &s))
    289     0    stevel 		return (s);
    290     0    stevel 	longjmp(xdr_err, 1);
    291     0    stevel 	/* NOTREACHED */
    292     0    stevel }
    293     0    stevel 
    294     0    stevel ushort_t
    295     0    stevel showxdr_u_short(char *fmt)
    296     0    stevel {
    297     0    stevel 	int pos;
    298     0    stevel 	ushort_t val;
    299     0    stevel 
    300     0    stevel 	pos = getxdr_pos();
    301     0    stevel 	val = getxdr_u_short();
    302     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, val);
    303     0    stevel 	return (val);
    304     0    stevel }
    305     0    stevel 
    306     0    stevel long
    307     0    stevel getxdr_long()
    308     0    stevel {
    309     0    stevel 	long l;
    310     0    stevel 
    311     0    stevel 	if (xdr_long(&xdrm, &l))
    312     0    stevel 		return (l);
    313     0    stevel 	longjmp(xdr_err, 1);
    314     0    stevel 	/* NOTREACHED */
    315     0    stevel }
    316     0    stevel 
    317     0    stevel long
    318     0    stevel showxdr_long(char *fmt)
    319     0    stevel {
    320     0    stevel 	int pos; long val;
    321     0    stevel 
    322     0    stevel 	pos = getxdr_pos();
    323     0    stevel 	val = getxdr_long();
    324     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, val);
    325     0    stevel 	return (val);
    326     0    stevel }
    327     0    stevel 
    328     0    stevel ulong_t
    329     0    stevel getxdr_u_long()
    330     0    stevel {
    331     0    stevel 	ulong_t l;
    332     0    stevel 
    333     0    stevel 	if (xdr_u_long(&xdrm, &l))
    334     0    stevel 		return (l);
    335     0    stevel 	longjmp(xdr_err, 1);
    336     0    stevel 	/* NOTREACHED */
    337     0    stevel }
    338     0    stevel 
    339     0    stevel ulong_t
    340     0    stevel showxdr_u_long(char *fmt)
    341     0    stevel {
    342     0    stevel 	int pos;
    343     0    stevel 	ulong_t val;
    344     0    stevel 
    345     0    stevel 	pos = getxdr_pos();
    346     0    stevel 	val = getxdr_u_long();
    347     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, val);
    348     0    stevel 	return (val);
    349     0    stevel }
    350     0    stevel 
    351     0    stevel longlong_t
    352     0    stevel getxdr_longlong()
    353     0    stevel {
    354     0    stevel 	longlong_t l;
    355     0    stevel 
    356     0    stevel 	if (xdr_longlong_t(&xdrm, &l))
    357     0    stevel 		return (l);
    358     0    stevel 	longjmp(xdr_err, 1);
    359     0    stevel 	/* NOTREACHED */
    360     0    stevel }
    361     0    stevel 
    362     0    stevel longlong_t
    363     0    stevel showxdr_longlong(char *fmt)
    364     0    stevel {
    365     0    stevel 	int pos; longlong_t val;
    366     0    stevel 
    367     0    stevel 	pos = getxdr_pos();
    368     0    stevel 	val = getxdr_longlong();
    369     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, val);
    370     0    stevel 	return (val);
    371     0    stevel }
    372     0    stevel 
    373     0    stevel u_longlong_t
    374     0    stevel getxdr_u_longlong()
    375     0    stevel {
    376     0    stevel 	u_longlong_t l;
    377     0    stevel 
    378     0    stevel 	if (xdr_u_longlong_t(&xdrm, &l))
    379     0    stevel 		return (l);
    380     0    stevel 	longjmp(xdr_err, 1);
    381     0    stevel 	/* NOTREACHED */
    382     0    stevel }
    383     0    stevel 
    384     0    stevel u_longlong_t
    385     0    stevel showxdr_u_longlong(char *fmt)
    386     0    stevel {
    387     0    stevel 	int pos; u_longlong_t val;
    388     0    stevel 
    389     0    stevel 	pos = getxdr_pos();
    390     0    stevel 	val = getxdr_u_longlong();
    391     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, val);
    392     0    stevel 	return (val);
    393     0    stevel }
    394     0    stevel 
    395     0    stevel bool_t
    396     0    stevel getxdr_bool()
    397     0    stevel {
    398     0    stevel 	bool_t b;
    399     0    stevel 
    400     0    stevel 	if (xdr_bool(&xdrm, &b))
    401     0    stevel 		return (b);
    402     0    stevel 	longjmp(xdr_err, 1);
    403     0    stevel 	/* NOTREACHED */
    404     0    stevel }
    405     0    stevel 
    406     0    stevel bool_t
    407     0    stevel showxdr_bool(char *fmt)
    408     0    stevel {
    409     0    stevel 	int pos; bool_t val;
    410     0    stevel 
    411     0    stevel 	pos = getxdr_pos();
    412     0    stevel 	val = getxdr_bool();
    413     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt,
    414     0    stevel 	    val ? "True" : "False");
    415     0    stevel 	return (val);
    416     0    stevel }
    417     0    stevel 
    418     0    stevel char *
    419     0    stevel getxdr_opaque(char *p, int len)
    420     0    stevel {
    421     0    stevel 	if (xdr_opaque(&xdrm, p, len))
    422     0    stevel 		return (p);
    423     0    stevel 	longjmp(xdr_err, 1);
    424     0    stevel 	/* NOTREACHED */
    425     0    stevel }
    426     0    stevel 
    427     0    stevel char *
    428     0    stevel getxdr_string(char *p, /* len+1 bytes or longer */
    429     0    stevel 	int len)
    430     0    stevel {
    431     0    stevel 	if (xdr_string(&xdrm, &p, len))
    432     0    stevel 		return (p);
    433     0    stevel 	longjmp(xdr_err, 1);
    434     0    stevel 	/* NOTREACHED */
    435     0    stevel }
    436     0    stevel 
    437     0    stevel char *
    438     0    stevel showxdr_string(int len, /* XDR length */
    439     0    stevel 	char *fmt)
    440     0    stevel {
    441     0    stevel 	static int buff_len = 0;
    442     0    stevel 	static char *buff = NULL;
    443     0    stevel 	int pos;
    444     0    stevel 
    445     0    stevel 	/*
    446     0    stevel 	 * XDR strings don't necessarily have a trailing null over the
    447     0    stevel 	 * wire.  However, the XDR code will put one in for us.  Make sure
    448     0    stevel 	 * we have allocated room for it.
    449     0    stevel 	 */
    450     0    stevel 	len++;
    451     0    stevel 
    452     0    stevel 	if ((len > buff_len) || (buff_len == 0)) {
    453     0    stevel 		if (buff)
    454     0    stevel 			free(buff);
    455     0    stevel 		if ((buff = (char *)malloc(len)) == NULL)
    456     0    stevel 			pr_err("showxdr_string: no mem");
    457     0    stevel 		buff_len = len;
    458     0    stevel 	}
    459     0    stevel 	pos = getxdr_pos();
    460     0    stevel 	getxdr_string(buff, len);
    461     0    stevel 	(void) strcpy(buff+60, "...");
    462     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, buff);
    463     0    stevel 	return (buff);
    464     0    stevel }
    465     0    stevel 
    466     0    stevel char *
    467     0    stevel getxdr_bytes(uint_t *lenp)
    468     0    stevel {
    469     0    stevel 	static char buff[1024];
    470     0    stevel 	char *p = buff;
    471     0    stevel 
    472     0    stevel 	if (xdr_bytes(&xdrm, &p, lenp, 1024))
    473     0    stevel 		return (buff);
    474     0    stevel 	longjmp(xdr_err, 1);
    475     0    stevel 	/* NOTREACHED */
    476     0    stevel }
    477     0    stevel 
    478     0    stevel char *
    479     0    stevel getxdr_context(char *p, int len)
    480     0    stevel {
    481     0    stevel 	ushort_t size;
    482     0    stevel 
    483     0    stevel 	size = getxdr_u_short();
    484     0    stevel 	if (((int)size > 0) && ((int)size < len) && getxdr_opaque(p, size))
    485     0    stevel 		return (p);
    486     0    stevel 	longjmp(xdr_err, 1);
    487     0    stevel 	/* NOTREACHED */
    488     0    stevel }
    489     0    stevel 
    490     0    stevel char *
    491     0    stevel showxdr_context(char *fmt)
    492     0    stevel {
    493     0    stevel 	ushort_t size;
    494     0    stevel 	static char buff[1024];
    495     0    stevel 	int pos;
    496     0    stevel 
    497     0    stevel 	pos = getxdr_pos();
    498     0    stevel 	size = getxdr_u_short();
    499     0    stevel 	if (((int)size > 0) && ((int)size < 1024) &&
    500     0    stevel 	    getxdr_opaque(buff, size)) {
    501     0    stevel 		(void) sprintf(get_line(pos, getxdr_pos()), fmt, buff);
    502     0    stevel 		return (buff);
    503     0    stevel 	}
    504     0    stevel 	longjmp(xdr_err, 1);
    505     0    stevel 	/* NOTREACHED */
    506     0    stevel }
    507     0    stevel 
    508     0    stevel enum_t
    509     0    stevel getxdr_enum()
    510     0    stevel {
    511     0    stevel 	enum_t e;
    512     0    stevel 
    513     0    stevel 	if (xdr_enum(&xdrm, &e))
    514     0    stevel 		return (e);
    515     0    stevel 	longjmp(xdr_err, 1);
    516     0    stevel 	/* NOTREACHED */
    517     0    stevel }
    518     0    stevel 
    519     0    stevel void
    520     0    stevel xdr_skip(int delta)
    521     0    stevel {
    522     0    stevel 	uint_t pos;
    523     0    stevel 	if (delta % 4 != 0 || delta < 0)
    524     0    stevel 		longjmp(xdr_err, 1);
    525     0    stevel 	/* Check for overflow */
    526     0    stevel 	pos = xdr_getpos(&xdrm);
    527     0    stevel 	if ((pos + delta) < pos)
    528     0    stevel 		longjmp(xdr_err, 1);
    529     0    stevel 	/* xdr_setpos() checks for buffer overrun */
    530     0    stevel 	if (xdr_setpos(&xdrm, pos + delta) == FALSE)
    531     0    stevel 		longjmp(xdr_err, 1);
    532     0    stevel }
    533     0    stevel 
    534     0    stevel int
    535     0    stevel getxdr_pos()
    536     0    stevel {
    537     0    stevel 	return (xdr_getpos(&xdrm));
    538     0    stevel }
    539     0    stevel 
    540     0    stevel void
    541     0    stevel setxdr_pos(int pos)
    542     0    stevel {
    543     0    stevel 	xdr_setpos(&xdrm, pos);
    544     0    stevel }
    545     0    stevel 
    546     0    stevel void
    547     0    stevel show_space()
    548     0    stevel {
    549     0    stevel 	(void) get_line(0, 0);
    550     0    stevel }
    551     0    stevel 
    552     0    stevel void
    553     0    stevel show_trailer()
    554     0    stevel {
    555     0    stevel 	show_space();
    556     0    stevel }
    557     0    stevel 
    558     0    stevel char *
    559     0    stevel getxdr_date()
    560     0    stevel {
    561     0    stevel 	time_t sec;
    562     0    stevel 	int  usec;
    563     0    stevel 	static char buff[64];
    564     0    stevel 	char *p;
    565     0    stevel 	struct tm my_time;	/* private buffer to avoid collision */
    566     0    stevel 				/* between gmtime and strftime */
    567     0    stevel 	struct tm *tmp;
    568     0    stevel 
    569     0    stevel 	sec  = getxdr_long();
    570     0    stevel 	usec = getxdr_long();
    571     0    stevel 	if (sec == -1)
    572     0    stevel 		return ("-1 ");
    573     0    stevel 
    574     0    stevel 	if (sec < 3600 * 24 * 365) {	/* assume not a date */
    575     0    stevel 		(void) sprintf(buff, "%d.%06d", sec, usec);
    576     0    stevel 	} else {
    577     0    stevel 		tmp = gmtime(&sec);
    578     0    stevel 		(void) memcpy(&my_time, tmp, sizeof (struct tm));
    579     0    stevel 		strftime(buff, sizeof (buff), "%d-%h-%y %T.", &my_time);
    580     0    stevel 		p = buff + strlen(buff);
    581     0    stevel 		(void) sprintf(p, "%06d GMT", usec);
    582     0    stevel 	}
    583     0    stevel 	return (buff);
    584     0    stevel }
    585     0    stevel 
    586     0    stevel char *
    587     0    stevel showxdr_date(char *fmt)
    588     0    stevel {
    589     0    stevel 	int pos;
    590     0    stevel 	char *p;
    591     0    stevel 
    592     0    stevel 	pos = getxdr_pos();
    593     0    stevel 	p = getxdr_date();
    594     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, p);
    595     0    stevel 	return (p);
    596     0    stevel }
    597     0    stevel 
    598     0    stevel char *
    599     0    stevel getxdr_date_ns(void)
    600     0    stevel {
    601     0    stevel 	time_t sec, nsec;
    602     0    stevel 
    603     0    stevel 	sec  = getxdr_long();
    604     0    stevel 	nsec = getxdr_long();
    605     0    stevel 	if (sec == -1)
    606     0    stevel 		return ("-1 ");
    607     0    stevel 	else
    608     0    stevel 		return (format_time(sec, nsec));
    609     0    stevel }
    610     0    stevel 
    611     0    stevel /*
    612     0    stevel  * Format the given time.
    613     0    stevel  */
    614     0    stevel char *
    615     0    stevel format_time(int64_t sec, uint32_t nsec)
    616     0    stevel {
    617     0    stevel 	static char buff[64];
    618     0    stevel 	char *p;
    619     0    stevel 	struct tm my_time;	/* private buffer to avoid collision */
    620     0    stevel 				/* between gmtime and strftime */
    621     0    stevel 	struct tm *tmp;
    622     0    stevel 
    623     0    stevel 	if (sec < 3600 * 24 * 365) {
    624     0    stevel 		/* assume not a date; includes negative times */
    625     0    stevel 		(void) sprintf(buff, "%lld.%06d", sec, nsec);
    626     0    stevel 	} else if (sec > INT32_MAX) {
    627     0    stevel 		/*
    628     0    stevel 		 * XXX No routines are available yet for formatting 64-bit
    629     0    stevel 		 * times.
    630     0    stevel 		 */
    631     0    stevel 		(void) sprintf(buff, "%lld.%06d", sec, nsec);
    632     0    stevel 	} else {
    633     0    stevel 		time_t sec32 = (time_t)sec;
    634     0    stevel 
    635     0    stevel 		tmp = gmtime(&sec32);
    636     0    stevel 		memcpy(&my_time, tmp, sizeof (struct tm));
    637     0    stevel 		strftime(buff, sizeof (buff), "%d-%h-%y %T.", &my_time);
    638     0    stevel 		p = buff + strlen(buff);
    639     0    stevel 		(void) sprintf(p, "%09d GMT", nsec);
    640     0    stevel 	}
    641     0    stevel 	return (buff);
    642     0    stevel }
    643     0    stevel 
    644     0    stevel char *
    645     0    stevel showxdr_date_ns(char *fmt)
    646     0    stevel {
    647     0    stevel 	int pos;
    648     0    stevel 	char *p;
    649     0    stevel 
    650     0    stevel 	pos = getxdr_pos();
    651     0    stevel 	p = getxdr_date_ns();
    652     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, p);
    653     0    stevel 	return (p);
    654     0    stevel }
    655     0    stevel 
    656     0    stevel char *
    657     0    stevel getxdr_time()
    658     0    stevel {
    659     0    stevel 	time_t sec;
    660     0    stevel 	static char buff[64];
    661     0    stevel 	struct tm my_time;	/* private buffer to avoid collision */
    662     0    stevel 				/* between gmtime and strftime */
    663     0    stevel 	struct tm *tmp;
    664     0    stevel 
    665     0    stevel 	sec  = getxdr_long();
    666     0    stevel 	if (sec == -1)
    667     0    stevel 		return ("-1 ");
    668     0    stevel 
    669     0    stevel 	if (sec < 3600 * 24 * 365) {	/* assume not a date */
    670     0    stevel 		(void) sprintf(buff, "%d", sec);
    671     0    stevel 	} else {
    672     0    stevel 		tmp = gmtime(&sec);
    673     0    stevel 		memcpy(&my_time, tmp, sizeof (struct tm));
    674     0    stevel 		strftime(buff, sizeof (buff), "%d-%h-%y %T", &my_time);
    675     0    stevel 	}
    676     0    stevel 	return (buff);
    677     0    stevel }
    678     0    stevel 
    679     0    stevel char *
    680     0    stevel showxdr_time(char *fmt)
    681     0    stevel {
    682     0    stevel 	int pos;
    683     0    stevel 	char *p;
    684     0    stevel 
    685     0    stevel 	pos = getxdr_pos();
    686     0    stevel 	p = getxdr_time();
    687     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, p);
    688     0    stevel 	return (p);
    689     0    stevel }
    690     0    stevel 
    691     0    stevel char *
    692     0    stevel getxdr_hex(int len)
    693     0    stevel {
    694     0    stevel 	int i, j;
    695     0    stevel 	static char hbuff[1024];
    696     0    stevel 	char rbuff[1024];
    697     0    stevel 	static char *hexstr = "0123456789ABCDEF";
    698     0    stevel 	char toobig = 0;
    699     0    stevel 
    700     0    stevel 	if (len == 0) {
    701     0    stevel 		hbuff[0] = '\0';
    702     0    stevel 		return (hbuff);
    703     0    stevel 	}
    704     0    stevel 	if (len > 1024)
    705     0    stevel 		len = 1024;
    706     0    stevel 	if (len < 0 || xdr_opaque(&xdrm, rbuff, len) == FALSE) {
    707     0    stevel 		longjmp(xdr_err, 1);
    708     0    stevel 	}
    709     0    stevel 
    710     0    stevel 	if (len * 2 > sizeof (hbuff)) {
    711     0    stevel 		toobig++;
    712     0    stevel 		len = sizeof (hbuff) / 2;
    713     0    stevel 	}
    714     0    stevel 
    715     0    stevel 	j = 0;
    716     0    stevel 	for (i = 0; i < len; i++) {
    717     0    stevel 		hbuff[j++] = hexstr[rbuff[i] >> 4 & 0x0f];
    718     0    stevel 		hbuff[j++] = hexstr[rbuff[i] & 0x0f];
    719     0    stevel 	}
    720     0    stevel 
    721     0    stevel 	if (toobig) {
    722     0    stevel 		hbuff[len * 2 - strlen("<Too Long>")] = '\0';
    723     0    stevel 		strcat(hbuff, "<Too Long>");
    724     0    stevel 	} else
    725     0    stevel 		hbuff[j] = '\0';
    726     0    stevel 
    727     0    stevel 	return (hbuff);
    728     0    stevel }
    729     0    stevel 
    730     0    stevel char *
    731     0    stevel showxdr_hex(int len, char *fmt)
    732     0    stevel {
    733     0    stevel 	int pos;
    734     0    stevel 	char *p;
    735     0    stevel 
    736     0    stevel 	pos = getxdr_pos();
    737     0    stevel 	p = getxdr_hex(len);
    738     0    stevel 	(void) sprintf(get_line(pos, getxdr_pos()), fmt, p);
    739     0    stevel 	return (p);
    740     0    stevel }
    741     0    stevel 
    742     0    stevel static void
    743     0    stevel hexdump(char *data, int datalen)
    744     0    stevel {
    745     0    stevel 	char *p;
    746     0    stevel 	ushort_t *p16 = (ushort_t *)data;
    747     0    stevel 	char *p8 = data;
    748     0    stevel 	int i, left, len;
    749     0    stevel 	int chunk = 16;  /* 16 bytes per line */
    750     0    stevel 
    751     0    stevel 	printf("\n");
    752     0    stevel 
    753     0    stevel 	for (p = data; p < data + datalen; p += chunk) {
    754     0    stevel 		printf("\t%4d: ", p - data);
    755     0    stevel 		left = (data + datalen) - p;
    756     0    stevel 		len = MIN(chunk, left);
    757     0    stevel 		for (i = 0; i < (len / 2); i++)
    758     0    stevel 			printf("%04x ", ntohs(*p16++) & 0xffff);
    759     0    stevel 		if (len % 2) {
    760     0    stevel 			printf("%02x   ", *((unsigned char *)p16));
    761     0    stevel 		}
    762     0    stevel 		for (i = 0; i < (chunk - left) / 2; i++)
    763     0    stevel 			printf("     ");
    764     0    stevel 
    765     0    stevel 		printf("   ");
    766     0    stevel 		for (i = 0; i < len; i++, p8++)
    767     0    stevel 			printf("%c", isprint(*p8) ? *p8 : '.');
    768     0    stevel 		printf("\n");
    769     0    stevel 	}
    770     0    stevel 
    771     0    stevel 	printf("\n");
    772     0    stevel }
    773