156893Sfenner/* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */ 256893Sfenner 356893Sfenner/*- 456893Sfenner * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 556893Sfenner * All rights reserved. 656893Sfenner * 756893Sfenner * This code is derived from software contributed to The NetBSD Foundation 856893Sfenner * by Simon J. Gerraty. 956893Sfenner * 1056893Sfenner * Redistribution and use in source and binary forms, with or without 1156893Sfenner * modification, are permitted provided that the following conditions 1256893Sfenner * are met: 1356893Sfenner * 1. Redistributions of source code must retain the above copyright 1456893Sfenner * notice, this list of conditions and the following disclaimer. 1556893Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1656893Sfenner * notice, this list of conditions and the following disclaimer in the 1756893Sfenner * documentation and/or other materials provided with the distribution. 1856893Sfenner * 3. All advertising materials mentioning features or use of this software 1956893Sfenner * must display the following acknowledgement: 2056893Sfenner * This product includes software developed by the NetBSD 2156893Sfenner * Foundation, Inc. and its contributors. 2256893Sfenner * 4. Neither the name of The NetBSD Foundation nor the names of its 2356893Sfenner * contributors may be used to endorse or promote products derived 2456893Sfenner * from this software without specific prior written permission. 2556893Sfenner * 2656893Sfenner * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2756893Sfenner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2856893Sfenner * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2956893Sfenner * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 3056893Sfenner * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3156893Sfenner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3256893Sfenner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3356893Sfenner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3456893Sfenner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3556893Sfenner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3656893Sfenner * POSSIBILITY OF SUCH DAMAGE. 3756893Sfenner */ 3856893Sfenner/* 3956893Sfenner * @(#)Copyright (c) 1994, Simon J. Gerraty. 40127668Sbms * 4156893Sfenner * This is free software. It comes with NO WARRANTY. 42127668Sbms * Permission to use, modify and distribute this source code 4356893Sfenner * is granted subject to the following conditions. 44127668Sbms * 1/ that the above copyright notice and this notice 4556893Sfenner * are preserved in all copies. 4656893Sfenner */ 4756893Sfenner 4856893Sfenner#ifdef HAVE_CONFIG_H 4956893Sfenner#include "config.h" 5056893Sfenner#endif 5156893Sfenner 5256893Sfenner#ifndef lint 53127668Sbmsstatic const char rcsid[] _U_ = 54190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.24 2003-12-29 11:05:10 hannes Exp $"; 5556893Sfenner#endif 5656893Sfenner 57127668Sbms#include <tcpdump-stdinc.h> 5856893Sfenner 5956893Sfenner#include <stdio.h> 6056893Sfenner#include <stdlib.h> 6156893Sfenner#include <string.h> 6256893Sfenner 6356893Sfenner#include "interface.h" 6456893Sfenner#include "addrtoname.h" 6556893Sfenner 6698524Sfenner#define TELCMDS 6798524Sfenner#define TELOPTS 6898524Sfenner#include "telnet.h" 6956893Sfenner 7098524Sfenner/* normal */ 7198524Sfennerstatic const char *cmds[] = { 7298524Sfenner "IS", "SEND", "INFO", 7398524Sfenner}; 7498524Sfenner 7598524Sfenner/* 37: Authentication */ 7698524Sfennerstatic const char *authcmd[] = { 7798524Sfenner "IS", "SEND", "REPLY", "NAME", 7898524Sfenner}; 7998524Sfennerstatic const char *authtype[] = { 8098524Sfenner "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 8198524Sfenner "SRP", "RSA", "SSL", NULL, NULL, 8298524Sfenner "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS", 8398524Sfenner "NTLM", 8498524Sfenner}; 8598524Sfenner 8698524Sfenner/* 38: Encryption */ 8798524Sfennerstatic const char *enccmd[] = { 8898524Sfenner "IS", "SUPPORT", "REPLY", "START", "END", 8998524Sfenner "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID", 9098524Sfenner}; 9198524Sfennerstatic const char *enctype[] = { 9298524Sfenner "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64", 9398524Sfenner NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64", 9498524Sfenner}; 9598524Sfenner 9698524Sfenner#define STR_OR_ID(x, tab) \ 9798524Sfenner (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) 9898524Sfenner 9998524Sfennerstatic char * 10098524Sfennernumstr(int x) 10156893Sfenner{ 10298524Sfenner static char buf[20]; 10356893Sfenner 10498524Sfenner snprintf(buf, sizeof(buf), "%#x", x); 10598524Sfenner return buf; 10698524Sfenner} 10798524Sfenner 10898524Sfenner/* sp points to IAC byte */ 10998524Sfennerstatic int 11098524Sfennertelnet_parse(const u_char *sp, u_int length, int print) 11198524Sfenner{ 112127668Sbms int i, x; 113127668Sbms u_int c; 11498524Sfenner const u_char *osp, *p; 11598524Sfenner#define FETCH(c, sp, length) \ 11698524Sfenner do { \ 11798524Sfenner if (length < 1) \ 11898524Sfenner goto pktend; \ 11998524Sfenner TCHECK(*sp); \ 12098524Sfenner c = *sp++; \ 12198524Sfenner length--; \ 12298524Sfenner } while (0) 12398524Sfenner 12498524Sfenner osp = sp; 12598524Sfenner 12698524Sfenner FETCH(c, sp, length); 12798524Sfenner if (c != IAC) 12898524Sfenner goto pktend; 12998524Sfenner FETCH(c, sp, length); 13098524Sfenner if (c == IAC) { /* <IAC><IAC>! */ 13198524Sfenner if (print) 13298524Sfenner printf("IAC IAC"); 13398524Sfenner goto done; 13498524Sfenner } 13598524Sfenner 13698524Sfenner i = c - TELCMD_FIRST; 13798524Sfenner if (i < 0 || i > IAC - TELCMD_FIRST) 13898524Sfenner goto pktend; 13998524Sfenner 14098524Sfenner switch (c) { 14198524Sfenner case DONT: 14298524Sfenner case DO: 14398524Sfenner case WONT: 14498524Sfenner case WILL: 14598524Sfenner case SB: 14698524Sfenner /* DONT/DO/WONT/WILL x */ 14798524Sfenner FETCH(x, sp, length); 14898524Sfenner if (x >= 0 && x < NTELOPTS) { 14998524Sfenner if (print) 15098524Sfenner (void)printf("%s %s", telcmds[i], telopts[x]); 15198524Sfenner } else { 15298524Sfenner if (print) 15398524Sfenner (void)printf("%s %#x", telcmds[i], x); 15498524Sfenner } 15598524Sfenner if (c != SB) 15656893Sfenner break; 15798524Sfenner /* IAC SB .... IAC SE */ 15898524Sfenner p = sp; 159127668Sbms while (length > (u_int)(p + 1 - sp)) { 16098524Sfenner if (p[0] == IAC && p[1] == SE) 16198524Sfenner break; 16298524Sfenner p++; 16398524Sfenner } 16498524Sfenner if (*p != IAC) 16598524Sfenner goto pktend; 16698524Sfenner 16798524Sfenner switch (x) { 16898524Sfenner case TELOPT_AUTHENTICATION: 16998524Sfenner if (p <= sp) 17098524Sfenner break; 17198524Sfenner FETCH(c, sp, length); 17298524Sfenner if (print) 17398524Sfenner (void)printf(" %s", STR_OR_ID(c, authcmd)); 17498524Sfenner if (p <= sp) 17598524Sfenner break; 17698524Sfenner FETCH(c, sp, length); 17798524Sfenner if (print) 17898524Sfenner (void)printf(" %s", STR_OR_ID(c, authtype)); 17998524Sfenner break; 18098524Sfenner case TELOPT_ENCRYPT: 18198524Sfenner if (p <= sp) 18298524Sfenner break; 18398524Sfenner FETCH(c, sp, length); 18498524Sfenner if (print) 18598524Sfenner (void)printf(" %s", STR_OR_ID(c, enccmd)); 18698524Sfenner if (p <= sp) 18798524Sfenner break; 18898524Sfenner FETCH(c, sp, length); 18998524Sfenner if (print) 19098524Sfenner (void)printf(" %s", STR_OR_ID(c, enctype)); 19198524Sfenner break; 19256893Sfenner default: 19398524Sfenner if (p <= sp) 19456893Sfenner break; 19598524Sfenner FETCH(c, sp, length); 19698524Sfenner if (print) 19798524Sfenner (void)printf(" %s", STR_OR_ID(c, cmds)); 19856893Sfenner break; 19956893Sfenner } 20098524Sfenner while (p > sp) { 20198524Sfenner FETCH(x, sp, length); 20298524Sfenner if (print) 20398524Sfenner (void)printf(" %#x", x); 20498524Sfenner } 20598524Sfenner /* terminating IAC SE */ 20698524Sfenner if (print) 20798524Sfenner (void)printf(" SE"); 20898524Sfenner sp += 2; 20998524Sfenner length -= 2; 21098524Sfenner break; 21198524Sfenner default: 21298524Sfenner if (print) 21398524Sfenner (void)printf("%s", telcmds[i]); 21498524Sfenner goto done; 21598524Sfenner } 21698524Sfenner 21798524Sfennerdone: 21898524Sfenner return sp - osp; 21998524Sfenner 22098524Sfennertrunc: 22198524Sfenner (void)printf("[|telnet]"); 22298524Sfennerpktend: 22398524Sfenner return -1; 22498524Sfenner#undef FETCH 22598524Sfenner} 22698524Sfenner 22798524Sfennervoid 22898524Sfennertelnet_print(const u_char *sp, u_int length) 22998524Sfenner{ 23098524Sfenner int first = 1; 23198524Sfenner const u_char *osp; 23298524Sfenner int l; 23398524Sfenner 23498524Sfenner osp = sp; 235127668Sbms 23698524Sfenner while (length > 0 && *sp == IAC) { 23798524Sfenner l = telnet_parse(sp, length, 0); 23898524Sfenner if (l < 0) 23998524Sfenner break; 24098524Sfenner 24156893Sfenner /* 24256893Sfenner * now print it 24356893Sfenner */ 24456893Sfenner if (Xflag && 2 < vflag) { 24556893Sfenner if (first) 24698524Sfenner printf("\nTelnet:"); 247127668Sbms hex_print_with_offset("\n", sp, l, sp - osp); 24898524Sfenner if (l > 8) 24975115Sfenner printf("\n\t\t\t\t"); 25056893Sfenner else 25198524Sfenner printf("%*s\t", (8 - l) * 3, ""); 25298524Sfenner } else 25375115Sfenner printf("%s", (first) ? " [telnet " : ", "); 25498524Sfenner 25598524Sfenner (void)telnet_parse(sp, length, 1); 25656893Sfenner first = 0; 25798524Sfenner 25898524Sfenner sp += l; 25998524Sfenner length -= l; 26056893Sfenner } 26156893Sfenner if (!first) { 26256893Sfenner if (Xflag && 2 < vflag) 26356893Sfenner printf("\n"); 26456893Sfenner else 26556893Sfenner printf("]"); 26656893Sfenner } 26756893Sfenner} 268