Home | History | Annotate | Line # | Download | only in dist
print-telnet.c revision 1.3
      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.3 2013/04/06 19:33:08 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