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