156893Sfenner/*	$NetBSD: print-ascii.c,v 1.1 1999/09/30 14:49:12 sjg Exp $ 	*/
256893Sfenner
356893Sfenner/*-
456893Sfenner * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
556893Sfenner * All rights reserved.
656893Sfenner *
756893Sfenner * This code is derived from software contributed to The NetBSD Foundation
856893Sfenner * by Alan Barrett and Simon J. Gerraty.
956893Sfenner *
1056893Sfenner * Redistribution and use in source and binary forms, with or without
1156893Sfenner * modification, are permitted provided that the following conditions
1256893Sfenner * are met:
1356893Sfenner * 1. Redistributions of source code must retain the above copyright
1456893Sfenner *    notice, this list of conditions and the following disclaimer.
1556893Sfenner * 2. Redistributions in binary form must reproduce the above copyright
1656893Sfenner *    notice, this list of conditions and the following disclaimer in the
1756893Sfenner *    documentation and/or other materials provided with the distribution.
1856893Sfenner * 3. All advertising materials mentioning features or use of this software
1956893Sfenner *    must display the following acknowledgement:
2056893Sfenner *        This product includes software developed by the NetBSD
2156893Sfenner *        Foundation, Inc. and its contributors.
2256893Sfenner * 4. Neither the name of The NetBSD Foundation nor the names of its
2356893Sfenner *    contributors may be used to endorse or promote products derived
2456893Sfenner *    from this software without specific prior written permission.
2556893Sfenner *
2656893Sfenner * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2756893Sfenner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2856893Sfenner * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2956893Sfenner * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
3056893Sfenner * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3156893Sfenner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3256893Sfenner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3356893Sfenner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3456893Sfenner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3556893Sfenner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3656893Sfenner * POSSIBILITY OF SUCH DAMAGE.
3756893Sfenner */
3856893Sfenner
3956893Sfenner#ifdef HAVE_CONFIG_H
4056893Sfenner#include "config.h"
4156893Sfenner#endif
4256893Sfenner
4356893Sfenner#ifndef lint
44127668Sbmsstatic const char rcsid[] _U_ =
45190207Srpaulo     "@(#) $Header: /tcpdump/master/tcpdump/print-ascii.c,v 1.17 2005-07-06 20:53:32 guy Exp $";
4656893Sfenner#endif
47127668Sbms#include <tcpdump-stdinc.h>
4856893Sfenner#include <stdio.h>
4956893Sfenner
5056893Sfenner#include "interface.h"
5156893Sfenner
52127668Sbms#define ASCII_LINELENGTH 300
5356893Sfenner#define HEXDUMP_BYTES_PER_LINE 16
5456893Sfenner#define HEXDUMP_SHORTS_PER_LINE (HEXDUMP_BYTES_PER_LINE / 2)
5556893Sfenner#define HEXDUMP_HEXSTUFF_PER_SHORT 5 /* 4 hex digits and a space */
5656893Sfenner#define HEXDUMP_HEXSTUFF_PER_LINE \
5756893Sfenner		(HEXDUMP_HEXSTUFF_PER_SHORT * HEXDUMP_SHORTS_PER_LINE)
58127668Sbms
5956893Sfennervoid
60162017Ssamascii_print(register const u_char *cp, register u_int length)
6156893Sfenner{
62162017Ssam	register int s;
63162017Ssam
64162017Ssam	putchar('\n');
65162017Ssam	while (length > 0) {
66162017Ssam		s = *cp++;
67162017Ssam		length--;
68162017Ssam		if (!isgraph(s) &&
69162017Ssam		    (s != '\t' && s != ' ' && s != '\n' && s != '\r'))
70162017Ssam			putchar('.');
71162017Ssam		else
72162017Ssam			putchar(s);
73162017Ssam	}
74162017Ssam}
75162017Ssam
76162017Ssamvoid
77162017Ssamhex_and_ascii_print_with_offset(register const char *ident,
78162017Ssam    register const u_char *cp, register u_int length, register u_int oset)
79162017Ssam{
8056893Sfenner	register u_int i;
8156893Sfenner	register int s1, s2;
8256893Sfenner	register int nshorts;
8356893Sfenner	char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp;
84127668Sbms	char asciistuff[ASCII_LINELENGTH+1], *asp;
8556893Sfenner
8656893Sfenner	nshorts = length / sizeof(u_short);
8756893Sfenner	i = 0;
8856893Sfenner	hsp = hexstuff; asp = asciistuff;
8956893Sfenner	while (--nshorts >= 0) {
9056893Sfenner		s1 = *cp++;
9156893Sfenner		s2 = *cp++;
92162017Ssam		(void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
93162017Ssam		    " %02x%02x", s1, s2);
94162017Ssam		hsp += HEXDUMP_HEXSTUFF_PER_SHORT;
95162017Ssam		*(asp++) = (isgraph(s1) ? s1 : '.');
96162017Ssam		*(asp++) = (isgraph(s2) ? s2 : '.');
97162017Ssam		i++;
98162017Ssam		if (i >= HEXDUMP_SHORTS_PER_LINE) {
99127668Sbms			*hsp = *asp = '\0';
100162017Ssam			(void)printf("%s0x%04x: %-*s  %s",
101162017Ssam			    ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
102162017Ssam			    hexstuff, asciistuff);
103127668Sbms			i = 0; hsp = hexstuff; asp = asciistuff;
104127668Sbms			oset += HEXDUMP_BYTES_PER_LINE;
105127668Sbms		}
10656893Sfenner	}
10756893Sfenner	if (length & 1) {
10856893Sfenner		s1 = *cp++;
109162017Ssam		(void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
110162017Ssam		    " %02x", s1);
111162017Ssam		hsp += 3;
112162017Ssam		*(asp++) = (isgraph(s1) ? s1 : '.');
11356893Sfenner		++i;
11456893Sfenner	}
11556893Sfenner	if (i > 0) {
11656893Sfenner		*hsp = *asp = '\0';
117162017Ssam		(void)printf("%s0x%04x: %-*s  %s",
118162017Ssam		     ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
119162017Ssam		     hexstuff, asciistuff);
12056893Sfenner	}
12156893Sfenner}
12256893Sfenner
12356893Sfennervoid
124162017Ssamhex_and_ascii_print(register const char *ident, register const u_char *cp,
125162017Ssam    register u_int length)
12656893Sfenner{
127162017Ssam	hex_and_ascii_print_with_offset(ident, cp, length, 0);
12856893Sfenner}
129127668Sbms
13056893Sfenner/*
13156893Sfenner * telnet_print() wants this.  It is essentially default_print_unaligned()
13256893Sfenner */
13356893Sfennervoid
134146773Ssamhex_print_with_offset(register const char *ident, register const u_char *cp, register u_int length,
13556893Sfenner		      register u_int oset)
13656893Sfenner{
13756893Sfenner	register u_int i, s;
13856893Sfenner	register int nshorts;
13956893Sfenner
14056893Sfenner	nshorts = (u_int) length / sizeof(u_short);
14156893Sfenner	i = 0;
14256893Sfenner	while (--nshorts >= 0) {
14356893Sfenner		if ((i++ % 8) == 0) {
144127668Sbms			(void)printf("%s0x%04x: ", ident, oset);
14556893Sfenner			oset += HEXDUMP_BYTES_PER_LINE;
14656893Sfenner		}
14756893Sfenner		s = *cp++;
14856893Sfenner		(void)printf(" %02x%02x", s, *cp++);
14956893Sfenner	}
15056893Sfenner	if (length & 1) {
15156893Sfenner		if ((i % 8) == 0)
152127668Sbms			(void)printf("%s0x%04x: ", ident, oset);
15356893Sfenner		(void)printf(" %02x", *cp);
15456893Sfenner	}
15556893Sfenner}
15656893Sfenner
15756893Sfenner/*
15856893Sfenner * just for completeness
15956893Sfenner */
16056893Sfennervoid
161146773Ssamhex_print(register const char *ident, register const u_char *cp, register u_int length)
16256893Sfenner{
163127668Sbms	hex_print_with_offset(ident, cp, length, 0);
16456893Sfenner}
16556893Sfenner
16656893Sfenner#ifdef MAIN
16756893Sfennerint
16856893Sfennermain(int argc, char *argv[])
16956893Sfenner{
170162017Ssam	hex_print("\n\t", "Hello, World!\n", 14);
17156893Sfenner	printf("\n");
172162017Ssam	hex_and_ascii_print("\n\t", "Hello, World!\n", 14);
173162017Ssam	printf("\n");
17456893Sfenner	ascii_print("Hello, World!\n", 14);
17556893Sfenner	printf("\n");
17656893Sfenner#define TMSG "Now is the winter of our discontent...\n"
177162017Ssam	hex_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
17856893Sfenner	printf("\n");
179162017Ssam	hex_and_ascii_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
180162017Ssam	printf("\n");
18156893Sfenner	exit(0);
18256893Sfenner}
18356893Sfenner#endif /* MAIN */
184