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