print-telnet.c revision 56893
156893Sfenner/*	$NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40: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 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 *      @(#)Copyright (c) 1994, Simon J. Gerraty.
4056893Sfenner *
4156893Sfenner *      This is free software.  It comes with NO WARRANTY.
4256893Sfenner *      Permission to use, modify and distribute this source code
4356893Sfenner *      is granted subject to the following conditions.
4456893Sfenner *      1/ that the above copyright notice and this notice
4556893Sfenner *      are preserved in all copies.
4656893Sfenner */
4756893Sfenner
4856893Sfenner#ifdef HAVE_CONFIG_H
4956893Sfenner#include "config.h"
5056893Sfenner#endif
5156893Sfenner
5256893Sfenner#ifndef lint
5356893Sfennerstatic const char rcsid[] =
5456893Sfenner     "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.2.2.2 2000/01/11 06:58:28 fenner Exp $";
5556893Sfenner#endif
5656893Sfenner
5756893Sfenner#include <sys/param.h>
5856893Sfenner#include <sys/time.h>
5956893Sfenner#include <sys/types.h>
6056893Sfenner
6156893Sfenner#include <netinet/in.h>
6256893Sfenner#include <netinet/in_systm.h>
6356893Sfenner#include <netinet/ip.h>
6456893Sfenner#include <netinet/ip_var.h>
6556893Sfenner#include <netinet/tcp.h>
6656893Sfenner#include <netinet/tcpip.h>
6756893Sfenner
6856893Sfenner#define TELCMDS
6956893Sfenner#define TELOPTS
7056893Sfenner#include <arpa/telnet.h>
7156893Sfenner
7256893Sfenner#include <stdio.h>
7356893Sfenner#ifdef __STDC__
7456893Sfenner#include <stdlib.h>
7556893Sfenner#endif
7656893Sfenner#include <unistd.h>
7756893Sfenner#include <string.h>
7856893Sfenner
7956893Sfenner#include "interface.h"
8056893Sfenner#include "addrtoname.h"
8156893Sfenner
8256893Sfenner
8356893Sfenner#ifndef TELCMD_FIRST
8456893Sfenner# define TELCMD_FIRST SE
8556893Sfenner#endif
8656893Sfenner
8756893Sfennervoid
8856893Sfennertelnet_print(register const u_char *sp, u_int length)
8956893Sfenner{
9056893Sfenner	static char tnet[128];
9156893Sfenner	register int i, c, x;
9256893Sfenner	register u_char *rcp;
9356893Sfenner	int off, first = 1;
9456893Sfenner	u_char	*osp;
9556893Sfenner
9656893Sfenner	off = 0;
9756893Sfenner	x = 0;
9856893Sfenner
9956893Sfenner	while (length > 0 && *sp == IAC) {
10056893Sfenner		osp = (u_char *) sp;
10156893Sfenner		tnet[0] = '\0';
10256893Sfenner
10356893Sfenner		c = *sp++;
10456893Sfenner		length--;
10556893Sfenner		switch (*sp) {
10656893Sfenner		case IAC:			/* <IAC><IAC>! */
10756893Sfenner			if (length > 1 && sp[1] == IAC) {
10856893Sfenner				(void)strcpy(tnet, "IAC IAC");
10956893Sfenner			} else {
11056893Sfenner				length = 0;
11156893Sfenner				continue;
11256893Sfenner			}
11356893Sfenner			break;
11456893Sfenner		default:
11556893Sfenner			c = *sp++;
11656893Sfenner			length--;
11756893Sfenner			if ((i = c - TELCMD_FIRST) < 0
11856893Sfenner			    || i > IAC - TELCMD_FIRST) {
11956893Sfenner				(void)printf("unknown: ff%02x\n", c);
12056893Sfenner				return;
12156893Sfenner			}
12256893Sfenner			switch (c) {
12356893Sfenner			case DONT:
12456893Sfenner			case DO:
12556893Sfenner			case WONT:
12656893Sfenner			case WILL:
12756893Sfenner			case SB:
12856893Sfenner				x = *sp++; /* option */
12956893Sfenner				length--;
13056893Sfenner				if (x >= 0 && x < NTELOPTS) {
13156893Sfenner					(void)sprintf(tnet, "%s %s",
13256893Sfenner						      telcmds[i], telopts[x]);
13356893Sfenner				} else {
13456893Sfenner					(void)sprintf(tnet, "%s %#x",
13556893Sfenner						      telcmds[i], x);
13656893Sfenner				}
13756893Sfenner				break;
13856893Sfenner			default:
13956893Sfenner				(void)strcpy(tnet, telcmds[i]);
14056893Sfenner			}
14156893Sfenner			if (c == SB) {
14256893Sfenner				c = *sp++;
14356893Sfenner				length--;
14456893Sfenner				(void)strcat(tnet, c ? " SEND" : " IS '");
14556893Sfenner				rcp = (u_char *) sp;
14656893Sfenner				i = strlen(tnet);
14756893Sfenner				while (length > 0 && (x = *sp++) != IAC)
14856893Sfenner					--length;
14956893Sfenner				if (x == IAC) {
15056893Sfenner					if (2 < vflag
15156893Sfenner					    && i + 16 + sp - rcp < sizeof(tnet)) {
15256893Sfenner						(void)strncpy(&tnet[i], rcp, sp - rcp);
15356893Sfenner						i += (sp - rcp) - 1;
15456893Sfenner						tnet[i] = '\0';
15556893Sfenner					} else if (i + 8 < sizeof(tnet)) {
15656893Sfenner						(void)strcat(&tnet[i], "...");
15756893Sfenner					}
15856893Sfenner					if (*sp++ == SE
15956893Sfenner					    && i + 4 < sizeof(tnet))
16056893Sfenner						(void)strcat(tnet, c ? " SE" : "' SE");
16156893Sfenner				} else if (i + 16 < sizeof(tnet)) {
16256893Sfenner					(void)strcat(tnet, " truncated!");
16356893Sfenner				}
16456893Sfenner			}
16556893Sfenner			break;
16656893Sfenner		}
16756893Sfenner		/*
16856893Sfenner		 * now print it
16956893Sfenner		 */
17056893Sfenner		if (Xflag && 2 < vflag) {
17156893Sfenner			if (first)
17256893Sfenner				printf("\nTelnet:\n");
17356893Sfenner			i = sp - osp;
17456893Sfenner			hex_print_with_offset(osp, i, off);
17556893Sfenner			off += i;
17656893Sfenner			if (i > 8)
17756893Sfenner				printf("\n\t\t\t\t%s", tnet);
17856893Sfenner			else
17956893Sfenner				printf("%*s\t%s", (8 - i) * 3, "", tnet);
18056893Sfenner		} else {
18156893Sfenner			printf("%s%s", (first) ? " [telnet " : ", ", tnet);
18256893Sfenner		}
18356893Sfenner		first = 0;
18456893Sfenner	}
18556893Sfenner	if (!first) {
18656893Sfenner		if (Xflag && 2 < vflag)
18756893Sfenner			printf("\n");
18856893Sfenner		else
18956893Sfenner			printf("]");
19056893Sfenner	}
19156893Sfenner}
192