]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
Add baud rate support to telnet(1)
authorngie <ngie@FreeBSD.org>
Tue, 11 Nov 2014 04:06:05 +0000 (04:06 +0000)
committerngie <ngie@FreeBSD.org>
Tue, 11 Nov 2014 04:06:05 +0000 (04:06 +0000)
This implements part of RFC-2217

It's based off a patch originally written by Sujal Patel at Isilon, and
contributions from other Isilon employees.

PR: 173728
Phabric: D995
Reviewed by: markj, markm
MFC after: 2 weeks
Sponsored by: EMC / Isilon Storage Division

12 files changed:
contrib/telnet/arpa/telnet.h
contrib/telnet/telnet/baud.h [new file with mode: 0644]
contrib/telnet/telnet/commands.c
contrib/telnet/telnet/externs.h
contrib/telnet/telnet/main.c
contrib/telnet/telnet/sys_bsd.c
contrib/telnet/telnet/telnet.1
contrib/telnet/telnet/telnet.c
contrib/telnet/telnet/types.h
contrib/telnet/telnetd/sys_term.c
contrib/tzcode/stdtime/localtime.c
libexec/telnetd/Makefile

index 26f75fb3130386d42c8266c01dc859d85c6f8990..b028a1df794d94158caef665b5dcae645b3e1b2f 100644 (file)
@@ -127,6 +127,7 @@ extern char *telcmds[];
 #define        TELOPT_KERMIT   47      /* RFC2840 - Kermit */
 #define        TELOPT_EXOPL    255     /* extended-options-list */
 
+#define        COMPORT_SET_BAUDRATE    1       /* RFC2217 - Com Port Set Baud Rate */
 
 #define        NTELOPTS        (1+TELOPT_KERMIT)
 #ifdef TELOPTS
diff --git a/contrib/telnet/telnet/baud.h b/contrib/telnet/telnet/baud.h
new file mode 100644 (file)
index 0000000..c422535
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2014 EMC Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD).
+ */
+#if B4800 != 4800
+#define        DECODE_BAUD
+#endif
+
+#ifdef DECODE_BAUD
+#ifndef        B7200
+#define B7200   B4800
+#endif
+
+#ifndef        B14400
+#define B14400  B9600
+#endif
+
+#ifndef        B19200
+#define B19200  B14400
+#endif
+
+#ifndef        B28800
+#define B28800  B19200
+#endif
+
+#ifndef        B38400
+#define B38400  B28800
+#endif
+
+#ifndef B57600
+#define B57600  B38400
+#endif
+
+#ifndef B76800
+#define B76800  B57600
+#endif
+
+#ifndef B115200
+#define B115200 B76800
+#endif
+
+#ifndef B115200
+#define B115200 B76800
+#endif
+#endif
+
+#ifndef B230400
+#define B230400 B115200
+#endif
+
+/*
+ * A table of available terminal speeds
+ */
+struct termspeeds termspeeds[] = {
+       { 0,      B0 },
+       { 50,     B50 },
+       { 75,     B75 },
+       { 110,    B110 },
+       { 134,    B134 },
+       { 150,    B150 },
+       { 200,    B200 },
+       { 300,    B300 },
+       { 600,    B600 },
+       { 1200,   B1200 },
+       { 1800,   B1800 },
+       { 2400,   B2400 },
+       { 4800,   B4800 },
+#ifdef B7200
+       { 7200,   B7200 },
+#endif
+       { 9600,   B9600 },
+#ifdef B14400
+       { 14400,  B14400 },
+#endif
+#ifdef B19200
+       { 19200,  B19200 },
+#endif
+#ifdef B28800
+       { 28800,  B28800 },
+#endif
+#ifdef B38400
+       { 38400,  B38400 },
+#endif
+#ifdef B57600
+       { 57600,  B57600 },
+#endif
+#ifdef B115200
+       { 115200, B115200 },
+#endif
+#ifdef B230400
+       { 230400, B230400 },
+#endif
+       { -1,     0 }
+};
index c39b18744cae1cb81b78b527d75a03a92e25e61c..74cce6d5dedcdabd7b5fb232225683a88b804e19 100644 (file)
@@ -896,6 +896,7 @@ static struct setlist Setlist[] = {
     { "forw1", "alternate end of line character", NULL, termForw1Charp },
     { "forw2", "alternate end of line character", NULL, termForw2Charp },
     { "ayt",   "alternate AYT character", NULL, termAytCharp },
+    { "baudrate", "set remote baud rate", DoBaudRate, ComPortBaudRate },
     { NULL, NULL, NULL, NULL }
 };
 
index e07aebbdb82800676176c39ce0857f10087bb7c8..d42bddd4cd0993d1a7aa9b32a4ef803a7adcbbc8 100644 (file)
@@ -231,6 +231,10 @@ extern unsigned char
     NetTraceFile[];    /* Name of file where debugging output goes */
 extern void
     SetNetTrace(char *);       /* Function to change where debugging goes */
+extern unsigned char
+    ComPortBaudRate[]; /* Baud rate of the remote end */
+extern void
+    DoBaudRate(char *);        /* Function to set the baud rate of the remote end */
 
 extern jmp_buf
     toplevel;          /* For error conditions. */
@@ -475,6 +479,16 @@ extern cc_t termAytChar;
 # endif
 #endif
 
+typedef struct {
+    int
+       system,                 /* what the current time is */
+       echotoggle,             /* last time user entered echo character */
+       modenegotiated,         /* last time operating mode negotiated */
+       didnetreceive,          /* last time we read data from network */
+       gotDM;                  /* when did we last see a data mark */
+} Clocks;
+
+extern Clocks clocks;
 
 /* Ring buffer structures which are shared */
 
index f6eb1ffb08ef1381dc9392500921055a9288b67c..1ddec8256a071027bf7ef18dfe7801c9c0e651ed 100644 (file)
@@ -91,10 +91,10 @@ usage(void)
        fprintf(stderr, "usage: %s %s%s%s%s\n",
            prompt,
 #ifdef AUTHENTICATION
-           "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-c] [-d]",
-           "\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
+           "[-4] [-6] [-8] [-B baudrate] [-E] [-K] [-L] [-N] [-S tos] [-X atype]",
+           "\n\t[-c] [-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
 #else
-           "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-c] [-d]",
+           "[-4] [-6] [-8] [-B baudrate] [-E] [-L] [-N] [-S tos] [-c] [-d]",
            "\n\t[-e char] [-l user] [-n tracefile] ",
 #endif
            "[-r] [-s src_addr] [-u] ",
@@ -154,7 +154,7 @@ main(int argc, char *argv[])
 #define IPSECOPT
 #endif
        while ((ch = getopt(argc, argv,
-                           "468EKLNS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1)
+                           "468B:EKLNS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1)
 #undef IPSECOPT
        {
                switch(ch) {
@@ -169,6 +169,9 @@ main(int argc, char *argv[])
                case '8':
                        eight = 3;      /* binary output and input */
                        break;
+               case 'B':
+                       DoBaudRate(optarg);
+                       break;
                case 'E':
                        rlogin = escape = _POSIX_VDISABLE;
                        break;
index 9fba74feada9d5175dbb496f97a12a931853da3a..32f84bf85e4921a990305bf5c130398d6681f141 100644 (file)
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
 #include "defines.h"
 #include "externs.h"
 #include "types.h"
+#include "baud.h"
 
 int
        tout,                   /* Output file descriptor */
@@ -682,71 +683,6 @@ TerminalNewMode(int f)
 
 }
 
-/*
- * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD).
- */
-#if B4800 != 4800
-#define        DECODE_BAUD
-#endif
-
-#ifdef DECODE_BAUD
-#ifndef        B7200
-#define B7200   B4800
-#endif
-
-#ifndef        B14400
-#define B14400  B9600
-#endif
-
-#ifndef        B19200
-# define B19200 B14400
-#endif
-
-#ifndef        B28800
-#define B28800  B19200
-#endif
-
-#ifndef        B38400
-# define B38400 B28800
-#endif
-
-#ifndef B57600
-#define B57600  B38400
-#endif
-
-#ifndef B76800
-#define B76800  B57600
-#endif
-
-#ifndef B115200
-#define B115200 B76800
-#endif
-
-#ifndef B230400
-#define B230400 B115200
-#endif
-
-
-/*
- * This code assumes that the values B0, B50, B75...
- * are in ascending order.  They do not have to be
- * contiguous.
- */
-struct termspeeds {
-       long speed;
-       long value;
-} termspeeds[] = {
-       { 0,      B0 },      { 50,    B50 },    { 75,     B75 },
-       { 110,    B110 },    { 134,   B134 },   { 150,    B150 },
-       { 200,    B200 },    { 300,   B300 },   { 600,    B600 },
-       { 1200,   B1200 },   { 1800,  B1800 },  { 2400,   B2400 },
-       { 4800,   B4800 },   { 7200,  B7200 },  { 9600,   B9600 },
-       { 14400,  B14400 },  { 19200, B19200 }, { 28800,  B28800 },
-       { 38400,  B38400 },  { 57600, B57600 }, { 115200, B115200 },
-       { 230400, B230400 }, { -1,    B230400 }
-};
-#endif /* DECODE_BAUD */
-
 void
 TerminalSpeeds(long *ispeed, long *ospeed)
 {
index 2dce4c51dd55619100ba5d9f12075e339930997d..f55c62e87296f49d8d4f4b937cb2816a8aee99d5 100644 (file)
@@ -43,6 +43,7 @@ protocol
 .Sh SYNOPSIS
 .Nm
 .Op Fl 468EFKLNacdfruxy
+.Op Fl B Ar baudrate
 .Op Fl S Ar tos
 .Op Fl X Ar authtype
 .Op Fl e Ar escapechar
@@ -89,6 +90,9 @@ This causes an attempt to
 negotiate the
 .Dv TELNET BINARY
 option on both input and output.
+.It Fl B Ar baudrate
+Sets the baud rate to
+.Ar baudrate .
 .It Fl E
 Stops any character from being recognized as an escape character.
 .It Fl F
index 8c457cf613d257a62bdb0d86bac4d2a8423b9119..80f43b2fc0af85ec6f2f30430f3259b18924e409 100644 (file)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #include <stdlib.h>
 #include <term.h>
 #include <unistd.h>
+#include <arpa/inet.h>
 #include <arpa/telnet.h>
 
 #include "ring.h"
@@ -68,7 +69,7 @@ __FBSDID("$FreeBSD$");
 #include <libtelnet/encrypt.h>
 #endif
 #include <libtelnet/misc.h>
-\f
+
 #define        strip(x) ((my_want_state_is_wont(TELOPT_BINARY)) ? ((x)&0x7f) : (x))
 
 static unsigned char   subbuffer[SUBBUFSIZE],
@@ -162,7 +163,7 @@ static int is_unique(char *, char **, char **);
  */
 
 Clocks clocks;
-\f
+
 /*
  * Initialize telnet environment.
  */
@@ -196,7 +197,7 @@ init_telnet(void)
     flushline = 1;
     telrcv_state = TS_DATA;
 }
-\f
+
 
 /*
  * These routines are in charge of sending option negotiations
@@ -206,6 +207,42 @@ init_telnet(void)
  * is in disagreement as to what the current state should be.
  */
 
+unsigned char ComPortBaudRate[256];
+
+void
+DoBaudRate(char *arg)
+{
+    char *temp, temp2[10];
+    int i;
+    uint32_t baudrate;
+
+    errno = 0;
+    baudrate = (uint32_t)strtol(arg, &temp, 10);
+    if (temp[0] != '\0' || (baudrate == 0 && errno != 0))
+       ExitString("Invalid baud rate provided.\n", 1);
+
+    for (i = 1; termspeeds[i].speed != -1; i++)
+       if (baudrate == termspeeds[i].speed)
+           break;
+    if (termspeeds[i].speed == -1)
+       ExitString("Invalid baud rate provided.\n", 1);
+
+    strlcpy(ComPortBaudRate, arg, sizeof(ComPortBaudRate));
+
+    if (NETROOM() < sizeof(temp2)) {
+       ExitString("No room in buffer for baud rate.\n", 1);
+       /* NOTREACHED */
+    }
+
+    snprintf(temp2, sizeof(temp2), "%c%c%c%c....%c%c", IAC, SB, TELOPT_COMPORT,
+       COMPORT_SET_BAUDRATE, IAC, SE);
+
+    baudrate = htonl(baudrate);
+    memcpy(&temp2[4], &baudrate, sizeof(baudrate));
+    ring_supply_data(&netoring, temp2, sizeof(temp2));
+    printsub('>', &temp[2], sizeof(temp2) - 2);
+}
+
 void
 send_do(int c, int init)
 {
@@ -1084,7 +1121,7 @@ lm_mode(unsigned char *cmd, int len, int init)
        setconnmode(0); /* set changed mode */
 }
 
-\f
+
 
 /*
  * slc()
@@ -1628,7 +1665,7 @@ env_opt_end(int emptyok)
        }
 }
 
-\f
+
 
 int
 telrcv(void)
@@ -2013,7 +2050,7 @@ telsnd(void)
        ring_consumed(&ttyiring, count);
     return returnValue||count;         /* Non-zero if we did anything */
 }
-\f
+
 /*
  * Scheduler()
  *
index 191d311fd154f5044656d845e48c7ffce1f4a184..4db5292e49d85766fe362b5f619c64a8b7a18483 100644 (file)
@@ -40,13 +40,9 @@ typedef struct {
 
 extern Modelist modelist[];
 
-typedef struct {
-    int
-       system,                 /* what the current time is */
-       echotoggle,             /* last time user entered echo character */
-       modenegotiated,         /* last time operating mode negotiated */
-       didnetreceive,          /* last time we read data from network */
-       gotDM;                  /* when did we last see a data mark */
-} Clocks;
+struct termspeeds {
+    int speed;
+    int value;
+};
 
-extern Clocks clocks;
+extern struct termspeeds termspeeds[];
index 5a9421b1b1508b056e0fd174330f6f9b0f5b1c27..bdc43f6e1a2683eb26dfeb29c2238e56f900c0fb 100644 (file)
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
 
 #include "telnetd.h"
 #include "pathnames.h"
+#include "types.h"
+#include "baud.h"
 
 #ifdef AUTHENTICATION
 #include <libtelnet/auth.h>
@@ -743,56 +745,6 @@ tty_iscrnl(void)
 #endif
 }
 
-/*
- * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD).
- */
-#if B4800 != 4800
-#define        DECODE_BAUD
-#endif
-
-#ifdef DECODE_BAUD
-
-/*
- * A table of available terminal speeds
- */
-struct termspeeds {
-       int     speed;
-       int     value;
-} termspeeds[] = {
-       { 0,      B0 },      { 50,    B50 },    { 75,     B75 },
-       { 110,    B110 },    { 134,   B134 },   { 150,    B150 },
-       { 200,    B200 },    { 300,   B300 },   { 600,    B600 },
-       { 1200,   B1200 },   { 1800,  B1800 },  { 2400,   B2400 },
-       { 4800,   B4800 },
-#ifdef B7200
-       { 7200,  B7200 },
-#endif
-       { 9600,   B9600 },
-#ifdef B14400
-       { 14400,  B14400 },
-#endif
-#ifdef B19200
-       { 19200,  B19200 },
-#endif
-#ifdef B28800
-       { 28800,  B28800 },
-#endif
-#ifdef B38400
-       { 38400,  B38400 },
-#endif
-#ifdef B57600
-       { 57600,  B57600 },
-#endif
-#ifdef B115200
-       { 115200, B115200 },
-#endif
-#ifdef B230400
-       { 230400, B230400 },
-#endif
-       { -1,     0 }
-};
-#endif /* DECODE_BAUD */
-
 void
 tty_tspeed(int val)
 {
index 9605eeb30e5282bed887b2e81e8a9e82980628b6..51119f552a5534a7f4e0605f0d64a188af72ee88 100644 (file)
@@ -1792,7 +1792,11 @@ int      delta;
 
        number0 = *number;
        *number += delta;
-       return (*number < number0) != (delta < 0);
+       if ((*number < number0) != (delta < 0)) {
+               errno = EOVERFLOW;
+               return (1);
+       }
+       return (0);
 }
 
 static int
@@ -1804,7 +1808,11 @@ int      delta;
 
        number0 = *number;
        *number += delta;
-       return (*number < number0) != (delta < 0);
+       if ((*number < number0) != (delta < 0)) {
+               errno = EOVERFLOW;
+               return (1);
+       }
+       return (0);
 }
 
 static int
index 690b03c7ff95005fdd00bdce6a48d8ab891691a7..07de1970471ee870b475550e65ebf48a71899040 100644 (file)
@@ -25,6 +25,7 @@ CFLAGS+=      -DINET6
 .endif
 
 CFLAGS+=       -I${TELNETDIR}
+CFLAGS+=       -I${TELNETDIR}/telnet
 
 LIBTELNET=     ${.OBJDIR}/../../lib/libtelnet/libtelnet.a