• Hello Guest! We're hosting a challenge to welcome vintage Intel macs to the MLA during the month of July! See this thread for more information.
  • We've made some quality of life improvements to the Trading Post. More info here.

TashRouter: An AppleTalk Router

I checked it out and it works fine for me. With the new "route_lkup_replies=True" parameter I am able to print from an EtherTalk connected Macintosh to an LocalTalk connected ImageWriter II just fine (good test out for my newly acquired color ribbons!).

At the risk of public humiliation but for anybody else who tries this and also does not read posts correctly. TapPort needs to be renamed to LinuxTapPort in your starting script! ;-)
 
I spoke too soon. After that first print the IMII disappeared from the network. There are these errors:
Jul 11 13:05:14 wolfalice python3[18424]: Exception in thread Thread-13 (_run):
Jul 11 13:05:14 wolfalice python3[18424]: Traceback (most recent call last):
Jul 11 13:05:14 wolfalice python3[18424]: File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
Jul 11 13:05:14 wolfalice python3[18424]: self.run()
Jul 11 13:05:14 wolfalice python3[18424]: File "/usr/lib/python3.11/threading.py", line 975, in run
Jul 11 13:05:14 wolfalice python3[18424]: self._target(*self._args, **self._kwargs)
Jul 11 13:05:14 wolfalice python3[18424]: File "/home/chris/src/tashrouter1/tashrouter/service/name_information.py", line 326, in _run
Jul 11 13:05:14 wolfalice python3[18424]: router.route(Datagram(hop_count=0,
Jul 11 13:05:14 wolfalice python3[18424]: File "/home/chris/src/tashrouter1/tashrouter/router/router.py", line 155, in route
Jul 11 13:05:14 wolfalice python3[18424]: entry.port.unicast(datagram.destination_network, datagram.destination_node, datagram)
Jul 11 13:05:14 wolfalice python3[18424]: File "/home/chris/src/tashrouter1/tashrouter/port/localtalk/__init__.py", line 167, in unicast
Jul 11 13:05:14 wolfalice python3[18424]: self._send_frame_with_short_header(node, datagram)
Jul 11 13:05:14 wolfalice python3[18424]: File "/home/chris/src/tashrouter1/tashrouter/port/localtalk/__init__.py", line 152, in _send_frame_with_short_header
Jul 11 13:05:14 wolfalice python3[18424]: self.send_frame(bytes((destination_node, self.node, self.LLAP_APPLETALK_SHORT_HEADER)) + datagram.as_short_header_bytes())
Jul 11 13:05:14 wolfalice python3[18424]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jul 11 13:05:14 wolfalice python3[18424]: File "/home/chris/src/tashrouter1/tashrouter/datagram.py", line 125, in as_short_header_bytes
Jul 11 13:05:14 wolfalice python3[18424]: raise ValueError('invalid hop count %d, short-header datagrams may not have non-zero hop count' % self.hop_count)
Jul 11 13:05:14 wolfalice python3[18424]: ValueError: invalid hop count 1, short-header datagrams may not have non-zero hop count
 
I spoke too soon. After that first print the IMII disappeared from the network. There are these errors:
Hmm. So this is caused by LkupRouter routing a datagram that it's pretending it didn't originate, which means it'll have a hop count of 1, which means it can't be short-form... but it tries to make it short form and fails. I could solve this one of two ways:

One, I could force the generated LkUp-Reply to be a long-form DDP datagram. This is what I'm inclined to do, but I'm worried about this creating incompatibilities with edge cases like the Apple IIe Workstation Card trying to print to an ImageWriter on a different LocalTalk network. That is, the Workstation Card sends a BrRq to TashRouter on its network, this gets converted to a LkUp on the ImageWriter's network, whose LkUp-Reply gets sent by the braindead ImageWriter to the router address on its own network, which the LkupRouter realizes should have been sent to the Workstation Card, so it sends it to the Workstation Card... which doesn't understand long-form DDP datagrams. Anyone know if this is a valid concern? Does the Workstation Card understand long-form DDP datagrams? Is it even capable of sending BrRqs to a router?

Two, I could mark the generated LkUp-Reply as being originated from TashRouter, which means it'll have a hop count of 0 and therefore be able to be a short-form DDP datagram. But... this is an outright lie rather than a corrected error. However, if the situation I described above with the IIe Workstation Card is a real possibility, this may be the only way to proceed.

Paging @NJRoadfan - what do you think of this? (Anyone else welcome to weigh in too, of course.)
 
The Apple IIe Workstation card won't have a problem with NBP requests in long DDP packets, otherwise it wouldn't be able to locate services on other networks.

What the IIe card doesn't recognize is short form RTMP broadcasts, specifically the RTMP stub listener in the firmware. Other early AppleTalk devices have this limitation (read, LaserWriters) so every router I've come across uses short DDP headers on their LocalTalk ports for periodic RTMP broadcasts.

What likely happened with the ImageWriter card is that Apple took a shortcut and assumed that shortform DDP headers originated from the node that requested it. Why? Because its an optimized way of doing it (source node is always at a fixed offset) instead of inspecting the NBP tuple itself for the source node's address AND short form packets are only used on non-routed networks. If the card gets a long header, it inspects the header for the source node data since its possible its from another network. Once again this data is at a fixed offset, so can be quickly done.

Apple's own documentation has its faults too. Inside AppleTalk doesn't state that a router broadcasting local NBP lookup packets on routed non-extended networks need to be long form. Alot of this could be avoided if they detailed the exact sequence of events (with packet types) that should happen when a client makes a NBP Broadcast request on a routed non-extended network.
 
Sorry for the double post.... to add:

Apple doesn't appear to have written any sort of reference AppleTalk router software to accommodate the specifications they wrote in Inside AppleTalk and earlier drafts. The first routers appear to be from 1986 (maybe even late-85?), based on the SEAGATE code written by Stanford University. Since it was open source, it was widely copied and eventually found its way into commercial products, namely the Fastpath. I don't see any evidence that Apple wrote their own router or bridge software until Apple Internet Router and LocalTalk/LaserWriter Bridge appeared years later (1990 according to Usenet, draft docs are dated 1989).

Without that sort of "blueprint", companies like Webber got creative with the spec (since there wasn't one) and this lead to things like the ImageWriter card breaking with their gateway's software. I wouldn't be surprised if LaserWriters with their generous CPU and RAM, actually looked at the NBP lookup packet's tuple to determine the client's network and node numbers to send a NBP request back to.

Apple didn't make that mistake when they released the AURP specification. They clearly state in the docs that AIR 3.0 is the reference implimentation and to use that when designing a router.
 
The Apple IIe Workstation card won't have a problem with NBP requests in long DDP packets
I could force the generated LkUp-Reply to be a long-form DDP datagram
Okay, this is what I did, it's been pushed to github - @fergycool, can you give this a try?

Inside AppleTalk doesn't state that a router broadcasting local NBP lookup packets on routed non-extended networks need to be long form.
Besides the erroneous behavior of the AT ImageWriter and friends, are there any consequences of them being short form? TashRouter's Name Information Service broadcasts short-form DDP datagrams, and always has done, as far as I'm aware. I was resistant to force them to always be long-form (favoring the LkupRouter solution), but it's been long enough that I can't remember why exactly. Maybe I'll dig back into this thread and see if anything jogs my memory...
 
I also need to figure out how to route LToUDP over a different lan/interface other than the appletalk one.
It defaults to 0.0.0.0, but you can change the interface address for LtoudpPort by passing the intf_address argument to it, comme ça:
Python:
router = Router('router', ports=(
  LtoudpPort(seed_network=1, seed_zone_name=b'LToUDP Network', intf_address='1.2.3.4'),
  MacvtapPort(macvtap_name='macvtap0', seed_network_min=3, seed_network_max=5, seed_zone_names=[b'EtherTalk Network']),
))
 
Since I have an easy way to trace packets on LocalTalk now here is the flow of NBP packets with a Fastpath and without a router. Using the LaserJet 4MP as the example printer.

Router's node is 220 on both segments. Localtalk network number in routed examples is 5, Ethernet is 1.

Without Router:
-Client sends NBP Lookup to 0.255 with short DDP header.
-Printer sends NBP Reply direct to client with short DDP header.

With Router, Client in same network as printer:
-Client sends NBP Broadcast to 5.220 with short DDP header.
-Router sends NBP Lookup to 5.255 with long DDP header. Header's source net/node address is the router's.
-Printer sends NBP Reply direct to client with short DDP header.

With Router, Client on different network as printer:
-Client 1.240 sends NBP Broadcast to 1.220 with long DDP header.
-Router sends NBP Lookup to 5.255 with long DDP header. Header's source net/node address is the client's (1.240).
-Printer sends NBP Reply direct to router with long DDP header with client as the destination net/node in header.

Clearly my LaserJet is parsing the NBP tuple in the lookup packet to determine the source node in situation #2 since it can't glean the info from the header. Its likely the ImageWriter does too if it works fine with a Fastpath. Otherwise it wouldn't work OR the Fastpath re-transmits the erroneous packet that was directed to it back to the client it was intended for, but this isn't likely. My PR changed TashRouter is always use the client's address as the source net/node in a NBP reply packet regardless of where it came from.

I installed the AppleTalk ImageWriter driver and had it issue a NBP broadcast and it followed the same flow above (except for a reply since I don't have an actual printer), so the Fastpath isn't fudging packet headers if it see a NBP type of "ImageWriter" or "LQ".
 
Back
Top