17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5fb60e41dSss150715 * Common Development and Distribution License (the "License"). 6fb60e41dSss150715 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22fb60e41dSss150715 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*741913f0SGordon Ross * 25*741913f0SGordon Ross * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <stdio.h> 297c478bd9Sstevel@tonic-gate #include <stdlib.h> 307c478bd9Sstevel@tonic-gate #include <ctype.h> 317c478bd9Sstevel@tonic-gate #include <string.h> 327c478bd9Sstevel@tonic-gate #include <fcntl.h> 337c478bd9Sstevel@tonic-gate #include <string.h> 347c478bd9Sstevel@tonic-gate #include <sys/types.h> 357c478bd9Sstevel@tonic-gate #include <time.h> 367c478bd9Sstevel@tonic-gate #include <sys/time.h> 377c478bd9Sstevel@tonic-gate #include <sys/bufmod.h> 387c478bd9Sstevel@tonic-gate #include <setjmp.h> 39*741913f0SGordon Ross #include <stdarg.h> 407c478bd9Sstevel@tonic-gate #include <sys/socket.h> 417c478bd9Sstevel@tonic-gate #include <net/if.h> 427c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 437c478bd9Sstevel@tonic-gate #include <netinet/in.h> 447c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 457c478bd9Sstevel@tonic-gate #include <netinet/if_ether.h> 467c478bd9Sstevel@tonic-gate #include <rpc/types.h> 477c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 487c478bd9Sstevel@tonic-gate #include <inttypes.h> 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #include "snoop.h" 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate char *dlc_header; 537c478bd9Sstevel@tonic-gate char *src_name, *dst_name; 547c478bd9Sstevel@tonic-gate int pi_frame; 557c478bd9Sstevel@tonic-gate int pi_time_hour; 567c478bd9Sstevel@tonic-gate int pi_time_min; 577c478bd9Sstevel@tonic-gate int pi_time_sec; 587c478bd9Sstevel@tonic-gate int pi_time_usec; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate #ifndef MIN 617c478bd9Sstevel@tonic-gate #define MIN(a, b) ((a) < (b) ? (a) : (b)) 627c478bd9Sstevel@tonic-gate #endif 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate static void hexdump(char *, int); 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate /* 677c478bd9Sstevel@tonic-gate * This routine invokes the packet interpreters 687c478bd9Sstevel@tonic-gate * on a packet. There's some messing around 697c478bd9Sstevel@tonic-gate * setting up a few packet-externals before 707c478bd9Sstevel@tonic-gate * starting with the ethernet interpreter. 717c478bd9Sstevel@tonic-gate * Yes, we assume here that all packets will 727c478bd9Sstevel@tonic-gate * be ethernet packets. 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate void 757c478bd9Sstevel@tonic-gate process_pkt(struct sb_hdr *hdrp, char *pktp, int num, int flags) 767c478bd9Sstevel@tonic-gate { 777c478bd9Sstevel@tonic-gate int drops, pktlen; 787c478bd9Sstevel@tonic-gate struct timeval *tvp; 797c478bd9Sstevel@tonic-gate struct tm *tm; 807c478bd9Sstevel@tonic-gate extern int x_offset; 817c478bd9Sstevel@tonic-gate extern int x_length; 827c478bd9Sstevel@tonic-gate int offset, length; 837c478bd9Sstevel@tonic-gate static struct timeval ptv; 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate if (hdrp == NULL) 867c478bd9Sstevel@tonic-gate return; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate tvp = &hdrp->sbh_timestamp; 897c478bd9Sstevel@tonic-gate if (ptv.tv_sec == 0) 907c478bd9Sstevel@tonic-gate ptv = *tvp; 917c478bd9Sstevel@tonic-gate drops = hdrp->sbh_drops; 927c478bd9Sstevel@tonic-gate pktlen = hdrp->sbh_msglen; 937c478bd9Sstevel@tonic-gate if (pktlen <= 0) 947c478bd9Sstevel@tonic-gate return; 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* set up externals */ 977c478bd9Sstevel@tonic-gate dlc_header = pktp; 987c478bd9Sstevel@tonic-gate pi_frame = num; 997c478bd9Sstevel@tonic-gate tm = localtime(&tvp->tv_sec); 1007c478bd9Sstevel@tonic-gate pi_time_hour = tm->tm_hour; 1017c478bd9Sstevel@tonic-gate pi_time_min = tm->tm_min; 1027c478bd9Sstevel@tonic-gate pi_time_sec = tm->tm_sec; 1037c478bd9Sstevel@tonic-gate pi_time_usec = tvp->tv_usec; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate src_name = "?"; 1067c478bd9Sstevel@tonic-gate dst_name = "*"; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate click(hdrp->sbh_origlen); 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate (*interface->interpreter)(flags, dlc_header, hdrp->sbh_msglen, 1117c478bd9Sstevel@tonic-gate hdrp->sbh_origlen); 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate show_pktinfo(flags, num, src_name, dst_name, &ptv, tvp, drops, 1147c478bd9Sstevel@tonic-gate hdrp->sbh_origlen); 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate if (x_offset >= 0) { 1177c478bd9Sstevel@tonic-gate offset = MIN(x_offset, hdrp->sbh_msglen); 1187c478bd9Sstevel@tonic-gate offset -= (offset % 2); /* round down */ 1197c478bd9Sstevel@tonic-gate length = MIN(hdrp->sbh_msglen - offset, x_length); 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate hexdump(dlc_header + offset, length); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate ptv = *tvp; 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate /* 1297c478bd9Sstevel@tonic-gate * ************************************************************* 1307c478bd9Sstevel@tonic-gate * The following routines constitute a library 1317c478bd9Sstevel@tonic-gate * used by the packet interpreters to facilitate 1327c478bd9Sstevel@tonic-gate * the display of packet data. This library 1337c478bd9Sstevel@tonic-gate * of routines helps provide a consistent 1347c478bd9Sstevel@tonic-gate * "look and feel". 1357c478bd9Sstevel@tonic-gate */ 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate /* 1397c478bd9Sstevel@tonic-gate * Display the value of a flag bit in 1407c478bd9Sstevel@tonic-gate * a byte together with some text that 1417c478bd9Sstevel@tonic-gate * corresponds to its value - whether 1427c478bd9Sstevel@tonic-gate * true or false. 1437c478bd9Sstevel@tonic-gate */ 1447c478bd9Sstevel@tonic-gate char * 1457c478bd9Sstevel@tonic-gate getflag(int val, int mask, char *s_true, char *s_false) 1467c478bd9Sstevel@tonic-gate { 1477c478bd9Sstevel@tonic-gate static char buff[80]; 1487c478bd9Sstevel@tonic-gate char *p; 1497c478bd9Sstevel@tonic-gate int set; 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate (void) strcpy(buff, ".... .... = "); 1527c478bd9Sstevel@tonic-gate if (s_false == NULL) 1537c478bd9Sstevel@tonic-gate s_false = s_true; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate for (p = &buff[8]; p >= buff; p--) { 1567c478bd9Sstevel@tonic-gate if (*p == ' ') 1577c478bd9Sstevel@tonic-gate p--; 1587c478bd9Sstevel@tonic-gate if (mask & 0x1) { 1597c478bd9Sstevel@tonic-gate set = val & mask & 0x1; 1607c478bd9Sstevel@tonic-gate *p = set ? '1':'0'; 1617c478bd9Sstevel@tonic-gate (void) strcat(buff, set ? s_true: s_false); 1627c478bd9Sstevel@tonic-gate break; 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate mask >>= 1; 1657c478bd9Sstevel@tonic-gate val >>= 1; 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate return (buff); 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate XDR xdrm; 1717c478bd9Sstevel@tonic-gate jmp_buf xdr_err; 1727c478bd9Sstevel@tonic-gate int xdr_totlen; 1737c478bd9Sstevel@tonic-gate char *prot_prefix; 1747c478bd9Sstevel@tonic-gate char *prot_nest_prefix = ""; 1757c478bd9Sstevel@tonic-gate char *prot_title; 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate void 1787c478bd9Sstevel@tonic-gate show_header(char *pref, char *str, int len) 1797c478bd9Sstevel@tonic-gate { 1807c478bd9Sstevel@tonic-gate prot_prefix = pref; 1817c478bd9Sstevel@tonic-gate prot_title = str; 1827c478bd9Sstevel@tonic-gate (void) sprintf(get_detail_line(0, len), "%s%s----- %s -----", 1837c478bd9Sstevel@tonic-gate prot_nest_prefix, pref, str); 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate void 1877c478bd9Sstevel@tonic-gate xdr_init(char *addr, int len) 1887c478bd9Sstevel@tonic-gate { 1897c478bd9Sstevel@tonic-gate xdr_totlen = len; 1907c478bd9Sstevel@tonic-gate xdrmem_create(&xdrm, addr, len, XDR_DECODE); 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 193*741913f0SGordon Ross /* Note: begin+end are ignored in get_detail_line */ 1947c478bd9Sstevel@tonic-gate char * 1957c478bd9Sstevel@tonic-gate get_line(int begin, int end) 1967c478bd9Sstevel@tonic-gate { 1977c478bd9Sstevel@tonic-gate char *line; 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate line = get_detail_line(begin, end); 2007c478bd9Sstevel@tonic-gate (void) strcpy(line, prot_nest_prefix); 2017c478bd9Sstevel@tonic-gate (void) strcat(line, prot_prefix); 2027c478bd9Sstevel@tonic-gate return (line + strlen(line)); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate int 2067c478bd9Sstevel@tonic-gate get_line_remain(void) 2077c478bd9Sstevel@tonic-gate { 2087c478bd9Sstevel@tonic-gate return (MAXLINE - strlen(prot_nest_prefix) - strlen(prot_prefix)); 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate void 2127c478bd9Sstevel@tonic-gate show_line(char *str) 2137c478bd9Sstevel@tonic-gate { 214*741913f0SGordon Ross (void) strlcpy(get_line(0, 0), str, get_line_remain()); 215*741913f0SGordon Ross } 216*741913f0SGordon Ross 217*741913f0SGordon Ross void 218*741913f0SGordon Ross show_printf(char *fmt, ...) 219*741913f0SGordon Ross { 220*741913f0SGordon Ross va_list ap; 221*741913f0SGordon Ross 222*741913f0SGordon Ross va_start(ap, fmt); 223*741913f0SGordon Ross (void) vsnprintf(get_line(0, 0), get_line_remain(), fmt, ap); 224*741913f0SGordon Ross va_end(ap); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate char 2287c478bd9Sstevel@tonic-gate getxdr_char() 2297c478bd9Sstevel@tonic-gate { 2307c478bd9Sstevel@tonic-gate char s; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate if (xdr_char(&xdrm, &s)) 2337c478bd9Sstevel@tonic-gate return (s); 2347c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 2357c478bd9Sstevel@tonic-gate /* NOTREACHED */ 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate char 2397c478bd9Sstevel@tonic-gate showxdr_char(char *fmt) 2407c478bd9Sstevel@tonic-gate { 2417c478bd9Sstevel@tonic-gate int pos; char val; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 2447c478bd9Sstevel@tonic-gate val = getxdr_char(); 2457c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, val); 2467c478bd9Sstevel@tonic-gate return (val); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate uchar_t 2507c478bd9Sstevel@tonic-gate getxdr_u_char() 2517c478bd9Sstevel@tonic-gate { 2527c478bd9Sstevel@tonic-gate uchar_t s; 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate if (xdr_u_char(&xdrm, &s)) 2557c478bd9Sstevel@tonic-gate return (s); 2567c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 2577c478bd9Sstevel@tonic-gate /* NOTREACHED */ 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate uchar_t 2617c478bd9Sstevel@tonic-gate showxdr_u_char(char *fmt) 2627c478bd9Sstevel@tonic-gate { 2637c478bd9Sstevel@tonic-gate int pos; 2647c478bd9Sstevel@tonic-gate uchar_t val; 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 2677c478bd9Sstevel@tonic-gate val = getxdr_u_char(); 2687c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, val); 2697c478bd9Sstevel@tonic-gate return (val); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate short 2737c478bd9Sstevel@tonic-gate getxdr_short() 2747c478bd9Sstevel@tonic-gate { 2757c478bd9Sstevel@tonic-gate short s; 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate if (xdr_short(&xdrm, &s)) 2787c478bd9Sstevel@tonic-gate return (s); 2797c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 2807c478bd9Sstevel@tonic-gate /* NOTREACHED */ 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate short 2847c478bd9Sstevel@tonic-gate showxdr_short(char *fmt) 2857c478bd9Sstevel@tonic-gate { 2867c478bd9Sstevel@tonic-gate int pos; short val; 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 2897c478bd9Sstevel@tonic-gate val = getxdr_short(); 2907c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, val); 2917c478bd9Sstevel@tonic-gate return (val); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate ushort_t 2957c478bd9Sstevel@tonic-gate getxdr_u_short() 2967c478bd9Sstevel@tonic-gate { 2977c478bd9Sstevel@tonic-gate ushort_t s; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate if (xdr_u_short(&xdrm, &s)) 3007c478bd9Sstevel@tonic-gate return (s); 3017c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 3027c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate ushort_t 3067c478bd9Sstevel@tonic-gate showxdr_u_short(char *fmt) 3077c478bd9Sstevel@tonic-gate { 3087c478bd9Sstevel@tonic-gate int pos; 3097c478bd9Sstevel@tonic-gate ushort_t val; 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 3127c478bd9Sstevel@tonic-gate val = getxdr_u_short(); 3137c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, val); 3147c478bd9Sstevel@tonic-gate return (val); 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate long 3187c478bd9Sstevel@tonic-gate getxdr_long() 3197c478bd9Sstevel@tonic-gate { 3207c478bd9Sstevel@tonic-gate long l; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate if (xdr_long(&xdrm, &l)) 3237c478bd9Sstevel@tonic-gate return (l); 3247c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 3257c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate long 3297c478bd9Sstevel@tonic-gate showxdr_long(char *fmt) 3307c478bd9Sstevel@tonic-gate { 3317c478bd9Sstevel@tonic-gate int pos; long val; 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 3347c478bd9Sstevel@tonic-gate val = getxdr_long(); 3357c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, val); 3367c478bd9Sstevel@tonic-gate return (val); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate ulong_t 3407c478bd9Sstevel@tonic-gate getxdr_u_long() 3417c478bd9Sstevel@tonic-gate { 3427c478bd9Sstevel@tonic-gate ulong_t l; 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate if (xdr_u_long(&xdrm, &l)) 3457c478bd9Sstevel@tonic-gate return (l); 3467c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 3477c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate ulong_t 3517c478bd9Sstevel@tonic-gate showxdr_u_long(char *fmt) 3527c478bd9Sstevel@tonic-gate { 3537c478bd9Sstevel@tonic-gate int pos; 3547c478bd9Sstevel@tonic-gate ulong_t val; 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 3577c478bd9Sstevel@tonic-gate val = getxdr_u_long(); 3587c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, val); 3597c478bd9Sstevel@tonic-gate return (val); 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate longlong_t 3637c478bd9Sstevel@tonic-gate getxdr_longlong() 3647c478bd9Sstevel@tonic-gate { 3657c478bd9Sstevel@tonic-gate longlong_t l; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate if (xdr_longlong_t(&xdrm, &l)) 3687c478bd9Sstevel@tonic-gate return (l); 3697c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 3707c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate longlong_t 3747c478bd9Sstevel@tonic-gate showxdr_longlong(char *fmt) 3757c478bd9Sstevel@tonic-gate { 3767c478bd9Sstevel@tonic-gate int pos; longlong_t val; 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 3797c478bd9Sstevel@tonic-gate val = getxdr_longlong(); 3807c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, val); 3817c478bd9Sstevel@tonic-gate return (val); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate u_longlong_t 3857c478bd9Sstevel@tonic-gate getxdr_u_longlong() 3867c478bd9Sstevel@tonic-gate { 3877c478bd9Sstevel@tonic-gate u_longlong_t l; 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate if (xdr_u_longlong_t(&xdrm, &l)) 3907c478bd9Sstevel@tonic-gate return (l); 3917c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 3927c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate u_longlong_t 3967c478bd9Sstevel@tonic-gate showxdr_u_longlong(char *fmt) 3977c478bd9Sstevel@tonic-gate { 3987c478bd9Sstevel@tonic-gate int pos; u_longlong_t val; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 4017c478bd9Sstevel@tonic-gate val = getxdr_u_longlong(); 4027c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, val); 4037c478bd9Sstevel@tonic-gate return (val); 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate bool_t 4077c478bd9Sstevel@tonic-gate getxdr_bool() 4087c478bd9Sstevel@tonic-gate { 4097c478bd9Sstevel@tonic-gate bool_t b; 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate if (xdr_bool(&xdrm, &b)) 4127c478bd9Sstevel@tonic-gate return (b); 4137c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 4147c478bd9Sstevel@tonic-gate /* NOTREACHED */ 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate bool_t 4187c478bd9Sstevel@tonic-gate showxdr_bool(char *fmt) 4197c478bd9Sstevel@tonic-gate { 4207c478bd9Sstevel@tonic-gate int pos; bool_t val; 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 4237c478bd9Sstevel@tonic-gate val = getxdr_bool(); 4247c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, 4257c478bd9Sstevel@tonic-gate val ? "True" : "False"); 4267c478bd9Sstevel@tonic-gate return (val); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate char * 4307c478bd9Sstevel@tonic-gate getxdr_opaque(char *p, int len) 4317c478bd9Sstevel@tonic-gate { 4327c478bd9Sstevel@tonic-gate if (xdr_opaque(&xdrm, p, len)) 4337c478bd9Sstevel@tonic-gate return (p); 4347c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 4357c478bd9Sstevel@tonic-gate /* NOTREACHED */ 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate char * 4397c478bd9Sstevel@tonic-gate getxdr_string(char *p, /* len+1 bytes or longer */ 4407c478bd9Sstevel@tonic-gate int len) 4417c478bd9Sstevel@tonic-gate { 4427c478bd9Sstevel@tonic-gate if (xdr_string(&xdrm, &p, len)) 4437c478bd9Sstevel@tonic-gate return (p); 4447c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 4457c478bd9Sstevel@tonic-gate /* NOTREACHED */ 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate char * 4497c478bd9Sstevel@tonic-gate showxdr_string(int len, /* XDR length */ 4507c478bd9Sstevel@tonic-gate char *fmt) 4517c478bd9Sstevel@tonic-gate { 4527c478bd9Sstevel@tonic-gate static int buff_len = 0; 4537c478bd9Sstevel@tonic-gate static char *buff = NULL; 4547c478bd9Sstevel@tonic-gate int pos; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate /* 4577c478bd9Sstevel@tonic-gate * XDR strings don't necessarily have a trailing null over the 4587c478bd9Sstevel@tonic-gate * wire. However, the XDR code will put one in for us. Make sure 4597c478bd9Sstevel@tonic-gate * we have allocated room for it. 4607c478bd9Sstevel@tonic-gate */ 4617c478bd9Sstevel@tonic-gate len++; 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate if ((len > buff_len) || (buff_len == 0)) { 4647c478bd9Sstevel@tonic-gate if (buff) 4657c478bd9Sstevel@tonic-gate free(buff); 4667c478bd9Sstevel@tonic-gate if ((buff = (char *)malloc(len)) == NULL) 4677c478bd9Sstevel@tonic-gate pr_err("showxdr_string: no mem"); 4687c478bd9Sstevel@tonic-gate buff_len = len; 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 4717c478bd9Sstevel@tonic-gate getxdr_string(buff, len); 4727c478bd9Sstevel@tonic-gate (void) strcpy(buff+60, "..."); 4737c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, buff); 4747c478bd9Sstevel@tonic-gate return (buff); 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate char * 4787c478bd9Sstevel@tonic-gate getxdr_bytes(uint_t *lenp) 4797c478bd9Sstevel@tonic-gate { 4807c478bd9Sstevel@tonic-gate static char buff[1024]; 4817c478bd9Sstevel@tonic-gate char *p = buff; 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate if (xdr_bytes(&xdrm, &p, lenp, 1024)) 4847c478bd9Sstevel@tonic-gate return (buff); 4857c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 4867c478bd9Sstevel@tonic-gate /* NOTREACHED */ 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate char * 4907c478bd9Sstevel@tonic-gate getxdr_context(char *p, int len) 4917c478bd9Sstevel@tonic-gate { 4927c478bd9Sstevel@tonic-gate ushort_t size; 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate size = getxdr_u_short(); 4957c478bd9Sstevel@tonic-gate if (((int)size > 0) && ((int)size < len) && getxdr_opaque(p, size)) 4967c478bd9Sstevel@tonic-gate return (p); 4977c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 4987c478bd9Sstevel@tonic-gate /* NOTREACHED */ 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate char * 5027c478bd9Sstevel@tonic-gate showxdr_context(char *fmt) 5037c478bd9Sstevel@tonic-gate { 5047c478bd9Sstevel@tonic-gate ushort_t size; 5057c478bd9Sstevel@tonic-gate static char buff[1024]; 5067c478bd9Sstevel@tonic-gate int pos; 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 5097c478bd9Sstevel@tonic-gate size = getxdr_u_short(); 5107c478bd9Sstevel@tonic-gate if (((int)size > 0) && ((int)size < 1024) && 5117c478bd9Sstevel@tonic-gate getxdr_opaque(buff, size)) { 5127c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, buff); 5137c478bd9Sstevel@tonic-gate return (buff); 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 5167c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5177c478bd9Sstevel@tonic-gate } 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate enum_t 5207c478bd9Sstevel@tonic-gate getxdr_enum() 5217c478bd9Sstevel@tonic-gate { 5227c478bd9Sstevel@tonic-gate enum_t e; 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate if (xdr_enum(&xdrm, &e)) 5257c478bd9Sstevel@tonic-gate return (e); 5267c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 5277c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate void 5317c478bd9Sstevel@tonic-gate xdr_skip(int delta) 5327c478bd9Sstevel@tonic-gate { 5337c478bd9Sstevel@tonic-gate uint_t pos; 5347c478bd9Sstevel@tonic-gate if (delta % 4 != 0 || delta < 0) 5357c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 5367c478bd9Sstevel@tonic-gate /* Check for overflow */ 5377c478bd9Sstevel@tonic-gate pos = xdr_getpos(&xdrm); 5387c478bd9Sstevel@tonic-gate if ((pos + delta) < pos) 5397c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 5407c478bd9Sstevel@tonic-gate /* xdr_setpos() checks for buffer overrun */ 5417c478bd9Sstevel@tonic-gate if (xdr_setpos(&xdrm, pos + delta) == FALSE) 5427c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate int 5467c478bd9Sstevel@tonic-gate getxdr_pos() 5477c478bd9Sstevel@tonic-gate { 5487c478bd9Sstevel@tonic-gate return (xdr_getpos(&xdrm)); 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate void 5527c478bd9Sstevel@tonic-gate setxdr_pos(int pos) 5537c478bd9Sstevel@tonic-gate { 5547c478bd9Sstevel@tonic-gate xdr_setpos(&xdrm, pos); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate void 5587c478bd9Sstevel@tonic-gate show_space() 5597c478bd9Sstevel@tonic-gate { 5607c478bd9Sstevel@tonic-gate (void) get_line(0, 0); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate void 5647c478bd9Sstevel@tonic-gate show_trailer() 5657c478bd9Sstevel@tonic-gate { 5667c478bd9Sstevel@tonic-gate show_space(); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate char * 5707c478bd9Sstevel@tonic-gate getxdr_date() 5717c478bd9Sstevel@tonic-gate { 5727c478bd9Sstevel@tonic-gate time_t sec; 5737c478bd9Sstevel@tonic-gate int usec; 5747c478bd9Sstevel@tonic-gate static char buff[64]; 5757c478bd9Sstevel@tonic-gate char *p; 5767c478bd9Sstevel@tonic-gate struct tm my_time; /* private buffer to avoid collision */ 5777c478bd9Sstevel@tonic-gate /* between gmtime and strftime */ 5787c478bd9Sstevel@tonic-gate struct tm *tmp; 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate sec = getxdr_long(); 5817c478bd9Sstevel@tonic-gate usec = getxdr_long(); 5827c478bd9Sstevel@tonic-gate if (sec == -1) 5837c478bd9Sstevel@tonic-gate return ("-1 "); 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate if (sec < 3600 * 24 * 365) { /* assume not a date */ 5867c478bd9Sstevel@tonic-gate (void) sprintf(buff, "%d.%06d", sec, usec); 5877c478bd9Sstevel@tonic-gate } else { 5887c478bd9Sstevel@tonic-gate tmp = gmtime(&sec); 5897c478bd9Sstevel@tonic-gate (void) memcpy(&my_time, tmp, sizeof (struct tm)); 5907c478bd9Sstevel@tonic-gate strftime(buff, sizeof (buff), "%d-%h-%y %T.", &my_time); 5917c478bd9Sstevel@tonic-gate p = buff + strlen(buff); 5927c478bd9Sstevel@tonic-gate (void) sprintf(p, "%06d GMT", usec); 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate return (buff); 5957c478bd9Sstevel@tonic-gate } 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate char * 5987c478bd9Sstevel@tonic-gate showxdr_date(char *fmt) 5997c478bd9Sstevel@tonic-gate { 6007c478bd9Sstevel@tonic-gate int pos; 6017c478bd9Sstevel@tonic-gate char *p; 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 6047c478bd9Sstevel@tonic-gate p = getxdr_date(); 6057c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, p); 6067c478bd9Sstevel@tonic-gate return (p); 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate char * 6107c478bd9Sstevel@tonic-gate getxdr_date_ns(void) 6117c478bd9Sstevel@tonic-gate { 6127c478bd9Sstevel@tonic-gate time_t sec, nsec; 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate sec = getxdr_long(); 6157c478bd9Sstevel@tonic-gate nsec = getxdr_long(); 6167c478bd9Sstevel@tonic-gate if (sec == -1) 6177c478bd9Sstevel@tonic-gate return ("-1 "); 6187c478bd9Sstevel@tonic-gate else 6197c478bd9Sstevel@tonic-gate return (format_time(sec, nsec)); 6207c478bd9Sstevel@tonic-gate } 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate /* 6237c478bd9Sstevel@tonic-gate * Format the given time. 6247c478bd9Sstevel@tonic-gate */ 6257c478bd9Sstevel@tonic-gate char * 6267c478bd9Sstevel@tonic-gate format_time(int64_t sec, uint32_t nsec) 6277c478bd9Sstevel@tonic-gate { 6287c478bd9Sstevel@tonic-gate static char buff[64]; 6297c478bd9Sstevel@tonic-gate char *p; 6307c478bd9Sstevel@tonic-gate struct tm my_time; /* private buffer to avoid collision */ 6317c478bd9Sstevel@tonic-gate /* between gmtime and strftime */ 6327c478bd9Sstevel@tonic-gate struct tm *tmp; 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate if (sec < 3600 * 24 * 365) { 6357c478bd9Sstevel@tonic-gate /* assume not a date; includes negative times */ 6367c478bd9Sstevel@tonic-gate (void) sprintf(buff, "%lld.%06d", sec, nsec); 6377c478bd9Sstevel@tonic-gate } else if (sec > INT32_MAX) { 6387c478bd9Sstevel@tonic-gate /* 6397c478bd9Sstevel@tonic-gate * XXX No routines are available yet for formatting 64-bit 6407c478bd9Sstevel@tonic-gate * times. 6417c478bd9Sstevel@tonic-gate */ 6427c478bd9Sstevel@tonic-gate (void) sprintf(buff, "%lld.%06d", sec, nsec); 6437c478bd9Sstevel@tonic-gate } else { 6447c478bd9Sstevel@tonic-gate time_t sec32 = (time_t)sec; 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate tmp = gmtime(&sec32); 6477c478bd9Sstevel@tonic-gate memcpy(&my_time, tmp, sizeof (struct tm)); 6487c478bd9Sstevel@tonic-gate strftime(buff, sizeof (buff), "%d-%h-%y %T.", &my_time); 6497c478bd9Sstevel@tonic-gate p = buff + strlen(buff); 6507c478bd9Sstevel@tonic-gate (void) sprintf(p, "%09d GMT", nsec); 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate return (buff); 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate char * 6567c478bd9Sstevel@tonic-gate showxdr_date_ns(char *fmt) 6577c478bd9Sstevel@tonic-gate { 6587c478bd9Sstevel@tonic-gate int pos; 6597c478bd9Sstevel@tonic-gate char *p; 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 6627c478bd9Sstevel@tonic-gate p = getxdr_date_ns(); 6637c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, p); 6647c478bd9Sstevel@tonic-gate return (p); 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate char * 6687c478bd9Sstevel@tonic-gate getxdr_time() 6697c478bd9Sstevel@tonic-gate { 6707c478bd9Sstevel@tonic-gate time_t sec; 6717c478bd9Sstevel@tonic-gate static char buff[64]; 6727c478bd9Sstevel@tonic-gate struct tm my_time; /* private buffer to avoid collision */ 6737c478bd9Sstevel@tonic-gate /* between gmtime and strftime */ 6747c478bd9Sstevel@tonic-gate struct tm *tmp; 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate sec = getxdr_long(); 6777c478bd9Sstevel@tonic-gate if (sec == -1) 6787c478bd9Sstevel@tonic-gate return ("-1 "); 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate if (sec < 3600 * 24 * 365) { /* assume not a date */ 6817c478bd9Sstevel@tonic-gate (void) sprintf(buff, "%d", sec); 6827c478bd9Sstevel@tonic-gate } else { 6837c478bd9Sstevel@tonic-gate tmp = gmtime(&sec); 6847c478bd9Sstevel@tonic-gate memcpy(&my_time, tmp, sizeof (struct tm)); 6857c478bd9Sstevel@tonic-gate strftime(buff, sizeof (buff), "%d-%h-%y %T", &my_time); 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate return (buff); 6887c478bd9Sstevel@tonic-gate } 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate char * 6917c478bd9Sstevel@tonic-gate showxdr_time(char *fmt) 6927c478bd9Sstevel@tonic-gate { 6937c478bd9Sstevel@tonic-gate int pos; 6947c478bd9Sstevel@tonic-gate char *p; 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 6977c478bd9Sstevel@tonic-gate p = getxdr_time(); 6987c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, p); 6997c478bd9Sstevel@tonic-gate return (p); 7007c478bd9Sstevel@tonic-gate } 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate char * 7037c478bd9Sstevel@tonic-gate getxdr_hex(int len) 7047c478bd9Sstevel@tonic-gate { 7057c478bd9Sstevel@tonic-gate int i, j; 7067c478bd9Sstevel@tonic-gate static char hbuff[1024]; 7077c478bd9Sstevel@tonic-gate char rbuff[1024]; 7087c478bd9Sstevel@tonic-gate static char *hexstr = "0123456789ABCDEF"; 7097c478bd9Sstevel@tonic-gate char toobig = 0; 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate if (len == 0) { 7127c478bd9Sstevel@tonic-gate hbuff[0] = '\0'; 7137c478bd9Sstevel@tonic-gate return (hbuff); 7147c478bd9Sstevel@tonic-gate } 7157c478bd9Sstevel@tonic-gate if (len > 1024) 7167c478bd9Sstevel@tonic-gate len = 1024; 7177c478bd9Sstevel@tonic-gate if (len < 0 || xdr_opaque(&xdrm, rbuff, len) == FALSE) { 7187c478bd9Sstevel@tonic-gate longjmp(xdr_err, 1); 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate if (len * 2 > sizeof (hbuff)) { 7227c478bd9Sstevel@tonic-gate toobig++; 7237c478bd9Sstevel@tonic-gate len = sizeof (hbuff) / 2; 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate j = 0; 7277c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) { 7287c478bd9Sstevel@tonic-gate hbuff[j++] = hexstr[rbuff[i] >> 4 & 0x0f]; 7297c478bd9Sstevel@tonic-gate hbuff[j++] = hexstr[rbuff[i] & 0x0f]; 7307c478bd9Sstevel@tonic-gate } 7317c478bd9Sstevel@tonic-gate 7327c478bd9Sstevel@tonic-gate if (toobig) { 7337c478bd9Sstevel@tonic-gate hbuff[len * 2 - strlen("<Too Long>")] = '\0'; 7347c478bd9Sstevel@tonic-gate strcat(hbuff, "<Too Long>"); 7357c478bd9Sstevel@tonic-gate } else 7367c478bd9Sstevel@tonic-gate hbuff[j] = '\0'; 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate return (hbuff); 7397c478bd9Sstevel@tonic-gate } 7407c478bd9Sstevel@tonic-gate 7417c478bd9Sstevel@tonic-gate char * 7427c478bd9Sstevel@tonic-gate showxdr_hex(int len, char *fmt) 7437c478bd9Sstevel@tonic-gate { 7447c478bd9Sstevel@tonic-gate int pos; 7457c478bd9Sstevel@tonic-gate char *p; 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate pos = getxdr_pos(); 7487c478bd9Sstevel@tonic-gate p = getxdr_hex(len); 7497c478bd9Sstevel@tonic-gate (void) sprintf(get_line(pos, getxdr_pos()), fmt, p); 7507c478bd9Sstevel@tonic-gate return (p); 7517c478bd9Sstevel@tonic-gate } 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate static void 7547c478bd9Sstevel@tonic-gate hexdump(char *data, int datalen) 7557c478bd9Sstevel@tonic-gate { 7567c478bd9Sstevel@tonic-gate char *p; 7577c478bd9Sstevel@tonic-gate ushort_t *p16 = (ushort_t *)data; 7587c478bd9Sstevel@tonic-gate char *p8 = data; 7597c478bd9Sstevel@tonic-gate int i, left, len; 7607c478bd9Sstevel@tonic-gate int chunk = 16; /* 16 bytes per line */ 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate printf("\n"); 7637c478bd9Sstevel@tonic-gate 7647c478bd9Sstevel@tonic-gate for (p = data; p < data + datalen; p += chunk) { 7657c478bd9Sstevel@tonic-gate printf("\t%4d: ", p - data); 7667c478bd9Sstevel@tonic-gate left = (data + datalen) - p; 7677c478bd9Sstevel@tonic-gate len = MIN(chunk, left); 7687c478bd9Sstevel@tonic-gate for (i = 0; i < (len / 2); i++) 7697c478bd9Sstevel@tonic-gate printf("%04x ", ntohs(*p16++) & 0xffff); 7707c478bd9Sstevel@tonic-gate if (len % 2) { 7717c478bd9Sstevel@tonic-gate printf("%02x ", *((unsigned char *)p16)); 7727c478bd9Sstevel@tonic-gate } 7737c478bd9Sstevel@tonic-gate for (i = 0; i < (chunk - left) / 2; i++) 7747c478bd9Sstevel@tonic-gate printf(" "); 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate printf(" "); 7777c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++, p8++) 7787c478bd9Sstevel@tonic-gate printf("%c", isprint(*p8) ? *p8 : '.'); 7797c478bd9Sstevel@tonic-gate printf("\n"); 7807c478bd9Sstevel@tonic-gate } 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate printf("\n"); 7837c478bd9Sstevel@tonic-gate } 784*741913f0SGordon Ross 785*741913f0SGordon Ross char * 786*741913f0SGordon Ross show_string(const char *str, int dlen, int maxlen) 787*741913f0SGordon Ross /* 788*741913f0SGordon Ross * Prints len bytes from str enclosed in quotes. 789*741913f0SGordon Ross * If len is negative, length is taken from strlen(str). 790*741913f0SGordon Ross * No more than maxlen bytes will be printed. Longer 791*741913f0SGordon Ross * strings are flagged with ".." after the closing quote. 792*741913f0SGordon Ross * Non-printing characters are converted to C-style escape 793*741913f0SGordon Ross * codes or octal digits. 794*741913f0SGordon Ross */ 795*741913f0SGordon Ross { 796*741913f0SGordon Ross #define TBSIZE 256 797*741913f0SGordon Ross static char tbuff[TBSIZE]; 798*741913f0SGordon Ross const char *p; 799*741913f0SGordon Ross char *pp; 800*741913f0SGordon Ross int printable = 0; 801*741913f0SGordon Ross int c, len; 802*741913f0SGordon Ross 803*741913f0SGordon Ross len = dlen > maxlen ? maxlen : dlen; 804*741913f0SGordon Ross dlen = len; 805*741913f0SGordon Ross 806*741913f0SGordon Ross for (p = str, pp = tbuff; len; p++, len--) { 807*741913f0SGordon Ross switch (c = *p & 0xFF) { 808*741913f0SGordon Ross case '\n': (void) strcpy(pp, "\\n"); pp += 2; break; 809*741913f0SGordon Ross case '\b': (void) strcpy(pp, "\\b"); pp += 2; break; 810*741913f0SGordon Ross case '\t': (void) strcpy(pp, "\\t"); pp += 2; break; 811*741913f0SGordon Ross case '\r': (void) strcpy(pp, "\\r"); pp += 2; break; 812*741913f0SGordon Ross case '\f': (void) strcpy(pp, "\\f"); pp += 2; break; 813*741913f0SGordon Ross default: 814*741913f0SGordon Ross if (isascii(c) && isprint(c)) { 815*741913f0SGordon Ross *pp++ = c; 816*741913f0SGordon Ross printable++; 817*741913f0SGordon Ross } else { 818*741913f0SGordon Ross (void) snprintf(pp, TBSIZE - (pp - tbuff), 819*741913f0SGordon Ross isdigit(*(p + 1)) ? 820*741913f0SGordon Ross "\\%03o" : "\\%o", c); 821*741913f0SGordon Ross pp += strlen(pp); 822*741913f0SGordon Ross } 823*741913f0SGordon Ross break; 824*741913f0SGordon Ross } 825*741913f0SGordon Ross *pp = '\0'; 826*741913f0SGordon Ross /* 827*741913f0SGordon Ross * Check for overflow of temporary buffer. Allow for 828*741913f0SGordon Ross * the next character to be a \nnn followed by a trailing 829*741913f0SGordon Ross * null. If not, then just bail with what we have. 830*741913f0SGordon Ross */ 831*741913f0SGordon Ross if (pp + 5 >= &tbuff[TBSIZE]) { 832*741913f0SGordon Ross break; 833*741913f0SGordon Ross } 834*741913f0SGordon Ross } 835*741913f0SGordon Ross return (printable > dlen / 2 ? tbuff : ""); 836*741913f0SGordon Ross } 837