aboutsummaryrefslogtreecommitdiffstats
path: root/packet-telnet.c
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2004-07-18 18:06:47 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2004-07-18 18:06:47 +0000
commit669db206cb1f270046ad400fff7655e20c63e723 (patch)
tree4eff24a2e16c8963e497e1fc575f35e6af59bd26 /packet-telnet.c
parentae46c27a38700af669ef907491081f09df6f6b2c (diff)
Move dissectors to epan/dissectors directory.
Also move ncp222.py, x11-fields, process-x11-fields.pl, make-reg-dotc, and make-reg-dotc.py. Adjust #include lines in files that include packet-*.h files. svn path=/trunk/; revision=11410
Diffstat (limited to 'packet-telnet.c')
-rw-r--r--packet-telnet.c1601
1 files changed, 0 insertions, 1601 deletions
diff --git a/packet-telnet.c b/packet-telnet.c
deleted file mode 100644
index 2f76364754..0000000000
--- a/packet-telnet.c
+++ /dev/null
@@ -1,1601 +0,0 @@
-/* packet-telnet.c
- * Routines for Telnet packet dissection; see RFC 854 and RFC 855
- * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
- *
- * $Id$
- *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
- * Copyright 1998 Gerald Combs
- *
- * Copied from packet-pop.c
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/* Telnet authentication options as per RFC2941
- * Kerberos v5 telnet authentication as per RFC2942
- */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdio.h>
-
-#include <string.h>
-#include <glib.h>
-#include <epan/packet.h>
-#include <epan/strutil.h>
-#include "packet-kerberos.h"
-
-static int proto_telnet = -1;
-static int hf_telnet_auth_cmd = -1;
-static int hf_telnet_auth_name = -1;
-static int hf_telnet_auth_type = -1;
-static int hf_telnet_auth_mod_who = -1;
-static int hf_telnet_auth_mod_how = -1;
-static int hf_telnet_auth_mod_cred_fwd = -1;
-static int hf_telnet_auth_mod_enc = -1;
-static int hf_telnet_auth_krb5_type = -1;
-
-static gint ett_telnet = -1;
-static gint ett_telnet_subopt = -1;
-static gint ett_status_subopt = -1;
-static gint ett_rcte_subopt = -1;
-static gint ett_olw_subopt = -1;
-static gint ett_ops_subopt = -1;
-static gint ett_crdisp_subopt = -1;
-static gint ett_htstops_subopt = -1;
-static gint ett_htdisp_subopt = -1;
-static gint ett_ffdisp_subopt = -1;
-static gint ett_vtstops_subopt = -1;
-static gint ett_vtdisp_subopt = -1;
-static gint ett_lfdisp_subopt = -1;
-static gint ett_extasc_subopt = -1;
-static gint ett_bytemacro_subopt = -1;
-static gint ett_det_subopt = -1;
-static gint ett_supdupout_subopt = -1;
-static gint ett_sendloc_subopt = -1;
-static gint ett_termtype_subopt = -1;
-static gint ett_tacacsui_subopt = -1;
-static gint ett_outmark_subopt = -1;
-static gint ett_tlocnum_subopt = -1;
-static gint ett_tn3270reg_subopt = -1;
-static gint ett_x3pad_subopt = -1;
-static gint ett_naws_subopt = -1;
-static gint ett_tspeed_subopt = -1;
-static gint ett_rfc_subopt = -1;
-static gint ett_linemode_subopt = -1;
-static gint ett_xdpyloc_subopt = -1;
-static gint ett_env_subopt = -1;
-static gint ett_auth_subopt = -1;
-static gint ett_enc_subopt = -1;
-static gint ett_newenv_subopt = -1;
-static gint ett_tn3270e_subopt = -1;
-static gint ett_xauth_subopt = -1;
-static gint ett_charset_subopt = -1;
-static gint ett_rsp_subopt = -1;
-static gint ett_comport_subopt = -1;
-
-
-/* Some defines for Telnet */
-
-#define TCP_PORT_TELNET 23
-
-#define TN_IAC 255
-#define TN_DONT 254
-#define TN_DO 253
-#define TN_WONT 252
-#define TN_WILL 251
-#define TN_SB 250
-#define TN_GA 249
-#define TN_EL 248
-#define TN_EC 247
-#define TN_AYT 246
-#define TN_AO 245
-#define TN_IP 244
-#define TN_BRK 243
-#define TN_DM 242
-#define TN_NOP 241
-#define TN_SE 240
-#define TN_EOR 239
-#define TN_ABORT 238
-#define TN_SUSP 237
-#define TN_EOF 236
-
-
-typedef enum {
- NO_LENGTH, /* option has no data, hence no length */
- FIXED_LENGTH, /* option always has the same length */
- VARIABLE_LENGTH /* option is variable-length - optlen is minimum */
-} tn_opt_len_type;
-
-/* Member of table of IP or TCP options. */
-typedef struct tn_opt {
- char *name; /* name of option */
- gint *subtree_index; /* pointer to subtree index for option */
- tn_opt_len_type len_type; /* type of option length field */
- int optlen; /* value length should be (minimum if VARIABLE) */
- void (*dissect)(packet_info *pinfo, const char *, tvbuff_t *, int, int, proto_tree *);
- /* routine to dissect option */
-} tn_opt;
-
-static void
-dissect_string_subopt(packet_info *pinfo _U_, const char *optname, tvbuff_t *tvb, int offset, int len,
- proto_tree *tree)
-{
- guint8 cmd;
-
- cmd = tvb_get_guint8(tvb, offset);
- switch (cmd) {
-
- case 0: /* IS */
- proto_tree_add_text(tree, tvb, offset, 1, "Here's my %s", optname);
- offset++;
- len--;
- if (len > 0) {
- proto_tree_add_text(tree, tvb, offset, len, "Value: %s",
- tvb_format_text(tvb, offset, len));
- }
- break;
-
- case 1: /* SEND */
- proto_tree_add_text(tree, tvb, offset, 1, "Send your %s", optname);
- offset++;
- len--;
- if (len > 0)
- proto_tree_add_text(tree, tvb, offset, len, "Extra data");
- break;
-
- default:
- proto_tree_add_text(tree, tvb, offset, 1, "Invalid %s subcommand %u",
- optname, cmd);
- offset++;
- len--;
- if (len > 0)
- proto_tree_add_text(tree, tvb, offset, len, "Subcommand data");
- break;
- }
-}
-
-static void
-dissect_outmark_subopt(packet_info *pinfo _U_, const char *optname _U_, tvbuff_t *tvb, int offset,
- int len, proto_tree *tree)
-{
- guint8 cmd;
- int gs_offset, datalen;
-
- while (len > 0) {
- cmd = tvb_get_guint8(tvb, offset);
- switch (cmd) {
-
- case 6: /* ACK */
- proto_tree_add_text(tree, tvb, offset, 1, "ACK");
- break;
-
- case 21: /* NAK */
- proto_tree_add_text(tree, tvb, offset, 1, "NAK");
- break;
-
- case 'D':
- proto_tree_add_text(tree, tvb, offset, 1, "Default");
- break;
-
- case 'T':
- proto_tree_add_text(tree, tvb, offset, 1, "Top");
- break;
-
- case 'B':
- proto_tree_add_text(tree, tvb, offset, 1, "Bottom");
- break;
-
- case 'L':
- proto_tree_add_text(tree, tvb, offset, 1, "Left");
- break;
-
- case 'R':
- proto_tree_add_text(tree, tvb, offset, 1, "Right");
- break;
-
- default:
- proto_tree_add_text(tree, tvb, offset, 1, "Bogus value: %u", cmd);
- break;
- }
- offset++;
- len--;
-
- /* Look for a GS */
- gs_offset = tvb_find_guint8(tvb, offset, len, 29);
- if (gs_offset == -1) {
- /* None found - run to the end of the packet. */
- gs_offset = offset + len;
- }
- datalen = gs_offset - offset;
- if (datalen > 0) {
- proto_tree_add_text(tree, tvb, offset, datalen, "Banner: %s",
- tvb_format_text(tvb, offset, datalen));
- offset += datalen;
- len -= datalen;
- }
- }
-}
-
-static void
-dissect_htstops_subopt(packet_info *pinfo _U_, const char *optname, tvbuff_t *tvb, int offset, int len,
- proto_tree *tree)
-{
- guint8 cmd;
- guint8 tabval;
-
- cmd = tvb_get_guint8(tvb, offset);
- switch (cmd) {
-
- case 0: /* IS */
- proto_tree_add_text(tree, tvb, offset, 1, "Here's my %s", optname);
- offset++;
- len--;
- break;
-
- case 1: /* SEND */
- proto_tree_add_text(tree, tvb, offset, 1, "Send your %s", optname);
- offset++;
- len--;
- break;
-
- default:
- proto_tree_add_text(tree, tvb, offset, 1, "Invalid %s subcommand %u",
- optname, cmd);
- offset++;
- len--;
- if (len > 0)
- proto_tree_add_text(tree, tvb, offset, len, "Subcommand data");
- return;
- }
-
- while (len > 0) {
- tabval = tvb_get_guint8(tvb, offset);
- switch (tabval) {
-
- case 0:
- proto_tree_add_text(tree, tvb, offset, 1,
- "Sender wants to handle tab stops");
- break;
-
- default:
- proto_tree_add_text(tree, tvb, offset, 1,
- "Sender wants receiver to handle tab stop at %u",
- tabval);
- break;
-
- case 251:
- case 252:
- case 253:
- case 254:
- proto_tree_add_text(tree, tvb, offset, 1,
- "Invalid value: %u", tabval);
- break;
-
- case 255:
- proto_tree_add_text(tree, tvb, offset, 1,
- "Sender wants receiver to handle tab stops");
- break;
- }
- offset++;
- len--;
- }
-}
-
-static void
-dissect_naws_subopt(packet_info *pinfo _U_, const char *optname _U_, tvbuff_t *tvb, int offset,
- int len _U_, proto_tree *tree)
-{
- proto_tree_add_text(tree, tvb, offset, 2, "Width: %u",
- tvb_get_ntohs(tvb, offset));
- offset += 2;
- proto_tree_add_text(tree, tvb, offset, 2, "Height: %u",
- tvb_get_ntohs(tvb, offset));
-}
-
-/* BEGIN RFC-2217 (COM Port Control) Definitions */
-
-#define TNCOMPORT_SIGNATURE 0
-#define TNCOMPORT_SETBAUDRATE 1
-#define TNCOMPORT_SETDATASIZE 2
-#define TNCOMPORT_SETPARITY 3
-#define TNCOMPORT_SETSTOPSIZE 4
-#define TNCOMPORT_SETCONTROL 5
-#define TNCOMPORT_NOTIFYLINESTATE 6
-#define TNCOMPORT_NOTIFYMODEMSTATE 7
-#define TNCOMPORT_FLOWCONTROLSUSPEND 8
-#define TNCOMPORT_FLOWCONTROLRESUME 9
-#define TNCOMPORT_SETLINESTATEMASK 10
-#define TNCOMPORT_SETMODEMSTATEMASK 11
-#define TNCOMPORT_PURGEDATA 12
-
-/* END RFC-2217 (COM Port Control) Definitions */
-
-static void
-dissect_comport_subopt(packet_info *pinfo _U_, const char *optname, tvbuff_t *tvb, int offset, int len,
- proto_tree *tree)
-{static const char *datasizes[] = {
- "Request",
- "<invalid>",
- "<invalid>",
- "<invalid>",
- "<invalid>",
- "5",
- "6",
- "7",
- "8"
- };
- static const char *parities[] = {
- "Request",
- "None",
- "Odd",
- "Even",
- "Mark",
- "Space"
- };
- static const char *stops[] = {
- "Request",
- "1",
- "2",
- "1.5"
- };
- static const char *control[] = {
- "Output Flow Control Request",
- "Output Flow: None",
- "Output Flow: XON/XOFF",
- "Output Flow: CTS/RTS",
- "Break Request",
- "Break: ON",
- "Break: OFF",
- "DTR Request",
- "DTR: ON",
- "DTR: OFF",
- "RTS Request",
- "RTS: ON",
- "RTS: OFF",
- "Input Flow Control Request",
- "Input Flow: None",
- "Input Flow: XON/XOFF",
- "Input Flow: CTS/RTS",
- "Output Flow: DCD",
- "Input Flow: DTR",
- "Output Flow: DSR"
- };
- static const char *linestate_bits[] = {
- "Data Ready",
- "Overrun Error",
- "Parity Error",
- "Framing Error",
- "Break Detected",
- "Transfer Holding Register Empty",
- "Transfer Shift Register Empty",
- "Timeout Error"
- };
- static const char *modemstate_bits[] = {
- "DCTS",
- "DDSR",
- "TERI",
- "DDCD",
- "CTS",
- "DSR",
- "RI",
- "DCD"
- };
- static const char *purges[] = {
- "Purge None",
- "Purge RX",
- "Purge TX",
- "Purge RX/TX"
- };
-
- guint8 cmd;
- guint8 isservercmd;
- char *source;
-
- cmd = tvb_get_guint8(tvb, offset);
- isservercmd = cmd > 99;
- cmd = (isservercmd) ? (cmd - 100) : cmd;
- source = (isservercmd) ? "Server" : "Client";
- switch (cmd) {
-
- case TNCOMPORT_SIGNATURE:
- len--;
- if (len == 0) {
- proto_tree_add_text(tree, tvb, offset, 1, "%s Requests Signature",source);
- } else {
- guint8 *sig = tvb_get_string(tvb, offset + 1, len);
- proto_tree_add_text(tree, tvb, offset, 1 + len, "%s Signature: %s",source, sig);
- g_free(sig);
- }
- break;
-
- case TNCOMPORT_SETBAUDRATE:
- len--;
- if (len >= 4) {
- guint32 baud = tvb_get_ntohl(tvb, offset+1);
- if (baud == 0) {
- proto_tree_add_text(tree, tvb, offset, 5, "%s Requests Baud Rate",source);
- } else {
- proto_tree_add_text(tree, tvb, offset, 5, "%s Baud Rate: %d",source,baud);
- }
- } else {
- proto_tree_add_text(tree, tvb, offset, 1 + len, "%s <Invalid Baud Rate Packet>",source);
- }
- break;
-
- case TNCOMPORT_SETDATASIZE:
- len--;
- if (len >= 1) {
- guint8 datasize = tvb_get_guint8(tvb, offset+1);
- const char *ds = (datasize > 8) ? "<invalid>" : datasizes[datasize];
- proto_tree_add_text(tree, tvb, offset, 2, "%s Data Size: %s",source,ds);
- } else {
- proto_tree_add_text(tree, tvb, offset, 1 + len, "%s <Invalid Data Size Packet>",source);
- }
- break;
-
- case TNCOMPORT_SETPARITY:
- len--;
- if (len >= 1) {
- guint8 parity = tvb_get_guint8(tvb, offset+1);
- const char *pr = (parity > 5) ? "<invalid>" : parities[parity];
- proto_tree_add_text(tree, tvb, offset, 2, "%s Parity: %s",source,pr);
- } else {
- proto_tree_add_text(tree, tvb, offset, 1 + len, "%s <Invalid Parity Packet>",source);
- }
- break;
-
- case TNCOMPORT_SETSTOPSIZE:
- len--;
- if (len >= 1) {
- guint8 stop = tvb_get_guint8(tvb, offset+1);
- const char *st = (stop > 3) ? "<invalid>" : stops[stop];
- proto_tree_add_text(tree, tvb, offset, 2, "%s Stop: %s",source,st);
- } else {
- proto_tree_add_text(tree, tvb, offset, 1 + len, "%s <Invalid Stop Packet>",source);
- }
- break;
-
- case TNCOMPORT_SETCONTROL:
- len--;
- if (len >= 1) {
- guint8 crt = tvb_get_guint8(tvb, offset+1);
- const char *c = (crt > 19) ? "Control: <invalid>" : control[crt];
- proto_tree_add_text(tree, tvb, offset, 2, "%s %s",source,c);
- } else {
- proto_tree_add_text(tree, tvb, offset, 1 + len, "%s <Invalid Control Packet>",source);
- }
- break;
-
- case TNCOMPORT_SETLINESTATEMASK:
- case TNCOMPORT_NOTIFYLINESTATE:
- len--;
- if (len >= 1) {
- const char *print_pattern = (cmd == TNCOMPORT_SETLINESTATEMASK) ?
- "%s Set Linestate Mask: %s" : "%s Linestate: %s";
- char ls_buffer[512];
- guint8 ls = tvb_get_guint8(tvb, offset+1);
- int print_count = 0;
- int idx;
- ls_buffer[0] = '\0';
- for (idx = 0; idx < 8; idx++) {
- int bit = ls & 1;
- if (bit) {
- if (print_count != 0) {
- strcat(ls_buffer,", ");
- }
- strcat(ls_buffer,linestate_bits[idx]);
- print_count++;
- }
- ls = ls >> 1;
- }
- proto_tree_add_text(tree, tvb, offset, 2, print_pattern, source, ls_buffer);
- } else {
- const char *print_pattern = (cmd == TNCOMPORT_SETLINESTATEMASK) ?
- "%s <Invalid Linestate Mask>" : "%s <Invalid Linestate Packet>";
- proto_tree_add_text(tree, tvb, offset, 1 + len, print_pattern, source);
- }
- break;
-
- case TNCOMPORT_SETMODEMSTATEMASK:
- case TNCOMPORT_NOTIFYMODEMSTATE:
- len--;
- if (len >= 1) {
- const char *print_pattern = (cmd == TNCOMPORT_SETMODEMSTATEMASK) ?
- "%s Set Modemstate Mask: %s" : "%s Modemstate: %s";
- char ms_buffer[256];
- guint8 ms = tvb_get_guint8(tvb, offset+1);
- int print_count = 0;
- int idx;
- ms_buffer[0] = '\0';
- for (idx = 0; idx < 8; idx++) {
- int bit = ms & 1;
- if (bit) {
- if (print_count != 0) {
- strcat(ms_buffer,", ");
- }
- strcat(ms_buffer,modemstate_bits[idx]);
- print_count++;
- }
- ms = ms >> 1;
- }
- proto_tree_add_text(tree, tvb, offset, 2, print_pattern, source, ms_buffer);
- } else {
- const char *print_pattern = (cmd == TNCOMPORT_SETMODEMSTATEMASK) ?
- "%s <Invalid Modemstate Mask>" : "%s <Invalid Modemstate Packet>";
- proto_tree_add_text(tree, tvb, offset, 1 + len, print_pattern, source);
- }
- break;
-
- case TNCOMPORT_FLOWCONTROLSUSPEND:
- len--;
- proto_tree_add_text(tree, tvb, offset, 1, "%s Flow Control Suspend",source);
- break;
-
- case TNCOMPORT_FLOWCONTROLRESUME:
- len--;
- proto_tree_add_text(tree, tvb, offset, 1, "%s Flow Control Resume",source);
- break;
-
- case TNCOMPORT_PURGEDATA:
- len--;
- if (len >= 1) {
- guint8 purge = tvb_get_guint8(tvb, offset+1);
- const char *p = (purge > 3) ? "<Purge invalid>" : purges[purge];
- proto_tree_add_text(tree, tvb, offset, 2, "%s %s",source,p);
- } else {
- proto_tree_add_text(tree, tvb, offset, 1 + len, "%s <Invalid Purge Packet>",source);
- }
- break;
-
- default:
- proto_tree_add_text(tree, tvb, offset, 1, "Invalid %s subcommand %u",
- optname, cmd);
- offset++;
- len--;
- if (len > 0)
- proto_tree_add_text(tree, tvb, offset, len, "Subcommand data");
- return;
- }
-
-}
-
-static const value_string rfc_opt_vals[] = {
- { 0, "OFF" },
- { 1, "ON" },
- { 2, "RESTART-ANY" },
- { 3, "RESTART-XON" },
- { 0, NULL }
-};
-
-static void
-dissect_rfc_subopt(packet_info *pinfo _U_, const char *optname _U_, tvbuff_t *tvb, int offset,
- int len _U_, proto_tree *tree)
-{
- guint8 cmd;
-
- cmd = tvb_get_guint8(tvb, offset);
- proto_tree_add_text(tree, tvb, offset, 2, "%s",
- val_to_str(cmd, rfc_opt_vals, "Unknown (%u)"));
-}
-
-
-#define TN_AC_IS 0
-#define TN_AC_SEND 1
-#define TN_AC_REPLY 2
-#define TN_AC_NAME 3
-static const value_string auth_cmd_vals[] = {
- { TN_AC_IS, "IS" },
- { TN_AC_SEND, "SEND" },
- { TN_AC_REPLY, "REPLY" },
- { TN_AC_NAME, "NAME" },
- { 0, NULL }
-};
-
-#define TN_AT_NULL 0
-#define TN_AT_KRB4 1
-#define TN_AT_KRB5 2
-#define TN_AT_SPX 3
-#define TN_AT_MINK 4
-#define TN_AT_SRP 5
-#define TN_AT_RSA 6
-#define TN_AT_SSL 7
-#define TN_AT_LOKI 10
-#define TN_AT_SSA 11
-#define TN_AT_KEA_SJ 12
-#define TN_AT_KEA_SJ_INTEG 13
-#define TN_AT_DSS 14
-#define TN_AT_NTLM 15
-static const value_string auth_type_vals[] = {
- { TN_AT_NULL, "NULL" },
- { TN_AT_KRB4, "Kerberos v4" },
- { TN_AT_KRB5, "Kerberos v5" },
- { TN_AT_SPX, "SPX" },
- { TN_AT_MINK, "MINK" },
- { TN_AT_SRP, "SRP" },
- { TN_AT_RSA, "RSA" },
- { TN_AT_SSL, "SSL" },
- { TN_AT_LOKI, "LOKI" },
- { TN_AT_SSA, "SSA" },
- { TN_AT_KEA_SJ, "KEA_SJ" },
- { TN_AT_KEA_SJ_INTEG, "KEA_SJ_INTEG" },
- { TN_AT_DSS, "DSS" },
- { TN_AT_NTLM, "NTLM" },
- { 0, NULL }
-};
-static const true_false_string auth_mod_cred_fwd = {
- "Client WILL forward auth creds",
- "Client will NOT forward auth creds"
-};
-static const true_false_string auth_mod_who = {
- "Mask server to client",
- "Mask client to server"
-};
-static const true_false_string auth_mod_how = {
- "MUTUAL authentication",
- "One Way authentication"
-};
-#define TN_AM_OFF 0x00
-#define TN_AM_USING_TELOPT 0x01
-#define TN_AM_AFTER_EXCHANGE 0x02
-#define TN_AM_RESERVED 0x04
-static const value_string auth_mod_enc[] = {
- { TN_AM_OFF, "Off" },
- { TN_AM_USING_TELOPT, "Telnet Options" },
- { TN_AM_AFTER_EXCHANGE, "After Exchange" },
- { TN_AM_RESERVED, "Reserved" },
- { 0, NULL }
-};
-#define TN_KRB5_TYPE_AUTH 0
-#define TN_KRB5_TYPE_REJECT 1
-#define TN_KRB5_TYPE_ACCEPT 2
-#define TN_KRB5_TYPE_RESPONSE 3
-#define TN_KRB5_TYPE_FORWARD 4
-#define TN_KRB5_TYPE_FORWARD_ACCEPT 5
-#define TN_KRB5_TYPE_FORWARD_REJECT 6
-static const value_string auth_krb5_types[] = {
- { TN_KRB5_TYPE_AUTH, "Auth" },
- { TN_KRB5_TYPE_REJECT, "Reject" },
- { TN_KRB5_TYPE_ACCEPT, "Accept" },
- { TN_KRB5_TYPE_RESPONSE, "Response" },
- { TN_KRB5_TYPE_FORWARD, "Forward" },
- { TN_KRB5_TYPE_FORWARD_ACCEPT, "Forward Accept" },
- { TN_KRB5_TYPE_FORWARD_REJECT, "Forward Reject" },
- { 0, NULL }
-};
-static void
-dissect_authentication_type_pair(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, proto_tree *tree)
-{
- guint8 type, mod;
-
- type=tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_telnet_auth_type, tvb, offset, 1, type);
-
- mod=tvb_get_guint8(tvb, offset+1);
- proto_tree_add_uint(tree, hf_telnet_auth_mod_enc, tvb, offset+1, 1, mod);
- proto_tree_add_boolean(tree, hf_telnet_auth_mod_cred_fwd, tvb, offset+1, 1, mod);
- proto_tree_add_boolean(tree, hf_telnet_auth_mod_how, tvb, offset+1, 1, mod);
- proto_tree_add_boolean(tree, hf_telnet_auth_mod_who, tvb, offset+1, 1, mod);
-}
-
-/* no kerberos blobs are ever >10kb ? (arbitrary limit) */
-#define MAX_KRB5_BLOB_LEN 10240
-
-static tvbuff_t *
-unescape_and_tvbuffify_telnet_option(packet_info *pinfo, tvbuff_t *tvb, int offset, int len)
-{
- tvbuff_t *krb5_tvb;
- guint8 *buf;
- const guint8 *spos;
- guint8 *dpos;
- int skip, l;
-
- if(len>=MAX_KRB5_BLOB_LEN)
- return NULL;
-
- spos=tvb_get_ptr(tvb, offset, len);
- /* XXX we never g_free() this one. This is done automagically
- when the parent tvb is destroyed?
- */
- buf=g_malloc(len);
- dpos=buf;
- skip=0;
- l=len;
- while(l>0){
- if((spos[0]==0xff) && (spos[1]==0xff)){
- skip++;
- l-=2;
- *(dpos++)=0xff;
- spos+=2;
- continue;
- }
- *(dpos++)=*(spos++);
- l--;
- }
- krb5_tvb = tvb_new_real_data(buf, len-skip, len-skip);
- tvb_set_child_real_data_tvbuff(tvb, krb5_tvb);
- add_new_data_source(pinfo, krb5_tvb, "Unpacked Telnet Uption");
-
- return krb5_tvb;
-}
-
-
-/* as per RFC2942 */
-static void
-dissect_krb5_authentication_data(packet_info *pinfo, tvbuff_t *tvb, int offset, int len, proto_tree *tree, guint8 acmd)
-{
- tvbuff_t *krb5_tvb;
- guint8 krb5_cmd;
-
- dissect_authentication_type_pair(pinfo, tvb, offset, tree);
- offset+=2;
- len-=2;
-
-
- krb5_cmd=tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_telnet_auth_krb5_type, tvb, offset, 1, krb5_cmd);
- offset++;
- len--;
-
-
- /* IAC SB AUTHENTICATION IS <authentication-type-pair> AUTH <Kerberos V5 KRB_AP_REQ message> IAC SE */
- if((acmd==TN_AC_IS)&&(krb5_cmd==TN_KRB5_TYPE_AUTH)){
- krb5_tvb=unescape_and_tvbuffify_telnet_option(pinfo, tvb, offset, len);
- if(krb5_tvb)
- dissect_kerberos_main(krb5_tvb, pinfo, tree, FALSE, NULL);
- else
- proto_tree_add_text(tree, tvb, offset, len, "Kerberos blob (too long to dissect - length %u > %u",
- len, MAX_KRB5_BLOB_LEN);
- }
-
-
-
- /* IAC SB AUTHENTICATION REPLY <authentication-type-pair> ACCEPT IAC SE */
- /* nothing more to dissect */
-
-
-
- /* IAC SB AUTHENTICATION REPLY <authentication-type-pair> REJECT <optional reason for rejection> IAC SE*/
-/*qqq*/
-
-
- /* IAC SB AUTHENTICATION REPLY <authentication-type-pair> RESPONSE <KRB_AP_REP message> IAC SE */
- if((acmd==TN_AC_REPLY)&&(krb5_cmd==TN_KRB5_TYPE_RESPONSE)){
- krb5_tvb=unescape_and_tvbuffify_telnet_option(pinfo, tvb, offset, len);
- dissect_kerberos_main(krb5_tvb, pinfo, tree, FALSE, NULL);
- }
-
-
- /* IAC SB AUTHENTICATION <authentication-type-pair> FORWARD <KRB_CRED message> IAC SE */
- /* XXX unclear what this one looks like */
-
-
- /* IAC SB AUTHENTICATION <authentication-type-pair> FORWARD_ACCEPT IAC SE */
- /* nothing more to dissect */
-
-
-
- /* IAC SB AUTHENTICATION <authentication-type-pair> FORWARD_REJECT */
- /* nothing more to dissect */
-}
-
-static void
-dissect_authentication_subopt(packet_info *pinfo, const char *optname _U_, tvbuff_t *tvb, int offset, int len, proto_tree *tree)
-{
- guint8 acmd;
- char name[256];
-
-/* XXX here we should really split it up in a conversation struct keeping
- track of what method we actually use and not just assume it is always
- kerberos v5
-*/
- acmd=tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(tree, hf_telnet_auth_cmd, tvb, offset, 1, acmd);
- offset++;
- len--;
-
- switch(acmd){
- case TN_AC_REPLY:
- case TN_AC_IS:
- /* XXX here we shouldnt just assume it is krb5 */
- dissect_krb5_authentication_data(pinfo, tvb, offset, len, tree, acmd);
- break;
- case TN_AC_SEND:
- while(len>0){
- dissect_authentication_type_pair(pinfo, tvb, offset, tree);
- offset+=2;
- len-=2;
- }
- break;
- case TN_AC_NAME:
- if(len<255){
- tvb_memcpy(tvb, name, offset, len);
- name[len]=0;
- } else {
- strcpy(name, "<...name too long...>");
- }
- proto_tree_add_string(tree, hf_telnet_auth_name, tvb, offset, len, name);
- break;
- }
-}
-
-static tn_opt options[] = {
- {
- "Binary Transmission", /* RFC 856 */
- NULL, /* no suboption negotiation */
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "Echo", /* RFC 857 */
- NULL, /* no suboption negotiation */
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "Reconnection", /* DOD Protocol Handbook */
- NULL,
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "Suppress Go Ahead", /* RFC 858 */
- NULL, /* no suboption negotiation */
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "Approx Message Size Negotiation", /* Ethernet spec(!) */
- NULL,
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "Status", /* RFC 859 */
- &ett_status_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Timing Mark", /* RFC 860 */
- NULL, /* no suboption negotiation */
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "Remote Controlled Trans and Echo", /* RFC 726 */
- &ett_rcte_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Output Line Width", /* DOD Protocol Handbook */
- &ett_olw_subopt,
- VARIABLE_LENGTH, /* XXX - fill me in */
- 0, /* XXX - fill me in */
- NULL /* XXX - fill me in */
- },
- {
- "Output Page Size", /* DOD Protocol Handbook */
- &ett_ops_subopt,
- VARIABLE_LENGTH, /* XXX - fill me in */
- 0, /* XXX - fill me in */
- NULL /* XXX - fill me in */
- },
- {
- "Output Carriage-Return Disposition", /* RFC 652 */
- &ett_crdisp_subopt,
- FIXED_LENGTH,
- 2,
- NULL /* XXX - fill me in */
- },
- {
- "Output Horizontal Tab Stops", /* RFC 653 */
- &ett_htstops_subopt,
- VARIABLE_LENGTH,
- 1,
- dissect_htstops_subopt
- },
- {
- "Output Horizontal Tab Disposition", /* RFC 654 */
- &ett_htdisp_subopt,
- FIXED_LENGTH,
- 2,
- NULL /* XXX - fill me in */
- },
- {
- "Output Formfeed Disposition", /* RFC 655 */
- &ett_ffdisp_subopt,
- FIXED_LENGTH,
- 2,
- NULL /* XXX - fill me in */
- },
- {
- "Output Vertical Tabstops", /* RFC 656 */
- &ett_vtstops_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Output Vertical Tab Disposition", /* RFC 657 */
- &ett_vtdisp_subopt,
- FIXED_LENGTH,
- 2,
- NULL /* XXX - fill me in */
- },
- {
- "Output Linefeed Disposition", /* RFC 658 */
- &ett_lfdisp_subopt,
- FIXED_LENGTH,
- 2,
- NULL /* XXX - fill me in */
- },
- {
- "Extended ASCII", /* RFC 698 */
- &ett_extasc_subopt,
- FIXED_LENGTH,
- 2,
- NULL /* XXX - fill me in */
- },
- {
- "Logout", /* RFC 727 */
- NULL, /* no suboption negotiation */
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "Byte Macro", /* RFC 735 */
- &ett_bytemacro_subopt,
- VARIABLE_LENGTH,
- 2,
- NULL /* XXX - fill me in */
- },
- {
- "Data Entry Terminal", /* RFC 732, RFC 1043 */
- &ett_det_subopt,
- VARIABLE_LENGTH,
- 2,
- NULL /* XXX - fill me in */
- },
- {
- "SUPDUP", /* RFC 734, RFC 736 */
- NULL, /* no suboption negotiation */
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "SUPDUP Output", /* RFC 749 */
- &ett_supdupout_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Send Location", /* RFC 779 */
- &ett_sendloc_subopt,
- VARIABLE_LENGTH,
- 0,
- NULL /* XXX - fill me in */
- },
- {
- "Terminal Type", /* RFC 1091 */
- &ett_termtype_subopt,
- VARIABLE_LENGTH,
- 1,
- dissect_string_subopt
- },
- {
- "End of Record", /* RFC 885 */
- NULL, /* no suboption negotiation */
- NO_LENGTH,
- 0,
- NULL
- },
- {
- "TACACS User Identification", /* RFC 927 */
- &ett_tacacsui_subopt,
- FIXED_LENGTH,
- 4,
- NULL /* XXX - fill me in */
- },
- {
- "Output Marking", /* RFC 933 */
- &ett_outmark_subopt,
- VARIABLE_LENGTH,
- 1,
- dissect_outmark_subopt,
- },
- {
- "Terminal Location Number", /* RFC 946 */
- &ett_tlocnum_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Telnet 3270 Regime", /* RFC 1041 */
- &ett_tn3270reg_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "X.3 PAD", /* RFC 1053 */
- &ett_x3pad_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Negotiate About Window Size", /* RFC 1073, DW183 */
- &ett_naws_subopt,
- FIXED_LENGTH,
- 4,
- dissect_naws_subopt
- },
- {
- "Terminal Speed", /* RFC 1079 */
- &ett_tspeed_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Remote Flow Control", /* RFC 1372 */
- &ett_rfc_subopt,
- FIXED_LENGTH,
- 1,
- dissect_rfc_subopt
- },
- {
- "Linemode", /* RFC 1184 */
- &ett_linemode_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "X Display Location", /* RFC 1096 */
- &ett_xdpyloc_subopt,
- VARIABLE_LENGTH,
- 1,
- dissect_string_subopt
- },
- {
- "Environment Option", /* RFC 1408, RFC 1571 */
- &ett_env_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Authentication Option", /* RFC 2941 */
- &ett_auth_subopt,
- VARIABLE_LENGTH,
- 1,
- dissect_authentication_subopt
- },
- {
- "Encryption Option", /* RFC 2946 */
- &ett_enc_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "New Environment Option", /* RFC 1572 */
- &ett_newenv_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "TN3270E", /* RFC 1647 */
- &ett_tn3270e_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "XAUTH", /* XAUTH */
- &ett_xauth_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "CHARSET", /* CHARSET */
- &ett_charset_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "Remote Serial Port", /* Remote Serial Port */
- &ett_rsp_subopt,
- VARIABLE_LENGTH,
- 1,
- NULL /* XXX - fill me in */
- },
- {
- "COM Port Control", /* RFC 2217 */
- &ett_comport_subopt,
- VARIABLE_LENGTH,
- 1,
- dissect_comport_subopt
- },
-
-};
-
-#define NOPTIONS (sizeof options / sizeof options[0])
-
-static int
-telnet_sub_option(packet_info *pinfo, proto_tree *telnet_tree, tvbuff_t *tvb, int start_offset)
-{
- proto_tree *ti, *option_tree;
- int offset = start_offset;
- guint8 opt_byte;
- int subneg_len;
- const char *opt;
- gint ett;
- int iac_offset;
- guint len;
- void (*dissect)(packet_info *, const char *, tvbuff_t *, int, int, proto_tree *);
- gint cur_offset;
- gboolean iac_found;
-
- offset += 2; /* skip IAC and SB */
-
- /* Get the option code */
- opt_byte = tvb_get_guint8(tvb, offset);
- if (opt_byte > NOPTIONS) {
- opt = "<unknown option>";
- ett = ett_telnet_subopt;
- dissect = NULL;
- } else {
- opt = options[opt_byte].name;
- if (options[opt_byte].subtree_index != NULL)
- ett = *(options[opt_byte].subtree_index);
- else
- ett = ett_telnet_subopt;
- dissect = options[opt_byte].dissect;
- }
- offset++;
-
- /* Search for an unescaped IAC. */
- cur_offset = offset;
- iac_found = FALSE;
- len = tvb_length_remaining(tvb, offset);
- do {
- iac_offset = tvb_find_guint8(tvb, cur_offset, len, TN_IAC);
- iac_found = TRUE;
- if (iac_offset == -1) {
- /* None found - run to the end of the packet. */
- offset += len;
- } else {
- if (((guint)(iac_offset + 1) >= len) ||
- (tvb_get_guint8(tvb, iac_offset + 1) != TN_IAC)) {
- /* We really found a single IAC, so we're done */
- offset = iac_offset;
- } else {
- /*
- * We saw an escaped IAC, so we have to move ahead to the
- * next section
- */
- iac_found = FALSE;
- cur_offset = iac_offset + 2;
- }
- }
-
- } while (!iac_found);
-
- subneg_len = offset - start_offset;
-
- ti = proto_tree_add_text(telnet_tree, tvb, start_offset, subneg_len,
- "Suboption Begin: %s", opt);
- option_tree = proto_item_add_subtree(ti, ett);
- start_offset += 3; /* skip IAC, SB, and option code */
- subneg_len -= 3;
-
- if (subneg_len > 0) {
- switch (options[opt_byte].len_type) {
-
- case NO_LENGTH:
- /* There isn't supposed to *be* sub-option negotiation for this. */
- proto_tree_add_text(option_tree, tvb, start_offset, subneg_len,
- "Bogus suboption data");
- return offset;
-
- case FIXED_LENGTH:
- /* Make sure the length is what it's supposed to be. */
- if (subneg_len != options[opt_byte].optlen) {
- proto_tree_add_text(option_tree, tvb, start_offset, subneg_len,
- "Suboption parameter length is %d, should be %d",
- subneg_len, options[opt_byte].optlen);
- return offset;
- }
- break;
-
- case VARIABLE_LENGTH:
- /* Make sure the length is greater than the minimum. */
- if (subneg_len < options[opt_byte].optlen) {
- proto_tree_add_text(option_tree, tvb, start_offset, subneg_len,
- "Suboption parameter length is %d, should be at least %d",
- subneg_len, options[opt_byte].optlen);
- return offset;
- }
- break;
- }
-
- /* Now dissect the suboption parameters. */
- if (dissect != NULL) {
- /* We have a dissector for this suboption's parameters; call it. */
- (*dissect)(pinfo, opt, tvb, start_offset, subneg_len, option_tree);
- } else {
- /* We don't have a dissector for them; just show them as data. */
- proto_tree_add_text(option_tree, tvb, start_offset, subneg_len,
- "Option data");
- }
- }
- return offset;
-}
-
-static int
-telnet_will_wont_do_dont(proto_tree *telnet_tree, tvbuff_t *tvb,
- int start_offset, char *type)
-{
- int offset = start_offset;
- guint8 opt_byte;
- const char *opt;
-
- offset += 2; /* skip IAC and WILL,WONT,DO,DONT} */
- opt_byte = tvb_get_guint8(tvb, offset);
- if (opt_byte > NOPTIONS)
- opt = "<unknown option>";
- else
- opt = options[opt_byte].name;
- offset++;
-
- proto_tree_add_text(telnet_tree, tvb, start_offset, 3,
- "Command: %s %s", type, opt);
- return offset;
-}
-
-static int
-telnet_command(packet_info *pinfo, proto_tree *telnet_tree, tvbuff_t *tvb, int start_offset)
-{
- int offset = start_offset;
- guchar optcode;
-
- offset += 1; /* skip IAC */
- optcode = tvb_get_guint8(tvb, offset);
- offset++;
- switch(optcode) {
-
- case TN_EOF:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: End of File");
- break;
-
- case TN_SUSP:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Suspend Current Process");
- break;
-
- case TN_ABORT:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Abort Process");
- break;
-
- case TN_EOR:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: End of Record");
- break;
-
- case TN_SE:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Suboption End");
- break;
-
- case TN_NOP:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: No Operation");
- break;
-
- case TN_DM:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Data Mark");
- break;
-
- case TN_BRK:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Break");
- break;
-
- case TN_IP:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Interrupt Process");
- break;
-
- case TN_AO:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Abort Output");
- break;
-
- case TN_AYT:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Are You There?");
- break;
-
- case TN_EC:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Escape Character");
- break;
-
- case TN_EL:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Erase Line");
- break;
-
- case TN_GA:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Go Ahead");
- break;
-
- case TN_SB:
- offset = telnet_sub_option(pinfo, telnet_tree, tvb, start_offset);
- break;
-
- case TN_WILL:
- offset = telnet_will_wont_do_dont(telnet_tree, tvb, start_offset,
- "Will");
- break;
-
- case TN_WONT:
- offset = telnet_will_wont_do_dont(telnet_tree, tvb, start_offset,
- "Won't");
- break;
-
- case TN_DO:
- offset = telnet_will_wont_do_dont(telnet_tree, tvb, start_offset,
- "Do");
- break;
-
- case TN_DONT:
- offset = telnet_will_wont_do_dont(telnet_tree, tvb, start_offset,
- "Don't");
- break;
-
- default:
- proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
- "Command: Unknown (0x%02x)", optcode);
- break;
- }
-
- return offset;
-}
-
-static void
-telnet_add_text(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
-{
- gint next_offset;
- int linelen;
- guint8 c;
- gboolean last_char_was_cr;
-
- while (len != 0 && tvb_offset_exists(tvb, offset)) {
- /*
- * Find the end of the line.
- */
- linelen = tvb_find_line_end(tvb, offset, len, &next_offset, FALSE);
- len -= next_offset - offset; /* subtract out the line's characters */
-
- /*
- * In Telnet, CR NUL is the way you send a CR by itself in the
- * default ASCII mode; don't treat CR by itself as a line ending,
- * treat only CR NUL, CR LF, or LF by itself as a line ending.
- */
- if (next_offset == offset + linelen + 1 && len >= 1) {
- /*
- * Well, we saw a one-character line ending, so either it's a CR
- * or an LF; we have at least two characters left, including the
- * CR.
- *
- * If the line ending is a CR, skip all subsequent CRs; at
- * least one capture appeared to have multiple CRs at the end of
- * a line.
- */
- if (tvb_get_guint8(tvb, offset + linelen) == '\r') {
- last_char_was_cr = TRUE;
- while (len != 0 && tvb_offset_exists(tvb, next_offset)) {
- c = tvb_get_guint8(tvb, next_offset);
- next_offset++; /* skip over that character */
- len--;
- if (c == '\n' || (c == '\0' && last_char_was_cr)) {
- /*
- * LF is a line ending, whether preceded by CR or not.
- * NUL is a line ending if preceded by CR.
- */
- break;
- }
- last_char_was_cr = (c == '\r');
- }
- }
- }
-
- /*
- * Now compute the length of the line *including* the end-of-line
- * indication, if any; we display it all.
- */
- linelen = next_offset - offset;
-
- proto_tree_add_text(tree, tvb, offset, linelen,
- "Data: %s",
- tvb_format_text(tvb, offset, linelen));
- offset = next_offset;
- }
-}
-
-static void
-dissect_telnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- proto_tree *telnet_tree, *ti;
-
-
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "TELNET");
-
- if (check_col(pinfo->cinfo, COL_INFO))
- col_add_fstr(pinfo->cinfo, COL_INFO, "Telnet Data ...");
-
- if (tree) {
- gint offset = 0;
- guint len;
- int data_len;
- gint iac_offset;
-
- ti = proto_tree_add_item(tree, proto_telnet, tvb, offset, -1, FALSE);
- telnet_tree = proto_item_add_subtree(ti, ett_telnet);
-
- /*
- * Scan through the buffer looking for an IAC byte.
- */
- while ((len = tvb_length_remaining(tvb, offset)) > 0) {
- iac_offset = tvb_find_guint8(tvb, offset, len, TN_IAC);
- if (iac_offset != -1) {
- /*
- * We found an IAC byte.
- * If there's any data before it, add that data to the
- * tree, a line at a time.
- */
- data_len = iac_offset - offset;
- if (data_len > 0)
- telnet_add_text(telnet_tree, tvb, offset, data_len);
-
- /*
- * Now interpret the command.
- */
- offset = telnet_command(pinfo, telnet_tree, tvb, iac_offset);
- }
- else {
- /*
- * We found no IAC byte, so what remains in the buffer
- * is the last of the data in the packet.
- * Add it to the tree, a line at a time, and then quit.
- */
- telnet_add_text(telnet_tree, tvb, offset, len);
- break;
- }
- }
- }
-}
-
-void
-proto_register_telnet(void)
-{
- static hf_register_info hf[] = {
- { &hf_telnet_auth_name,
- { "Name", "telnet.auth.name", FT_STRING, BASE_NONE,
- NULL, 0, "Name of user being authenticated", HFILL }},
- { &hf_telnet_auth_cmd,
- { "Auth Cmd", "telnet.auth.cmd", FT_UINT8, BASE_DEC,
- VALS(auth_cmd_vals), 0, "Authentication Command", HFILL }},
- { &hf_telnet_auth_type,
- { "Auth Type", "telnet.auth.type", FT_UINT8, BASE_DEC,
- VALS(auth_type_vals), 0, "Authentication Type", HFILL }},
- { &hf_telnet_auth_mod_cred_fwd,
- { "Cred Fwd", "telnet.auth.mod.cred_fwd", FT_BOOLEAN, 8,
- TFS(&auth_mod_cred_fwd), 0x08, "Modifier: Whether client will forward creds or not", HFILL }},
- { &hf_telnet_auth_mod_who,
- { "Who", "telnet.auth.mod.who", FT_BOOLEAN, 8,
- TFS(&auth_mod_who), 0x01, "Modifier: Who to mask", HFILL }},
- { &hf_telnet_auth_mod_how,
- { "How", "telnet.auth.mod.how", FT_BOOLEAN, 8,
- TFS(&auth_mod_how), 0x02, "Modifier: How to mask", HFILL }},
- { &hf_telnet_auth_mod_enc,
- { "Encrypt", "telnet.auth.mod.enc", FT_UINT8, BASE_DEC,
- VALS(auth_mod_enc), 0x14, "Modifier: How to enable Encryption", HFILL }},
- { &hf_telnet_auth_krb5_type,
- { "Command", "telnet.auth.krb5.cmd", FT_UINT8, BASE_DEC,
- VALS(auth_krb5_types), 0, "Krb5 Authentication sub-command", HFILL }},
-
- };
- static gint *ett[] = {
- &ett_telnet,
- &ett_telnet_subopt,
- &ett_status_subopt,
- &ett_rcte_subopt,
- &ett_olw_subopt,
- &ett_ops_subopt,
- &ett_crdisp_subopt,
- &ett_htstops_subopt,
- &ett_htdisp_subopt,
- &ett_ffdisp_subopt,
- &ett_vtstops_subopt,
- &ett_vtdisp_subopt,
- &ett_lfdisp_subopt,
- &ett_extasc_subopt,
- &ett_bytemacro_subopt,
- &ett_det_subopt,
- &ett_supdupout_subopt,
- &ett_sendloc_subopt,
- &ett_termtype_subopt,
- &ett_tacacsui_subopt,
- &ett_outmark_subopt,
- &ett_tlocnum_subopt,
- &ett_tn3270reg_subopt,
- &ett_x3pad_subopt,
- &ett_naws_subopt,
- &ett_tspeed_subopt,
- &ett_rfc_subopt,
- &ett_linemode_subopt,
- &ett_xdpyloc_subopt,
- &ett_env_subopt,
- &ett_auth_subopt,
- &ett_enc_subopt,
- &ett_newenv_subopt,
- &ett_tn3270e_subopt,
- &ett_xauth_subopt,
- &ett_charset_subopt,
- &ett_rsp_subopt,
- &ett_comport_subopt,
- };
-
- proto_telnet = proto_register_protocol("Telnet", "TELNET", "telnet");
- proto_register_field_array(proto_telnet, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
-}
-
-void
-proto_reg_handoff_telnet(void)
-{
- dissector_handle_t telnet_handle;
-
- telnet_handle = create_dissector_handle(dissect_telnet, proto_telnet);
- dissector_add("tcp.port", TCP_PORT_TELNET, telnet_handle);
-}