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