TailTalk: 一个基于 Rust 和 Tokio 的现代异步用户空间 AppleTalk 协议栈
摘要
TailTalk 是一个使用 Rust 和 Tokio 实现的现代异步用户空间 AppleTalk 协议栈,旨在构建能够通过 EtherTalk 或 LocalTalk 网络与经典 Mac 通信的实现。
查看缓存全文
缓存时间: 2026/09/13 14:38
FeralFirmware/TailTalk
来源:https://github.com/FeralFirmware/TailTalk
TailTalk
TailTalk 被设计为一套“工具包“,用于在 Linux、Mac OS 和 Windows 系统上通过 EtherTalk 或 LocalTalk 网络构建完全用户空间的 AppleTalk 实现。它从零开始构建,完全不依赖 Netatalk 或任何内核驱动程序——它只需要一个原始套接字和/或兼容 TashTalk 的设备(用于 LocalTalk),以及面对老旧计算机的耐心。它提供了一个完整的 AppleTalk 协议栈,并且多个实例可以同时在同一台机器上运行。
我启动这个项目是为了能够向我的旧 Mac 传输文件/从旧 Mac 接收文件,向 LaserWriter、ImageWriter 和联网的 StyleWriter 发送打印任务,并编写现代的异步软件与它们通信。目前 TailTalk 仅适用于无路由器的设置——正在努力使其能够优雅地加入有路由器存在的网络,但此功能尚未加入主线代码。
协议栈的每个部分都旨在尽可能“零配置“,就像在那个时代的 Mac 上运行一样。只需插上它,启动,一切就应顺畅运行,无需任何繁琐设置。
这个项目是一个正在开发中的原型,因此可能存在错误和缺失功能。
TailTalk GUI
这是目前面向用户、与 TashTalk USB 配合使用的程序。它包含一个 AFP 服务器,理论上应能与几乎所有配备 LocalTalk 端口的 Mac 配合工作。它还能导入 Stuff-It 压缩包和软盘镜像文件,并将它们加载到共享路径中,同时保留资源分支,然后供远程客户端访问。
它还额外支持将具备 LocalTalk 功能的 LaserWriter、ImageWriter 和 StyleWriter 以 AirPrint / IPP 打印机的形式共享到现代网络,以及将现代打印机共享给经典的 Mac。最新版本可在此处找到:
https://github.com/FeralFirmware/TailTalk/releases/latest
功能
针对几乎所有主要的 AppleTalk 协议,提供数据包解析器和完全异步的 API。
- AppleTalk 地址解析协议(AARP)
- 数据报传输协议(DDP)
- 名称绑定协议(NBP)
- AppleTalk 事务协议(ATP)
- 打印机访问协议(PAP)
- AppleTalk 会话协议(ASP)
- AppleTalk 文件协议(AFP)
- AppleTalk 数据流协议(ADSP)
它还支持与 TashTalk 配合用于 LocalTalk Mac。
AARP/DDP 底层可以在进程内(默认)或在共享守护进程 tailtalkd 中运行。该守护进程拥有接口,并通过 Unix 或 UDP 套接字上的 protobuf 协议,将 DDP 套接字、寻址和路由规则提供给多个客户端——既可以从 TailTalk (TalkStack::builder().daemon_unix(..)) 使用,也可以从纯 C 客户端使用。详情请参阅 docs/daemon-protocol.md。
构建
先决条件
此项目需要 Rust 1.90 或更高版本,可以从 rustup.rs (https://rustup.rs) 安装。默认情况下,这应会为您的操作系统和 CPU 架构安装匹配的编译器。
此项目使用 cargo-packager 来构建 Linux 的 AppImage、macOS 的 App 包以及 Windows 的安装程序。使用 cargo install cargo-packager 安装它。
仅限 Windows
请确保已按照 rustup 手册 (https://rust-lang.github.io/rustup/installation/windows-msvc.html) 的说明安装了 Windows MSVC 先决条件。
Windows 需要将 npcap SDK 保存在计算机的某个位置。可从 npcap.com (https://npcap.com/#download) 获取。将 LIB 环境变量指向解压后的 SDK 所在文件夹,例如:C:\npcap-sdk-1.13\Lib\x64
运行构建
安装先决条件后,从本仓库根目录运行 cargo build --release 以构建所有内容,或者仅构建 TailTalk GUI 则运行 cargo build -p tailtalk-gui --release。
构建完成后,二进制文件应位于 target/release/。
然后根据您的操作系统运行以下命令:
# Linux
cargo packager --release -f appimage -p tailtalk-gui
# macOS
cargo packager --release -p tailtalk-gui
# Windows
cargo packager --release -f nsis -p tailtalk-gui
生成的包将放置在 dist/ 目录中。
TashTalk USB
快速入门指南:Setup.md
TashTalk USB 使用 Silicon Labs CP210x USB 转 UART 桥接芯片(VID 10c4,PID ea60)。
Linux
cp210x 内核模块很可能已安装,但默认情况下设备节点仅 root 可访问。要授予您的用户权限而无需 root 权限,请创建一个 udev 规则:
echo 'SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", TAG+="uaccess"' \
| sudo tee /etc/udev/rules.d/99-tashtalk-usb.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
运行这些命令后,拔下并重新插入 TashTalk USB 设备。它将显示为 /dev/ttyUSB0(或类似设备)并且无需 root 即可访问。
Windows
从 Silicon Labs (https://www.silabs.com/software-and-tools/usb-to-uart-bridge-vcp-drivers?tab=downloads) 安装 CP210x VCP Windows 驱动程序。
从 npcap.com (https://npcap.com/#download) 安装 npcap 1.88。
MacOS
macOS 11 及更高版本原生支持 CP2102N USB 芯片。对于 10.12 到 10.15 版本,需要安装 Silicon Labs 提供的驱动程序才能识别设备:https://www.silabs.com/software-and-tools/usb-to-uart-bridge-vcp-drivers?tab=downloads
EtherTalk
在 macOS 上,EtherTalk 默认被编译到 GUI 中,因为 macOS 自带 libpcap。在 Linux 和 Windows 上,它是可选的:在安装了 libpcap (libpcap-dev) 或 npcap SDK 后,使用 cargo build -p tailtalk-gui --features ethertalk 进行构建。
macOS
数据包捕获和注入通过 /dev/bpf* 进行,默认情况下仅 root 可访问。要以普通用户身份使用 EtherTalk,请安装 Wireshark 磁盘镜像中附带的 ChmodBPF 包(或运行 brew install --cask wireshark-chmodbpf)。它会创建一个 access_bpf 组,将 BPF 设备分配给该组,并将您添加到该组。
组成员资格仅对新登录会话生效,因此之后请注销并重新登录。在此之前,以及如果完全未安装 ChmodBPF,GUI 会隐藏以太网接口选择器,而不是提供无法启动的传输方式。
现有程序
我编写了 4 个演示程序,用于在开发过程中验证此软件的功能:
- aep-echo - 一个简单的回显程序,向目标地址发送回显请求并打印响应时间。
- afp-server - 一个兼容 AFP 1.0、1.1 和 2.0 的 AFP 服务器。目前仍在开发中,但能够读写经典 Mac 系统的文件。支持基本的目录浏览和文件操作。
- nbp-lookup - 根据提供的请求字符串执行 NBP 查询并返回结果。
- pap-print - 将 PostScript 文件发送到 PAP 打印机。主要针对 LaserWriter,并且仅在我自己的 4/600 PS 上测试过。
- tailtalkd - TailTalk 底层守护进程。拥有物理 AppleTalk 接口,并通过 Unix/UDP 套接字向客户端应用程序提供 DDP 套接字、寻址和路由。
- tailtalk-gui - 一个简单的 GUI,用于通过 EtherTalk 和/或 LocalTalk(通过 TashTalk)将文件夹共享为卷。
所有示例都使用原始套接字(如果启用了 EtherTalk)运行协议栈的完整副本,因此需要以 root 身份运行,或者对编译后的二进制文件应用适当的 setcap(在 macOS 上,使用 ChmodBPF 代替,请参阅 EtherTalk)。如果仅使用 TashTalk,则不需要此操作。
测试
除了单元测试之外,我发现测试此软件的最佳方式是使用真实硬件。我目前的测试设置包括:
- 运行 TailTalk 的 Linux 机器
- 通过以太网运行 Mac OS 9.2 的 PowerBook G3
- 通过 AsanteTalk 连接的 LaserWriter 4/600 PS
- 通过 EtherTalk 适配器连接的 Color StyleWriter 2200
- 配有 LocalTalk 选件卡的 ImageWriter II
- 通过 AsanteTalk 运行 System 7.1 的 Macintosh SE/30
- 通过 AsanteTalk 运行 System 6.0.8 的 Macintosh Classic
AsanteTalk
AsanteTalk 首次通电时,它会在以太网一侧“监听“传入的数据包,然后才选择运行的 EtherTalk 阶段。如果它没有看到任何 EtherTalk Phase 2 数据包,它将默认为 Phase 1。TailTalk 支持 Phase 1,这对于 LaserWriter、NBP 和一些基本操作运行良好,但不适用于 AFP(Mac 会发现 AFP TailTalk 服务器,但我们的响应似乎被丢弃)。
贡献
我很希望看到这个项目发展成可以用来构建更完整 AppleTalk 实现的东西。欢迎所有贡献,但请先开一个 issue 讨论您想要做的更改。此外,Pull Request 应注明该更改在哪些系统上进行了验证。这个项目让我意识到旧系统是多么奇特。
许可证
此项目根据 GNU 通用公共许可证 v3.0 授权 - 有关详细信息,请参见 LICENSE 文件。
相似文章
宣布 Topcoat: 一个使用 Rust 构建全栈响应式 Web 应用程序的框架
Tokio 宣布 Topcoat,一个模块化、开箱即用的 Rust 框架,用于构建全栈响应式 Web 应用程序,完全服务器端渲染,具有类似于 HTMX 的响应式指令。
Tokio 应用程序的快速优化原则
本文概述了在 Rust 中优化 Tokio 应用程序的最佳实践,涵盖了延迟与吞吐量以及调试策略等原则。
谁在运行你的 Rust Future?动手实践入门异步 Rust
这是一套动手实践教程系列,旨在弥合理解异步 Rust 内部机制(Future、poll、Pin、执行器)与使用 Tokio 部署实际异步代码之间的差距,面向熟悉 JavaScript 异步和基础 Rust 的开发者。
Rust 中的尾调用解释器 – Jimmy Ostler
Jimmy Ostler 深入探讨了 Rust 中的尾调用解释器,实现并基准测试了多种虚拟机分发技术,包括 switch 分发、子例程线程化和尾调用优化的机器。
multistack - 本地编码代理的 TUI 编排工具
本文介绍了 multistack,这是一款基于 Ratatui 用 Rust 开发的轻量级 TUI 编排工具,专为本地编码代理设计;为契合 zerostack 的设计理念,该工具被打造得极为轻便。希望它能对大家有所帮助!