print-ascii.c revision 285830
160107Sobrien/*	$NetBSD: print-ascii.c,v 1.1 1999/09/30 14:49:12 sjg Exp $ 	*/
243334Syokota
343334Syokota/*-
443334Syokota * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
543334Syokota * All rights reserved.
643334Syokota *
743334Syokota * This code is derived from software contributed to The NetBSD Foundation
843334Syokota * by Alan Barrett and Simon J. Gerraty.
943334Syokota *
1043334Syokota * Redistribution and use in source and binary forms, with or without
1143334Syokota * modification, are permitted provided that the following conditions
1243334Syokota * are met:
1343334Syokota * 1. Redistributions of source code must retain the above copyright
1443334Syokota *    notice, this list of conditions and the following disclaimer.
1543334Syokota * 2. Redistributions in binary form must reproduce the above copyright
1643334Syokota *    notice, this list of conditions and the following disclaimer in the
1743334Syokota *    documentation and/or other materials provided with the distribution.
1843334Syokota * 3. All advertising materials mentioning features or use of this software
1943334Syokota *    must display the following acknowledgement:
2043334Syokota *        This product includes software developed by the NetBSD
2143334Syokota *        Foundation, Inc. and its contributors.
2243334Syokota * 4. Neither the name of The NetBSD Foundation nor the names of its
2343334Syokota *    contributors may be used to endorse or promote products derived
2461127Sroberto *    from this software without specific prior written permission.
2543334Syokota *
2643334Syokota * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2743334Syokota * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2843334Syokota * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2943334Syokota * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
3043334Syokota * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3143334Syokota * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3243334Syokota * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3343334Syokota * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3443334Syokota * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3543334Syokota * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3643334Syokota * POSSIBILITY OF SUCH DAMAGE.
3743334Syokota */
3843334Syokota
3943334Syokota#ifdef HAVE_CONFIG_H
4043334Syokota#include "config.h"
4143334Syokota#endif
4243334Syokota
4343334Syokota#ifndef lint
4443334Syokotastatic const char rcsid[] _U_ =
4543334Syokota     "@(#) $Header: /tcpdump/master/tcpdump/print-ascii.c,v 1.17 2005-07-06 20:53:32 guy Exp $";
4643334Syokota#endif
4743334Syokota#include <tcpdump-stdinc.h>
4843334Syokota#include <stdio.h>
4943334Syokota
5043334Syokota#include "interface.h"
5143334Syokota
5243334Syokota#define ASCII_LINELENGTH 300
5343334Syokota#define HEXDUMP_BYTES_PER_LINE 16
5443334Syokota#define HEXDUMP_SHORTS_PER_LINE (HEXDUMP_BYTES_PER_LINE / 2)
5543334Syokota#define HEXDUMP_HEXSTUFF_PER_SHORT 5 /* 4 hex digits and a space */
5643334Syokota#define HEXDUMP_HEXSTUFF_PER_LINE \
5743334Syokota		(HEXDUMP_HEXSTUFF_PER_SHORT * HEXDUMP_SHORTS_PER_LINE)
5843334Syokota
5943334Syokotavoid
6043334Syokotaascii_print(register const u_char *cp, register u_int length)
6143334Syokota{
6243334Syokota	register int s;
6343334Syokota
6443334Syokota	putchar('\n');
6543334Syokota	while (length > 0) {
6643334Syokota		s = *cp++;
6743334Syokota		length--;
6843334Syokota		if (!isgraph(s) &&
6943334Syokota		    (s != '\t' && s != ' ' && s != '\n' && s != '\r'))
7043334Syokota			putchar('.');
7143334Syokota		else
7243334Syokota			putchar(s);
7343334Syokota	}
7443334Syokota}
7543334Syokota
7643334Syokotavoid
7743334Syokotahex_and_ascii_print_with_offset(register const char *ident,
7843334Syokota    register const u_char *cp, register u_int length, register u_int oset)
7943334Syokota{
8043334Syokota	register u_int i;
8143334Syokota	register int s1, s2;
8243334Syokota	register int nshorts;
8343334Syokota	char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp;
8443334Syokota	char asciistuff[ASCII_LINELENGTH+1], *asp;
8543334Syokota
8643334Syokota	nshorts = length / sizeof(u_short);
8743334Syokota	i = 0;
8843334Syokota	hsp = hexstuff; asp = asciistuff;
8943334Syokota	while (--nshorts >= 0) {
9043334Syokota		s1 = *cp++;
9143334Syokota		s2 = *cp++;
9243334Syokota		(void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
9343334Syokota		    " %02x%02x", s1, s2);
9443334Syokota		hsp += HEXDUMP_HEXSTUFF_PER_SHORT;
9543334Syokota		*(asp++) = (isgraph(s1) ? s1 : '.');
9643334Syokota		*(asp++) = (isgraph(s2) ? s2 : '.');
9743334Syokota		i++;
9874119Sache		if (i >= HEXDUMP_SHORTS_PER_LINE) {
9943334Syokota			*hsp = *asp = '\0';
10043334Syokota			(void)printf("%s0x%04x: %-*s  %s",
10143334Syokota			    ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
10243334Syokota			    hexstuff, asciistuff);
10343334Syokota			i = 0; hsp = hexstuff; asp = asciistuff;
10443334Syokota			oset += HEXDUMP_BYTES_PER_LINE;
10543334Syokota		}
10643334Syokota	}
10743334Syokota	if (length & 1) {
10874119Sache		s1 = *cp++;
10943334Syokota		(void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
11043334Syokota		    " %02x", s1);
11143334Syokota		hsp += 3;
11243334Syokota		*(asp++) = (isgraph(s1) ? s1 : '.');
11343334Syokota		++i;
11443334Syokota	}
115	if (i > 0) {
116		*hsp = *asp = '\0';
117		(void)printf("%s0x%04x: %-*s  %s",
118		     ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
119		     hexstuff, asciistuff);
120	}
121}
122
123void
124hex_and_ascii_print(register const char *ident, register const u_char *cp,
125    register u_int length)
126{
127	hex_and_ascii_print_with_offset(ident, cp, length, 0);
128}
129
130/*
131 * telnet_print() wants this.  It is essentially default_print_unaligned()
132 */
133void
134hex_print_with_offset(register const char *ident, register const u_char *cp, register u_int length,
135		      register u_int oset)
136{
137	register u_int i, s;
138	register int nshorts;
139
140	nshorts = (u_int) length / sizeof(u_short);
141	i = 0;
142	while (--nshorts >= 0) {
143		if ((i++ % 8) == 0) {
144			(void)printf("%s0x%04x: ", ident, oset);
145			oset += HEXDUMP_BYTES_PER_LINE;
146		}
147		s = *cp++;
148		(void)printf(" %02x%02x", s, *cp++);
149	}
150	if (length & 1) {
151		if ((i % 8) == 0)
152			(void)printf("%s0x%04x: ", ident, oset);
153		(void)printf(" %02x", *cp);
154	}
155}
156
157/*
158 * just for completeness
159 */
160void
161hex_print(register const char *ident, register const u_char *cp, register u_int length)
162{
163	hex_print_with_offset(ident, cp, length, 0);
164}
165
166#ifdef MAIN
167int
168main(int argc, char *argv[])
169{
170	hex_print("\n\t", "Hello, World!\n", 14);
171	printf("\n");
172	hex_and_ascii_print("\n\t", "Hello, World!\n", 14);
173	printf("\n");
174	ascii_print("Hello, World!\n", 14);
175	printf("\n");
176#define TMSG "Now is the winter of our discontent...\n"
177	hex_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
178	printf("\n");
179	hex_and_ascii_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
180	printf("\n");
181	exit(0);
182}
183#endif /* MAIN */
184