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[] = 54a90e161bSBill Fenner "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.18 2001/09/10 06:40:08 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> 60685295f4SBill Fenner #include <ctype.h> 61b0453382SBill Fenner 62b0453382SBill Fenner #include <netinet/in.h> 63b0453382SBill Fenner 64b0453382SBill Fenner #include <stdio.h> 65b0453382SBill Fenner #include <stdlib.h> 66b0453382SBill Fenner #include <unistd.h> 67b0453382SBill Fenner #include <string.h> 68b0453382SBill Fenner 69b0453382SBill Fenner #include "interface.h" 70b0453382SBill Fenner #include "addrtoname.h" 71b0453382SBill Fenner 72a90e161bSBill Fenner #define TELCMDS 73a90e161bSBill Fenner #define TELOPTS 74a90e161bSBill Fenner #include "telnet.h" 75b0453382SBill Fenner 76a90e161bSBill Fenner /* normal */ 77a90e161bSBill Fenner static const char *cmds[] = { 78a90e161bSBill Fenner "IS", "SEND", "INFO", 79a90e161bSBill Fenner }; 80a90e161bSBill Fenner 81a90e161bSBill Fenner /* 37: Authentication */ 82a90e161bSBill Fenner static const char *authcmd[] = { 83a90e161bSBill Fenner "IS", "SEND", "REPLY", "NAME", 84a90e161bSBill Fenner }; 85a90e161bSBill Fenner static const char *authtype[] = { 86a90e161bSBill Fenner "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 87a90e161bSBill Fenner "SRP", "RSA", "SSL", NULL, NULL, 88a90e161bSBill Fenner "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS", 89a90e161bSBill Fenner "NTLM", 90a90e161bSBill Fenner }; 91a90e161bSBill Fenner 92a90e161bSBill Fenner /* 38: Encryption */ 93a90e161bSBill Fenner static const char *enccmd[] = { 94a90e161bSBill Fenner "IS", "SUPPORT", "REPLY", "START", "END", 95a90e161bSBill Fenner "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID", 96a90e161bSBill Fenner }; 97a90e161bSBill Fenner static const char *enctype[] = { 98a90e161bSBill Fenner "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64", 99a90e161bSBill Fenner NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64", 100a90e161bSBill Fenner }; 101a90e161bSBill Fenner 102a90e161bSBill Fenner #define STR_OR_ID(x, tab) \ 103a90e161bSBill Fenner (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) 104a90e161bSBill Fenner 105a90e161bSBill Fenner static char * 106a90e161bSBill Fenner numstr(int x) 107b0453382SBill Fenner { 108a90e161bSBill Fenner static char buf[20]; 109b0453382SBill Fenner 110a90e161bSBill Fenner snprintf(buf, sizeof(buf), "%#x", x); 111a90e161bSBill Fenner return buf; 112b0453382SBill Fenner } 113a90e161bSBill Fenner 114a90e161bSBill Fenner /* sp points to IAC byte */ 115a90e161bSBill Fenner static int 116a90e161bSBill Fenner telnet_parse(const u_char *sp, u_int length, int print) 117a90e161bSBill Fenner { 118a90e161bSBill Fenner int i, c, x; 119a90e161bSBill Fenner const u_char *osp, *p; 120a90e161bSBill Fenner #define FETCH(c, sp, length) \ 121a90e161bSBill Fenner do { \ 122a90e161bSBill Fenner if (length < 1) \ 123a90e161bSBill Fenner goto pktend; \ 124a90e161bSBill Fenner TCHECK(*sp); \ 125a90e161bSBill Fenner c = *sp++; \ 126a90e161bSBill Fenner length--; \ 127a90e161bSBill Fenner } while (0) 128a90e161bSBill Fenner 129a90e161bSBill Fenner osp = sp; 130a90e161bSBill Fenner 131a90e161bSBill Fenner FETCH(c, sp, length); 132a90e161bSBill Fenner if (c != IAC) 133a90e161bSBill Fenner goto pktend; 134a90e161bSBill Fenner FETCH(c, sp, length); 135a90e161bSBill Fenner if (c == IAC) { /* <IAC><IAC>! */ 136a90e161bSBill Fenner if (print) 137a90e161bSBill Fenner printf("IAC IAC"); 138a90e161bSBill Fenner goto done; 139b0453382SBill Fenner } 140a90e161bSBill Fenner 141a90e161bSBill Fenner i = c - TELCMD_FIRST; 142a90e161bSBill Fenner if (i < 0 || i > IAC - TELCMD_FIRST) 143a90e161bSBill Fenner goto pktend; 144a90e161bSBill Fenner 145b0453382SBill Fenner switch (c) { 146b0453382SBill Fenner case DONT: 147b0453382SBill Fenner case DO: 148b0453382SBill Fenner case WONT: 149b0453382SBill Fenner case WILL: 150b0453382SBill Fenner case SB: 151a90e161bSBill Fenner /* DONT/DO/WONT/WILL x */ 152a90e161bSBill Fenner FETCH(x, sp, length); 153b0453382SBill Fenner if (x >= 0 && x < NTELOPTS) { 154a90e161bSBill Fenner if (print) 155a90e161bSBill Fenner (void)printf("%s %s", telcmds[i], telopts[x]); 156b0453382SBill Fenner } else { 157a90e161bSBill Fenner if (print) 158a90e161bSBill Fenner (void)printf("%s %#x", telcmds[i], x); 159b0453382SBill Fenner } 160a90e161bSBill Fenner if (c != SB) 161a90e161bSBill Fenner break; 162a90e161bSBill Fenner /* IAC SB .... IAC SE */ 163a90e161bSBill Fenner p = sp; 164a90e161bSBill Fenner while (length > p + 1 - sp) { 165a90e161bSBill Fenner if (p[0] == IAC && p[1] == SE) 166a90e161bSBill Fenner break; 167a90e161bSBill Fenner p++; 168a90e161bSBill Fenner } 169a90e161bSBill Fenner if (*p != IAC) 170a90e161bSBill Fenner goto pktend; 171a90e161bSBill Fenner 172a90e161bSBill Fenner switch (x) { 173a90e161bSBill Fenner case TELOPT_AUTHENTICATION: 174a90e161bSBill Fenner if (p <= sp) 175a90e161bSBill Fenner break; 176a90e161bSBill Fenner FETCH(c, sp, length); 177a90e161bSBill Fenner if (print) 178a90e161bSBill Fenner (void)printf(" %s", STR_OR_ID(c, authcmd)); 179a90e161bSBill Fenner if (p <= sp) 180a90e161bSBill Fenner break; 181a90e161bSBill Fenner FETCH(c, sp, length); 182a90e161bSBill Fenner if (print) 183a90e161bSBill Fenner (void)printf(" %s", STR_OR_ID(c, authtype)); 184a90e161bSBill Fenner break; 185a90e161bSBill Fenner case TELOPT_ENCRYPT: 186a90e161bSBill Fenner if (p <= sp) 187a90e161bSBill Fenner break; 188a90e161bSBill Fenner FETCH(c, sp, length); 189a90e161bSBill Fenner if (print) 190a90e161bSBill Fenner (void)printf(" %s", STR_OR_ID(c, enccmd)); 191a90e161bSBill Fenner if (p <= sp) 192a90e161bSBill Fenner break; 193a90e161bSBill Fenner FETCH(c, sp, length); 194a90e161bSBill Fenner if (print) 195a90e161bSBill Fenner (void)printf(" %s", STR_OR_ID(c, enctype)); 196b0453382SBill Fenner break; 197b0453382SBill Fenner default: 198a90e161bSBill Fenner if (p <= sp) 199a90e161bSBill Fenner break; 200a90e161bSBill Fenner FETCH(c, sp, length); 201a90e161bSBill Fenner if (print) 202a90e161bSBill Fenner (void)printf(" %s", STR_OR_ID(c, cmds)); 203b0453382SBill Fenner break; 204b0453382SBill Fenner } 205a90e161bSBill Fenner while (p > sp) { 206a90e161bSBill Fenner FETCH(x, sp, length); 207a90e161bSBill Fenner if (print) 208a90e161bSBill Fenner (void)printf(" %#x", x); 209a90e161bSBill Fenner } 210a90e161bSBill Fenner /* terminating IAC SE */ 211a90e161bSBill Fenner if (print) 212a90e161bSBill Fenner (void)printf(" SE"); 213a90e161bSBill Fenner sp += 2; 214a90e161bSBill Fenner length -= 2; 215a90e161bSBill Fenner break; 216a90e161bSBill Fenner default: 217a90e161bSBill Fenner if (print) 218a90e161bSBill Fenner (void)printf("%s", telcmds[i]); 219a90e161bSBill Fenner goto done; 220a90e161bSBill Fenner } 221a90e161bSBill Fenner 222a90e161bSBill Fenner done: 223a90e161bSBill Fenner return sp - osp; 224a90e161bSBill Fenner 225a90e161bSBill Fenner trunc: 226a90e161bSBill Fenner (void)printf("[|telnet]"); 227a90e161bSBill Fenner pktend: 228a90e161bSBill Fenner return -1; 229a90e161bSBill Fenner #undef FETCH 230a90e161bSBill Fenner } 231a90e161bSBill Fenner 232a90e161bSBill Fenner void 233a90e161bSBill Fenner telnet_print(const u_char *sp, u_int length) 234a90e161bSBill Fenner { 235a90e161bSBill Fenner int first = 1; 236a90e161bSBill Fenner const u_char *osp; 237a90e161bSBill Fenner int l; 238a90e161bSBill Fenner 239a90e161bSBill Fenner osp = sp; 240a90e161bSBill Fenner 241a90e161bSBill Fenner while (length > 0 && *sp == IAC) { 242a90e161bSBill Fenner l = telnet_parse(sp, length, 0); 243a90e161bSBill Fenner if (l < 0) 244a90e161bSBill Fenner break; 245a90e161bSBill Fenner 246b0453382SBill Fenner /* 247b0453382SBill Fenner * now print it 248b0453382SBill Fenner */ 249b0453382SBill Fenner if (Xflag && 2 < vflag) { 250b0453382SBill Fenner if (first) 251a90e161bSBill Fenner printf("\nTelnet:"); 252a90e161bSBill Fenner hex_print_with_offset(sp, l, sp - osp); 253a90e161bSBill Fenner if (l > 8) 254685295f4SBill Fenner printf("\n\t\t\t\t"); 255b0453382SBill Fenner else 256a90e161bSBill Fenner printf("%*s\t", (8 - l) * 3, ""); 257a90e161bSBill Fenner } else 258685295f4SBill Fenner printf("%s", (first) ? " [telnet " : ", "); 259a90e161bSBill Fenner 260a90e161bSBill Fenner (void)telnet_parse(sp, length, 1); 261b0453382SBill Fenner first = 0; 262a90e161bSBill Fenner 263a90e161bSBill Fenner sp += l; 264a90e161bSBill Fenner length -= l; 265b0453382SBill Fenner } 266b0453382SBill Fenner if (!first) { 267b0453382SBill Fenner if (Xflag && 2 < vflag) 268b0453382SBill Fenner printf("\n"); 269b0453382SBill Fenner else 270b0453382SBill Fenner printf("]"); 271b0453382SBill Fenner } 272b0453382SBill Fenner } 273