xref: /freebsd/contrib/tcpdump/print-ascii.c (revision 2ebc47db5b33ca26b73b76374760c587c38ef385)
1b0453382SBill Fenner /*	$NetBSD: print-ascii.c,v 1.1 1999/09/30 14:49:12 sjg Exp $ 	*/
2b0453382SBill Fenner 
3b0453382SBill Fenner /*-
4b0453382SBill Fenner  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5b0453382SBill Fenner  * All rights reserved.
6b0453382SBill Fenner  *
7b0453382SBill Fenner  * This code is derived from software contributed to The NetBSD Foundation
8b0453382SBill Fenner  * by Alan Barrett and Simon J. Gerraty.
9b0453382SBill Fenner  *
10b0453382SBill Fenner  * Redistribution and use in source and binary forms, with or without
11b0453382SBill Fenner  * modification, are permitted provided that the following conditions
12b0453382SBill Fenner  * are met:
13b0453382SBill Fenner  * 1. Redistributions of source code must retain the above copyright
14b0453382SBill Fenner  *    notice, this list of conditions and the following disclaimer.
15b0453382SBill Fenner  * 2. Redistributions in binary form must reproduce the above copyright
16b0453382SBill Fenner  *    notice, this list of conditions and the following disclaimer in the
17b0453382SBill Fenner  *    documentation and/or other materials provided with the distribution.
18b0453382SBill Fenner  * 3. All advertising materials mentioning features or use of this software
19b0453382SBill Fenner  *    must display the following acknowledgement:
20b0453382SBill Fenner  *        This product includes software developed by the NetBSD
21b0453382SBill Fenner  *        Foundation, Inc. and its contributors.
22b0453382SBill Fenner  * 4. Neither the name of The NetBSD Foundation nor the names of its
23b0453382SBill Fenner  *    contributors may be used to endorse or promote products derived
24b0453382SBill Fenner  *    from this software without specific prior written permission.
25b0453382SBill Fenner  *
26b0453382SBill Fenner  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27b0453382SBill Fenner  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28b0453382SBill Fenner  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29b0453382SBill Fenner  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30b0453382SBill Fenner  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31b0453382SBill Fenner  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32b0453382SBill Fenner  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33b0453382SBill Fenner  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34b0453382SBill Fenner  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35b0453382SBill Fenner  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36b0453382SBill Fenner  * POSSIBILITY OF SUCH DAMAGE.
37b0453382SBill Fenner  */
38b0453382SBill Fenner 
39b0453382SBill Fenner #ifdef HAVE_CONFIG_H
40b0453382SBill Fenner #include "config.h"
41b0453382SBill Fenner #endif
42b0453382SBill Fenner 
43b0453382SBill Fenner #ifndef lint
445b0fe478SBruce M Simpson static const char rcsid[] _U_ =
452ebc47dbSSam Leffler      "@(#) $Header: /tcpdump/master/tcpdump/print-ascii.c,v 1.16.2.1 2005/07/06 20:54:49 guy Exp $";
46b0453382SBill Fenner #endif
475b0fe478SBruce M Simpson #include <tcpdump-stdinc.h>
48b0453382SBill Fenner #include <stdio.h>
49b0453382SBill Fenner 
50b0453382SBill Fenner #include "interface.h"
51b0453382SBill Fenner 
525b0fe478SBruce M Simpson #define ASCII_LINELENGTH 300
53b0453382SBill Fenner #define HEXDUMP_BYTES_PER_LINE 16
54b0453382SBill Fenner #define HEXDUMP_SHORTS_PER_LINE (HEXDUMP_BYTES_PER_LINE / 2)
55b0453382SBill Fenner #define HEXDUMP_HEXSTUFF_PER_SHORT 5 /* 4 hex digits and a space */
56b0453382SBill Fenner #define HEXDUMP_HEXSTUFF_PER_LINE \
57b0453382SBill Fenner 		(HEXDUMP_HEXSTUFF_PER_SHORT * HEXDUMP_SHORTS_PER_LINE)
58b0453382SBill Fenner 
59b0453382SBill Fenner void
602ebc47dbSSam Leffler ascii_print(register const u_char *cp, register u_int length)
612ebc47dbSSam Leffler {
622ebc47dbSSam Leffler 	register int s;
632ebc47dbSSam Leffler 
642ebc47dbSSam Leffler 	putchar('\n');
652ebc47dbSSam Leffler 	while (length > 0) {
662ebc47dbSSam Leffler 		s = *cp++;
672ebc47dbSSam Leffler 		length--;
682ebc47dbSSam Leffler 		if (!isgraph(s) &&
692ebc47dbSSam Leffler 		    (s != '\t' && s != ' ' && s != '\n' && s != '\r'))
702ebc47dbSSam Leffler 			putchar('.');
712ebc47dbSSam Leffler 		else
722ebc47dbSSam Leffler 			putchar(s);
732ebc47dbSSam Leffler 	}
742ebc47dbSSam Leffler }
752ebc47dbSSam Leffler 
762ebc47dbSSam Leffler void
772ebc47dbSSam Leffler hex_and_ascii_print_with_offset(register const char *ident,
782ebc47dbSSam Leffler     register const u_char *cp, register u_int length, register u_int oset)
79b0453382SBill Fenner {
80b0453382SBill Fenner 	register u_int i;
81b0453382SBill Fenner 	register int s1, s2;
82b0453382SBill Fenner 	register int nshorts;
83b0453382SBill Fenner 	char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp;
845b0fe478SBruce M Simpson 	char asciistuff[ASCII_LINELENGTH+1], *asp;
85b0453382SBill Fenner 
86b0453382SBill Fenner 	nshorts = length / sizeof(u_short);
87b0453382SBill Fenner 	i = 0;
88b0453382SBill Fenner 	hsp = hexstuff; asp = asciistuff;
89b0453382SBill Fenner 	while (--nshorts >= 0) {
90b0453382SBill Fenner 		s1 = *cp++;
91b0453382SBill Fenner 		s2 = *cp++;
92685295f4SBill Fenner 		(void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
93685295f4SBill Fenner 		    " %02x%02x", s1, s2);
94b0453382SBill Fenner 		hsp += HEXDUMP_HEXSTUFF_PER_SHORT;
95b0453382SBill Fenner 		*(asp++) = (isgraph(s1) ? s1 : '.');
96b0453382SBill Fenner 		*(asp++) = (isgraph(s2) ? s2 : '.');
975b0fe478SBruce M Simpson 		i++;
982ebc47dbSSam Leffler 		if (i >= HEXDUMP_SHORTS_PER_LINE) {
99b0453382SBill Fenner 			*hsp = *asp = '\0';
1005b0fe478SBruce M Simpson 			(void)printf("%s0x%04x: %-*s  %s",
1015b0fe478SBruce M Simpson 			    ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
102b0453382SBill Fenner 			    hexstuff, asciistuff);
103b0453382SBill Fenner 			i = 0; hsp = hexstuff; asp = asciistuff;
104b0453382SBill Fenner 			oset += HEXDUMP_BYTES_PER_LINE;
105b0453382SBill Fenner 		}
106b0453382SBill Fenner 	}
107b0453382SBill Fenner 	if (length & 1) {
108b0453382SBill Fenner 		s1 = *cp++;
109685295f4SBill Fenner 		(void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
110685295f4SBill Fenner 		    " %02x", s1);
111b0453382SBill Fenner 		hsp += 3;
112b0453382SBill Fenner 		*(asp++) = (isgraph(s1) ? s1 : '.');
113b0453382SBill Fenner 		++i;
114b0453382SBill Fenner 	}
115b0453382SBill Fenner 	if (i > 0) {
116b0453382SBill Fenner 		*hsp = *asp = '\0';
1175b0fe478SBruce M Simpson 		(void)printf("%s0x%04x: %-*s  %s",
1185b0fe478SBruce M Simpson 		     ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
119b0453382SBill Fenner 		     hexstuff, asciistuff);
120b0453382SBill Fenner 	}
121b0453382SBill Fenner }
122b0453382SBill Fenner 
123b0453382SBill Fenner void
1242ebc47dbSSam Leffler hex_and_ascii_print(register const char *ident, register const u_char *cp,
1252ebc47dbSSam Leffler     register u_int length)
126b0453382SBill Fenner {
1272ebc47dbSSam Leffler 	hex_and_ascii_print_with_offset(ident, cp, length, 0);
128b0453382SBill Fenner }
129b0453382SBill Fenner 
130b0453382SBill Fenner /*
131b0453382SBill Fenner  * telnet_print() wants this.  It is essentially default_print_unaligned()
132b0453382SBill Fenner  */
133b0453382SBill Fenner void
1341de50e9fSSam Leffler hex_print_with_offset(register const char *ident, register const u_char *cp, register u_int length,
135b0453382SBill Fenner 		      register u_int oset)
136b0453382SBill Fenner {
137b0453382SBill Fenner 	register u_int i, s;
138b0453382SBill Fenner 	register int nshorts;
139b0453382SBill Fenner 
140b0453382SBill Fenner 	nshorts = (u_int) length / sizeof(u_short);
141b0453382SBill Fenner 	i = 0;
142b0453382SBill Fenner 	while (--nshorts >= 0) {
143b0453382SBill Fenner 		if ((i++ % 8) == 0) {
1445b0fe478SBruce M Simpson 			(void)printf("%s0x%04x: ", ident, oset);
145b0453382SBill Fenner 			oset += HEXDUMP_BYTES_PER_LINE;
146b0453382SBill Fenner 		}
147b0453382SBill Fenner 		s = *cp++;
148b0453382SBill Fenner 		(void)printf(" %02x%02x", s, *cp++);
149b0453382SBill Fenner 	}
150b0453382SBill Fenner 	if (length & 1) {
151b0453382SBill Fenner 		if ((i % 8) == 0)
1525b0fe478SBruce M Simpson 			(void)printf("%s0x%04x: ", ident, oset);
153b0453382SBill Fenner 		(void)printf(" %02x", *cp);
154b0453382SBill Fenner 	}
155b0453382SBill Fenner }
156b0453382SBill Fenner 
157b0453382SBill Fenner /*
158b0453382SBill Fenner  * just for completeness
159b0453382SBill Fenner  */
160b0453382SBill Fenner void
1611de50e9fSSam Leffler hex_print(register const char *ident, register const u_char *cp, register u_int length)
162b0453382SBill Fenner {
1635b0fe478SBruce M Simpson 	hex_print_with_offset(ident, cp, length, 0);
164b0453382SBill Fenner }
165b0453382SBill Fenner 
166b0453382SBill Fenner #ifdef MAIN
167b0453382SBill Fenner int
168b0453382SBill Fenner main(int argc, char *argv[])
169b0453382SBill Fenner {
1702ebc47dbSSam Leffler 	hex_print("\n\t", "Hello, World!\n", 14);
1712ebc47dbSSam Leffler 	printf("\n");
1722ebc47dbSSam Leffler 	hex_and_ascii_print("\n\t", "Hello, World!\n", 14);
173b0453382SBill Fenner 	printf("\n");
174b0453382SBill Fenner 	ascii_print("Hello, World!\n", 14);
175b0453382SBill Fenner 	printf("\n");
176b0453382SBill Fenner #define TMSG "Now is the winter of our discontent...\n"
1772ebc47dbSSam Leffler 	hex_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
1782ebc47dbSSam Leffler 	printf("\n");
1792ebc47dbSSam Leffler 	hex_and_ascii_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
180b0453382SBill Fenner 	printf("\n");
181b0453382SBill Fenner 	exit(0);
182b0453382SBill Fenner }
183b0453382SBill Fenner #endif /* MAIN */
184