···11+Copyright (c) 2026 joshua stein <jcs@jcs.org>
22+33+Permission to use, copy, modify, and distribute this software for any
44+purpose with or without fee is hereby granted, provided that the above
55+copyright notice and this permission notice appear in all copies.
66+77+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
88+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
99+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1010+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1111+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1212+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1313+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+89
README.md
···11+# atalk-proxy
22+33+`atalk-proxy` listens for AppleTalk DDP (Datagram Delivery Protocol) and
44+AARP (AppleTalk Address Resolution Protocol) traffic on two ethernet interfaces
55+and proxies packets between them.
66+77+There are other solutions for this such as
88+[multitalk](https://github.com/sfiera/multitalk)
99+but this one has a few features I needed:
1010+1111+- It does not require kernel or libpcap support for AppleTalk, as is the
1212+ situation on OpenBSD. Packets are found by looking for specific bytes in the
1313+ header.
1414+1515+- It drops privileges after opening listening sockets using
1616+ [`pledge`](https://man.openbsd.org/pledge).
1717+1818+- Bare AARP packets that appear on the wire without a Logical-Link Control
1919+ header are given an LLC encapsulation before proxying.
2020+2121+- AARP replies that are sent out from the local side (`-t`) are inspected and
2222+ the MAC address of the sender is replaced with the MAC of the egress (`-e`)
2323+ interface.
2424+ This works as a
2525+ "[proxy ARP](https://en.wikipedia.org/wiki/Proxy_ARP)"
2626+ solution so other network devices know to send traffic to the device running
2727+ the proxy to reach devices on the proxy's other interface, which is likely
2828+ needed on Wi-Fi networks.
2929+3030+## Installation
3131+3232+ $ git clone https://github.com/jcs/atalk-proxy
3333+ $ cd atalk-proxy
3434+ $ make
3535+3636+`atalk-proxy` was written on OpenBSD and has only been tested there.
3737+3838+## Usage
3939+4040+When using an emulated Macintosh Plus in
4141+[pce](https://github.com/jcs/pce)
4242+on my laptop, configured with an emulated DaynaPort SCSI ethernet device, and
4343+configured to use EtherTalk for AppleTalk traffic, it sends packets out through
4444+a
4545+[`tap`](https://man.openbsd.org/tap)
4646+interface on my laptop.
4747+4848+I then run `atalk-proxy` to proxy traffic between that `tap0` interface and my
4949+laptop's wireless `iwx0` interface.
5050+That usage for me looks like:
5151+5252+ $ doas ./atalk-proxy -e iwx0 -t tap0
5353+5454+This enables the emulated device to communicate with other devices on my
5555+network using AppleTalk.
5656+5757+The `-d` flag can be used to print debugging information where each forwarded
5858+packet is described.
5959+6060+ $ doas ./atalk-proxy -d -e iwx0 -t tap0
6161+ [12:47:35.599] [iwx0] listening on egress using outbound MAC 00:d4:9e:x:x:x
6262+ [12:47:35.599] [tap0] listening on tap
6363+ [12:47:45.386] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
6464+ [12:47:45.741] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
6565+ [12:47:46.072] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
6666+ [12:47:46.402] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
6767+ [12:47:46.734] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
6868+ [12:47:47.063] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
6969+ [12:47:47.420] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
7070+ [12:47:47.735] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
7171+ [12:47:48.067] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
7272+ [12:47:48.396] [tap0] [ 50] AARP: is there a 65512.1? [-> iwx0]
7373+ [12:47:48.750] [tap0] [ 42] ZIP: GetNetInfo [-> iwx0]
7474+ [12:47:49.566] [tap0] [ 42] ZIP: GetNetInfo [-> iwx0]
7575+ [12:47:50.404] [tap0] [ 42] ZIP: GetNetInfo [-> iwx0]
7676+ [12:47:51.270] [tap0] [ 67] NBP: lookup: "nanomac:Macintosh Plus@*" [-> iwx0]
7777+ [12:47:52.324] [tap0] [ 67] NBP: lookup: "nanomac:Macintosh Plus@*" [-> iwx0]
7878+ [12:47:53.231] [tap0] [ 67] NBP: lookup: "nanomac:Macintosh Plus@*" [-> iwx0]
7979+ [12:47:57.418] [tap0] [ 56] NBP: lookup: "=:AFPServer@*" [-> iwx0]
8080+ [12:47:57.580] [iwx0] [ 42] AARP: who has 57344.0? tell 256.12 [-> tap0]
8181+ [12:47:57.610] [tap0] [ 50] AARP: 65512.12 is at 00:80:19:c0:c0:c0: replacing MAC in outbound AARP reply [-> iwx0]
8282+ [12:47:57.612] [iwx0] [ 57] NBP: reply[1]: "fs:AFPServer@*" [-> tap0]
8383+ [12:47:58.593] [tap0] [621] echo from 65512.1 to 65280.224 [-> iwx0]
8484+ [12:47:58.596] [iwx0] [621] echo from 65280.224 to 65512.1 [-> tap0]
8585+ [12:47:58.622] [tap0] [ 43] transaction protocol [-> iwx0]
8686+ [12:47:58.628] [iwx0] [470] transaction protocol [-> tap0]
8787+ [12:47:59.134] [tap0] [ 56] NBP: lookup: "=:AFPServer@*" [-> iwx0]
8888+ [12:47:59.443] [iwx0] [ 57] NBP: reply[1]: "fs:AFPServer@*" [-> tap0]
8989+ [12:48:00.337] [tap0] [ 43] transaction protocol [-> iwx0]