141c99275SPeter Avalos /* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */
241c99275SPeter Avalos
341c99275SPeter Avalos /*-
441c99275SPeter Avalos * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
541c99275SPeter Avalos * All rights reserved.
641c99275SPeter Avalos *
741c99275SPeter Avalos * This code is derived from software contributed to The NetBSD Foundation
841c99275SPeter Avalos * by Simon J. Gerraty.
941c99275SPeter Avalos *
1041c99275SPeter Avalos * Redistribution and use in source and binary forms, with or without
1141c99275SPeter Avalos * modification, are permitted provided that the following conditions
1241c99275SPeter Avalos * are met:
1341c99275SPeter Avalos * 1. Redistributions of source code must retain the above copyright
1441c99275SPeter Avalos * notice, this list of conditions and the following disclaimer.
1541c99275SPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright
1641c99275SPeter Avalos * notice, this list of conditions and the following disclaimer in the
1741c99275SPeter Avalos * documentation and/or other materials provided with the distribution.
1841c99275SPeter Avalos * 3. All advertising materials mentioning features or use of this software
1941c99275SPeter Avalos * must display the following acknowledgement:
2041c99275SPeter Avalos * This product includes software developed by the NetBSD
2141c99275SPeter Avalos * Foundation, Inc. and its contributors.
2241c99275SPeter Avalos * 4. Neither the name of The NetBSD Foundation nor the names of its
2341c99275SPeter Avalos * contributors may be used to endorse or promote products derived
2441c99275SPeter Avalos * from this software without specific prior written permission.
2541c99275SPeter Avalos *
2641c99275SPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2741c99275SPeter Avalos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2841c99275SPeter Avalos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2941c99275SPeter Avalos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
3041c99275SPeter Avalos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3141c99275SPeter Avalos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3241c99275SPeter Avalos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3341c99275SPeter Avalos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3441c99275SPeter Avalos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3541c99275SPeter Avalos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3641c99275SPeter Avalos * POSSIBILITY OF SUCH DAMAGE.
3741c99275SPeter Avalos */
3841c99275SPeter Avalos /*
3941c99275SPeter Avalos * @(#)Copyright (c) 1994, Simon J. Gerraty.
4041c99275SPeter Avalos *
4141c99275SPeter Avalos * This is free software. It comes with NO WARRANTY.
4241c99275SPeter Avalos * Permission to use, modify and distribute this source code
4341c99275SPeter Avalos * is granted subject to the following conditions.
4441c99275SPeter Avalos * 1/ that the above copyright notice and this notice
4541c99275SPeter Avalos * are preserved in all copies.
4641c99275SPeter Avalos */
4741c99275SPeter Avalos
48411677aeSAaron LI /* \summary: Telnet option printer */
49411677aeSAaron LI
5041c99275SPeter Avalos #ifdef HAVE_CONFIG_H
51*ed775ee7SAntonio Huete Jimenez #include <config.h>
5241c99275SPeter Avalos #endif
5341c99275SPeter Avalos
54*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
5541c99275SPeter Avalos
5641c99275SPeter Avalos #include <stdio.h>
5741c99275SPeter Avalos
58411677aeSAaron LI #include "netdissect.h"
59*ed775ee7SAntonio Huete Jimenez #include "extract.h"
60411677aeSAaron LI
61411677aeSAaron LI
62411677aeSAaron LI /* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */
63411677aeSAaron LI
64411677aeSAaron LI /*
65411677aeSAaron LI * Definitions for the TELNET protocol.
66411677aeSAaron LI */
67411677aeSAaron LI #define IAC 255 /* interpret as command: */
68411677aeSAaron LI #define DONT 254 /* you are not to use option */
69411677aeSAaron LI #define DO 253 /* please, you use option */
70411677aeSAaron LI #define WONT 252 /* I won't use option */
71411677aeSAaron LI #define WILL 251 /* I will use option */
72411677aeSAaron LI #define SB 250 /* interpret as subnegotiation */
73411677aeSAaron LI #define GA 249 /* you may reverse the line */
74411677aeSAaron LI #define EL 248 /* erase the current line */
75411677aeSAaron LI #define EC 247 /* erase the current character */
76411677aeSAaron LI #define AYT 246 /* are you there */
77411677aeSAaron LI #define AO 245 /* abort output--but let prog finish */
78411677aeSAaron LI #define IP 244 /* interrupt process--permanently */
79411677aeSAaron LI #define BREAK 243 /* break */
80411677aeSAaron LI #define DM 242 /* data mark--for connect. cleaning */
81411677aeSAaron LI #define NOP 241 /* nop */
82411677aeSAaron LI #define SE 240 /* end sub negotiation */
83411677aeSAaron LI #define EOR 239 /* end of record (transparent mode) */
84411677aeSAaron LI #define ABORT 238 /* Abort process */
85411677aeSAaron LI #define SUSP 237 /* Suspend process */
86411677aeSAaron LI #define xEOF 236 /* End of file: EOF is already used... */
87411677aeSAaron LI
88411677aeSAaron LI #define SYNCH 242 /* for telfunc calls */
89411677aeSAaron LI
90411677aeSAaron LI static const char *telcmds[] = {
91411677aeSAaron LI "EOF", "SUSP", "ABORT", "EOR",
92411677aeSAaron LI "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
93411677aeSAaron LI "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
94411677aeSAaron LI };
95411677aeSAaron LI
96411677aeSAaron LI #define TELCMD_FIRST xEOF
97411677aeSAaron LI #define TELCMD_LAST IAC
98411677aeSAaron LI #define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
99411677aeSAaron LI (unsigned int)(x) >= TELCMD_FIRST)
100411677aeSAaron LI #define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
101411677aeSAaron LI
102411677aeSAaron LI /* telnet options */
103411677aeSAaron LI #define TELOPT_BINARY 0 /* 8-bit data path */
104411677aeSAaron LI #define TELOPT_ECHO 1 /* echo */
105411677aeSAaron LI #define TELOPT_RCP 2 /* prepare to reconnect */
106411677aeSAaron LI #define TELOPT_SGA 3 /* suppress go ahead */
107411677aeSAaron LI #define TELOPT_NAMS 4 /* approximate message size */
108411677aeSAaron LI #define TELOPT_STATUS 5 /* give status */
109411677aeSAaron LI #define TELOPT_TM 6 /* timing mark */
110411677aeSAaron LI #define TELOPT_RCTE 7 /* remote controlled transmission and echo */
111411677aeSAaron LI #define TELOPT_NAOL 8 /* negotiate about output line width */
112411677aeSAaron LI #define TELOPT_NAOP 9 /* negotiate about output page size */
113411677aeSAaron LI #define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
114411677aeSAaron LI #define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
115411677aeSAaron LI #define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
116411677aeSAaron LI #define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
117411677aeSAaron LI #define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
118411677aeSAaron LI #define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
119411677aeSAaron LI #define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
120411677aeSAaron LI #define TELOPT_XASCII 17 /* extended ascic character set */
121411677aeSAaron LI #define TELOPT_LOGOUT 18 /* force logout */
122411677aeSAaron LI #define TELOPT_BM 19 /* byte macro */
123411677aeSAaron LI #define TELOPT_DET 20 /* data entry terminal */
124411677aeSAaron LI #define TELOPT_SUPDUP 21 /* supdup protocol */
125411677aeSAaron LI #define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
126411677aeSAaron LI #define TELOPT_SNDLOC 23 /* send location */
127411677aeSAaron LI #define TELOPT_TTYPE 24 /* terminal type */
128411677aeSAaron LI #define TELOPT_EOR 25 /* end or record */
129411677aeSAaron LI #define TELOPT_TUID 26 /* TACACS user identification */
130411677aeSAaron LI #define TELOPT_OUTMRK 27 /* output marking */
131411677aeSAaron LI #define TELOPT_TTYLOC 28 /* terminal location number */
132411677aeSAaron LI #define TELOPT_3270REGIME 29 /* 3270 regime */
133411677aeSAaron LI #define TELOPT_X3PAD 30 /* X.3 PAD */
134411677aeSAaron LI #define TELOPT_NAWS 31 /* window size */
135411677aeSAaron LI #define TELOPT_TSPEED 32 /* terminal speed */
136411677aeSAaron LI #define TELOPT_LFLOW 33 /* remote flow control */
137411677aeSAaron LI #define TELOPT_LINEMODE 34 /* Linemode option */
138411677aeSAaron LI #define TELOPT_XDISPLOC 35 /* X Display Location */
139411677aeSAaron LI #define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
140411677aeSAaron LI #define TELOPT_AUTHENTICATION 37/* Authenticate */
141411677aeSAaron LI #define TELOPT_ENCRYPT 38 /* Encryption option */
142411677aeSAaron LI #define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
143411677aeSAaron LI #define TELOPT_EXOPL 255 /* extended-options-list */
144411677aeSAaron LI
145411677aeSAaron LI
146411677aeSAaron LI #define NTELOPTS (1+TELOPT_NEW_ENVIRON)
147411677aeSAaron LI static const char *telopts[NTELOPTS+1] = {
148411677aeSAaron LI "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
149411677aeSAaron LI "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
150411677aeSAaron LI "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
151411677aeSAaron LI "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
152411677aeSAaron LI "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
153411677aeSAaron LI "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
154411677aeSAaron LI "TACACS UID", "OUTPUT MARKING", "TTYLOC",
155411677aeSAaron LI "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
156411677aeSAaron LI "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
157411677aeSAaron LI "ENCRYPT", "NEW-ENVIRON",
158411677aeSAaron LI 0,
159411677aeSAaron LI };
160411677aeSAaron LI #define TELOPT_FIRST TELOPT_BINARY
161411677aeSAaron LI #define TELOPT_LAST TELOPT_NEW_ENVIRON
162411677aeSAaron LI #define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
163411677aeSAaron LI #define TELOPT(x) telopts[(x)-TELOPT_FIRST]
164411677aeSAaron LI
165411677aeSAaron LI /* sub-option qualifiers */
166411677aeSAaron LI #define TELQUAL_IS 0 /* option is... */
167411677aeSAaron LI #define TELQUAL_SEND 1 /* send option */
168411677aeSAaron LI #define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
169411677aeSAaron LI #define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
170411677aeSAaron LI #define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
171411677aeSAaron LI
172411677aeSAaron LI #define LFLOW_OFF 0 /* Disable remote flow control */
173411677aeSAaron LI #define LFLOW_ON 1 /* Enable remote flow control */
174411677aeSAaron LI #define LFLOW_RESTART_ANY 2 /* Restart output on any char */
175411677aeSAaron LI #define LFLOW_RESTART_XON 3 /* Restart output only on XON */
176411677aeSAaron LI
177411677aeSAaron LI /*
178411677aeSAaron LI * LINEMODE suboptions
179411677aeSAaron LI */
180411677aeSAaron LI
181411677aeSAaron LI #define LM_MODE 1
182411677aeSAaron LI #define LM_FORWARDMASK 2
183411677aeSAaron LI #define LM_SLC 3
184411677aeSAaron LI
185411677aeSAaron LI #define MODE_EDIT 0x01
186411677aeSAaron LI #define MODE_TRAPSIG 0x02
187411677aeSAaron LI #define MODE_ACK 0x04
188411677aeSAaron LI #define MODE_SOFT_TAB 0x08
189411677aeSAaron LI #define MODE_LIT_ECHO 0x10
190411677aeSAaron LI
191411677aeSAaron LI #define MODE_MASK 0x1f
192411677aeSAaron LI
193411677aeSAaron LI #define SLC_SYNCH 1
194411677aeSAaron LI #define SLC_BRK 2
195411677aeSAaron LI #define SLC_IP 3
196411677aeSAaron LI #define SLC_AO 4
197411677aeSAaron LI #define SLC_AYT 5
198411677aeSAaron LI #define SLC_EOR 6
199411677aeSAaron LI #define SLC_ABORT 7
200411677aeSAaron LI #define SLC_EOF 8
201411677aeSAaron LI #define SLC_SUSP 9
202411677aeSAaron LI #define SLC_EC 10
203411677aeSAaron LI #define SLC_EL 11
204411677aeSAaron LI #define SLC_EW 12
205411677aeSAaron LI #define SLC_RP 13
206411677aeSAaron LI #define SLC_LNEXT 14
207411677aeSAaron LI #define SLC_XON 15
208411677aeSAaron LI #define SLC_XOFF 16
209411677aeSAaron LI #define SLC_FORW1 17
210411677aeSAaron LI #define SLC_FORW2 18
211411677aeSAaron LI #define SLC_MCL 19
212411677aeSAaron LI #define SLC_MCR 20
213411677aeSAaron LI #define SLC_MCWL 21
214411677aeSAaron LI #define SLC_MCWR 22
215411677aeSAaron LI #define SLC_MCBOL 23
216411677aeSAaron LI #define SLC_MCEOL 24
217411677aeSAaron LI #define SLC_INSRT 25
218411677aeSAaron LI #define SLC_OVER 26
219411677aeSAaron LI #define SLC_ECR 27
220411677aeSAaron LI #define SLC_EWR 28
221411677aeSAaron LI #define SLC_EBOL 29
222411677aeSAaron LI #define SLC_EEOL 30
223411677aeSAaron LI
224411677aeSAaron LI #define NSLC 30
225411677aeSAaron LI
226411677aeSAaron LI /*
227411677aeSAaron LI * For backwards compatibility, we define SLC_NAMES to be the
228411677aeSAaron LI * list of names if SLC_NAMES is not defined.
229411677aeSAaron LI */
230411677aeSAaron LI #define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
231411677aeSAaron LI "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
232411677aeSAaron LI "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
233411677aeSAaron LI "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \
234411677aeSAaron LI "MCEOL", "INSRT", "OVER", "ECR", "EWR", \
235411677aeSAaron LI "EBOL", "EEOL", \
236411677aeSAaron LI 0,
237411677aeSAaron LI
238411677aeSAaron LI #ifdef SLC_NAMES
239411677aeSAaron LI const char *slc_names[] = {
240411677aeSAaron LI SLC_NAMELIST
241411677aeSAaron LI };
242411677aeSAaron LI #else
243411677aeSAaron LI extern char *slc_names[];
244411677aeSAaron LI #define SLC_NAMES SLC_NAMELIST
245411677aeSAaron LI #endif
246411677aeSAaron LI
247411677aeSAaron LI #define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
248411677aeSAaron LI #define SLC_NAME(x) slc_names[x]
249411677aeSAaron LI
250411677aeSAaron LI #define SLC_NOSUPPORT 0
251411677aeSAaron LI #define SLC_CANTCHANGE 1
252411677aeSAaron LI #define SLC_VARIABLE 2
253411677aeSAaron LI #define SLC_DEFAULT 3
254411677aeSAaron LI #define SLC_LEVELBITS 0x03
255411677aeSAaron LI
256411677aeSAaron LI #define SLC_FUNC 0
257411677aeSAaron LI #define SLC_FLAGS 1
258411677aeSAaron LI #define SLC_VALUE 2
259411677aeSAaron LI
260411677aeSAaron LI #define SLC_ACK 0x80
261411677aeSAaron LI #define SLC_FLUSHIN 0x40
262411677aeSAaron LI #define SLC_FLUSHOUT 0x20
263411677aeSAaron LI
264411677aeSAaron LI #define OLD_ENV_VAR 1
265411677aeSAaron LI #define OLD_ENV_VALUE 0
266411677aeSAaron LI #define NEW_ENV_VAR 0
267411677aeSAaron LI #define NEW_ENV_VALUE 1
268411677aeSAaron LI #define ENV_ESC 2
269411677aeSAaron LI #define ENV_USERVAR 3
270411677aeSAaron LI
271411677aeSAaron LI /*
272411677aeSAaron LI * AUTHENTICATION suboptions
273411677aeSAaron LI */
274411677aeSAaron LI
275411677aeSAaron LI /*
276411677aeSAaron LI * Who is authenticating who ...
277411677aeSAaron LI */
278411677aeSAaron LI #define AUTH_WHO_CLIENT 0 /* Client authenticating server */
279411677aeSAaron LI #define AUTH_WHO_SERVER 1 /* Server authenticating client */
280411677aeSAaron LI #define AUTH_WHO_MASK 1
281411677aeSAaron LI
282411677aeSAaron LI #define AUTHTYPE_NULL 0
283411677aeSAaron LI #define AUTHTYPE_KERBEROS_V4 1
284411677aeSAaron LI #define AUTHTYPE_KERBEROS_V5 2
285411677aeSAaron LI #define AUTHTYPE_SPX 3
286411677aeSAaron LI #define AUTHTYPE_MINK 4
287411677aeSAaron LI #define AUTHTYPE_CNT 5
288411677aeSAaron LI
289411677aeSAaron LI #define AUTHTYPE_TEST 99
290411677aeSAaron LI
291411677aeSAaron LI #ifdef AUTH_NAMES
292411677aeSAaron LI const char *authtype_names[] = {
293411677aeSAaron LI "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
294411677aeSAaron LI };
295411677aeSAaron LI #else
296411677aeSAaron LI extern char *authtype_names[];
297411677aeSAaron LI #endif
298411677aeSAaron LI
299411677aeSAaron LI #define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
300411677aeSAaron LI #define AUTHTYPE_NAME(x) authtype_names[x]
301411677aeSAaron LI
302411677aeSAaron LI /*
303411677aeSAaron LI * ENCRYPTion suboptions
304411677aeSAaron LI */
305411677aeSAaron LI #define ENCRYPT_IS 0 /* I pick encryption type ... */
306411677aeSAaron LI #define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
307411677aeSAaron LI #define ENCRYPT_REPLY 2 /* Initial setup response */
308411677aeSAaron LI #define ENCRYPT_START 3 /* Am starting to send encrypted */
309411677aeSAaron LI #define ENCRYPT_END 4 /* Am ending encrypted */
310411677aeSAaron LI #define ENCRYPT_REQSTART 5 /* Request you start encrypting */
311411677aeSAaron LI #define ENCRYPT_REQEND 6 /* Request you send encrypting */
312411677aeSAaron LI #define ENCRYPT_ENC_KEYID 7
313411677aeSAaron LI #define ENCRYPT_DEC_KEYID 8
314411677aeSAaron LI #define ENCRYPT_CNT 9
315411677aeSAaron LI
316411677aeSAaron LI #define ENCTYPE_ANY 0
317411677aeSAaron LI #define ENCTYPE_DES_CFB64 1
318411677aeSAaron LI #define ENCTYPE_DES_OFB64 2
319411677aeSAaron LI #define ENCTYPE_CNT 3
320411677aeSAaron LI
321411677aeSAaron LI #ifdef ENCRYPT_NAMES
322411677aeSAaron LI const char *encrypt_names[] = {
323411677aeSAaron LI "IS", "SUPPORT", "REPLY", "START", "END",
324411677aeSAaron LI "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
325411677aeSAaron LI 0,
326411677aeSAaron LI };
327411677aeSAaron LI const char *enctype_names[] = {
328411677aeSAaron LI "ANY", "DES_CFB64", "DES_OFB64", 0,
329411677aeSAaron LI };
330411677aeSAaron LI #else
331411677aeSAaron LI extern char *encrypt_names[];
332411677aeSAaron LI extern char *enctype_names[];
333411677aeSAaron LI #endif
334411677aeSAaron LI
335411677aeSAaron LI #define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
336411677aeSAaron LI #define ENCRYPT_NAME(x) encrypt_names[x]
337411677aeSAaron LI
338411677aeSAaron LI #define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
339411677aeSAaron LI #define ENCTYPE_NAME(x) enctype_names[x]
34041c99275SPeter Avalos
34141c99275SPeter Avalos /* normal */
34241c99275SPeter Avalos static const char *cmds[] = {
34341c99275SPeter Avalos "IS", "SEND", "INFO",
34441c99275SPeter Avalos };
34541c99275SPeter Avalos
34641c99275SPeter Avalos /* 37: Authentication */
34741c99275SPeter Avalos static const char *authcmd[] = {
34841c99275SPeter Avalos "IS", "SEND", "REPLY", "NAME",
34941c99275SPeter Avalos };
35041c99275SPeter Avalos static const char *authtype[] = {
35141c99275SPeter Avalos "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK",
35241c99275SPeter Avalos "SRP", "RSA", "SSL", NULL, NULL,
35341c99275SPeter Avalos "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS",
35441c99275SPeter Avalos "NTLM",
35541c99275SPeter Avalos };
35641c99275SPeter Avalos
35741c99275SPeter Avalos /* 38: Encryption */
35841c99275SPeter Avalos static const char *enccmd[] = {
35941c99275SPeter Avalos "IS", "SUPPORT", "REPLY", "START", "END",
36041c99275SPeter Avalos "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID",
36141c99275SPeter Avalos };
36241c99275SPeter Avalos static const char *enctype[] = {
36341c99275SPeter Avalos "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64",
36441c99275SPeter Avalos NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64",
36541c99275SPeter Avalos };
36641c99275SPeter Avalos
36741c99275SPeter Avalos #define STR_OR_ID(x, tab) \
36841c99275SPeter Avalos (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
36941c99275SPeter Avalos
37041c99275SPeter Avalos static char *
numstr(int x)37141c99275SPeter Avalos numstr(int x)
37241c99275SPeter Avalos {
37341c99275SPeter Avalos static char buf[20];
37441c99275SPeter Avalos
37541c99275SPeter Avalos snprintf(buf, sizeof(buf), "%#x", x);
37641c99275SPeter Avalos return buf;
37741c99275SPeter Avalos }
37841c99275SPeter Avalos
37941c99275SPeter Avalos /* sp points to IAC byte */
38041c99275SPeter Avalos static int
telnet_parse(netdissect_options * ndo,const u_char * sp,u_int length,int print)381411677aeSAaron LI telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print)
38241c99275SPeter Avalos {
38341c99275SPeter Avalos int i, x;
38441c99275SPeter Avalos u_int c;
38541c99275SPeter Avalos const u_char *osp, *p;
38641c99275SPeter Avalos #define FETCH(c, sp, length) \
38741c99275SPeter Avalos do { \
38841c99275SPeter Avalos if (length < 1) \
38941c99275SPeter Avalos goto pktend; \
390*ed775ee7SAntonio Huete Jimenez c = GET_U_1(sp); \
391*ed775ee7SAntonio Huete Jimenez sp++; \
39241c99275SPeter Avalos length--; \
39341c99275SPeter Avalos } while (0)
39441c99275SPeter Avalos
39541c99275SPeter Avalos osp = sp;
39641c99275SPeter Avalos
39741c99275SPeter Avalos FETCH(c, sp, length);
39841c99275SPeter Avalos if (c != IAC)
39941c99275SPeter Avalos goto pktend;
40041c99275SPeter Avalos FETCH(c, sp, length);
40141c99275SPeter Avalos if (c == IAC) { /* <IAC><IAC>! */
40241c99275SPeter Avalos if (print)
403*ed775ee7SAntonio Huete Jimenez ND_PRINT("IAC IAC");
40441c99275SPeter Avalos goto done;
40541c99275SPeter Avalos }
40641c99275SPeter Avalos
40741c99275SPeter Avalos i = c - TELCMD_FIRST;
40841c99275SPeter Avalos if (i < 0 || i > IAC - TELCMD_FIRST)
40941c99275SPeter Avalos goto pktend;
41041c99275SPeter Avalos
41141c99275SPeter Avalos switch (c) {
41241c99275SPeter Avalos case DONT:
41341c99275SPeter Avalos case DO:
41441c99275SPeter Avalos case WONT:
41541c99275SPeter Avalos case WILL:
41641c99275SPeter Avalos case SB:
41741c99275SPeter Avalos /* DONT/DO/WONT/WILL x */
41841c99275SPeter Avalos FETCH(x, sp, length);
41941c99275SPeter Avalos if (x >= 0 && x < NTELOPTS) {
42041c99275SPeter Avalos if (print)
421*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s %s", telcmds[i], telopts[x]);
42241c99275SPeter Avalos } else {
42341c99275SPeter Avalos if (print)
424*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s %#x", telcmds[i], x);
42541c99275SPeter Avalos }
42641c99275SPeter Avalos if (c != SB)
42741c99275SPeter Avalos break;
42841c99275SPeter Avalos /* IAC SB .... IAC SE */
42941c99275SPeter Avalos p = sp;
43041c99275SPeter Avalos while (length > (u_int)(p + 1 - sp)) {
431*ed775ee7SAntonio Huete Jimenez if (GET_U_1(p) == IAC && GET_U_1(p + 1) == SE)
43241c99275SPeter Avalos break;
43341c99275SPeter Avalos p++;
43441c99275SPeter Avalos }
435*ed775ee7SAntonio Huete Jimenez if (GET_U_1(p) != IAC)
43641c99275SPeter Avalos goto pktend;
43741c99275SPeter Avalos
43841c99275SPeter Avalos switch (x) {
43941c99275SPeter Avalos case TELOPT_AUTHENTICATION:
44041c99275SPeter Avalos if (p <= sp)
44141c99275SPeter Avalos break;
44241c99275SPeter Avalos FETCH(c, sp, length);
44341c99275SPeter Avalos if (print)
444*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %s", STR_OR_ID(c, authcmd));
44541c99275SPeter Avalos if (p <= sp)
44641c99275SPeter Avalos break;
44741c99275SPeter Avalos FETCH(c, sp, length);
44841c99275SPeter Avalos if (print)
449*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %s", STR_OR_ID(c, authtype));
45041c99275SPeter Avalos break;
45141c99275SPeter Avalos case TELOPT_ENCRYPT:
45241c99275SPeter Avalos if (p <= sp)
45341c99275SPeter Avalos break;
45441c99275SPeter Avalos FETCH(c, sp, length);
45541c99275SPeter Avalos if (print)
456*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %s", STR_OR_ID(c, enccmd));
45741c99275SPeter Avalos if (p <= sp)
45841c99275SPeter Avalos break;
45941c99275SPeter Avalos FETCH(c, sp, length);
46041c99275SPeter Avalos if (print)
461*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %s", STR_OR_ID(c, enctype));
46241c99275SPeter Avalos break;
46341c99275SPeter Avalos default:
46441c99275SPeter Avalos if (p <= sp)
46541c99275SPeter Avalos break;
46641c99275SPeter Avalos FETCH(c, sp, length);
46741c99275SPeter Avalos if (print)
468*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %s", STR_OR_ID(c, cmds));
46941c99275SPeter Avalos break;
47041c99275SPeter Avalos }
47141c99275SPeter Avalos while (p > sp) {
47241c99275SPeter Avalos FETCH(x, sp, length);
47341c99275SPeter Avalos if (print)
474*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %#x", x);
47541c99275SPeter Avalos }
47641c99275SPeter Avalos /* terminating IAC SE */
47741c99275SPeter Avalos if (print)
478*ed775ee7SAntonio Huete Jimenez ND_PRINT(" SE");
47941c99275SPeter Avalos sp += 2;
48041c99275SPeter Avalos break;
48141c99275SPeter Avalos default:
48241c99275SPeter Avalos if (print)
483*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", telcmds[i]);
48441c99275SPeter Avalos goto done;
48541c99275SPeter Avalos }
48641c99275SPeter Avalos
48741c99275SPeter Avalos done:
488*ed775ee7SAntonio Huete Jimenez return (int)(sp - osp);
48941c99275SPeter Avalos
49041c99275SPeter Avalos pktend:
49141c99275SPeter Avalos return -1;
49241c99275SPeter Avalos #undef FETCH
49341c99275SPeter Avalos }
49441c99275SPeter Avalos
49541c99275SPeter Avalos void
telnet_print(netdissect_options * ndo,const u_char * sp,u_int length)496411677aeSAaron LI telnet_print(netdissect_options *ndo, const u_char *sp, u_int length)
49741c99275SPeter Avalos {
49841c99275SPeter Avalos int first = 1;
49941c99275SPeter Avalos const u_char *osp;
50041c99275SPeter Avalos int l;
50141c99275SPeter Avalos
502*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "telnet";
50341c99275SPeter Avalos osp = sp;
50441c99275SPeter Avalos
505*ed775ee7SAntonio Huete Jimenez while (length > 0 && GET_U_1(sp) == IAC) {
506411677aeSAaron LI /*
507411677aeSAaron LI * Parse the Telnet command without printing it,
508411677aeSAaron LI * to determine its length.
509411677aeSAaron LI */
510411677aeSAaron LI l = telnet_parse(ndo, sp, length, 0);
51141c99275SPeter Avalos if (l < 0)
51241c99275SPeter Avalos break;
51341c99275SPeter Avalos
51441c99275SPeter Avalos /*
51541c99275SPeter Avalos * now print it
51641c99275SPeter Avalos */
517411677aeSAaron LI if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag) {
51841c99275SPeter Avalos if (first)
519*ed775ee7SAntonio Huete Jimenez ND_PRINT("\nTelnet:");
520*ed775ee7SAntonio Huete Jimenez hex_print_with_offset(ndo, "\n", sp, l, (u_int)(sp - osp));
52141c99275SPeter Avalos if (l > 8)
522*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\t\t\t");
52341c99275SPeter Avalos else
524*ed775ee7SAntonio Huete Jimenez ND_PRINT("%*s\t", (8 - l) * 3, "");
52541c99275SPeter Avalos } else
526*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", (first) ? " [telnet " : ", ");
52741c99275SPeter Avalos
528411677aeSAaron LI (void)telnet_parse(ndo, sp, length, 1);
52941c99275SPeter Avalos first = 0;
53041c99275SPeter Avalos
53141c99275SPeter Avalos sp += l;
53241c99275SPeter Avalos length -= l;
53341c99275SPeter Avalos }
53441c99275SPeter Avalos if (!first) {
535411677aeSAaron LI if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag)
536*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n");
53741c99275SPeter Avalos else
538*ed775ee7SAntonio Huete Jimenez ND_PRINT("]");
53941c99275SPeter Avalos }
54041c99275SPeter Avalos }
541