How To Setup a Raspberry Pi Packet Radio Node with Zork

posted in: Project | 34

packet radio

I got my ham radio license eight years ago so I could use it for a high altitude balloon project with some friends from college. We had a lot of fun, but I haven’t used the license much since then. I get into it for a few weeks every couple of years and then get bored. I just don’t have much interest in talking to strangers over the air. I’ve always been much more fascinated by the idea of packet radio. Sending data over the airwaves without any centralized infrastructure just sounded cool and also reminded me of the things I’ve read about the pre-Internet days. Back then the primary way to connect with other computers was via BBS. I was a bit too young and missed out on those days, but still find the concept interesting.

I thought packet radio could be a way to experience that sort of technology in the modern world. The main problem is that there isn’t a whole lot of good information about this stuff online. It seems kind of scattered, plus most of the programs you can find to do this stuff seem to have been written twenty years ago, so they often are buggy or don’t work at all. This is especially true if you try to stick with Windows software. After a lot of trial and error, I managed to turn my Raspberry Pi into a functioning packet radio node. Then I figured out how to run Zork on it! I thought I’d document the process here for others who may want to try the same thing. Here’s a video to demonstrate how it works!


In order to setup your own packet node with a RasPi, you are going to need a couple of things:

  • Raspberry Pi with SD card
  • Amateur radio transceiver and antenna
  • KISS TNC with Serial cable
  • USB to Serial adapter
  • List of packet nodes in your area

My Setup

  • Raspberry Pi 2
  • ICOM IC-207 Mobile Radio
  • Magmount antenna on a cookie sheet
  • Kantronics 9612+ TNC in KISS mode

Make sure your radio can tune to the frequencies of the packet nodes in your area. If it can’t, you won’t be communicating with anyone! Once that’s setup, you’ll need to make sure your TNC is in KISS mode and properly connected to your radio. This is entirely dependant on your specific hardware setup, so you’ll have to figure that part out on your own. If you don’t have a TNC, checkout the TNC-Pi project for a cheap KISS TNC specifically designed to work with the RasPi. The TNC will usually use a serial cable to connect to the computer. I believe the Pi has a built-in serial port, but you would need to build an adapter to use it. I just use a USB to serial adapter to get the TNC talking with the Pi.

Setup the Base OS

The first step is to setup the base operating system. I chose Raspbian since it’s pretty much the standard Pi OS. I downloaded the minimal image from the Raspbian website. At the time of this writing, it was Raspbian Jessie Lite. Once the image was downloaded, I flashed it onto a micro SD card. Then I plugged in the Pi’s Ethernet cable, plugged in the SD card, and booted up the device.

I ran an nmap scan of my network to find the Pi.

sudo nmap -sP

One device showed up with a RasPi MAC address.

Nmap scan report for raspberrypi (
Host is up (0.0013s latency).
MAC Address: B8:27:EB:B6:A6:A3 (Raspberry Pi Foundation)

Then I connected to the IP via SSH and logged in with the default credentials. Next, I changed the default password.

pi@raspberrypi:~ $ passwd
Changing password for pi.
(current) UNIX password: 
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

Then I updated the system.

pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get upgrade

I installed all available updates. The next step was to setup WiFi so I could get rid of the Ethernet cable. If you don’t have a WiFi card, you can skip this part. First I made sure the WiFi card was being recognized automatically.

pi@raspberrypi:~ $ iwconfig
wlan0 unassociated Nickname:"<WIFI@REALTEK>"
 Mode:Managed Frequency=2.412 GHz Access Point: Not-Associated 
 Retry:off RTS thr:off Fragment thr:off
 Power Management:off
 Link Quality:0 Signal level:0 Noise level:0
 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
 Tx excessive retries:0 Invalid misc:0 Missed beacon:0

In my case it was being registered as wlan0. Now we need to edit the wpa_supplicant config and restart the network interface.

pi@raspberrypi:~ $ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

I went to the bottom of the file and added the following lines. Be sure to change the SSID and PSK to match your own network.


Then I restarted the WiFi interface and checked to ensure it had an IP address.

pi@raspberrypi:~ $ sudo ifdown wlan0
pi@raspberrypi:~ $ sudo ifup wlan0
pi@raspberrypi:~ $ ifconfig wlan0

wlan0 Link encap:Ethernet HWaddr 74:da:38:5a:6e:e0 
 inet addr: Bcast: Mask:
 inet6 addr: fe80::26f5:8a4f:824c:b75e/64 Scope:Link
 RX packets:24 errors:0 dropped:6 overruns:0 frame:0
 TX packets:37 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000 
 RX bytes:2933 (2.8 KiB) TX bytes:8033 (7.8 KiB)

Perfect! Now I can get rid of the Ethernet able and then reconnect on the new IP address. Now the base system is configured and ready!

Install and Configure AX.25

All of the packet radio stuff works on top of the AX.25 protocol. So let’s install some AX.25 tools and programs.

pi@raspberrypi:~ $ sudo apt-get install ax25-tools ax25-node ax25-apps telnet

Now we have to configure an AX25 port. This port acts as a network interface for your packet radio.

pi@raspberrypi:~ $ sudo nano /etc/ax25/axports

This file should contain two example lines, both commented out with a “#” character in front. Add a new line that looks like this:

0       CALLSIGN-N        9600    255     2       145.030 MHz (1200bps)

Let’s break down each of these things:

  • 0 – Name of the port. It can be a number or a text name. I just choose zero for simplicity.
  • CALLSIGN-N – This is your callsign with a number specified afterwards. I’m not too sure on the importance of the number. I just choose -9 for mine.
  • 9600 – This is the speed of the port. I believe it is the speed between the computer and the TNC, not the speed of the radio connection. In my case it’s 9600 baud.
  • 255 – Paclen. I’m not sure what this does, I just set mine to 255 and it works.
  • 2 – Window. Again, I’m not sure about this one. I set it to 2 and it works just fine.
  • 145.030 MHz (1200bps) – This is a text description. You can put anything you want here to help remind you what this port is.

Now let’s setup a netrom port. Netrom is another packet protocol that runs on top of AX.25. It has a build in routing mechanism that makes it easier to connect to other packet nodes. If you want to setup your own node, then you want to setup netrom. If you only want to connect to other nodes, you don’t have to configure the netrom stuff but it will make it a lot easier to connect to remote nodes.

pi@raspberrypi:~ $ sudo nano /etc/ax25/nrports

Then add a line like this:

netrom CALLSIGN-N #ALIAS 255     145.030 MHz (1200bps)

Let’s break it down again.

  • netrom – The port name. It can be anything. I choose netrom for simplicity.
  • CALLSIGN-N – Same as before. Just make it the same callsign and number.
  • #ALIAS – this is an alias for your netrom packet node. This is like an alternate name people can use to connect to your node. In my area, this is usually based on location. For example, a node on top of Mount Walker would be called #WALKER.
  • 255 – Paclen. Again I’m not sure what this is but I leave it at 255 and it works.
  • 145.030 MHz (1200bps) – A description of the netrom port. Can be anything you want.

Now we’ll edit the daemon config file.

pi@raspberrypi:~ $ sudo nano /etc/ax25/ax25d.conf

You can delete everything in the file and replace it with the below text. Just be sure to edit it to match the ports you configured.

NOCALL * * * * * * L
default * * * * * * - root /usr/sbin/ax25-node ax25-node

NOCALL * * * * * * L
default * * * * * * - root /usr/sbin/ax25-node ax25-node

First, be sure to update the section headings. So [CALLSIGN-N VIA 0] should be updated to your callsign with the -9 or whatever number you chose in the axports file. “VIA 0” should be updated to include the AX.25 port name you configured earlier in the axports file. In my case the port name is the number zero. “<netrom>” should be updated to the netrom port name you configured in the nrports file.

Now we can bring up the AX.25 interface.

sudo kissattach /dev/ttyUSB0 0

You will need to replace “/dev/ttyUSB0” with the correct serial port for your KISS TNC. The final number zero is the name of the AX.25 port you configured in the axports file. You can use ifconfig to verify that the ax.25 port is now online.

pi@raspberrypi:~ $ ifconfig ax0
ax0 Link encap:AMPR AX.25 HWaddr CALLSIGN-N 
 RX packets:0 errors:0 dropped:0 overruns:0 frame:0
 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:10 
 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

At this point, you should be able to test your settings. The first thing you can do is setup a listener on the AX.25 port. Open a new SSH console session and run the following command:

pi@raspberrypi:~ $ sudo axlisten -c -a

The screen will go blank and it will look like nothing is happening. Really, this program is listening to the AX.25 port and it will display all packets your modem sees, regardless of if they are meant for your station or not. If you leave this running for a while, you should eventually see some packet data as long as you are tuned to an active frequency and your settings are all correct.

Another test you can do is to actually connect to a local packet station! If you leave the axlisten command running in its own session, you’ll be able to see your outbound packets as well as any responses. It’s great for debugging. My area has a few Winlink 2000 BBS’s, so I just chose one to connect to as a test.The closest one to me is W7EUG-10 on 145.030 MHz. I manually tuned my radio to this frequency. Then I initiated the connection:

pi@raspberrypi:~ $ axcall 0 W7EUG-10

The zero is the axport you configured earlier. If you are able to communicate with the BBS, you should see something like this in the axlisten output.

0: fm KE7SAL-9 to W7EUG-10 ctl SABM+ 
0: fm W7EUG-10 to KE7SAL-9 ctl UA- 
0: fm W7EUG-10 to KE7SAL-9 ctl I00^ pid=F0(Text) len 40 
0000 Lane County ARES/RACES OADN RMS GatewayM 
0: fm KE7SAL-9 to W7EUG-10 ctl RR1v

KE7SAL-9 is my callsign. W7EUG-10 is the BBS. Back in the axcall console, I can see output from the BBS and I can now issue commands. A good one to start with is HELP. This BBS outputs pages of data with the HELP command. To disconnect, just type “BYE” and hit enter.

Configure the Packet Node

Now that the AX.25 stuff is working, we can setup the packet node. We want our node to startup automatically at boot. We want it to listen for incoming connections and present users with the proper prompt, permissions and commands.

First we’ll edit the node.conf file. This file controls the main settings for your node.

pi@raspberrypi:~ $ sudo nano /etc/ax25/node.conf

Most of the file can be left as the default. The important things to change are the HostName and NodeId, Also make sure the Nrport is configured to the netrom port name you specified earlier. In my case, the port name is “netrom”. Here are what those lines look like for me:

HostName        KE7SAL-9
NodeId          CARMEL:KE7SAL-9
NrPort          netrom

Next we’ll edit the permissions for the node. You can configure it so your user needs to enter a password. This is handy if you provide your own user with special permissions that you don’t want other users to have access to.

pi@raspberrypi:~ $ sudo nano /etc/ax25/node.perms

You can read all about the permissions and settings by reading the node.perms man page. Here’s what I have in my node.perms file.

# user type port passwd perms
ke7sal * * PASS 255

# Default permissions per connection type.
* ax25 * * 7
* netrom * * 7
* local * * 7
* ampr * * 7
* inet * * 7
* host * * 7

This configuration should give my own callsign all permissions (255) but requires that I enter the password “PASS”. The default permissions for all connection types is 7, which should allow outgoing AX.25 and netrom connections but no telnet.

Now we can configure netrom broadcasting. This will tell your node how to handle processing broadcasts from other nodes and also allows you to configure some settings for your own broadcasts.

pi@raspberrypi:~ $ sudo nano /etc/ax25/nrbroadcast

Once again, the man page has a lot of good information. My setup looks like this:

# ax25_name min_obs def_qual worst_qual verbose
0 5 192 100 0

Now we can create the netrom port.

pi@raspberrypi:~ $ sudo nrattach netrom

Now to make it easy to connect to the local packet node from the shell, we can set it up as a TCP/IP service. First we’ll define the service and port.

pi@raspberrypi:~ $ sudo nano /etc/services

Add the following line all the way at the bottom. You can change port 4444 to any unused port.

ax25-node       4444/tcp        # KE7SAL packet node

Then we’ll configure the service to start automatically at boot time.

pi@raspberrypi:~ $ sudo nano /etc/inetd.conf

Add the following line all the way at the bottom.

ax25-node stream tcp nowait root /usr/sbin/ax25-node ax25-node

Then restart the inetd service.

pi@raspberrypi:~ $ sudo service inetd restart

Now you can telnet into your local packet node from the command line! You can also telnet to it from another system as long as your Pi is on the same network and you have port 4444 opened up to remote connections.

pi@raspberrypi:~ $ telnet localhost 4444
Trying ::1...
Connected to localhost.
Escape character is '^]'.

LinuxNode v0.3.2 (KE7SAL-9)


Sweet! It’s working! Now you can log in using the callsign (and possibly password) you specified in the node.perms file. Once logged in, you should get a prompt like this.

#CARMEL:KE7SAL-9 Welcome to KE7SAL-9 network node

Type ? for a list of commands. help <commandname> gives a description
of the named command.


You can type ? to get a list of all commands. A good test to run is to see if you can connect to another local packet node. Tune your radio to the node’s frequency and then issue a call from your node using AX.25. To do this from within your own node, enter the following command.


C stands for CONNECT. You can also type CONNECT if you want. The zero is the ax.25 port configured in the axports file. Finally, WALKER is the alias of my local packet node. You will have to change this to your own local packet node’s alias or callsign. If all goes well, you should be greeted with the node’s prompt!

#CARMEL:KE7SAL-9 Trying WALKER on port 0... Type <RETURN> to abort
#CARMEL:KE7SAL-9 Connected to WALKER on port 0 (Escape: CTRL-T)

You can type BYE to disconnect.

#CARMEL:KE7SAL-9 Trying WALKER on port 0... Type <RETURN> to abort
#CARMEL:KE7SAL-9 Connected to WALKER on port 0 (Escape: CTRL-T)
#CARMEL:KE7SAL-9 Reconnected to KE7SAL-9

#CARMEL:KE7SAL-9 Goodbye
Connection closed by foreign host.

Now we node the node is communicating with the radio properly. We still have a few things left to do in order to finish configuring it. Mainly, we want the node to listen for netrom broadcasts from other nodes so it can populate its own netrom table. This makes it much easier to connect to foreign nodes, even if they are multiple hops away from your own! We also need to make sure we have a server listening for incomming connections from other systems. It only takes two commands.

pi@raspberrypi:~ $ sudo netromd
pi@raspberrypi:~ $ sudo ax25d

That’s it! The first command will start the netromd service. It will listen for broadcasts from other nodes and then update your local node’s routing table as needed. It will also periodically send out broadcasts of its own. The second command starts the ax25d service, which will actually listen for incoming AX.25 connections and then send the users to the node software according to your configuration files. So now you have a fully functional node, but there are still a few more tweaks you should do to make your life easier. You don’t want to have to manually startup all of the node software whenever you reboot the Pi, so in the next section we’ll setup some automation to make it happen automatically at boot.

Start the Node at Boot

There are multiple ways to do this, some more desirable than others. I’m going to go with the quick and dirty route. Basically, I’m just going to throw all the commands in /etc/rc.local so they will be run at the end of the boot process.

pi@raspberrypi:~ $ sudo nano /etc/rc.local

Add the following to the end of the file, before the “exit 0” line. You want to make sure there is no “exit” command before this stuff or the script will exit before your new commands run!

/sbin/modprobe ax25                  # Load ax.25 kernel module
/sbin/modprobe netrom                # Load netrom kernel module
/usr/sbin/kissattach /dev/ttyUSB0 0  # Create the AX.25 interface
/usr/sbin/nrattach netrom            # Create the netrom interface
/usr/sbin/netromd                    # Start the netrom service
/usr/sbin/ax25d                      # Start ax.25 service and start listening

Then you can reboot the Pi and hope everything starts properly.

pi@raspberrypi:~ $ sudo reboot

Backup the Node List

Most nodes will broadcast their list every 30 or 60 minutes. When your node sees this broadcast it updates its own table, making it easier for your users to connect to other nodes. When you reboot your node, your list will be emptied, making your node more difficult to use. You’ll have to wait to receive more broadcasts. Something you can do to make things a bit nicer is to backup your node list regularly, then restore the list at boot time. You can do that pretty simply.

First, create the restore script and give it the proper permissions.

pi@raspberrypi:~ $ sudo touch /etc/ax25/
pi@raspberrypi:~ $ sudo chmod u+x /etc/ax25/

Then create a cronjob to regularly backup the nodes to this file.

pi@raspberrypi:~ $ sudo crontab -e

I set mine up to run every hour by adding this line.

0 * * * * /usr/sbin/nodesave /etc/ax25/

The nodesave command creates an executable script that will re-add all the previously known nodes. So all you have to do is make the output file executable and run it at boot time. We can run it at boot by adding this line to the end of /etc/rc.local.


To make sure it works, first wait for your node list to populate. This may take an hour or so depending on how other nodes are configured in your area. Once you have nodes in the list, check to see if the file was updated by crontab.

pi@raspberrypi:~ $ cat /etc/ax25/

You can see that mine backed up properly. Then you just need to reboot. When the Pi is back online, log back into your packet node and list all of the known nodes. If it’s empty, then something went wrong. Otherwise, it’s all good!

What Now?

Now you have your awesome packet node setup. What can you do with it? In my area, the nodes seem to exist solely for emergency communications. The BBS functions are all disabled and there’s nothing really interesting to do on the nodes. I think they are mostly used to host digital chat sessions for emergency response coordination. The Pi should be pretty good for this sort of thing because it’s inexpensive and low power. Following these instructions, and using a TNC-PI with a Baeofeng, you could setup your own packet node for around $100. Not bad!

That’s all fine and dandy, but if there’s no emergency happening then it’s boring! The most fun I’ve had is hopping from node to node to try and get as far away from my station as possible. I’ve also started mapping out where the nodes are and how they are all linked, but that gets boring too. I wanted to do something more fun with my node, so I setup Zork! That’s right, if you connect to my packet node, you can play Zork over the air! It’s really slow, but it does work! Here’s how I did it.

In order to play Zork on linux, you need an emulator. In this case, I used Frotz.

pi@raspberrypi:~ $ sudo apt-get install frotz

Then I downloaded Zork directly from infocom.

pi@raspberrypi:~ $ mkdir ~/games
pi@raspberrypi:~ $ mkdir ~/games/zork
pi@raspberrypi:~ $ cd ~/games/zork
pi@raspberrypi:~/games/zork $ curl >
pi@raspberrypi:~/games/zork $ unzip

Now I can launch zork locally.

pi@raspberrypi:~/games/zork $ frotz DATA/ZORK1.DAT

The next step was to find a way to allow node users to launch the emulator and play Zork. I first had to create a shell script to launch the application properly.

pi@raspberrypi:~ $ nano

Then I added the following:

export HOME="/home/pi"
export TERM="linux"
/usr/games/frotz /home/pi/games/zork/DATA/ZORK1.DAT

Then allow execution.

pi@raspberrypi:~ $ chmod u+x

When you normally launch zork from the console, you only need to type in the last line. When it’s launched from ax25-node, you need to export those terminal variables or Frotz won’t launch. Now that the script is written, we need to create a new command on the node so users can launch Zork.

pi@raspberrypi:~ $ sudo nano /etc/ax25/node.conf

I scrolled down the to ExtCmd section and added this line to the bottom.

ExtCmd ZOrk 1 pi /home/pi/ NULL

This creates a new command called ZOrk. The capital ZO acts as a shortcut so you don’t have to type the entire command. It will launch the script under the context of the pi user. The NULL portion just has to be there or the node won’t execute at all. I’m not sure why this is.

Now if I log into my node and type the ? command, I get this.

CARMEL:KE7SAL-9 Commands:
?, Bye, Connect, ECho, Escape, Finger, Help, HOst, Info, Links
Mheard, NLinks, Nodes, PIng, Ports, Routes, Status, TAlk, Telnet, TIme
Users, ZConnect, ZOrk, ZTelnet

If I enter ZORK, it launches the game!

ZORK I: The Great Underground Empire
Copyright (c) 1981, 1982, 1983 Infocom, Inc. All rights reserved.
ZORK is a registered trademark of Infocom, Inc.
Revision 88 / Serial number 840726

West of House
You are standing in an open field west of a white house, with a boarded front
There is a small mailbox here.


Now if a ham radio operator connects to my node, they can play Zork over the radio at a blazing 1200 baud! It’s mostly useless, but I thought it was fun!

34 Responses

  1. Dmitriy

    Wow, that is amazing post. Thank you. I wish we have some packet radio nets here in Ukraine (is there some in Europe? not sure). I wish to repeat your experiance!

  2. Great work on this one. I had an old Rasp Pi sitting around collecting dust and this article encouraged me to put it to good use. I now currently have an operational packet node here in Baton Rouge, LA.

    • Thanks! I’m glad this article inspired someone else to put together a node. It’s fun to see how far away you can get on just 2M… even if it is incredibly slow.

  3. Wow. This exactly what I was looking for! Hopefully you’ll see my soon to be node linking to yours. I’m wondering if you can play BBS door games on this set up.

    If so, I’ll invite you to play Legend of the Red Dragon once mine is up !

    • KD9FQT - Matt

      Rocky – I’m almost finished with my Allstar / IRLP / Echolink & 900 mhz repeater, and the next project on my list was to build a packet BBS with door games.. specifically Legend of the Red Dragon. Flirting with Violet, some of the ridiculous creatures you run into when you fight, etc makes it an entertaining game to this day! I’m thinking about making the Legend of the Red Dragon game accessible both over the Internet somehow and via packet radio, so everyone could enjoy.

      Great information in this article! I’m 31, so I just barely missed the BBS days, but I’m still an avid collector and experimenter with 1980s computing technology.

  4. Richard,

    After trying to get JNOS to work on the Raspberry pi with only marginal success I read your offering using netrom. I think this will meet my needs. Thanks for the great work.


  5. Richard,

    After much trial and error, reading man pages and your very well presented step by step procedure for implementing netrom I am unable to determine why I am receiving this message when implementing nrattach .

    pi@PacketHost:~ $ sudo nrattach netrom
    nrattach: SIOCGIFFLAGS: No such device
    nrattach: cannot find free NET/ROM device
    I am using the original pi-1, (C)2011, and a TNC-pi board with the latest 2016-11-25-raspbian-jessy.img on the SD card. Connecting to a TNC set up in my station works very well with the axcall and axlisten commands. I am just unable to implement netrom. Since it seemed as though you implemented netrom so easily there must be a fundamental flaw in my configuration. If you would point me in the proper direction it would be greatly appreciated.


    • Did you ever get this working? Sorry I never replied, I somehow totally missed your message. I haven’t played with my node in a while so I’m not sure what the problem is off the top of my head but I do still have it setup so I could look at mine again if you are still trying to figure this out.

      • I am stuck here as well, not sure what I did wrong

      • I had this problem too. Check you have the netrom kernel module loaded (lsmod | grep netrom), if not, load it (modprobe netrom) – for some reason it doesn’t seem to auto-load when needed. Also – in addition to the daemons listed above, you may also wish to start mheardd to ensure the list of heard stations is kept updated. Also, when restarting, your node will lose its list of routes – there’s a ‘nodesave’ command that will generate a list for import after a restart.
        Rick – thanks for this guide – it was just what I needed!

        • You should be able to auto-load netrom by adding to the /etc/modules file.

  6. Hello from kf4hav. My name is Brian. This was an excellent article. I used your post to set my weather station up on my packet node. I also have fbb bbs running smoothly. Now I am going to implement the games portion, although packet is mostly dead in my area. It is still something to play with grin.

  7. Awesome!, and thanks for the quick response on youtube. I’ll be reading your code in the next few days. 🙂

  8. I did have to run modprobe netrom that worked for me but now I’m stuck
    This services file does not exist on my new rasberry pi

    pi@raspberrypi:~ $ sudo nano /etc/services
    Add the following line all the way at the bottom. You can change port 4444 to any unused port.

    pi@raspberrypi:/etc $ ls
    adduser.conf init.d python
    alternatives initramfs-tools python2.7
    apache2 inputrc python3
    apparmor.d insserv python3.4
    apt insserv.conf rc0.d
    avahi insserv.conf.d rc1.d
    ax25 iproute2 rc2.d
    bash.bashrc issue rc3.d
    bash_completion rc4.d
    bash_completion.d kbd rc5.d
    bindresvport.blacklist kernel rc6.d
    binfmt.d ldap rc.local
    bluetooth rcS.d
    ca-certificates request-key.d
    ca-certificates.conf resolvconf
    calendar resolv.conf
    chromium-browser libaudit.conf resolvconf.conf
    console-setup libnl-3 rmt
    cron.d libreoffice rpc
    cron.daily lightdm rpi-issue
    cron.hourly lighttpd rsyslog.conf
    cron.monthly locale.alias rsyslog.d
    crontab locale.gen RTIMULib.ini
    cron.weekly localtime samba
    dbus-1 logcheck securetty
    debconf.conf login.defs security
    debian_version logrotate.conf selinux
    default logrotate.d services
    deluser.conf machine-id sgml
    dhcp magic shadow
    dhcp3 magic.mime shells
    dhcpcd.conf mailcap skel
    dhcpcd.duid mailcap.order ssh
    dictionaries-common manpath.config ssl
    dillo menu-methods staff-group-for-usr-local
    dphys-swapfile mime.types subgid
    dpkg mke2fs.conf subgid-
    drirc modprobe.d subuid
    emacs modules subuid-
    environment modules-load.d sudoers
    esound moria-hours sudoers.d motd sysctl.conf
    fb.modes mtab sysctl.d
    fonts nanorc systemd
    fstab netconfig terminfo
    fuse.conf nethack timezone
    gai.conf network timidity
    gconf networks tmpfiles.d
    gdb newt triggerhappy
    ghostscript nsswitch.conf ucf.conf
    gnome ntp.conf udev
    groff openal udisks2
    group opt ufw
    gshadow os-release usb_modeswitch.conf
    gss PackageKit usb_modeswitch.d
    gtk-2.0 pam.conf vim
    gtk-3.0 pam.d vnc
    host.conf passwd wgetrc
    hostname perl wildmidi
    hosts plymouth wpa_supplicant
    hosts.allow polkit-1 X11
    hosts.deny ppp xdg
    idmapd.conf profile xml
    ifplugd profile.d xpdf
    inetd.conf protocols
    init pulse
    pi@raspberrypi:/etc $

    • Did you get this figured out? Are you running Raspbian or some other Pi distribution?

  9. Rick:

    An excellent article, but I am puzzled by one line. I am a newbie to Linux, so pardon my ignorance….

    In ax25d.conf, you have this line:

    default * * * * * * – root /usr/sbin/ax25-node ax25-node

    However, in my Raspberry Pi install, there is no folder /usr/sbin/ax25-node; however, there is a file named ax25-node in the /usr/sbin folder.

    So I modified that line to read:

    default * * * * * * – root /usr/sbin ax25-node

    Which seems to work, especially after I applied the fix that Steve M0SPN recommended.

    Can you take a moment to explain the difference?

    Thank you!

    • Jeff,

      Based on the manual for ax25d, the “/usr/sbin/ax25-node” should be “the full pathname of the command to be run, with no arguments specified”. The “ax25-node” part at the end should be, “the text that should appear in a ps as the command name running (normally the same as except without the directory path information”. So I think I had it correct in my post. If you changes the CMD portion to just /usr/sbin, I’m not sure how it would still work.

  10. And following from my earlier post, I’ve attempted to run “telnet localhost 4444”, with these results:

    Trying ::1…
    Connected to localhost.
    Escape character is ‘^]’.
    Connection closed by foreign host.

    And the connection stops right there. I’ve been researching into the “Connection closed by foreign host”, and it appears to be caused by any number of issues. Have you experienced this?

  11. I had this working with Zork running but I loaded the new Stretch version OS and AX.25 no longer seems to be able to make the TNC talk. The Kantronics 9612+ TNC works If I use it in command mode with putty. But put it in kiss mode INTFACE KISS and cycle power and do kissattach and nothing happens. The Xmit light never lights up on the TNC. Do you have any ideas?

    sudo kissattach /dev/ttyUSB0 1
    AX.25 port 1 bound to device ax0
    pi@raspberry:~ $ ifconfig ax0
    ax0: flags=67 mtu 255
    ax25 KF7OML-1 txqueuelen 10 (AMPR AX.25)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    pi@raspberry:~ $ sudo axcall 1 SMTN
    GW4PTS AX.25 Connect v1.11

    pi@raspberry:~ $ sudo axlisten -c -a
    Could not initialize color support.
    1: fm KF7OML-1 to SMTN ctl SABM+
    1: fm KF7OML-1 to SMTN ctl SABM+

    pi@raspberry:~ $ ifconfig ax0
    ax0: flags=67 mtu 255
    ax25 KF7OML-1 txqueuelen 10 (AMPR AX.25)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 4 bytes 76 (76.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    GNU nano 2.7.4 File: /etc/ax25/axports

    # /etc/ax25/axports
    # The format of this file is:
    # name callsign speed paclen window description
    1 KF7OML-1 1200 255 2 144.630 MHz (1200 bps)
    #2 OH2BNS-9 38400 255 7 TNOS/Linux (38400 bps)

    GNU nano 2.7.4 File: /etc/ax25/nrports

    # /etc/ax25/nrports
    # The format of this file is:
    # name callsign alias paclen description
    netrom KF7OML-1 ZORK 255 145.630 Mhz (1200bps)

    GNU nano 2.7.4 File: /etc/ax25/nrports

    # /etc/ax25/nrports
    # The format of this file is:
    # name callsign alias paclen description
    netrom KF7OML-1 ZORK 255 145.630 Mhz (1200bps)

    cat /etc/os-release
    PRETTY_NAME=”Raspbian GNU/Linux 9 (stretch)”
    NAME=”Raspbian GNU/Linux”
    VERSION=”9 (stretch)”

  12. Good morning!

    I worked around the “Connection closed by foreign host” issue. For this line in /etc/inetd.conf

    ax25-node stream tcp nowait root /usr/sbin ax25-node

    I changed “nowait” to “wait”.

  13. Add the following line all the way at the bottom.

    ax25-node stream tcp nowait root /usr/sbin/ax5-node ax25-node

    This is a typo on this line in your webpage. It should say
    ax25-node stream tcp nowait root /usr/sbin/ax25-node ax25-node

    This fixed my telnet function, I can login now, but I still cant get my Kantronics to axcall
    I tried going back to jesse and it still didnt work. So I’m totally perplexed.
    Can you add your kantronics setup file?


  14. Now we’ll edit the daemon config file. You can delete everything in the file and replace it with the below text. Just be sure to edit it to match the ports you configured.

    NOCALL * * * * * * L
    default * * * * * * – root /usr/sbin/ax25-node ax25-node

    NOCALL * * * * * * L
    default * * * * * * – root /usr/sbin/ax25-node ax25-node
    First, be sure to update the section headings. So [CALLSIGN-N VIA 0] should be updated to your callsign with the -9 or whatever number you chose in the axports file. “VIA 0” should be updated to include the AX.25 port name you configured earlier in the axports file. In my case the port name is the number zero. “” should be updated to the netrom port name you configured in the nrports file.

    I am not understanding how to do this

    • Thank you for bringing that to my attention. I’ll update the article. The file you need to edit is /etc/ax25/ax25d.conf

  15. Hi,
    I got lost at modifying the Daemon config. The instructions up to that point were thorough. Without research, I don’t know where the daemon config is….it would have been smoother to include the command for opening that file…like “sudo nano daemon.config” or….

    • Thank you for bringing that to my attention. I’ll update the article. The file you need to edit is /etc/ax25/ax25d.conf

  16. Rick,
    Great instruction! The best I’ve found. I suspect I’ve missed a step, but I’m near the end of setting up Raspberry Pi but the command “telnet localhost 4444” yields the following result.
    telnet: unable to connect to remote host: Connection refused.
    I’ve tried with both my wifi system and a direct connection to my modem.
    Any ideas?

  17. Found my error. Tenet is now working.

  18. Telnet times out without hands-on activity. Does anyone know how to disable that feature?

  19. hi, is it possible to route a tnc over the internet to other nodes they connected to the internet? in my area there a no hf nodes anymore, so I wanted to use a tnc and pi as local hf node that’s connected over the internet

  20. Thanks brother. This is the best walk through of setting up a packet bbs that I’ve seen. Mainly becaused it worked and the one hickup was taken care of in the comments. keep it up.


  21. Greg Fenton

    I really miss the old BBS systems of my youth and have been after reliving them for such a long time.

    I wanted to set up a doors system on my TNC but couldn’t figure out how to achieve it. I thought I would be stuck with nothing more than the built in mailbox on my Kantronics TNC.
    Thanks to your guide, and after jumping through a couple of hoops I got it all working and now have Zork 1, 2 and 3 running over my packet radio node. I’m off to find more stuff I can add to the BBS 🙂

    Your straightforward approach means I can extend it however I wish.

    Best de M0ODZ/nhs