PiModem project

I recently got a Mac IIci and wanted to be able to use it to connect to BBSes, and hopefully, the Internet.

I found a couple of options which used SLiRP, but they weren't quite what I was wanted as they're a bit finnicky and would often got stuck in a state where the client computer couldn't resume or restart the session without me pulling out my laptop and SSHing into the Raspberry PI.

I then found the PiModem Project which is exactly what I wanted, and after some tweaking works great. The instructions are mostly complete and accurate, but time moves on and package names change and software updates require modest configuration changes. Most of what's here came from them, with a few changes to make it work on current Raspbian install.

I used a USB serial adapter, since I have about 20 of the things, so I was able to skip right to software installation.

I pulled a "new" version of tcpser from git, and build that version.

cd ~
git clone https://github.com/FozzTexx/tcpser.git
cd tpser
make
sudo cp -p tcpser /usr/local/bin

Once it was built, I did a quick test. I already had the null modem adapter and MiniDIN-8 adapter for the Mac, so I did all the testing in Z-Term on the Mac itself.

I started tcpser on the Pi, and figured out it wanted to run as root. There's a couple of ways around this, but as this Pi Zero W isn't for anything but this, I didn't care when a simple sudo was sufficient.

sudo tcpser -s 38400 -d /dev/ttyUSB0

You'd want to adjust the port speed (38400, in this example) and your device (ttyUSB0) to whatever your hardware supports, if that's too fast for your serial client.

For old Macs, you're probably good up to 115,200 at the least - the old serial ports were 230k because serial was used for AppleTalk, so they had faster serial than was usual for the era.

A quick 'ATZ' saw an 'OK' as a return in Z-Term, so it was clearly working as a modem and that part of this setup was complete.

I also want this to start at boot so that the Pi is basically just a modem appliance, so I used the provided instructions to create some scripts and systemd bits so that it'd auto-run on startup.

I had to make just a couple of minor changes to their configuration around permissions and some software that I didn't need - the USB adapter handles hardware error correction and flow control so I don't need some of the added software.

Created the following files, as root:

/usr/local/bin/start_tcpser.sh

#!/bin/bash

phonebook="/home/USERNAME/phonebook.txt"
baud='38400'
dev='/dev/ttyUSB0'

for i in `cat $phonebook`; do
	n="$n -n$i "
done

/usr/local/bin/tcpser -l4 -s ${baud} -d ${dev} $n

/etc/systemd/system/tcpser.service

[Unit]
Description=Modem emulator tcpser
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/usr/local/bin
ExecStart=/usr/local/bin/start_tcpser.sh
Restart=on-abort

[Install]
WantedBy=multi-user.target

/home/pi/phonebook.txt

5551000=bbs.fozztexx.com
5551001=particlesbbs.dyndns.org:6400

You can add any phone number and BBS hostname or IP you want. This lets you add a 'phone number' to a terminal client that really only supports numbers so you can build a BBS directory you're dialing.

Next up, start the service:

sudo chmod +x /usr/local/bin/start_tcpser.sh
sudo systemctl daemon-reload
sudo systemctl enable tcpser
sudo systemctl start tcpser

I did another test at this point, including dialing 555-1000 and immediately the BBS login screen appeared in Z-Term. Success!

But, we're not quite done: that's half of what I wanted. Next, I wanted to have the option to "dial up" to the internet via PPP.

We need to add a couple of pieces of software to act as a dial-up ISP:

sudo apt install telnet xinetd netkit-telnetd ppp

Debian/Raspbian are swapping default telnetd packages, and installing just "telnetd" won't end up with a working configuration (or, at least, I was not able to diagnose and resolve it's lack of output when tcpser was connecting to it).

Couple of configuration changes are required; pppd needs to be setuid and you'll need a user that has it's login shell set to pppd:

sudo chmod a+s /usr/sbin/pppd
sudo useradd -m ppp
sudo usermod -aG dip ppp
sudo usermod -s /usr/sbin/pppd ppp
sudo touch /home/ppp/.hushlogin

We also need to configure pppd, by replacing two files with new contents:

sudo mv /etc/ppp/options /etc/ppp/options.orig
sudo mv /etc/ppp/pap-secrets /etc/ppp/pap-secrets.origAnd

/etc/ppp/options

# We will be doing PPP over Telnet - disable serial control.
local

# Terminate connection if remote side stops responding.
lcp-echo-interval 30
lcp-echo-failure 4

# Debug adds a lot of detail into the system logs regarding PPP negotiation.
# This is helpful in debugging client issues.
debug

# IP addresses to use in local:remote format.  We use NAT to share
# the Wi-Fi connection, make sure these are outside of your real subnet.
10.10.10.1:10.10.10.2

# Any DNS IP is good, and you can change this to your preferred provider/local
# resolver
ms-dns 1.1.1.1

# Other sensible options
asyncmap 0
passive
noipx

/etc/ppp/pap-secrets

# Allow any username/password
*	*	""	*

For the telnet connection which launches the pppd daemon, you'll want to create two files:

/etc/xinetd.d/pppd

service pppd
{
    type = UNLISTED
    flags  = REUSE
    socket_type = stream
    wait  = no
    user  = root
    server  = /usr/sbin/in.telnetd
    server_args = -h -L /usr/local/bin/ppplogin
    disable  = no
    bind  = 127.0.0.1
    port = 2323
}

/usr/local/bin/ppplogin

#!/bin/bash
/bin/login -f ppp

And a little more housekeeping so that everything has proper permissions and starts running at boot:

sudo chmod +x /usr/local/bin/ppplogin
sudo systemctl enable xinetd
sudo systemctl restart xinetd

And then testing to ensure port 2323 is listening:

pi@raspberrypi:~ $ netstat -an |grep :2323
tcp        0      0 0.0.0.0:2323            0.0.0.0:*               LISTEN

For IP traffic to work, we also need to enable NAT and IP forwarding so that your traffic can leave the local PI:

sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
sudo sh -c "iptables-save > /etc/iptables.rules"

For IP Forwarding, edit /etc/sysctl.conf and uncomment the ip_forward line:

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

And more housekeeping for automatic application of these rules at boot:

/etc/network/if-pre-up.d/iptables

#!/bin/bash
iptables-restore < /etc/iptables.rules

And then make it executable and test that it's applying properly on reboot:

sudo chmod +x /etc/network/if-pre-up.d/iptables
sudo reboot

You'll want to check that it's applied properly, and if so, we're done!

user@raspberrypi:~ $ cat /proc/sys/net/ipv4/ip_forward
1

user@raspberrypi:~ $ sudo iptables -t nat -L POSTROUTING -nv
Chain POSTROUTING (policy ACCEPT 3 packets, 337 bytes)
 pkts bytes target     prot opt in     out     source               destination
   11   927 MASQUERADE  0    --  *      wlan0   0.0.0.0/0            0.0.0.0/0

You'll want to add a line to your phonebook so you can "call" your "ISP":

echo "8675309=localhost:2323" >> /home/USERNAME/phonebook.txt
sudo service tcpser restart

You can now add this to your PPP dialer of choice, and hey presto, the joys of dialup internet access are yours again.