-/* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */
+/* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* are preserved in all copies.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+/* \summary: Telnet option printer */
+
+#include <config.h>
-#include <tcpdump-stdinc.h>
+#include "netdissect-stdinc.h"
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "interface.h"
+#include "netdissect.h"
+#include "extract.h"
-#define TELCMDS
-#define TELOPTS
-/* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */
+/* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */
/*
* Definitions for the TELNET protocol.
#define SYNCH 242 /* for telfunc calls */
-#ifdef TELCMDS
-const char *telcmds[] = {
+static const char *telcmds[] = {
"EOF", "SUSP", "ABORT", "EOR",
"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
};
-#else
-extern char *telcmds[];
-#endif
#define TELCMD_FIRST xEOF
#define TELCMD_LAST IAC
#define TELOPT_STATUS 5 /* give status */
#define TELOPT_TM 6 /* timing mark */
#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
-#define TELOPT_NAOL 8 /* negotiate about output line width */
-#define TELOPT_NAOP 9 /* negotiate about output page size */
+#define TELOPT_NAOL 8 /* negotiate about output line width */
+#define TELOPT_NAOP 9 /* negotiate about output page size */
#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
-#define TELOPT_XASCII 17 /* extended ascic character set */
+#define TELOPT_XASCII 17 /* extended ascii character set */
#define TELOPT_LOGOUT 18 /* force logout */
#define TELOPT_BM 19 /* byte macro */
#define TELOPT_DET 20 /* data entry terminal */
#define NTELOPTS (1+TELOPT_NEW_ENVIRON)
-#ifdef TELOPTS
-const char *telopts[NTELOPTS+1] = {
+static const char *telopts[NTELOPTS+1] = {
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
#define TELOPT_LAST TELOPT_NEW_ENVIRON
#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
-#endif
/* sub-option qualifiers */
#define TELQUAL_IS 0 /* option is... */
/* sp points to IAC byte */
static int
-telnet_parse(const u_char *sp, u_int length, int print)
+telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print)
{
int i, x;
u_int c;
do { \
if (length < 1) \
goto pktend; \
- TCHECK(*sp); \
- c = *sp++; \
+ c = GET_U_1(sp); \
+ sp++; \
length--; \
} while (0)
FETCH(c, sp, length);
if (c == IAC) { /* <IAC><IAC>! */
if (print)
- printf("IAC IAC");
+ ND_PRINT("IAC IAC");
goto done;
}
FETCH(x, sp, length);
if (x >= 0 && x < NTELOPTS) {
if (print)
- (void)printf("%s %s", telcmds[i], telopts[x]);
+ ND_PRINT("%s %s", telcmds[i], telopts[x]);
} else {
if (print)
- (void)printf("%s %#x", telcmds[i], x);
+ ND_PRINT("%s %#x", telcmds[i], x);
}
if (c != SB)
break;
/* IAC SB .... IAC SE */
p = sp;
while (length > (u_int)(p + 1 - sp)) {
- if (p[0] == IAC && p[1] == SE)
+ if (GET_U_1(p) == IAC && GET_U_1(p + 1) == SE)
break;
p++;
}
- if (*p != IAC)
+ if (GET_U_1(p) != IAC)
goto pktend;
switch (x) {
break;
FETCH(c, sp, length);
if (print)
- (void)printf(" %s", STR_OR_ID(c, authcmd));
+ ND_PRINT(" %s", STR_OR_ID(c, authcmd));
if (p <= sp)
break;
FETCH(c, sp, length);
if (print)
- (void)printf(" %s", STR_OR_ID(c, authtype));
+ ND_PRINT(" %s", STR_OR_ID(c, authtype));
break;
case TELOPT_ENCRYPT:
if (p <= sp)
break;
FETCH(c, sp, length);
if (print)
- (void)printf(" %s", STR_OR_ID(c, enccmd));
+ ND_PRINT(" %s", STR_OR_ID(c, enccmd));
if (p <= sp)
break;
FETCH(c, sp, length);
if (print)
- (void)printf(" %s", STR_OR_ID(c, enctype));
+ ND_PRINT(" %s", STR_OR_ID(c, enctype));
break;
default:
if (p <= sp)
break;
FETCH(c, sp, length);
if (print)
- (void)printf(" %s", STR_OR_ID(c, cmds));
+ ND_PRINT(" %s", STR_OR_ID(c, cmds));
break;
}
while (p > sp) {
FETCH(x, sp, length);
if (print)
- (void)printf(" %#x", x);
+ ND_PRINT(" %#x", x);
}
/* terminating IAC SE */
if (print)
- (void)printf(" SE");
+ ND_PRINT(" SE");
sp += 2;
- length -= 2;
break;
default:
if (print)
- (void)printf("%s", telcmds[i]);
+ ND_PRINT("%s", telcmds[i]);
goto done;
}
done:
- return sp - osp;
+ return (int)(sp - osp);
-trunc:
- (void)printf("[|telnet]");
pktend:
return -1;
#undef FETCH
}
void
-telnet_print(const u_char *sp, u_int length)
+telnet_print(netdissect_options *ndo, const u_char *sp, u_int length)
{
int first = 1;
const u_char *osp;
int l;
+ ndo->ndo_protocol = "telnet";
osp = sp;
- while (length > 0 && *sp == IAC) {
- l = telnet_parse(sp, length, 0);
+ while (length > 0 && GET_U_1(sp) == IAC) {
+ /*
+ * Parse the Telnet command without printing it,
+ * to determine its length.
+ */
+ l = telnet_parse(ndo, sp, length, 0);
if (l < 0)
break;
/*
* now print it
*/
- if (Xflag && 2 < vflag) {
+ if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag) {
if (first)
- printf("\nTelnet:");
- hex_print_with_offset(gndo,"\n", sp, l, sp - osp);
+ ND_PRINT("\nTelnet:");
+ hex_print_with_offset(ndo, "\n", sp, l, (u_int)(sp - osp));
if (l > 8)
- printf("\n\t\t\t\t");
+ ND_PRINT("\n\t\t\t\t");
else
- printf("%*s\t", (8 - l) * 3, "");
+ ND_PRINT("%*s\t", (8 - l) * 3, "");
} else
- printf("%s", (first) ? " [telnet " : ", ");
+ ND_PRINT("%s", (first) ? " [telnet " : ", ");
- (void)telnet_parse(sp, length, 1);
+ (void)telnet_parse(ndo, sp, length, 1);
first = 0;
sp += l;
length -= l;
}
if (!first) {
- if (Xflag && 2 < vflag)
- printf("\n");
+ if (ndo->ndo_Xflag && 2 < ndo->ndo_vflag)
+ ND_PRINT("\n");
else
- printf("]");
+ ND_PRINT("]");
}
}