1 /* NetBSD: print-ascii.c,v 1.1 1999/09/30 14:49:12 sjg Exp */ 2 3 /*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Alan Barrett and Simon J. Gerraty. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 __RCSID("$NetBSD: print-ascii.c,v 1.4 2014/11/20 03:05:03 christos Exp $"); 35 #endif 36 37 #define NETDISSECT_REWORKED 38 #ifdef HAVE_CONFIG_H 39 #include "config.h" 40 #endif 41 42 #include <tcpdump-stdinc.h> 43 #include <stdio.h> 44 45 #include "interface.h" 46 47 #define ASCII_LINELENGTH 300 48 #define HEXDUMP_BYTES_PER_LINE 16 49 #define HEXDUMP_SHORTS_PER_LINE (HEXDUMP_BYTES_PER_LINE / 2) 50 #define HEXDUMP_HEXSTUFF_PER_SHORT 5 /* 4 hex digits and a space */ 51 #define HEXDUMP_HEXSTUFF_PER_LINE \ 52 (HEXDUMP_HEXSTUFF_PER_SHORT * HEXDUMP_SHORTS_PER_LINE) 53 54 void 55 ascii_print(netdissect_options *ndo, 56 const u_char *cp, u_int length) 57 { 58 register u_char s; 59 60 ND_PRINT((ndo, "\n")); 61 while (length > 0) { 62 s = *cp++; 63 length--; 64 if (s == '\r') { 65 /* 66 * Don't print CRs at the end of the line; they 67 * don't belong at the ends of lines on UN*X, 68 * and the standard I/O library will give us one 69 * on Windows so we don't need to print one 70 * ourselves. 71 * 72 * In the middle of a line, just print a '.'. 73 */ 74 if (length > 1 && *cp != '\n') 75 ND_PRINT((ndo, ".")); 76 } else { 77 if (!ND_ISGRAPH(s) && 78 (s != '\t' && s != ' ' && s != '\n')) 79 ND_PRINT((ndo, ".")); 80 else 81 ND_PRINT((ndo, "%c", s)); 82 } 83 } 84 } 85 86 void 87 hex_and_ascii_print_with_offset(netdissect_options *ndo, register const char *ident, 88 register const u_char *cp, register u_int length, register u_int oset) 89 { 90 register u_int i; 91 register int s1, s2; 92 register int nshorts; 93 char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp; 94 char asciistuff[ASCII_LINELENGTH+1], *asp; 95 96 nshorts = length / sizeof(u_short); 97 i = 0; 98 hsp = hexstuff; asp = asciistuff; 99 while (--nshorts >= 0) { 100 s1 = *cp++; 101 s2 = *cp++; 102 (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff), 103 " %02x%02x", s1, s2); 104 hsp += HEXDUMP_HEXSTUFF_PER_SHORT; 105 *(asp++) = (ND_ISGRAPH(s1) ? s1 : '.'); 106 *(asp++) = (ND_ISGRAPH(s2) ? s2 : '.'); 107 i++; 108 if (i >= HEXDUMP_SHORTS_PER_LINE) { 109 *hsp = *asp = '\0'; 110 ND_PRINT((ndo, "%s0x%04x: %-*s %s", 111 ident, oset, HEXDUMP_HEXSTUFF_PER_LINE, 112 hexstuff, asciistuff)); 113 i = 0; hsp = hexstuff; asp = asciistuff; 114 oset += HEXDUMP_BYTES_PER_LINE; 115 } 116 } 117 if (length & 1) { 118 s1 = *cp++; 119 (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff), 120 " %02x", s1); 121 hsp += 3; 122 *(asp++) = (ND_ISGRAPH(s1) ? s1 : '.'); 123 ++i; 124 } 125 if (i > 0) { 126 *hsp = *asp = '\0'; 127 ND_PRINT((ndo, "%s0x%04x: %-*s %s", 128 ident, oset, HEXDUMP_HEXSTUFF_PER_LINE, 129 hexstuff, asciistuff)); 130 } 131 } 132 133 void 134 hex_and_ascii_print(netdissect_options *ndo, register const char *ident, 135 register const u_char *cp, register u_int length) 136 { 137 hex_and_ascii_print_with_offset(ndo, ident, cp, length, 0); 138 } 139 140 /* 141 * telnet_print() wants this. It is essentially default_print_unaligned() 142 */ 143 void 144 hex_print_with_offset(netdissect_options *ndo, 145 const char *ident, const u_char *cp, u_int length, 146 u_int oset) 147 { 148 register u_int i, s; 149 register int nshorts; 150 151 nshorts = (u_int) length / sizeof(u_short); 152 i = 0; 153 while (--nshorts >= 0) { 154 if ((i++ % 8) == 0) { 155 ND_PRINT((ndo,"%s0x%04x: ", ident, oset)); 156 oset += HEXDUMP_BYTES_PER_LINE; 157 } 158 s = *cp++; 159 ND_PRINT((ndo," %02x%02x", s, *cp++)); 160 } 161 if (length & 1) { 162 if ((i % 8) == 0) 163 ND_PRINT((ndo,"%s0x%04x: ", ident, oset)); 164 ND_PRINT((ndo," %02x", *cp)); 165 } 166 } 167 168 /* 169 * just for completeness 170 */ 171 void 172 hex_print(netdissect_options *ndo,const char *ident, const u_char *cp, u_int length) 173 { 174 hex_print_with_offset(ndo, ident, cp, length, 0); 175 } 176 177 #ifdef MAIN 178 int 179 main(int argc, char *argv[]) 180 { 181 hex_print("\n\t", "Hello, World!\n", 14); 182 printf("\n"); 183 hex_and_ascii_print("\n\t", "Hello, World!\n", 14); 184 printf("\n"); 185 ascii_print("Hello, World!\n", 14); 186 printf("\n"); 187 #define TMSG "Now is the winter of our discontent...\n" 188 hex_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100); 189 printf("\n"); 190 hex_and_ascii_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100); 191 printf("\n"); 192 exit(0); 193 } 194 #endif /* MAIN */ 195