Dosbox-staging: Telnet support enablement for "softmodem" serial ports

Created on 28 Aug 2020  ·  9Comments  ·  Source: dosbox-staging/dosbox-staging

I was often asked why DOS terminal programs would fail to download files from BBSes when using DOSBox (e.g. using traditional serial/modem transfer protocols like XMODEM, YMODEM, ZMODEM). I'd seen it reported and confirmed that when a "serialX" port is configured in a DOSBox .conf as device of type "modem", that it does indeed, by default, not support Telnet. It may appear to support Telnet as it'll connect to Telnet servers, but it won't actually escape sent-IAC characters, unescape received-IAC characters or recognize or respond to Telnet commands. The "nullmodem" devicetype does support a "telnet:1" parameter to enable Telnet support, but that's not really helpful to those attempting to use DOS terminals to connect to Telnet BBSes on the Internet.

I looked through the DOSBox Wiki and Manual and really could find nothing about enabling Telnet support for "modem" (softmodem) serial devices. So I looked through the DOSBox source code and foudn this little bit of code in softmodem.cpp:

else if (strstr(cmdbuf,"NET1")) {
                telnetmode = true;
                SendRes(ResOK);
                return;
        }

That's some interesting code there. So if the 4 characters "NET1" appear _anywhere_ in _any_ AT command received by this softmodem, it'll enable Telnet support and then immediately stop parsing the command and return "OK". That's pretty terrible AT command parsing there (what if "NET1" happens to be in the hostname you're trying to connect to?), but whatever. I tried typing "ATNET1", and indeed it works: the next connection using "ATD..." did indeed support Telnet.

So...

  1. Please document this ATNET0/1 command (1 to turn Telnet support on 0, to turn if off).
  2. Please fix the AT command parser: strstr() is almost never what you actually want to use.
  3. Please support the "telnet:1" option in the .conf file to enable telnet suport for "modem" devices by default.

Happy to discuss further,

Thanks, BBS users and sysops thank you.

bug

All 9 comments

Thanks for issues in the softmodem code @rswindell.

Please document this ATNET0/1 command

We do mention the NET1 command in README (see below), however perhaps it could be improved.

In github, you can 'fork this project', edit the README directly in your fork (using Github's web editor), and then push your change back to us. Your help in documenting this thoroughly would be appreciated!

BBS Gaming
----------
DOSBox's serial interface can emulate a telephone modem, which allows original
DOS terminal applications to either dial or host a BBS on the Internet 
via the Telnet protocol.

First, configure DOSBox with a serial port emulating a modem:

   [serial]
   serial1 = modem listenport:2323

Next, launch your favorite DOS terminal or BBS hosting software and configure
its corresponding serial port with default settings, as follows:

  COM1:
    - COM port 1
    - 8N1 data-bits, stop-bits, and parity
    - 57600 baud
    - 03F8 address
    - IRQ4 interrupt
    - 16550 fifo enabled
    - Software flow control (Xon/Xoff) enabled
    - Hardware flow control (CTS/RTS) enabled
    - Hardware flow control (DSR/DTR) disabled

To dial BBSes on the Internet:

  1) Set your dialing prefix to: ATNET1^MATDT to ensure file-transfers
     and command mode transitions and handled properly.

  2) Set the phone number of the BBS to its hostname or IP, optionally
     followed by the Telnet port number, for example:

      - Phone number on non-standard port: remote.bbs.com:2323
      - Phone number on standard port 23: remote.bbs.com

To host a DOS-based BBS:

 1) Configure your DOSBox serial port to listen on a Telnet port greater
    than 1024. This allows you to run DOSbox with normal user privileges
    as opposed to granting it root or administrator privileges, for example:

    [serial]
    serial1 = modem listenport:2323

 2) Configure your DOSBox machine to use a static IP address or be assigned
    a static IP via DHCP, which can typically be configured in your router.

 3) If your DOSBox machine is behind a router/firewall, add a port-
    fowarding entry to listen on TCP port 23 and pass it through to
    port 2323 to your DOSBox machine's IP address.  This allows Internet
    users to "dial" your BBS using the default Telnet port.

Please fix the AT command parser: strstr() is almost never what you actually want to use.

What do you suggest we replace strstr() with to similarly detect this substring inside a (char*) stream?

Please support the "telnet:1" option in the .conf file to enable telnet suport for "modem" devices by default.

Sounds like a good suggestion. So this would "default" the device as if NET1 was set from the get-go?

What do you suggest we replace strstr() with to similarly detect this substring inside a (char*) stream?

AT command parsing should be from left-to-right, supporting multiple commands in the same string (multple commands may exist between the "AT" and the '\r'). The way the AT command parser in DOSbox is written today, you cannot connect to any hostname with "net0" or "net1" anywhere within it. e.g. "ATD net1.vert.synchro.net" is treated as though it was just "ATNET1", which is clearly wrong (no dial/connect is attempted). A fix would consist of more than simply replacing strstr() with some other function call.

Sounds like a good suggestion. So this would "default" the device as if NET1 was set from the get-go?

The ask here is: if the "telnet:1" option is present in the .conf file, DOSbox softmodem would behave the same as if the "NET1" AT-command were set from the get-go.

Currently, the "telnet:1" option is only supported for the "nullmodem" devicetype.

When the 'D' command is received by a Hayes compatible modem, everything after (and before the '\r') is treated as the dial-pattern (e.g. phone number, IP address, hostname). The problem with using strstr() in this case is that it skips (ignores) everything before the pattern you're searching for so you don't know if the pattern was the argument to a command or the command itself. The command parser need to process all the commands following the "AT", in order (from left to right), and for any commands which will terminate the parsing (e.g. the 'D' command), terminate once the command is processed.

The problem with the way the "NET0" or "NET1" command parsing is implemented in DOSbox isn't unique to the "D" command, I was just using that as an example. Any AT commands coming before or after the "NET0" or "NET1" in the command string are also ignored.

A Hayes compatible modem can process commands like "AT&F&C1&D2S95=3Ddial-pattern\r". The DOSbox softmodem AT command processor doesn't support any other commands being included in the same command string as either the "NET0" or "NET1" and even worse, if those strings happen to appear in a command argument (for example, a dial-pattern to the 'D' command), the parser treats the string as a command. e.g. "AT Dnet1.vert.synchro.net" does not work as it should.

Thanks for the thorough explanation @rswindell!

@rswindell , when you have a chance, please compile and test branch kc/modem-toggles-1 or test the binaries above, and let us know what you think.

You should be able to enable telnet-mode for a given serial softmodem in the config file using the proposed telnet:1 flag.

Telnet-mode can now be toggled via the AT commands: +NET1 and +NET0.

Telnet-mode mode persists across resets (ATZ), and will stay in the mode you've set it to. Dosbox's console output will report when the telnet-mode changes.

The runtime switching of telnet-mode using +NET1 (or 0) can now be part of a multi-AT command set, and it will not influence the dial-string.
For example, the following should work as expected:

ATI3+NET1Dmyhost.NET0test.org

The README file has been updated; let us know if it looks OK or how it should change to further improve the description.

Curious if this works as expected for you!

@rswindell Thank you so much for the bug report and detailed explanations :) Issue got closed automatically the moment I merged #582 to master.

When you'll have a moment, please test and tell us if everything is now in order :) If you'll find some fault or something missing - simply comment here and I'll reopen the issue (or simply create a new one).

This feature will be released in upcoming 0.76.0 version, but until then it can be tested in our development builds: link to the newest development ones are here: https://dosbox-staging.github.io/downloads/devel/

Thank you guys for the quick and thorough response.

I tested dosbox-staging version v0.76.0-alpha-690-g21a5 today and indeed, the "telnet:1" option in the .conf file works and the AT "+NET1" and "+NET0" commands work.

Only one observation there, and I don't know if it actually matters, but "AT+" commands are usually of the form "AT+[word]=[value]" - so to be consistent with that syntax, the DOSbox telnet commands would be "AT+NET=0" or "AT+NET=1". It probably doesn't actually matter however, but just thought I'd mention it.

Great work guys!

Thanks for the tests @rswindell!

Indeed.. I had also thought about the = (seeing other examples), but wanted to minimize the amount of syntax (and code) changes needed to implement this in hopes of upstream adopting this. If all DOSBox's out there can make this switch then that will provide a consistent experience for users.

Was this page helpful?
0 / 5 - 0 ratings