1b0453382SBill Fenner /* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */
2b0453382SBill Fenner
3b0453382SBill Fenner /*-
4b0453382SBill Fenner * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5b0453382SBill Fenner * All rights reserved.
6b0453382SBill Fenner *
7b0453382SBill Fenner * This code is derived from software contributed to The NetBSD Foundation
8b0453382SBill Fenner * by Simon J. Gerraty.
9b0453382SBill Fenner *
10b0453382SBill Fenner * Redistribution and use in source and binary forms, with or without
11b0453382SBill Fenner * modification, are permitted provided that the following conditions
12b0453382SBill Fenner * are met:
13b0453382SBill Fenner * 1. Redistributions of source code must retain the above copyright
14b0453382SBill Fenner * notice, this list of conditions and the following disclaimer.
15b0453382SBill Fenner * 2. Redistributions in binary form must reproduce the above copyright
16b0453382SBill Fenner * notice, this list of conditions and the following disclaimer in the
17b0453382SBill Fenner * documentation and/or other materials provided with the distribution.
18b0453382SBill Fenner * 3. All advertising materials mentioning features or use of this software
19b0453382SBill Fenner * must display the following acknowledgement:
20b0453382SBill Fenner * This product includes software developed by the NetBSD
21b0453382SBill Fenner * Foundation, Inc. and its contributors.
22b0453382SBill Fenner * 4. Neither the name of The NetBSD Foundation nor the names of its
23b0453382SBill Fenner * contributors may be used to endorse or promote products derived
24b0453382SBill Fenner * from this software without specific prior written permission.
25b0453382SBill Fenner *
26b0453382SBill Fenner * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27b0453382SBill Fenner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28b0453382SBill Fenner * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29b0453382SBill Fenner * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30b0453382SBill Fenner * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31b0453382SBill Fenner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32b0453382SBill Fenner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33b0453382SBill Fenner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34b0453382SBill Fenner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35b0453382SBill Fenner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36b0453382SBill Fenner * POSSIBILITY OF SUCH DAMAGE.
37b0453382SBill Fenner */
38b0453382SBill Fenner /*
39b0453382SBill Fenner * @(#)Copyright (c) 1994, Simon J. Gerraty.
40b0453382SBill Fenner *
41b0453382SBill Fenner * This is free software. It comes with NO WARRANTY.
42b0453382SBill Fenner * Permission to use, modify and distribute this source code
43b0453382SBill Fenner * is granted subject to the following conditions.
44b0453382SBill Fenner * 1/ that the above copyright notice and this notice
45b0453382SBill Fenner * are preserved in all copies.
46b0453382SBill Fenner */
47b0453382SBill Fenner
483340d773SGleb Smirnoff /* \summary: Telnet option printer */
493340d773SGleb Smirnoff
50b0453382SBill Fenner #ifdef HAVE_CONFIG_H
51ee67461eSJoseph Mingrone #include <config.h>
52b0453382SBill Fenner #endif
53b0453382SBill Fenner
54ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
55b0453382SBill Fenner
56b0453382SBill Fenner #include <stdio.h>
57b0453382SBill Fenner
583340d773SGleb Smirnoff #include "netdissect.h"
59ee67461eSJoseph Mingrone #include "extract.h"
603340d773SGleb Smirnoff
613c602fabSXin LI
623c602fabSXin LI /* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */
633c602fabSXin LI
643c602fabSXin LI /*
653c602fabSXin LI * Definitions for the TELNET protocol.
663c602fabSXin LI */
673c602fabSXin LI #define IAC 255 /* interpret as command: */
683c602fabSXin LI #define DONT 254 /* you are not to use option */
693c602fabSXin LI #define DO 253 /* please, you use option */
703c602fabSXin LI #define WONT 252 /* I won't use option */
713c602fabSXin LI #define WILL 251 /* I will use option */
723c602fabSXin LI #define SB 250 /* interpret as subnegotiation */
733c602fabSXin LI #define GA 249 /* you may reverse the line */
743c602fabSXin LI #define EL 248 /* erase the current line */
753c602fabSXin LI #define EC 247 /* erase the current character */
763c602fabSXin LI #define AYT 246 /* are you there */
773c602fabSXin LI #define AO 245 /* abort output--but let prog finish */
783c602fabSXin LI #define IP 244 /* interrupt process--permanently */
793c602fabSXin LI #define BREAK 243 /* break */
803c602fabSXin LI #define DM 242 /* data mark--for connect. cleaning */
813c602fabSXin LI #define NOP 241 /* nop */
823c602fabSXin LI #define SE 240 /* end sub negotiation */
833c602fabSXin LI #define EOR 239 /* end of record (transparent mode) */
843c602fabSXin LI #define ABORT 238 /* Abort process */
853c602fabSXin LI #define SUSP 237 /* Suspend process */
863c602fabSXin LI #define xEOF 236 /* End of file: EOF is already used... */
873c602fabSXin LI
883c602fabSXin LI #define SYNCH 242 /* for telfunc calls */
893c602fabSXin LI
903340d773SGleb Smirnoff static const char *telcmds[] = {
913c602fabSXin LI "EOF", "SUSP", "ABORT", "EOR",
923c602fabSXin LI "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
933c602fabSXin LI "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
943c602fabSXin LI };
953c602fabSXin LI
963c602fabSXin LI #define TELCMD_FIRST xEOF
973c602fabSXin LI #define TELCMD_LAST IAC
983c602fabSXin LI #define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
993c602fabSXin LI (unsigned int)(x) >= TELCMD_FIRST)
1003c602fabSXin LI #define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
1013c602fabSXin LI
1023c602fabSXin LI /* telnet options */
1033c602fabSXin LI #define TELOPT_BINARY 0 /* 8-bit data path */
1043c602fabSXin LI #define TELOPT_ECHO 1 /* echo */
1053c602fabSXin LI #define TELOPT_RCP 2 /* prepare to reconnect */
1063c602fabSXin LI #define TELOPT_SGA 3 /* suppress go ahead */
1073c602fabSXin LI #define TELOPT_NAMS 4 /* approximate message size */
1083c602fabSXin LI #define TELOPT_STATUS 5 /* give status */
1093c602fabSXin LI #define TELOPT_TM 6 /* timing mark */
1103c602fabSXin LI #define TELOPT_RCTE 7 /* remote controlled transmission and echo */
1113c602fabSXin LI #define TELOPT_NAOL 8 /* negotiate about output line width */
1123c602fabSXin LI #define TELOPT_NAOP 9 /* negotiate about output page size */
1133c602fabSXin LI #define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
1143c602fabSXin LI #define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
1153c602fabSXin LI #define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
1163c602fabSXin LI #define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
1173c602fabSXin LI #define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
1183c602fabSXin LI #define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
1193c602fabSXin LI #define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
1203c602fabSXin LI #define TELOPT_XASCII 17 /* extended ascic character set */
1213c602fabSXin LI #define TELOPT_LOGOUT 18 /* force logout */
1223c602fabSXin LI #define TELOPT_BM 19 /* byte macro */
1233c602fabSXin LI #define TELOPT_DET 20 /* data entry terminal */
1243c602fabSXin LI #define TELOPT_SUPDUP 21 /* supdup protocol */
1253c602fabSXin LI #define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
1263c602fabSXin LI #define TELOPT_SNDLOC 23 /* send location */
1273c602fabSXin LI #define TELOPT_TTYPE 24 /* terminal type */
1283c602fabSXin LI #define TELOPT_EOR 25 /* end or record */
1293c602fabSXin LI #define TELOPT_TUID 26 /* TACACS user identification */
1303c602fabSXin LI #define TELOPT_OUTMRK 27 /* output marking */
1313c602fabSXin LI #define TELOPT_TTYLOC 28 /* terminal location number */
1323c602fabSXin LI #define TELOPT_3270REGIME 29 /* 3270 regime */
1333c602fabSXin LI #define TELOPT_X3PAD 30 /* X.3 PAD */
1343c602fabSXin LI #define TELOPT_NAWS 31 /* window size */
1353c602fabSXin LI #define TELOPT_TSPEED 32 /* terminal speed */
1363c602fabSXin LI #define TELOPT_LFLOW 33 /* remote flow control */
1373c602fabSXin LI #define TELOPT_LINEMODE 34 /* Linemode option */
1383c602fabSXin LI #define TELOPT_XDISPLOC 35 /* X Display Location */
1393c602fabSXin LI #define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
1403c602fabSXin LI #define TELOPT_AUTHENTICATION 37/* Authenticate */
1413c602fabSXin LI #define TELOPT_ENCRYPT 38 /* Encryption option */
1423c602fabSXin LI #define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
1433c602fabSXin LI #define TELOPT_EXOPL 255 /* extended-options-list */
1443c602fabSXin LI
1453c602fabSXin LI
1463c602fabSXin LI #define NTELOPTS (1+TELOPT_NEW_ENVIRON)
1473340d773SGleb Smirnoff static const char *telopts[NTELOPTS+1] = {
1483c602fabSXin LI "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
1493c602fabSXin LI "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
1503c602fabSXin LI "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
1513c602fabSXin LI "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
1523c602fabSXin LI "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
1533c602fabSXin LI "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
1543c602fabSXin LI "TACACS UID", "OUTPUT MARKING", "TTYLOC",
1553c602fabSXin LI "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
1563c602fabSXin LI "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
1573c602fabSXin LI "ENCRYPT", "NEW-ENVIRON",
1583c602fabSXin LI 0,
1593c602fabSXin LI };
1603c602fabSXin LI #define TELOPT_FIRST TELOPT_BINARY
1613c602fabSXin LI #define TELOPT_LAST TELOPT_NEW_ENVIRON
1623c602fabSXin LI #define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
1633c602fabSXin LI #define TELOPT(x) telopts[(x)-TELOPT_FIRST]
1643c602fabSXin LI
1653c602fabSXin LI /* sub-option qualifiers */
1663c602fabSXin LI #define TELQUAL_IS 0 /* option is... */
1673c602fabSXin LI #define TELQUAL_SEND 1 /* send option */
1683c602fabSXin LI #define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
1693c602fabSXin LI #define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
1703c602fabSXin LI #define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
1713c602fabSXin LI
1723c602fabSXin LI #define LFLOW_OFF 0 /* Disable remote flow control */
1733c602fabSXin LI #define LFLOW_ON 1 /* Enable remote flow control */
1743c602fabSXin LI #define LFLOW_RESTART_ANY 2 /* Restart output on any char */
1753c602fabSXin LI #define LFLOW_RESTART_XON 3 /* Restart output only on XON */
1763c602fabSXin LI
1773c602fabSXin LI /*
1783c602fabSXin LI * LINEMODE suboptions
1793c602fabSXin LI */
1803c602fabSXin LI
1813c602fabSXin LI #define LM_MODE 1
1823c602fabSXin LI #define LM_FORWARDMASK 2
1833c602fabSXin LI #define LM_SLC 3
1843c602fabSXin LI
1853c602fabSXin LI #define MODE_EDIT 0x01
1863c602fabSXin LI #define MODE_TRAPSIG 0x02
1873c602fabSXin LI #define MODE_ACK 0x04
1883c602fabSXin LI #define MODE_SOFT_TAB 0x08
1893c602fabSXin LI #define MODE_LIT_ECHO 0x10
1903c602fabSXin LI
1913c602fabSXin LI #define MODE_MASK 0x1f
1923c602fabSXin LI
1933c602fabSXin LI #define SLC_SYNCH 1
1943c602fabSXin LI #define SLC_BRK 2
1953c602fabSXin LI #define SLC_IP 3
1963c602fabSXin LI #define SLC_AO 4
1973c602fabSXin LI #define SLC_AYT 5
1983c602fabSXin LI #define SLC_EOR 6
1993c602fabSXin LI #define SLC_ABORT 7
2003c602fabSXin LI #define SLC_EOF 8
2013c602fabSXin LI #define SLC_SUSP 9
2023c602fabSXin LI #define SLC_EC 10
2033c602fabSXin LI #define SLC_EL 11
2043c602fabSXin LI #define SLC_EW 12
2053c602fabSXin LI #define SLC_RP 13
2063c602fabSXin LI #define SLC_LNEXT 14
2073c602fabSXin LI #define SLC_XON 15
2083c602fabSXin LI #define SLC_XOFF 16
2093c602fabSXin LI #define SLC_FORW1 17
2103c602fabSXin LI #define SLC_FORW2 18
2113c602fabSXin LI #define SLC_MCL 19
2123c602fabSXin LI #define SLC_MCR 20
2133c602fabSXin LI #define SLC_MCWL 21
2143c602fabSXin LI #define SLC_MCWR 22
2153c602fabSXin LI #define SLC_MCBOL 23
2163c602fabSXin LI #define SLC_MCEOL 24
2173c602fabSXin LI #define SLC_INSRT 25
2183c602fabSXin LI #define SLC_OVER 26
2193c602fabSXin LI #define SLC_ECR 27
2203c602fabSXin LI #define SLC_EWR 28
2213c602fabSXin LI #define SLC_EBOL 29
2223c602fabSXin LI #define SLC_EEOL 30
2233c602fabSXin LI
2243c602fabSXin LI #define NSLC 30
2253c602fabSXin LI
2263c602fabSXin LI /*
2273c602fabSXin LI * For backwards compatibility, we define SLC_NAMES to be the
2283c602fabSXin LI * list of names if SLC_NAMES is not defined.
2293c602fabSXin LI */
2303c602fabSXin LI #define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
2313c602fabSXin LI "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
2323c602fabSXin LI "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
2333c602fabSXin LI "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \
2343c602fabSXin LI "MCEOL", "INSRT", "OVER", "ECR", "EWR", \
2353c602fabSXin LI "EBOL", "EEOL", \
2363c602fabSXin LI 0,
2373c602fabSXin LI
2383c602fabSXin LI #ifdef SLC_NAMES
2393c602fabSXin LI const char *slc_names[] = {
2403c602fabSXin LI SLC_NAMELIST
2413c602fabSXin LI };
2423c602fabSXin LI #else
2433c602fabSXin LI extern char *slc_names[];
2443c602fabSXin LI #define SLC_NAMES SLC_NAMELIST
2453c602fabSXin LI #endif
2463c602fabSXin LI
2473c602fabSXin LI #define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
2483c602fabSXin LI #define SLC_NAME(x) slc_names[x]
2493c602fabSXin LI
2503c602fabSXin LI #define SLC_NOSUPPORT 0
2513c602fabSXin LI #define SLC_CANTCHANGE 1
2523c602fabSXin LI #define SLC_VARIABLE 2
2533c602fabSXin LI #define SLC_DEFAULT 3
2543c602fabSXin LI #define SLC_LEVELBITS 0x03
2553c602fabSXin LI
2563c602fabSXin LI #define SLC_FUNC 0
2573c602fabSXin LI #define SLC_FLAGS 1
2583c602fabSXin LI #define SLC_VALUE 2
2593c602fabSXin LI
2603c602fabSXin LI #define SLC_ACK 0x80
2613c602fabSXin LI #define SLC_FLUSHIN 0x40
2623c602fabSXin LI #define SLC_FLUSHOUT 0x20
2633c602fabSXin LI
2643c602fabSXin LI #define OLD_ENV_VAR 1
2653c602fabSXin LI #define OLD_ENV_VALUE 0
2663c602fabSXin LI #define NEW_ENV_VAR 0
2673c602fabSXin LI #define NEW_ENV_VALUE 1
2683c602fabSXin LI #define ENV_ESC 2
2693c602fabSXin LI #define ENV_USERVAR 3
2703c602fabSXin LI
2713c602fabSXin LI /*
2723c602fabSXin LI * AUTHENTICATION suboptions
2733c602fabSXin LI */
2743c602fabSXin LI
2753c602fabSXin LI /*
2763c602fabSXin LI * Who is authenticating who ...
2773c602fabSXin LI */
2783c602fabSXin LI #define AUTH_WHO_CLIENT 0 /* Client authenticating server */
2793c602fabSXin LI #define AUTH_WHO_SERVER 1 /* Server authenticating client */
2803c602fabSXin LI #define AUTH_WHO_MASK 1
2813c602fabSXin LI
2823c602fabSXin LI #define AUTHTYPE_NULL 0
2833c602fabSXin LI #define AUTHTYPE_KERBEROS_V4 1
2843c602fabSXin LI #define AUTHTYPE_KERBEROS_V5 2
2853c602fabSXin LI #define AUTHTYPE_SPX 3
2863c602fabSXin LI #define AUTHTYPE_MINK 4
2873c602fabSXin LI #define AUTHTYPE_CNT 5
2883c602fabSXin LI
2893c602fabSXin LI #define AUTHTYPE_TEST 99
2903c602fabSXin LI
2913c602fabSXin LI #ifdef AUTH_NAMES
2923c602fabSXin LI const char *authtype_names[] = {
2933c602fabSXin LI "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
2943c602fabSXin LI };
2953c602fabSXin LI #else
2963c602fabSXin LI extern char *authtype_names[];
2973c602fabSXin LI #endif
2983c602fabSXin LI
2993c602fabSXin LI #define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
3003c602fabSXin LI #define AUTHTYPE_NAME(x) authtype_names[x]
3013c602fabSXin LI
3023c602fabSXin LI /*
3033c602fabSXin LI * ENCRYPTion suboptions
3043c602fabSXin LI */
3053c602fabSXin LI #define ENCRYPT_IS 0 /* I pick encryption type ... */
3063c602fabSXin LI #define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
3073c602fabSXin LI #define ENCRYPT_REPLY 2 /* Initial setup response */
3083c602fabSXin LI #define ENCRYPT_START 3 /* Am starting to send encrypted */
3093c602fabSXin LI #define ENCRYPT_END 4 /* Am ending encrypted */
3103c602fabSXin LI #define ENCRYPT_REQSTART 5 /* Request you start encrypting */
3113c602fabSXin LI #define ENCRYPT_REQEND 6 /* Request you send encrypting */
3123c602fabSXin LI #define ENCRYPT_ENC_KEYID 7
3133c602fabSXin LI #define ENCRYPT_DEC_KEYID 8
3143c602fabSXin LI #define ENCRYPT_CNT 9
3153c602fabSXin LI
3163c602fabSXin LI #define ENCTYPE_ANY 0
3173c602fabSXin LI #define ENCTYPE_DES_CFB64 1
3183c602fabSXin LI #define ENCTYPE_DES_OFB64 2
3193c602fabSXin LI #define ENCTYPE_CNT 3
3203c602fabSXin LI
3213c602fabSXin LI #ifdef ENCRYPT_NAMES
3223c602fabSXin LI const char *encrypt_names[] = {
3233c602fabSXin LI "IS", "SUPPORT", "REPLY", "START", "END",
3243c602fabSXin LI "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
3253c602fabSXin LI 0,
3263c602fabSXin LI };
3273c602fabSXin LI const char *enctype_names[] = {
3283c602fabSXin LI "ANY", "DES_CFB64", "DES_OFB64", 0,
3293c602fabSXin LI };
3303c602fabSXin LI #else
3313c602fabSXin LI extern char *encrypt_names[];
3323c602fabSXin LI extern char *enctype_names[];
3333c602fabSXin LI #endif
3343c602fabSXin LI
3353c602fabSXin LI #define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
3363c602fabSXin LI #define ENCRYPT_NAME(x) encrypt_names[x]
3373c602fabSXin LI
3383c602fabSXin LI #define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
3393c602fabSXin LI #define ENCTYPE_NAME(x) enctype_names[x]
340b0453382SBill Fenner
341a90e161bSBill Fenner /* normal */
342a90e161bSBill Fenner static const char *cmds[] = {
343a90e161bSBill Fenner "IS", "SEND", "INFO",
344a90e161bSBill Fenner };
345a90e161bSBill Fenner
346a90e161bSBill Fenner /* 37: Authentication */
347a90e161bSBill Fenner static const char *authcmd[] = {
348a90e161bSBill Fenner "IS", "SEND", "REPLY", "NAME",
349a90e161bSBill Fenner };
350a90e161bSBill Fenner static const char *authtype[] = {
351a90e161bSBill Fenner "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK",
352a90e161bSBill Fenner "SRP", "RSA", "SSL", NULL, NULL,
353a90e161bSBill Fenner "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS",
354a90e161bSBill Fenner "NTLM",
355a90e161bSBill Fenner };
356a90e161bSBill Fenner
357a90e161bSBill Fenner /* 38: Encryption */
358a90e161bSBill Fenner static const char *enccmd[] = {
359a90e161bSBill Fenner "IS", "SUPPORT", "REPLY", "START", "END",
360a90e161bSBill Fenner "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID",
361a90e161bSBill Fenner };
362a90e161bSBill Fenner static const char *enctype[] = {
363a90e161bSBill Fenner "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64",
364a90e161bSBill Fenner NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64",
365a90e161bSBill Fenner };
366a90e161bSBill Fenner
367a90e161bSBill Fenner #define STR_OR_ID(x, tab) \
368a90e161bSBill Fenner (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
369a90e161bSBill Fenner
370a90e161bSBill Fenner static char *
numstr(int x)371a90e161bSBill Fenner numstr(int x)
372b0453382SBill Fenner {
373a90e161bSBill Fenner static char buf[20];
374b0453382SBill Fenner
375a90e161bSBill Fenner snprintf(buf, sizeof(buf), "%#x", x);
376a90e161bSBill Fenner return buf;
377b0453382SBill Fenner }
378a90e161bSBill Fenner
379a90e161bSBill Fenner /* sp points to IAC byte */
380a90e161bSBill Fenner static int
telnet_parse(netdissect_options * ndo,const u_char * sp,u_int length,int print)3813c602fabSXin LI telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print)
382a90e161bSBill Fenner {
3835b0fe478SBruce M Simpson int i, x;
3845b0fe478SBruce M Simpson u_int c;
385a90e161bSBill Fenner const u_char *osp, *p;
386a90e161bSBill Fenner #define FETCH(c, sp, length) \
387a90e161bSBill Fenner do { \
388a90e161bSBill Fenner if (length < 1) \
389a90e161bSBill Fenner goto pktend; \
390ee67461eSJoseph Mingrone c = GET_U_1(sp); \
391ee67461eSJoseph Mingrone sp++; \
392a90e161bSBill Fenner length--; \
393a90e161bSBill Fenner } while (0)
394a90e161bSBill Fenner
395a90e161bSBill Fenner osp = sp;
396a90e161bSBill Fenner
397a90e161bSBill Fenner FETCH(c, sp, length);
398a90e161bSBill Fenner if (c != IAC)
399a90e161bSBill Fenner goto pktend;
400a90e161bSBill Fenner FETCH(c, sp, length);
401a90e161bSBill Fenner if (c == IAC) { /* <IAC><IAC>! */
402a90e161bSBill Fenner if (print)
403ee67461eSJoseph Mingrone ND_PRINT("IAC IAC");
404a90e161bSBill Fenner goto done;
405b0453382SBill Fenner }
406a90e161bSBill Fenner
407a90e161bSBill Fenner i = c - TELCMD_FIRST;
408a90e161bSBill Fenner if (i < 0 || i > IAC - TELCMD_FIRST)
409a90e161bSBill Fenner goto pktend;
410a90e161bSBill Fenner
411b0453382SBill Fenner switch (c) {
412b0453382SBill Fenner case DONT:
413b0453382SBill Fenner case DO:
414b0453382SBill Fenner case WONT:
415b0453382SBill Fenner case WILL:
416b0453382SBill Fenner case SB:
417a90e161bSBill Fenner /* DONT/DO/WONT/WILL x */
418a90e161bSBill Fenner FETCH(x, sp, length);
419b0453382SBill Fenner if (x >= 0 && x < NTELOPTS) {
420a90e161bSBill Fenner if (print)
421ee67461eSJoseph Mingrone ND_PRINT("%s %s", telcmds[i], telopts[x]);
422b0453382SBill Fenner } else {
423a90e161bSBill Fenner if (print)
424ee67461eSJoseph Mingrone ND_PRINT("%s %#x", telcmds[i], x);
425b0453382SBill Fenner }
426a90e161bSBill Fenner if (c != SB)
427a90e161bSBill Fenner break;
428a90e161bSBill Fenner /* IAC SB .... IAC SE */
429a90e161bSBill Fenner p = sp;
4305b0fe478SBruce M Simpson while (length > (u_int)(p + 1 - sp)) {
431ee67461eSJoseph Mingrone if (GET_U_1(p) == IAC && GET_U_1(p + 1) == SE)
432a90e161bSBill Fenner break;
433a90e161bSBill Fenner p++;
434a90e161bSBill Fenner }
435ee67461eSJoseph Mingrone if (GET_U_1(p) != IAC)
436a90e161bSBill Fenner goto pktend;
437a90e161bSBill Fenner
438a90e161bSBill Fenner switch (x) {
439a90e161bSBill Fenner case TELOPT_AUTHENTICATION:
440a90e161bSBill Fenner if (p <= sp)
441a90e161bSBill Fenner break;
442a90e161bSBill Fenner FETCH(c, sp, length);
443a90e161bSBill Fenner if (print)
444ee67461eSJoseph Mingrone ND_PRINT(" %s", STR_OR_ID(c, authcmd));
445a90e161bSBill Fenner if (p <= sp)
446a90e161bSBill Fenner break;
447a90e161bSBill Fenner FETCH(c, sp, length);
448a90e161bSBill Fenner if (print)
449ee67461eSJoseph Mingrone ND_PRINT(" %s", STR_OR_ID(c, authtype));
450a90e161bSBill Fenner break;
451a90e161bSBill Fenner case TELOPT_ENCRYPT:
452a90e161bSBill Fenner if (p <= sp)
453a90e161bSBill Fenner break;
454a90e161bSBill Fenner FETCH(c, sp, length);
455a90e161bSBill Fenner if (print)
456ee67461eSJoseph Mingrone ND_PRINT(" %s", STR_OR_ID(c, enccmd));
457a90e161bSBill Fenner if (p <= sp)
458a90e161bSBill Fenner break;
459a90e161bSBill Fenner FETCH(c, sp, length);
460a90e161bSBill Fenner if (print)
461ee67461eSJoseph Mingrone ND_PRINT(" %s", STR_OR_ID(c, enctype));
462b0453382SBill Fenner break;
463b0453382SBill Fenner default:
464a90e161bSBill Fenner if (p <= sp)
465a90e161bSBill Fenner break;
466a90e161bSBill Fenner FETCH(c, sp, length);
467a90e161bSBill Fenner if (print)
468ee67461eSJoseph Mingrone ND_PRINT(" %s", STR_OR_ID(c, cmds));
469b0453382SBill Fenner break;
470b0453382SBill Fenner }
471a90e161bSBill Fenner while (p > sp) {
472a90e161bSBill Fenner FETCH(x, sp, length);
473a90e161bSBill Fenner if (print)
474ee67461eSJoseph Mingrone ND_PRINT(" %#x", x);
475a90e161bSBill Fenner }
476a90e161bSBill Fenner /* terminating IAC SE */
477a90e161bSBill Fenner if (print)
478ee67461eSJoseph Mingrone ND_PRINT(" SE");
479a90e161bSBill Fenner sp += 2;
480a90e161bSBill Fenner break;
481a90e161bSBill Fenner default:
482a90e161bSBill Fenner if (print)
483ee67461eSJoseph Mingrone ND_PRINT("%s", telcmds[i]);
484a90e161bSBill Fenner goto done;
485a90e161bSBill Fenner }
486a90e161bSBill Fenner
487a90e161bSBill Fenner done:
488ee67461eSJoseph Mingrone return (int)(sp - osp);
489a90e161bSBill Fenner
490a90e161bSBill Fenner pktend:
491a90e161bSBill Fenner return -1;
492a90e161bSBill Fenner #undef FETCH
493a90e161bSBill Fenner }
494a90e161bSBill Fenner
495a90e161bSBill Fenner void
telnet_print(netdissect_options * ndo,const u_char * sp,u_int length)4963c602fabSXin LI telnet_print(netdissect_options *ndo, const u_char *sp, u_int length)
497a90e161bSBill Fenner {
498a90e161bSBill Fenner int first = 1;
499a90e161bSBill Fenner const u_char *osp;
500a90e161bSBill Fenner int l;
501a90e161bSBill Fenner
502ee67461eSJoseph Mingrone ndo->ndo_protocol = "telnet";
503a90e161bSBill Fenner osp = sp;
504a90e161bSBill Fenner
505ee67461eSJoseph Mingrone while (length > 0 && GET_U_1(sp) == IAC) {
5068bdc5a62SPatrick Kelsey /*
5078bdc5a62SPatrick Kelsey * Parse the Telnet command without printing it,
5088bdc5a62SPatrick Kelsey * to determine its length.
5098bdc5a62SPatrick Kelsey */
5103c602fabSXin LI l = telnet_parse(ndo, sp, length, 0);
511a90e161bSBill Fenner if (l < 0)
512a90e161bSBill Fenner break;
513a90e161bSBill Fenner
514b0453382SBill Fenner /*
515b0453382SBill Fenner * now print it
516b0453382SBill Fenner */
5173c602fabSXin LI if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag) {
518b0453382SBill Fenner if (first)
519ee67461eSJoseph Mingrone ND_PRINT("\nTelnet:");
520ee67461eSJoseph Mingrone hex_print_with_offset(ndo, "\n", sp, l, (u_int)(sp - osp));
521a90e161bSBill Fenner if (l > 8)
522ee67461eSJoseph Mingrone ND_PRINT("\n\t\t\t\t");
523b0453382SBill Fenner else
524ee67461eSJoseph Mingrone ND_PRINT("%*s\t", (8 - l) * 3, "");
525a90e161bSBill Fenner } else
526ee67461eSJoseph Mingrone ND_PRINT("%s", (first) ? " [telnet " : ", ");
527a90e161bSBill Fenner
5283c602fabSXin LI (void)telnet_parse(ndo, sp, length, 1);
529b0453382SBill Fenner first = 0;
530a90e161bSBill Fenner
531a90e161bSBill Fenner sp += l;
532a90e161bSBill Fenner length -= l;
533b0453382SBill Fenner }
534b0453382SBill Fenner if (!first) {
5353c602fabSXin LI if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag)
536ee67461eSJoseph Mingrone ND_PRINT("\n");
537b0453382SBill Fenner else
538ee67461eSJoseph Mingrone ND_PRINT("]");
539b0453382SBill Fenner }
540b0453382SBill Fenner }
541