diff options
Diffstat (limited to 'contrib/tcpdump/print-telnet.c')
-rw-r--r-- | contrib/tcpdump/print-telnet.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/contrib/tcpdump/print-telnet.c b/contrib/tcpdump/print-telnet.c new file mode 100644 index 0000000..4911e5c --- /dev/null +++ b/contrib/tcpdump/print-telnet.c @@ -0,0 +1,267 @@ +/* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */ + +/*- + * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Simon J. Gerraty. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* + * @(#)Copyright (c) 1994, Simon J. Gerraty. + * + * This is free software. It comes with NO WARRANTY. + * Permission to use, modify and distribute this source code + * is granted subject to the following conditions. + * 1/ that the above copyright notice and this notice + * are preserved in all copies. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.24 2003-12-29 11:05:10 hannes Exp $"; +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" + +#define TELCMDS +#define TELOPTS +#include "telnet.h" + +/* normal */ +static const char *cmds[] = { + "IS", "SEND", "INFO", +}; + +/* 37: Authentication */ +static const char *authcmd[] = { + "IS", "SEND", "REPLY", "NAME", +}; +static const char *authtype[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", + "SRP", "RSA", "SSL", NULL, NULL, + "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS", + "NTLM", +}; + +/* 38: Encryption */ +static const char *enccmd[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID", +}; +static const char *enctype[] = { + "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64", + NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64", +}; + +#define STR_OR_ID(x, tab) \ + (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) + +static char * +numstr(int x) +{ + static char buf[20]; + + snprintf(buf, sizeof(buf), "%#x", x); + return buf; +} + +/* sp points to IAC byte */ +static int +telnet_parse(const u_char *sp, u_int length, int print) +{ + int i, x; + u_int c; + const u_char *osp, *p; +#define FETCH(c, sp, length) \ + do { \ + if (length < 1) \ + goto pktend; \ + TCHECK(*sp); \ + c = *sp++; \ + length--; \ + } while (0) + + osp = sp; + + FETCH(c, sp, length); + if (c != IAC) + goto pktend; + FETCH(c, sp, length); + if (c == IAC) { /* <IAC><IAC>! */ + if (print) + printf("IAC IAC"); + goto done; + } + + i = c - TELCMD_FIRST; + if (i < 0 || i > IAC - TELCMD_FIRST) + goto pktend; + + switch (c) { + case DONT: + case DO: + case WONT: + case WILL: + case SB: + /* DONT/DO/WONT/WILL x */ + FETCH(x, sp, length); + if (x >= 0 && x < NTELOPTS) { + if (print) + (void)printf("%s %s", telcmds[i], telopts[x]); + } else { + if (print) + (void)printf("%s %#x", telcmds[i], x); + } + if (c != SB) + break; + /* IAC SB .... IAC SE */ + p = sp; + while (length > (u_int)(p + 1 - sp)) { + if (p[0] == IAC && p[1] == SE) + break; + p++; + } + if (*p != IAC) + goto pktend; + + switch (x) { + case TELOPT_AUTHENTICATION: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, authcmd)); + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, authtype)); + break; + case TELOPT_ENCRYPT: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, enccmd)); + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, enctype)); + break; + default: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, cmds)); + break; + } + while (p > sp) { + FETCH(x, sp, length); + if (print) + (void)printf(" %#x", x); + } + /* terminating IAC SE */ + if (print) + (void)printf(" SE"); + sp += 2; + length -= 2; + break; + default: + if (print) + (void)printf("%s", telcmds[i]); + goto done; + } + +done: + return sp - osp; + +trunc: + (void)printf("[|telnet]"); +pktend: + return -1; +#undef FETCH +} + +void +telnet_print(const u_char *sp, u_int length) +{ + int first = 1; + const u_char *osp; + int l; + + osp = sp; + + while (length > 0 && *sp == IAC) { + l = telnet_parse(sp, length, 0); + if (l < 0) + break; + + /* + * now print it + */ + if (Xflag && 2 < vflag) { + if (first) + printf("\nTelnet:"); + hex_print_with_offset("\n", sp, l, sp - osp); + if (l > 8) + printf("\n\t\t\t\t"); + else + printf("%*s\t", (8 - l) * 3, ""); + } else + printf("%s", (first) ? " [telnet " : ", "); + + (void)telnet_parse(sp, length, 1); + first = 0; + + sp += l; + length -= l; + } + if (!first) { + if (Xflag && 2 < vflag) + printf("\n"); + else + printf("]"); + } +} |