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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /* 32 * @(#)Copyright (c) 1994, Simon J. Gerraty. 33 * 34 * This is free software. It comes with NO WARRANTY. 35 * Permission to use, modify and distribute this source code 36 * is granted subject to the following conditions. 37 * 1/ that the above copyright notice and this notice 38 * are preserved in all copies. 39 */ 40 41 #ifdef HAVE_CONFIG_H 42 #include "config.h" 43 #endif 44 45 #include <sys/cdefs.h> 46 #ifndef lint 47 #if 0 48 static const char rcsid[] _U_ = 49 "@(#) Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.24 2003-12-29 11:05:10 hannes Exp"; 50 #else 51 __RCSID("$NetBSD: print-telnet.c,v 1.2 2010/12/05 05:11:31 christos Exp $"); 52 #endif 53 #endif 54 55 #include <tcpdump-stdinc.h> 56 57 #include <stdio.h> 58 #include <stdlib.h> 59 #include <string.h> 60 61 #include "interface.h" 62 #include "addrtoname.h" 63 64 #define TELCMDS 65 #define TELOPTS 66 #include "telnet.h" 67 68 /* normal */ 69 static const char *cmds[] = { 70 "IS", "SEND", "INFO", 71 }; 72 73 /* 37: Authentication */ 74 static const char *authcmd[] = { 75 "IS", "SEND", "REPLY", "NAME", 76 }; 77 static const char *authtype[] = { 78 "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 79 "SRP", "RSA", "SSL", NULL, NULL, 80 "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS", 81 "NTLM", 82 }; 83 84 /* 38: Encryption */ 85 static const char *enccmd[] = { 86 "IS", "SUPPORT", "REPLY", "START", "END", 87 "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID", 88 }; 89 static const char *enctype[] = { 90 "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64", 91 NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64", 92 }; 93 94 #define STR_OR_ID(x, tab) \ 95 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) 96 97 static char * 98 numstr(int x) 99 { 100 static char buf[20]; 101 102 snprintf(buf, sizeof(buf), "%#x", x); 103 return buf; 104 } 105 106 /* sp points to IAC byte */ 107 static int 108 telnet_parse(const u_char *sp, u_int length, int print) 109 { 110 int i, x; 111 u_int c; 112 const u_char *osp, *p; 113 #define FETCH(c, sp, length) \ 114 do { \ 115 if (length < 1) \ 116 goto pktend; \ 117 TCHECK(*sp); \ 118 c = *sp++; \ 119 length--; \ 120 } while (0) 121 122 osp = sp; 123 124 FETCH(c, sp, length); 125 if (c != IAC) 126 goto pktend; 127 FETCH(c, sp, length); 128 if (c == IAC) { /* <IAC><IAC>! */ 129 if (print) 130 printf("IAC IAC"); 131 goto done; 132 } 133 134 i = c - TELCMD_FIRST; 135 if (i < 0 || i > IAC - TELCMD_FIRST) 136 goto pktend; 137 138 switch (c) { 139 case DONT: 140 case DO: 141 case WONT: 142 case WILL: 143 case SB: 144 /* DONT/DO/WONT/WILL x */ 145 FETCH(x, sp, length); 146 if (x >= 0 && x < NTELOPTS) { 147 if (print) 148 (void)printf("%s %s", telcmds[i], telopts[x]); 149 } else { 150 if (print) 151 (void)printf("%s %#x", telcmds[i], x); 152 } 153 if (c != SB) 154 break; 155 /* IAC SB .... IAC SE */ 156 p = sp; 157 while (length > (u_int)(p + 1 - sp)) { 158 if (p[0] == IAC && p[1] == SE) 159 break; 160 p++; 161 } 162 if (*p != IAC) 163 goto pktend; 164 165 switch (x) { 166 case TELOPT_AUTHENTICATION: 167 if (p <= sp) 168 break; 169 FETCH(c, sp, length); 170 if (print) 171 (void)printf(" %s", STR_OR_ID(c, authcmd)); 172 if (p <= sp) 173 break; 174 FETCH(c, sp, length); 175 if (print) 176 (void)printf(" %s", STR_OR_ID(c, authtype)); 177 break; 178 case TELOPT_ENCRYPT: 179 if (p <= sp) 180 break; 181 FETCH(c, sp, length); 182 if (print) 183 (void)printf(" %s", STR_OR_ID(c, enccmd)); 184 if (p <= sp) 185 break; 186 FETCH(c, sp, length); 187 if (print) 188 (void)printf(" %s", STR_OR_ID(c, enctype)); 189 break; 190 default: 191 if (p <= sp) 192 break; 193 FETCH(c, sp, length); 194 if (print) 195 (void)printf(" %s", STR_OR_ID(c, cmds)); 196 break; 197 } 198 while (p > sp) { 199 FETCH(x, sp, length); 200 if (print) 201 (void)printf(" %#x", x); 202 } 203 /* terminating IAC SE */ 204 if (print) 205 (void)printf(" SE"); 206 sp += 2; 207 length -= 2; 208 break; 209 default: 210 if (print) 211 (void)printf("%s", telcmds[i]); 212 goto done; 213 } 214 215 done: 216 return sp - osp; 217 218 trunc: 219 (void)printf("[|telnet]"); 220 pktend: 221 return -1; 222 #undef FETCH 223 } 224 225 void 226 telnet_print(const u_char *sp, u_int length) 227 { 228 int first = 1; 229 const u_char *osp; 230 int l; 231 232 osp = sp; 233 234 while (length > 0 && *sp == IAC) { 235 l = telnet_parse(sp, length, 0); 236 if (l < 0) 237 break; 238 239 /* 240 * now print it 241 */ 242 if (Xflag && 2 < vflag) { 243 if (first) 244 printf("\nTelnet:"); 245 hex_print_with_offset("\n", sp, l, sp - osp); 246 if (l > 8) 247 printf("\n\t\t\t\t"); 248 else 249 printf("%*s\t", (8 - l) * 3, ""); 250 } else 251 printf("%s", (first) ? " [telnet " : ", "); 252 253 (void)telnet_parse(sp, length, 1); 254 first = 0; 255 256 sp += l; 257 length -= l; 258 } 259 if (!first) { 260 if (Xflag && 2 < vflag) 261 printf("\n"); 262 else 263 printf("]"); 264 } 265 } 266