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