• 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.

Help with AppleTalk routing

tashtari

PIC Whisperer
So I'm trying to put my (somewhat limited) networking knowledge into the creation of a flexible software AppleTalk router with support for TashTalk and LToUDP as well as EtherTalk and I've been perusing Inside AppleTalk to that end.

There is a nice flowchart of the routing algorithm on page 5-26 of IA which I've been trying to turn into code...

datagram_routing.png

...unfortunately, it doesn't specify what to do in the case of a datagram or a port that has a network number of 0x00, and I'm altogether confused as to how to handle these cases.

Here's the relevant portions of my code so far, complete with TODOs where I'm not sure of things:

Python:
def network_eq(a, b):
  '''Return whether network numbers are equivalent according to IA page 4-21.'''
  return True if 0 in (a, b) or a == b else False

# ...

  def process(self, rx_port, datagram):
    '''Process a Datagram from a port, discarding or routing and/or delivering it as appropriate.'''
    
    if not rx_port.extended_network and not datagram.long_ddp_header:
      # deliver (we wouldn't have received this datagram if it wasn't meant for us directly)
      self.deliver(datagram)
    elif network_eq(datagram.destination_network, rx_port.network) and datagram.destination_node in (rx_port.node, 0xFF):
      # deliver (this is the destination network and node, or this is the destination network for a broadcast)
      self.deliver(datagram)
    elif rx_port.network_min <= datagram.destination_network <= rx_port.network_max and datagram.destination_node == 0xFF:
      #TODO how to handle zero dest network or range of 0-0 on rx_port?
      # discard (network-specific broadcast not for this router)
      pass
    elif datagram.destination_network not in self.routing_table:
      #TODO should we skip this case if dest network is 0?
      # discard (can't get there from here)
      pass
    else:
      #TODO if dest network is 0, should we loop through the below with all entries in the routing table?
      entry = self.routing_table[datagram.destination_network]
      if entry.distance != 0:
        if datagram.hop_count < 15:
          # route (here isn't there but we know how to get there)
          entry.port.send(entry.network, entry.node, datagram.hop())
        else:
          # discard (excess hop count)
          pass
      elif datagram.destination_node == 0x00:
        # deliver (special 'any router' address, see IA page 4-7)
        self.deliver(datagram)
      elif network_eq(datagram.destination_network, entry.port.network) and datagram.destination_node == entry.port.node:
        # deliver (addressed to another port of this router's)
        self.deliver(datagram)
      else:
        if network_eq(datagram.destination_network, entry.port.network) and datagram.destination_node == 0xFF:
          # deliver (broadcast includes another port of this router's)
          self.deliver(datagram)
        # route (the destination is connected to us directly)
        entry.port.send(datagram.destination_network, datagram.destination_node, datagram)

Anyone willing to have a look, perchance to provide some direction? =)
 

cheesestraws

Well-known member
...unfortunately, it doesn't specify what to do in the case of a datagram or a port that has a network number of 0x00, and I'm altogether confused as to how to handle these cases.

Noting here following discussion on IRC:

Ports should never have network numbers of 0x00, it's illegal configuration.

Packets with a network number of 0x00 kind of behave like short-header DDP packets. That is:

The data plane of the router should drop it. You should never route a packet with network number 0. See Inside Appletalk 2nd. ed. p. 4-6.

The control plane of the router should consider it means "current network" (again, p. 4-6 is our source here.) So if a packet comes in on an interface of the router with network number 0 and node ID corresponding to the router's, it should answer it. But this probably means that something has gone wrong.
 

NJRoadfan

Well-known member
LocalTalk and EtherTalk Phase 1 ("non-extended" AppleTalk) on router-less networks are the only times you should see network 0x00. They are assigned a single network number by a router using RTMP. A router should not route any packets with a network destination of 0x00 as clients behind that router should have been given a number on startup by the router.

All the newer link-layers (EtherTalk Phase 2, TokenTalk, etc.) use network numbers. If no router is found (broadcasting network range), they self organize using the "startup range" of networks. Clients can also glean the network information via AARP packets and RTMP packets.
 
Top