print-telnet.c revision 56893
1/*	$NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40: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 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 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *        This product includes software developed by the NetBSD
21 *        Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38/*
39 *      @(#)Copyright (c) 1994, Simon J. Gerraty.
40 *
41 *      This is free software.  It comes with NO WARRANTY.
42 *      Permission to use, modify and distribute this source code
43 *      is granted subject to the following conditions.
44 *      1/ that the above copyright notice and this notice
45 *      are preserved in all copies.
46 */
47
48#ifdef HAVE_CONFIG_H
49#include "config.h"
50#endif
51
52#ifndef lint
53static const char rcsid[] =
54     "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.2.2.2 2000/01/11 06:58:28 fenner Exp $";
55#endif
56
57#include <sys/param.h>
58#include <sys/time.h>
59#include <sys/types.h>
60
61#include <netinet/in.h>
62#include <netinet/in_systm.h>
63#include <netinet/ip.h>
64#include <netinet/ip_var.h>
65#include <netinet/tcp.h>
66#include <netinet/tcpip.h>
67
68#define TELCMDS
69#define TELOPTS
70#include <arpa/telnet.h>
71
72#include <stdio.h>
73#ifdef __STDC__
74#include <stdlib.h>
75#endif
76#include <unistd.h>
77#include <string.h>
78
79#include "interface.h"
80#include "addrtoname.h"
81
82
83#ifndef TELCMD_FIRST
84# define TELCMD_FIRST SE
85#endif
86
87void
88telnet_print(register const u_char *sp, u_int length)
89{
90	static char tnet[128];
91	register int i, c, x;
92	register u_char *rcp;
93	int off, first = 1;
94	u_char	*osp;
95
96	off = 0;
97	x = 0;
98
99	while (length > 0 && *sp == IAC) {
100		osp = (u_char *) sp;
101		tnet[0] = '\0';
102
103		c = *sp++;
104		length--;
105		switch (*sp) {
106		case IAC:			/* <IAC><IAC>! */
107			if (length > 1 && sp[1] == IAC) {
108				(void)strcpy(tnet, "IAC IAC");
109			} else {
110				length = 0;
111				continue;
112			}
113			break;
114		default:
115			c = *sp++;
116			length--;
117			if ((i = c - TELCMD_FIRST) < 0
118			    || i > IAC - TELCMD_FIRST) {
119				(void)printf("unknown: ff%02x\n", c);
120				return;
121			}
122			switch (c) {
123			case DONT:
124			case DO:
125			case WONT:
126			case WILL:
127			case SB:
128				x = *sp++; /* option */
129				length--;
130				if (x >= 0 && x < NTELOPTS) {
131					(void)sprintf(tnet, "%s %s",
132						      telcmds[i], telopts[x]);
133				} else {
134					(void)sprintf(tnet, "%s %#x",
135						      telcmds[i], x);
136				}
137				break;
138			default:
139				(void)strcpy(tnet, telcmds[i]);
140			}
141			if (c == SB) {
142				c = *sp++;
143				length--;
144				(void)strcat(tnet, c ? " SEND" : " IS '");
145				rcp = (u_char *) sp;
146				i = strlen(tnet);
147				while (length > 0 && (x = *sp++) != IAC)
148					--length;
149				if (x == IAC) {
150					if (2 < vflag
151					    && i + 16 + sp - rcp < sizeof(tnet)) {
152						(void)strncpy(&tnet[i], rcp, sp - rcp);
153						i += (sp - rcp) - 1;
154						tnet[i] = '\0';
155					} else if (i + 8 < sizeof(tnet)) {
156						(void)strcat(&tnet[i], "...");
157					}
158					if (*sp++ == SE
159					    && i + 4 < sizeof(tnet))
160						(void)strcat(tnet, c ? " SE" : "' SE");
161				} else if (i + 16 < sizeof(tnet)) {
162					(void)strcat(tnet, " truncated!");
163				}
164			}
165			break;
166		}
167		/*
168		 * now print it
169		 */
170		if (Xflag && 2 < vflag) {
171			if (first)
172				printf("\nTelnet:\n");
173			i = sp - osp;
174			hex_print_with_offset(osp, i, off);
175			off += i;
176			if (i > 8)
177				printf("\n\t\t\t\t%s", tnet);
178			else
179				printf("%*s\t%s", (8 - i) * 3, "", tnet);
180		} else {
181			printf("%s%s", (first) ? " [telnet " : ", ", tnet);
182		}
183		first = 0;
184	}
185	if (!first) {
186		if (Xflag && 2 < vflag)
187			printf("\n");
188		else
189			printf("]");
190	}
191}
192