1*05b00f60SXin Li /* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */
2*05b00f60SXin Li
3*05b00f60SXin Li /*-
4*05b00f60SXin Li * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5*05b00f60SXin Li * All rights reserved.
6*05b00f60SXin Li *
7*05b00f60SXin Li * This code is derived from software contributed to The NetBSD Foundation
8*05b00f60SXin Li * by Simon J. Gerraty.
9*05b00f60SXin Li *
10*05b00f60SXin Li * Redistribution and use in source and binary forms, with or without
11*05b00f60SXin Li * modification, are permitted provided that the following conditions
12*05b00f60SXin Li * are met:
13*05b00f60SXin Li * 1. Redistributions of source code must retain the above copyright
14*05b00f60SXin Li * notice, this list of conditions and the following disclaimer.
15*05b00f60SXin Li * 2. Redistributions in binary form must reproduce the above copyright
16*05b00f60SXin Li * notice, this list of conditions and the following disclaimer in the
17*05b00f60SXin Li * documentation and/or other materials provided with the distribution.
18*05b00f60SXin Li * 3. All advertising materials mentioning features or use of this software
19*05b00f60SXin Li * must display the following acknowledgement:
20*05b00f60SXin Li * This product includes software developed by the NetBSD
21*05b00f60SXin Li * Foundation, Inc. and its contributors.
22*05b00f60SXin Li * 4. Neither the name of The NetBSD Foundation nor the names of its
23*05b00f60SXin Li * contributors may be used to endorse or promote products derived
24*05b00f60SXin Li * from this software without specific prior written permission.
25*05b00f60SXin Li *
26*05b00f60SXin Li * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27*05b00f60SXin Li * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28*05b00f60SXin Li * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29*05b00f60SXin Li * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30*05b00f60SXin Li * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31*05b00f60SXin Li * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32*05b00f60SXin Li * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33*05b00f60SXin Li * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34*05b00f60SXin Li * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35*05b00f60SXin Li * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36*05b00f60SXin Li * POSSIBILITY OF SUCH DAMAGE.
37*05b00f60SXin Li */
38*05b00f60SXin Li /*
39*05b00f60SXin Li * @(#)Copyright (c) 1994, Simon J. Gerraty.
40*05b00f60SXin Li *
41*05b00f60SXin Li * This is free software. It comes with NO WARRANTY.
42*05b00f60SXin Li * Permission to use, modify and distribute this source code
43*05b00f60SXin Li * is granted subject to the following conditions.
44*05b00f60SXin Li * 1/ that the above copyright notice and this notice
45*05b00f60SXin Li * are preserved in all copies.
46*05b00f60SXin Li */
47*05b00f60SXin Li
48*05b00f60SXin Li /* \summary: Telnet option printer */
49*05b00f60SXin Li
50*05b00f60SXin Li #ifdef HAVE_CONFIG_H
51*05b00f60SXin Li #include <config.h>
52*05b00f60SXin Li #endif
53*05b00f60SXin Li
54*05b00f60SXin Li #include "netdissect-stdinc.h"
55*05b00f60SXin Li
56*05b00f60SXin Li #include <stdio.h>
57*05b00f60SXin Li
58*05b00f60SXin Li #include "netdissect.h"
59*05b00f60SXin Li #include "extract.h"
60*05b00f60SXin Li
61*05b00f60SXin Li
62*05b00f60SXin Li /* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */
63*05b00f60SXin Li
64*05b00f60SXin Li /*
65*05b00f60SXin Li * Definitions for the TELNET protocol.
66*05b00f60SXin Li */
67*05b00f60SXin Li #define IAC 255 /* interpret as command: */
68*05b00f60SXin Li #define DONT 254 /* you are not to use option */
69*05b00f60SXin Li #define DO 253 /* please, you use option */
70*05b00f60SXin Li #define WONT 252 /* I won't use option */
71*05b00f60SXin Li #define WILL 251 /* I will use option */
72*05b00f60SXin Li #define SB 250 /* interpret as subnegotiation */
73*05b00f60SXin Li #define GA 249 /* you may reverse the line */
74*05b00f60SXin Li #define EL 248 /* erase the current line */
75*05b00f60SXin Li #define EC 247 /* erase the current character */
76*05b00f60SXin Li #define AYT 246 /* are you there */
77*05b00f60SXin Li #define AO 245 /* abort output--but let prog finish */
78*05b00f60SXin Li #define IP 244 /* interrupt process--permanently */
79*05b00f60SXin Li #define BREAK 243 /* break */
80*05b00f60SXin Li #define DM 242 /* data mark--for connect. cleaning */
81*05b00f60SXin Li #define NOP 241 /* nop */
82*05b00f60SXin Li #define SE 240 /* end sub negotiation */
83*05b00f60SXin Li #define EOR 239 /* end of record (transparent mode) */
84*05b00f60SXin Li #define ABORT 238 /* Abort process */
85*05b00f60SXin Li #define SUSP 237 /* Suspend process */
86*05b00f60SXin Li #define xEOF 236 /* End of file: EOF is already used... */
87*05b00f60SXin Li
88*05b00f60SXin Li #define SYNCH 242 /* for telfunc calls */
89*05b00f60SXin Li
90*05b00f60SXin Li static const char *telcmds[] = {
91*05b00f60SXin Li "EOF", "SUSP", "ABORT", "EOR",
92*05b00f60SXin Li "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
93*05b00f60SXin Li "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
94*05b00f60SXin Li };
95*05b00f60SXin Li
96*05b00f60SXin Li #define TELCMD_FIRST xEOF
97*05b00f60SXin Li #define TELCMD_LAST IAC
98*05b00f60SXin Li #define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
99*05b00f60SXin Li (unsigned int)(x) >= TELCMD_FIRST)
100*05b00f60SXin Li #define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
101*05b00f60SXin Li
102*05b00f60SXin Li /* telnet options */
103*05b00f60SXin Li #define TELOPT_BINARY 0 /* 8-bit data path */
104*05b00f60SXin Li #define TELOPT_ECHO 1 /* echo */
105*05b00f60SXin Li #define TELOPT_RCP 2 /* prepare to reconnect */
106*05b00f60SXin Li #define TELOPT_SGA 3 /* suppress go ahead */
107*05b00f60SXin Li #define TELOPT_NAMS 4 /* approximate message size */
108*05b00f60SXin Li #define TELOPT_STATUS 5 /* give status */
109*05b00f60SXin Li #define TELOPT_TM 6 /* timing mark */
110*05b00f60SXin Li #define TELOPT_RCTE 7 /* remote controlled transmission and echo */
111*05b00f60SXin Li #define TELOPT_NAOL 8 /* negotiate about output line width */
112*05b00f60SXin Li #define TELOPT_NAOP 9 /* negotiate about output page size */
113*05b00f60SXin Li #define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
114*05b00f60SXin Li #define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
115*05b00f60SXin Li #define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
116*05b00f60SXin Li #define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
117*05b00f60SXin Li #define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
118*05b00f60SXin Li #define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
119*05b00f60SXin Li #define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
120*05b00f60SXin Li #define TELOPT_XASCII 17 /* extended ascic character set */
121*05b00f60SXin Li #define TELOPT_LOGOUT 18 /* force logout */
122*05b00f60SXin Li #define TELOPT_BM 19 /* byte macro */
123*05b00f60SXin Li #define TELOPT_DET 20 /* data entry terminal */
124*05b00f60SXin Li #define TELOPT_SUPDUP 21 /* supdup protocol */
125*05b00f60SXin Li #define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
126*05b00f60SXin Li #define TELOPT_SNDLOC 23 /* send location */
127*05b00f60SXin Li #define TELOPT_TTYPE 24 /* terminal type */
128*05b00f60SXin Li #define TELOPT_EOR 25 /* end or record */
129*05b00f60SXin Li #define TELOPT_TUID 26 /* TACACS user identification */
130*05b00f60SXin Li #define TELOPT_OUTMRK 27 /* output marking */
131*05b00f60SXin Li #define TELOPT_TTYLOC 28 /* terminal location number */
132*05b00f60SXin Li #define TELOPT_3270REGIME 29 /* 3270 regime */
133*05b00f60SXin Li #define TELOPT_X3PAD 30 /* X.3 PAD */
134*05b00f60SXin Li #define TELOPT_NAWS 31 /* window size */
135*05b00f60SXin Li #define TELOPT_TSPEED 32 /* terminal speed */
136*05b00f60SXin Li #define TELOPT_LFLOW 33 /* remote flow control */
137*05b00f60SXin Li #define TELOPT_LINEMODE 34 /* Linemode option */
138*05b00f60SXin Li #define TELOPT_XDISPLOC 35 /* X Display Location */
139*05b00f60SXin Li #define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
140*05b00f60SXin Li #define TELOPT_AUTHENTICATION 37/* Authenticate */
141*05b00f60SXin Li #define TELOPT_ENCRYPT 38 /* Encryption option */
142*05b00f60SXin Li #define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
143*05b00f60SXin Li #define TELOPT_EXOPL 255 /* extended-options-list */
144*05b00f60SXin Li
145*05b00f60SXin Li
146*05b00f60SXin Li #define NTELOPTS (1+TELOPT_NEW_ENVIRON)
147*05b00f60SXin Li static const char *telopts[NTELOPTS+1] = {
148*05b00f60SXin Li "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
149*05b00f60SXin Li "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
150*05b00f60SXin Li "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
151*05b00f60SXin Li "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
152*05b00f60SXin Li "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
153*05b00f60SXin Li "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
154*05b00f60SXin Li "TACACS UID", "OUTPUT MARKING", "TTYLOC",
155*05b00f60SXin Li "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
156*05b00f60SXin Li "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
157*05b00f60SXin Li "ENCRYPT", "NEW-ENVIRON",
158*05b00f60SXin Li 0,
159*05b00f60SXin Li };
160*05b00f60SXin Li #define TELOPT_FIRST TELOPT_BINARY
161*05b00f60SXin Li #define TELOPT_LAST TELOPT_NEW_ENVIRON
162*05b00f60SXin Li #define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
163*05b00f60SXin Li #define TELOPT(x) telopts[(x)-TELOPT_FIRST]
164*05b00f60SXin Li
165*05b00f60SXin Li /* sub-option qualifiers */
166*05b00f60SXin Li #define TELQUAL_IS 0 /* option is... */
167*05b00f60SXin Li #define TELQUAL_SEND 1 /* send option */
168*05b00f60SXin Li #define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
169*05b00f60SXin Li #define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
170*05b00f60SXin Li #define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
171*05b00f60SXin Li
172*05b00f60SXin Li #define LFLOW_OFF 0 /* Disable remote flow control */
173*05b00f60SXin Li #define LFLOW_ON 1 /* Enable remote flow control */
174*05b00f60SXin Li #define LFLOW_RESTART_ANY 2 /* Restart output on any char */
175*05b00f60SXin Li #define LFLOW_RESTART_XON 3 /* Restart output only on XON */
176*05b00f60SXin Li
177*05b00f60SXin Li /*
178*05b00f60SXin Li * LINEMODE suboptions
179*05b00f60SXin Li */
180*05b00f60SXin Li
181*05b00f60SXin Li #define LM_MODE 1
182*05b00f60SXin Li #define LM_FORWARDMASK 2
183*05b00f60SXin Li #define LM_SLC 3
184*05b00f60SXin Li
185*05b00f60SXin Li #define MODE_EDIT 0x01
186*05b00f60SXin Li #define MODE_TRAPSIG 0x02
187*05b00f60SXin Li #define MODE_ACK 0x04
188*05b00f60SXin Li #define MODE_SOFT_TAB 0x08
189*05b00f60SXin Li #define MODE_LIT_ECHO 0x10
190*05b00f60SXin Li
191*05b00f60SXin Li #define MODE_MASK 0x1f
192*05b00f60SXin Li
193*05b00f60SXin Li #define SLC_SYNCH 1
194*05b00f60SXin Li #define SLC_BRK 2
195*05b00f60SXin Li #define SLC_IP 3
196*05b00f60SXin Li #define SLC_AO 4
197*05b00f60SXin Li #define SLC_AYT 5
198*05b00f60SXin Li #define SLC_EOR 6
199*05b00f60SXin Li #define SLC_ABORT 7
200*05b00f60SXin Li #define SLC_EOF 8
201*05b00f60SXin Li #define SLC_SUSP 9
202*05b00f60SXin Li #define SLC_EC 10
203*05b00f60SXin Li #define SLC_EL 11
204*05b00f60SXin Li #define SLC_EW 12
205*05b00f60SXin Li #define SLC_RP 13
206*05b00f60SXin Li #define SLC_LNEXT 14
207*05b00f60SXin Li #define SLC_XON 15
208*05b00f60SXin Li #define SLC_XOFF 16
209*05b00f60SXin Li #define SLC_FORW1 17
210*05b00f60SXin Li #define SLC_FORW2 18
211*05b00f60SXin Li #define SLC_MCL 19
212*05b00f60SXin Li #define SLC_MCR 20
213*05b00f60SXin Li #define SLC_MCWL 21
214*05b00f60SXin Li #define SLC_MCWR 22
215*05b00f60SXin Li #define SLC_MCBOL 23
216*05b00f60SXin Li #define SLC_MCEOL 24
217*05b00f60SXin Li #define SLC_INSRT 25
218*05b00f60SXin Li #define SLC_OVER 26
219*05b00f60SXin Li #define SLC_ECR 27
220*05b00f60SXin Li #define SLC_EWR 28
221*05b00f60SXin Li #define SLC_EBOL 29
222*05b00f60SXin Li #define SLC_EEOL 30
223*05b00f60SXin Li
224*05b00f60SXin Li #define NSLC 30
225*05b00f60SXin Li
226*05b00f60SXin Li /*
227*05b00f60SXin Li * For backwards compatibility, we define SLC_NAMES to be the
228*05b00f60SXin Li * list of names if SLC_NAMES is not defined.
229*05b00f60SXin Li */
230*05b00f60SXin Li #define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
231*05b00f60SXin Li "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
232*05b00f60SXin Li "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
233*05b00f60SXin Li "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \
234*05b00f60SXin Li "MCEOL", "INSRT", "OVER", "ECR", "EWR", \
235*05b00f60SXin Li "EBOL", "EEOL", \
236*05b00f60SXin Li 0,
237*05b00f60SXin Li
238*05b00f60SXin Li #ifdef SLC_NAMES
239*05b00f60SXin Li const char *slc_names[] = {
240*05b00f60SXin Li SLC_NAMELIST
241*05b00f60SXin Li };
242*05b00f60SXin Li #else
243*05b00f60SXin Li extern char *slc_names[];
244*05b00f60SXin Li #define SLC_NAMES SLC_NAMELIST
245*05b00f60SXin Li #endif
246*05b00f60SXin Li
247*05b00f60SXin Li #define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
248*05b00f60SXin Li #define SLC_NAME(x) slc_names[x]
249*05b00f60SXin Li
250*05b00f60SXin Li #define SLC_NOSUPPORT 0
251*05b00f60SXin Li #define SLC_CANTCHANGE 1
252*05b00f60SXin Li #define SLC_VARIABLE 2
253*05b00f60SXin Li #define SLC_DEFAULT 3
254*05b00f60SXin Li #define SLC_LEVELBITS 0x03
255*05b00f60SXin Li
256*05b00f60SXin Li #define SLC_FUNC 0
257*05b00f60SXin Li #define SLC_FLAGS 1
258*05b00f60SXin Li #define SLC_VALUE 2
259*05b00f60SXin Li
260*05b00f60SXin Li #define SLC_ACK 0x80
261*05b00f60SXin Li #define SLC_FLUSHIN 0x40
262*05b00f60SXin Li #define SLC_FLUSHOUT 0x20
263*05b00f60SXin Li
264*05b00f60SXin Li #define OLD_ENV_VAR 1
265*05b00f60SXin Li #define OLD_ENV_VALUE 0
266*05b00f60SXin Li #define NEW_ENV_VAR 0
267*05b00f60SXin Li #define NEW_ENV_VALUE 1
268*05b00f60SXin Li #define ENV_ESC 2
269*05b00f60SXin Li #define ENV_USERVAR 3
270*05b00f60SXin Li
271*05b00f60SXin Li /*
272*05b00f60SXin Li * AUTHENTICATION suboptions
273*05b00f60SXin Li */
274*05b00f60SXin Li
275*05b00f60SXin Li /*
276*05b00f60SXin Li * Who is authenticating who ...
277*05b00f60SXin Li */
278*05b00f60SXin Li #define AUTH_WHO_CLIENT 0 /* Client authenticating server */
279*05b00f60SXin Li #define AUTH_WHO_SERVER 1 /* Server authenticating client */
280*05b00f60SXin Li #define AUTH_WHO_MASK 1
281*05b00f60SXin Li
282*05b00f60SXin Li #define AUTHTYPE_NULL 0
283*05b00f60SXin Li #define AUTHTYPE_KERBEROS_V4 1
284*05b00f60SXin Li #define AUTHTYPE_KERBEROS_V5 2
285*05b00f60SXin Li #define AUTHTYPE_SPX 3
286*05b00f60SXin Li #define AUTHTYPE_MINK 4
287*05b00f60SXin Li #define AUTHTYPE_CNT 5
288*05b00f60SXin Li
289*05b00f60SXin Li #define AUTHTYPE_TEST 99
290*05b00f60SXin Li
291*05b00f60SXin Li #ifdef AUTH_NAMES
292*05b00f60SXin Li const char *authtype_names[] = {
293*05b00f60SXin Li "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
294*05b00f60SXin Li };
295*05b00f60SXin Li #else
296*05b00f60SXin Li extern char *authtype_names[];
297*05b00f60SXin Li #endif
298*05b00f60SXin Li
299*05b00f60SXin Li #define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
300*05b00f60SXin Li #define AUTHTYPE_NAME(x) authtype_names[x]
301*05b00f60SXin Li
302*05b00f60SXin Li /*
303*05b00f60SXin Li * ENCRYPTion suboptions
304*05b00f60SXin Li */
305*05b00f60SXin Li #define ENCRYPT_IS 0 /* I pick encryption type ... */
306*05b00f60SXin Li #define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
307*05b00f60SXin Li #define ENCRYPT_REPLY 2 /* Initial setup response */
308*05b00f60SXin Li #define ENCRYPT_START 3 /* Am starting to send encrypted */
309*05b00f60SXin Li #define ENCRYPT_END 4 /* Am ending encrypted */
310*05b00f60SXin Li #define ENCRYPT_REQSTART 5 /* Request you start encrypting */
311*05b00f60SXin Li #define ENCRYPT_REQEND 6 /* Request you send encrypting */
312*05b00f60SXin Li #define ENCRYPT_ENC_KEYID 7
313*05b00f60SXin Li #define ENCRYPT_DEC_KEYID 8
314*05b00f60SXin Li #define ENCRYPT_CNT 9
315*05b00f60SXin Li
316*05b00f60SXin Li #define ENCTYPE_ANY 0
317*05b00f60SXin Li #define ENCTYPE_DES_CFB64 1
318*05b00f60SXin Li #define ENCTYPE_DES_OFB64 2
319*05b00f60SXin Li #define ENCTYPE_CNT 3
320*05b00f60SXin Li
321*05b00f60SXin Li #ifdef ENCRYPT_NAMES
322*05b00f60SXin Li const char *encrypt_names[] = {
323*05b00f60SXin Li "IS", "SUPPORT", "REPLY", "START", "END",
324*05b00f60SXin Li "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
325*05b00f60SXin Li 0,
326*05b00f60SXin Li };
327*05b00f60SXin Li const char *enctype_names[] = {
328*05b00f60SXin Li "ANY", "DES_CFB64", "DES_OFB64", 0,
329*05b00f60SXin Li };
330*05b00f60SXin Li #else
331*05b00f60SXin Li extern char *encrypt_names[];
332*05b00f60SXin Li extern char *enctype_names[];
333*05b00f60SXin Li #endif
334*05b00f60SXin Li
335*05b00f60SXin Li #define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
336*05b00f60SXin Li #define ENCRYPT_NAME(x) encrypt_names[x]
337*05b00f60SXin Li
338*05b00f60SXin Li #define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
339*05b00f60SXin Li #define ENCTYPE_NAME(x) enctype_names[x]
340*05b00f60SXin Li
341*05b00f60SXin Li /* normal */
342*05b00f60SXin Li static const char *cmds[] = {
343*05b00f60SXin Li "IS", "SEND", "INFO",
344*05b00f60SXin Li };
345*05b00f60SXin Li
346*05b00f60SXin Li /* 37: Authentication */
347*05b00f60SXin Li static const char *authcmd[] = {
348*05b00f60SXin Li "IS", "SEND", "REPLY", "NAME",
349*05b00f60SXin Li };
350*05b00f60SXin Li static const char *authtype[] = {
351*05b00f60SXin Li "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK",
352*05b00f60SXin Li "SRP", "RSA", "SSL", NULL, NULL,
353*05b00f60SXin Li "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS",
354*05b00f60SXin Li "NTLM",
355*05b00f60SXin Li };
356*05b00f60SXin Li
357*05b00f60SXin Li /* 38: Encryption */
358*05b00f60SXin Li static const char *enccmd[] = {
359*05b00f60SXin Li "IS", "SUPPORT", "REPLY", "START", "END",
360*05b00f60SXin Li "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID",
361*05b00f60SXin Li };
362*05b00f60SXin Li static const char *enctype[] = {
363*05b00f60SXin Li "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64",
364*05b00f60SXin Li NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64",
365*05b00f60SXin Li };
366*05b00f60SXin Li
367*05b00f60SXin Li #define STR_OR_ID(x, tab) \
368*05b00f60SXin Li (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
369*05b00f60SXin Li
370*05b00f60SXin Li static char *
numstr(int x)371*05b00f60SXin Li numstr(int x)
372*05b00f60SXin Li {
373*05b00f60SXin Li static char buf[20];
374*05b00f60SXin Li
375*05b00f60SXin Li snprintf(buf, sizeof(buf), "%#x", x);
376*05b00f60SXin Li return buf;
377*05b00f60SXin Li }
378*05b00f60SXin Li
379*05b00f60SXin Li /* sp points to IAC byte */
380*05b00f60SXin Li static int
telnet_parse(netdissect_options * ndo,const u_char * sp,u_int length,int print)381*05b00f60SXin Li telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print)
382*05b00f60SXin Li {
383*05b00f60SXin Li int i, x;
384*05b00f60SXin Li u_int c;
385*05b00f60SXin Li const u_char *osp, *p;
386*05b00f60SXin Li #define FETCH(c, sp, length) \
387*05b00f60SXin Li do { \
388*05b00f60SXin Li if (length < 1) \
389*05b00f60SXin Li goto pktend; \
390*05b00f60SXin Li c = GET_U_1(sp); \
391*05b00f60SXin Li sp++; \
392*05b00f60SXin Li length--; \
393*05b00f60SXin Li } while (0)
394*05b00f60SXin Li
395*05b00f60SXin Li osp = sp;
396*05b00f60SXin Li
397*05b00f60SXin Li FETCH(c, sp, length);
398*05b00f60SXin Li if (c != IAC)
399*05b00f60SXin Li goto pktend;
400*05b00f60SXin Li FETCH(c, sp, length);
401*05b00f60SXin Li if (c == IAC) { /* <IAC><IAC>! */
402*05b00f60SXin Li if (print)
403*05b00f60SXin Li ND_PRINT("IAC IAC");
404*05b00f60SXin Li goto done;
405*05b00f60SXin Li }
406*05b00f60SXin Li
407*05b00f60SXin Li i = c - TELCMD_FIRST;
408*05b00f60SXin Li if (i < 0 || i > IAC - TELCMD_FIRST)
409*05b00f60SXin Li goto pktend;
410*05b00f60SXin Li
411*05b00f60SXin Li switch (c) {
412*05b00f60SXin Li case DONT:
413*05b00f60SXin Li case DO:
414*05b00f60SXin Li case WONT:
415*05b00f60SXin Li case WILL:
416*05b00f60SXin Li case SB:
417*05b00f60SXin Li /* DONT/DO/WONT/WILL x */
418*05b00f60SXin Li FETCH(x, sp, length);
419*05b00f60SXin Li if (x >= 0 && x < NTELOPTS) {
420*05b00f60SXin Li if (print)
421*05b00f60SXin Li ND_PRINT("%s %s", telcmds[i], telopts[x]);
422*05b00f60SXin Li } else {
423*05b00f60SXin Li if (print)
424*05b00f60SXin Li ND_PRINT("%s %#x", telcmds[i], x);
425*05b00f60SXin Li }
426*05b00f60SXin Li if (c != SB)
427*05b00f60SXin Li break;
428*05b00f60SXin Li /* IAC SB .... IAC SE */
429*05b00f60SXin Li p = sp;
430*05b00f60SXin Li while (length > (u_int)(p + 1 - sp)) {
431*05b00f60SXin Li if (GET_U_1(p) == IAC && GET_U_1(p + 1) == SE)
432*05b00f60SXin Li break;
433*05b00f60SXin Li p++;
434*05b00f60SXin Li }
435*05b00f60SXin Li if (GET_U_1(p) != IAC)
436*05b00f60SXin Li goto pktend;
437*05b00f60SXin Li
438*05b00f60SXin Li switch (x) {
439*05b00f60SXin Li case TELOPT_AUTHENTICATION:
440*05b00f60SXin Li if (p <= sp)
441*05b00f60SXin Li break;
442*05b00f60SXin Li FETCH(c, sp, length);
443*05b00f60SXin Li if (print)
444*05b00f60SXin Li ND_PRINT(" %s", STR_OR_ID(c, authcmd));
445*05b00f60SXin Li if (p <= sp)
446*05b00f60SXin Li break;
447*05b00f60SXin Li FETCH(c, sp, length);
448*05b00f60SXin Li if (print)
449*05b00f60SXin Li ND_PRINT(" %s", STR_OR_ID(c, authtype));
450*05b00f60SXin Li break;
451*05b00f60SXin Li case TELOPT_ENCRYPT:
452*05b00f60SXin Li if (p <= sp)
453*05b00f60SXin Li break;
454*05b00f60SXin Li FETCH(c, sp, length);
455*05b00f60SXin Li if (print)
456*05b00f60SXin Li ND_PRINT(" %s", STR_OR_ID(c, enccmd));
457*05b00f60SXin Li if (p <= sp)
458*05b00f60SXin Li break;
459*05b00f60SXin Li FETCH(c, sp, length);
460*05b00f60SXin Li if (print)
461*05b00f60SXin Li ND_PRINT(" %s", STR_OR_ID(c, enctype));
462*05b00f60SXin Li break;
463*05b00f60SXin Li default:
464*05b00f60SXin Li if (p <= sp)
465*05b00f60SXin Li break;
466*05b00f60SXin Li FETCH(c, sp, length);
467*05b00f60SXin Li if (print)
468*05b00f60SXin Li ND_PRINT(" %s", STR_OR_ID(c, cmds));
469*05b00f60SXin Li break;
470*05b00f60SXin Li }
471*05b00f60SXin Li while (p > sp) {
472*05b00f60SXin Li FETCH(x, sp, length);
473*05b00f60SXin Li if (print)
474*05b00f60SXin Li ND_PRINT(" %#x", x);
475*05b00f60SXin Li }
476*05b00f60SXin Li /* terminating IAC SE */
477*05b00f60SXin Li if (print)
478*05b00f60SXin Li ND_PRINT(" SE");
479*05b00f60SXin Li sp += 2;
480*05b00f60SXin Li break;
481*05b00f60SXin Li default:
482*05b00f60SXin Li if (print)
483*05b00f60SXin Li ND_PRINT("%s", telcmds[i]);
484*05b00f60SXin Li goto done;
485*05b00f60SXin Li }
486*05b00f60SXin Li
487*05b00f60SXin Li done:
488*05b00f60SXin Li return (int)(sp - osp);
489*05b00f60SXin Li
490*05b00f60SXin Li pktend:
491*05b00f60SXin Li return -1;
492*05b00f60SXin Li #undef FETCH
493*05b00f60SXin Li }
494*05b00f60SXin Li
495*05b00f60SXin Li void
telnet_print(netdissect_options * ndo,const u_char * sp,u_int length)496*05b00f60SXin Li telnet_print(netdissect_options *ndo, const u_char *sp, u_int length)
497*05b00f60SXin Li {
498*05b00f60SXin Li int first = 1;
499*05b00f60SXin Li const u_char *osp;
500*05b00f60SXin Li int l;
501*05b00f60SXin Li
502*05b00f60SXin Li ndo->ndo_protocol = "telnet";
503*05b00f60SXin Li osp = sp;
504*05b00f60SXin Li
505*05b00f60SXin Li while (length > 0 && GET_U_1(sp) == IAC) {
506*05b00f60SXin Li /*
507*05b00f60SXin Li * Parse the Telnet command without printing it,
508*05b00f60SXin Li * to determine its length.
509*05b00f60SXin Li */
510*05b00f60SXin Li l = telnet_parse(ndo, sp, length, 0);
511*05b00f60SXin Li if (l < 0)
512*05b00f60SXin Li break;
513*05b00f60SXin Li
514*05b00f60SXin Li /*
515*05b00f60SXin Li * now print it
516*05b00f60SXin Li */
517*05b00f60SXin Li if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag) {
518*05b00f60SXin Li if (first)
519*05b00f60SXin Li ND_PRINT("\nTelnet:");
520*05b00f60SXin Li hex_print_with_offset(ndo, "\n", sp, l, (u_int)(sp - osp));
521*05b00f60SXin Li if (l > 8)
522*05b00f60SXin Li ND_PRINT("\n\t\t\t\t");
523*05b00f60SXin Li else
524*05b00f60SXin Li ND_PRINT("%*s\t", (8 - l) * 3, "");
525*05b00f60SXin Li } else
526*05b00f60SXin Li ND_PRINT("%s", (first) ? " [telnet " : ", ");
527*05b00f60SXin Li
528*05b00f60SXin Li (void)telnet_parse(ndo, sp, length, 1);
529*05b00f60SXin Li first = 0;
530*05b00f60SXin Li
531*05b00f60SXin Li sp += l;
532*05b00f60SXin Li length -= l;
533*05b00f60SXin Li }
534*05b00f60SXin Li if (!first) {
535*05b00f60SXin Li if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag)
536*05b00f60SXin Li ND_PRINT("\n");
537*05b00f60SXin Li else
538*05b00f60SXin Li ND_PRINT("]");
539*05b00f60SXin Li }
540*05b00f60SXin Li }
541