• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

TashRouter: An AppleTalk Router

Phipli

Well-known member
Yeah, I basically can't use mini vmac to AirTalk if the mini vmac machine is on WiFi. If it is on ethernet, it is absolutely fine.
 

Andrew

Well-known member
I will try your suggestions and let you know. Its a shame if it wont work over wifi since this was the main motivation for the development of LToUDP
 

tashtari

PIC Whisperer
I made the README.md on GitHub a bit more newbie-friendly, suggestions welcome. Also, a few TashTalk Hat kits are back in stock in case anyone's been waiting on them.

Also also, paging @finkmac to share the details of their setup - AIUI, it uses TashRouter's TapPort and Netatalk 2.x, using Netatalk as the router for the EtherTalk network plus its own services, while TashRouter handles connections to TashTalk and LToUDP.
 

finkmac

NORTHERN TELECOM
I guess I've been called out :eek:o_O:cautious:🤔

So yes, I have tashrouter working in harmony with netatalk on the same raspberry pi.

The pi in question is a Pi2B running Raspbian Bullseye and equipped with a TashTalk Hat of Tashtari's design.

I experimented with the recommended macvtap interface but found it to be somewhat poorly documented.
In theory it's supposed to function like a bridge+tap, but I could not get that to work properly.

Instead, I just went with a classic tap + bridge setup.

I found the easiest way to set this up was to disable dhcpcd and use systemd networking to create the necessary interfaces on boot.

/etc/network/interfaces.d/br0
Code:
#loopback
auto lo
iface lo inet loopback

# Virtual interface
auto tap2
iface tap2 inet manual
   pre-up tunctl -t tap2 -u root
   up ip link set dev tap2 up
   down ip link set dev tap2 down

# Bridge interface
auto br0
iface br0 inet static
   address 10.40.0.216
   gateway 10.40.0.1
   dns-domain local.default.tel
   dns-nameservers 10.40.0.1 1.1.1.1 8.8.8.8
   bridge_ports eth0 tap2
   bridge_stp off
   bridge_maxwait 5

eth0 = the ethernet interface of the pi. I have predictable interface names disabled.
tap2 = the network tap. tashrouter will bind to this.
br0= a network bridge of tap2+eth0. Netatalk's atalkd daemon will be bound to this, which will allow netatalk to "hear" tashrouter.
this is also given a static IP address which will become the address of the pi.

Now a tashrouter script that binds to the tap interface must be created. This needs to be in the main tashrouter directory.

tap_router.py

Code:
import logging
import time

import tashrouter.netlog
from tashrouter.port.ethertalk.tap import TapPort
from tashrouter.port.localtalk.ltoudp import LtoudpPort
from tashrouter.port.localtalk.tashtalk import TashTalkPort
from tashrouter.router.router import Router


logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s: %(message)s')
#tashrouter.netlog.set_log_str_func(logging.debug)  # comment this line for speed and reduced spam

router = Router('router', ports=(
  LtoudpPort(seed_network=1, seed_zone_name=b'LToUDP Network'),
  TashTalkPort(serial_port='/dev/ttyAMA0', seed_network=2, seed_zone_name=b'TashTalk Network'),
  TapPort(tap_name='tap2', hw_addr=b'\xDE\xAD\xBE\xEF\xCA\xFE', seed_network_min=3, seed_network_max=5, seed_zone_names=[b'EtherTalk Network']),
))
print('router away!')
router.start()

try:
  while True: time.sleep(1)
except KeyboardInterrupt:
  router.stop()

The important parts here are:
from tashrouter.port.ethertalk.tap import TapPort
this tells tashrouter to make the tap ethertalk module(?) available
TapPort(tap_name='tap2', hw_addr=b'\xDE\xAD\xBE\xEF\xCA\xFE', seed_network_min=3, seed_network_max=5, seed_zone_names=[b'EtherTalk Network']),
this tells tashrouter to bind to the specified tap interface (tap2), and give it the specified MAC address (\xDE\xAD\xBE\xEF\xCA\xFE).

Finally, Netatalk's atalkd.conf needed to be edited.
add a new interface to the top of the file, "br0" and comment out the interface already specified.
Code:
br0
#eth0 -phase 2 -net 0-65534 -addr 65280.238

The other attributes will be magically populated when atalkd runs.

Now things are ready to run. If netatalk is already running it needs to be shut down, and tashrouter needs to be run first.

I use systemctl to stop all the netatalk services. You can probably get away with just stopping the atalkd service though...

If you DO want to stop all the netatalk services, just substitute the particular service name in place of atalkd. there's 5 in total. atalkd, afpd, papd, a2boot, and timelord.

systemctl stop atalkd

Then tashrouter needs to be started (using the tap script above)

python3 ~/tashrouter/tap_router.py just note that this will NOT run in the background, use tmux or screen to run it in a seperate window for now

When tashrouter is running properly, start atalkd.

systemctl start atalkd

Then, check the status.

systemctl status atalkd

If everything worked, it should say something like this:

Code:
Jan 12 20:03:08 raspbx atalkd[543]: zip_getnetinfo for br0
Jan 12 20:03:08 raspbx atalkd[543]: zip gnireply from 3.125 (br0 812)
Jan 12 20:03:08 raspbx atalkd[543]: zip_packet configured br0 from 3.125
Jan 12 20:03:09 raspbx atalkd[543]: rtmp_packet gateway 3.125 up
Jan 12 20:17:41 raspbx atalkd[543]: ready 0/0/0
Jan 12 20:17:41 raspbx systemd[1]: Started Netatalk AppleTalk daemon.

Things should now be working, you should be able to see the netatalk share in the EtherTalk zone. Grab a few Macs and emulators and test if it works via ethertalk, localtalk, and LToUDP.

But you probably want things to start at boot and generally be a bit neater.

To make things tidy, make a systemd unit for tashrouter.

First, quit tashrouter, and shutdown atalkd.

nano /etc/systemd/system/tashrouter.service
yeah there's probably a better place to put this...

Code:
[Unit]
Description=TashRouter Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3 /root/tashrouter/tap_router.py

[Install]
WantedBy=default.target

/root/tashrouter/tap_router.py = the location of your tap_router.py file in the tashrouter directory.

Save, reload systemd units.

systemctl daemon-reload

Then start the new unit.

systemctl start tashrouter

Check the status using systemctl status tashrouter and check if it's working. If it is, then systemctl enable tashrouter and it will start at boot.

This should be enough to have tashrouter start before netatalk, but if not... systemd overrides can be created to force netatalk to start after tashrouter. i haven't included them as i don't have them set up properly yet
 

NJRoadfan

Well-known member
My setup is similar except I skipped the bridged network. The atalkd router that netatalk comes with is a bit... temperamental, so I choose to have it see a separate tap interface and have it route across to Ethernet...or wifi.
 

slipperygrey

Well-known member
I use systemctl to stop all the netatalk services. You can probably get away with just stopping the atalkd service though...

You are correct with one exception: The afpd service is independent of the atalkd service, because afpd can run stand-alone as an ASIP (TCP-only) AFP server.

But for timelord/papd/a2boot, I defined the systemd unit files to be dependent on atalkd, so that taking down the latter will take down the others. It's a convenient shorthand that I use all the time.
 

treellama

Well-known member
I now have tashrouter working as well. The writeup by @finkmac was helpful. In my case, netatalk is running in a VM. I was able to run tashrouter in a separate VM, but with libvirt getting one to start up before the other was tricky. So I ended up using the tap / bridge setup above directly on the host machine instead, which systemd seems to bring up well before the libvirt machines (which are also on the same bridge). Now I can access my shares and timelord from the AirTalks!
 

shirsch

Well-known member
I'm trying to join the party, but need some more grounding in the fundamentals. For starters, what is the code in the tashtalk Git project as compared to tashrouter? Are they both needed? The tashtalkd code appears to want the name of an interface, but I do not know what it should be showing up as. It's possible my hardware is not working correctly, but it's built from a kit sent to me by Tashtari and I believe the PIC12F is programmed. How can I verify the basics before moving on to routing?

Also, I'm using a Pi Zero W so no ethernet available. It's unclear from reading through this topic whether Wifi will work. If it must be ethernet can I plug a USB-Ethernet adapter into the sole USB port?
 

tashtari

PIC Whisperer
what is the code in the tashtalk Git project as compared to tashrouter?
TashTalk is PIC microcontroller firmware that acts as an interface to LocalTalk, allowing anything with a UART to connect to a LocalTalk network. TashRouter is an AppleTalk router written in Python, able to route between EtherTalk and LocalTalk networks.

TashTalk and TashRouter can be used together - that is, one of the ways that TashRouter can route to/from a LocalTalk network is via a TashTalk interface (such as a TashTalk Raspberry Pi hat). However, they can also be used separately - neither one requires the other. TashTalk can also be used with tashtalkd, which is a simpler utility that bridges together an LToUDP network and a LocalTalk network via TashTalk, and TashRouter can route between LToUDP and EtherTalk and not involve TashTalk at all.

The tashtalkd code appears to want the name of an interface, but I do not know what it should be showing up as.
If I'm not mistaken, a Pi Zero W is similar to the Pi 3 Model B I use, so the "UART Setup" section of this document should be relevant. Long story short, the UART you want to use is at /dev/ttyAMA0, you just need to make sure that it (the "PL011" UART, not the "mini UART") is the one connected to the UART pins on the GPIO header.

How can I verify the basics before moving on to routing?
Connect your TashTalk hat to a LocalTalk network and start tashtalkd with the -vv command line switch (two levels of verbosity) - this will force it to make hex dumps of all network activity to the console. Then do something to cause some traffic on the LocalTalk network, such as opening the Chooser and clicking AppleShare. If your hat is working properly and the UART is set up properly, you should see packets going by looking for AppleShare servers.

It's unclear from reading through this topic whether Wifi will work.
Others are more familiar with this than I am, but as I understand it, some wifi routers damage EtherTalk packets when translating between wifi and wired Ethernet. I believe Linux-based routers (DD-WRT and such) are okay, but your mileage may vary.

If it must be ethernet can I plug a USB-Ethernet adapter into the sole USB port?
As long as the USB Ethernet adapter is supported by your operating system, it will be supported by TashRouter.
 
Last edited:

shirsch

Well-known member
And - success! The major obstacle was figuring out the missing pyserial dependency on Void Linux. It's not part of the base Python 3 install and the xbps-query tool simply could not find it (must be something I'm misunderstanding about it). Finally, by sheer luck, I guessed the correct package name 'python3-pyserial' and fired it up with './tashtalkd -vv -d /dev/ttyAMA0' and it's showing localtalk traffic. Now, on to trying the router.
 

shirsch

Well-known member
Ok.. That comes to a screeching halt on the first step:

Code:
$ sudo ip link add link wlan0 name macvtap0 type macvtap
Error: Unknown device type.

Any input on this appreciated!
 

finkmac

NORTHERN TELECOM
void linux does have the macvtap driver, have you created that device already?
 
Last edited:

shirsch

Well-known member
I'm sorry for being dense, but I've read through this topic twice and it's totally unclear what - if anything - I can do to attempt bridging through the wifi connection. I'm far from a newbie, but I'm also not a networking expert and generally find the linux tap/routing documentation impenetrable.

I'm running Void Linux, not raspbian. It's supposed to have the macvtap driver built in according to what I've read here.
 

tashtari

PIC Whisperer
They said they were using Void, though. Strange, my RPi Void install has macvtap (lsmod | grep macvtap shows it)... can you try running modprobe macvtap as root and see if it works after that?
 

shirsch

Well-known member
Code:
]$ modprobe macvtap
modprobe: FATAL: Module macvtap not found in directory /lib/modules/6.1.69_1

Blast. Once again, the xbps-query tool finds nothing. How exactly does one get it to accept a wildcard?
 

tashtari

PIC Whisperer
Huh, I guess they must have removed it from the kernel? My Void RPi is on 5.15.72_1 and hasn't been upgraded (since it's not connected to the internet). There is no xbps package that installs macvtap, it needs to be in the kernel. @finkmac What version of the kernel is your Void install on?
 

finkmac

NORTHERN TELECOM
now that I think of it, I'm pretty sure I was using 64bit void on my pi4 when I was messing with macvtap. perhaps a similar deal to raspbian.
 

tashtari

PIC Whisperer
Oh, no, I see what the problem is... the 32-bit Void RPi images don't have the macvtap driver either. My RPi (a 3B) is running aarch64, it looks like the Zero W requires armv6l.
 
Top