X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/003d0035f4db84d00b1b76802869c3563335612d..dbd0cbc147d140e9bd34eefa7b66a17f691d49e0:/print-telnet.c diff --git a/print-telnet.c b/print-telnet.c index df5370c8..4911e5ca 100644 --- a/print-telnet.c +++ b/print-telnet.c @@ -37,11 +37,11 @@ */ /* * @(#)Copyright (c) 1994, Simon J. Gerraty. - * + * * This is free software. It comes with NO WARRANTY. - * Permission to use, modify and distribute this source code + * 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 + * 1/ that the above copyright notice and this notice * are preserved in all copies. */ @@ -50,49 +50,74 @@ #endif #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.15 2001-06-25 23:03:57 itojun Exp $"; +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 -#include -#include -#include - -#include - -#define TELCMDS -#define TELOPTS -#include +#include #include #include -#include #include #include "interface.h" #include "addrtoname.h" -#ifndef TELCMD_FIRST -# define TELCMD_FIRST SE -#endif +#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", +}; -/* sp points to IAB byte */ +/* 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, c, x; + int i, x; + u_int c; const u_char *osp, *p; -#define PEEK(c, sp, length) \ - do { \ - if (length < 1) \ - goto trunc; \ - c = *sp; \ - } while (0) #define FETCH(c, sp, length) \ do { \ - PEEK((c), (sp), (length)); \ - sp++; \ + if (length < 1) \ + goto pktend; \ + TCHECK(*sp); \ + c = *sp++; \ length--; \ } while (0) @@ -100,7 +125,7 @@ telnet_parse(const u_char *sp, u_int length, int print) FETCH(c, sp, length); if (c != IAC) - goto trunc; + goto pktend; FETCH(c, sp, length); if (c == IAC) { /* ! */ if (print) @@ -110,7 +135,7 @@ telnet_parse(const u_char *sp, u_int length, int print) i = c - TELCMD_FIRST; if (i < 0 || i > IAC - TELCMD_FIRST) - goto trunc; + goto pktend; switch (c) { case DONT: @@ -131,33 +156,51 @@ telnet_parse(const u_char *sp, u_int length, int print) break; /* IAC SB .... IAC SE */ p = sp; - while (length > p + 1 - sp) { + while (length > (u_int)(p + 1 - sp)) { if (p[0] == IAC && p[1] == SE) break; p++; } if (*p != IAC) - goto trunc; - - PEEK(c, sp, length); - if (c) { - while (p > sp) { - FETCH(x, sp, length); - if (print) - (void)printf(" %#x", x); - } - } else { + 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(" IS '"); - while (p > sp) { - FETCH(x, sp, length); - if (print) - safeputchar(x); - } - /* terminating IAC SE */ + (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("'"); + (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) @@ -175,8 +218,9 @@ done: return sp - osp; trunc: + (void)printf("[|telnet]"); +pktend: return -1; -#undef PEEK #undef FETCH } @@ -188,7 +232,7 @@ telnet_print(const u_char *sp, u_int length) int l; osp = sp; - + while (length > 0 && *sp == IAC) { l = telnet_parse(sp, length, 0); if (l < 0) @@ -200,7 +244,7 @@ telnet_print(const u_char *sp, u_int length) if (Xflag && 2 < vflag) { if (first) printf("\nTelnet:"); - hex_print_with_offset(sp, l, sp - osp); + hex_print_with_offset("\n", sp, l, sp - osp); if (l > 8) printf("\n\t\t\t\t"); else