Wednesday, January 17, 2018

The AppleTalk experience: Mac OS 9 on SheepShaver and Netatalk on Ubuntu (Classic Power Macintosh 9500 PowerPC G4)

Mac OS 9 running in SheepShaver accessing shared files on three Ubuntu nodes over AppleTalk via netatalk
Apple Mac OS 9 in SheepShaver communicating over AppleTalk network protocol with Ubuntu Linux nodes via Netatalk

With 10 DECnet nodes connected to the global hobbyist HECnet network stable and staying up, I started to wonder what other non-Internet Protocol (non-TCP/IP) networking experiment I could run. Apple's classic AppleTalk protocol came to mind.


Originally released as AppleNet in 1983 for the Apple II and Lisa, AppleTalk has roots in Xerox XNS. AppleTalk's ancestry is no less illustrious than DECnet.

Despite phenomenal rise of the Internet Protocol (TCP/IP), AppleTalk was supported all the way to the 2009 release of Mac OS X Snow Leopard. Interoperability with TCP/IP was introduced as far back as 1988 with MacTCP and later MacIP (Wikipedia) which basically piggybacked IP over AppleTalk. However, my objective here was to stay away from IP completely, and focus on pure AppleTalk.

I had zero experience with AppleTalk networking. Fortunately, there is still enough reading material out on the 'net to get a feel for it. "Inside Macintosh: Networking" is a great book. The Netatalk 2.0 documentation is fabulous. And Cisco's Protocol Filter appendix is handy in deciphering stuff like 0x809b ether-type packets that suddenly pop up in packet dumps once AppleTalk kicks in. 0x809b is EtherTalk, "an Apple AppleTalk networking protocol that enables AppleTalk to communicate over Ethernet cabling."

Supratim Sanyal's Blog: AppleTalk Protocol EtherTalk (ethertype 0x809b) frames captured by iptraf-ng packet capture tool
EtherTalk (ethertype 0x809b) frames captured by iptraf-ng on Ubuntu Linux

Objectives


After reading around a bit, and not being a AppleTalk expert, I set myself the simplest of objectives of this experiment:

  1. Bring up a classic Macintosh virtual machine running Mac OS with Ubuntu Linux as host
  2. Configure Mac OS and the virtual machine to support AppleTalk networking
  3. Add AppleTalk support to Ubuntu Linux host machine
  4. Have the Mac OS virtual machine access files on Ubuntu host machine via AppleTalk
  5. Bring in more Ubuntu Linux boxes supporting AppleTalk to the happy AppleTalk island
As the screenshot at the top of this post demonstrates, this experiment is pretty successful. In summary, the objectives were met respectively by:
  1. SheepShaver on Ubuntu running Mac OS 9, with sheep_net kernel network module
  2. The Mac OS 9 installation procedure installs AppleTalk
  3. Netatalk 2.0
    • Netatalk version 2.2.5 on Ubuntu 17
    • Netatalk version 2.2.2 on Ubuntu 14
  4. Editing configuration files of Netatalk daemons
  5. Same as 4
A note of caution: I had initially grabbed and built Netatalk 3.0 from source, but fell back to Netatalk 2.0 because support for AppleTalk was discarded in Netatalk 3.0.

Configuring SheepShaver to run a virtual Classic Apple Power Macintosh 9500 / PowerPC G4 CPU with MacOS 9 on Ubuntu Linux

Build SheepShaver from Source


There is some documentation here and here which boil down to the following. The Ubuntu version I built and run SheepShaver on is Ubuntu 17.04.

First, make sure the required packages are installed.

$ sudo apt-get install build-essential autoconf git libx11-dev libesd0-dev gtk+3.0-dev libsdl-dev libgtk+2.0-dev

Then, with root privileges, edit the file /etc/sysctl.conf to add the following lines at the bottom (this allows SheepShaver to run from a non-root account):

# --

# Needed for SheepShaver Mac Classic emulator
# --
vm.mmap_min_addr=0


Still with root privileges, enter the following command (or reboot):

service procps start


The following script fetches the SheepShaver source code and builds it.


I found various packages, all from standard Ubuntu repositories, to get a autoconfig result of:

SDL support ...................... : none
BINCUE support ................... : no
LIBVHD support ................... : no
FBDev DGA support ................ : yes
XFree86 DGA support .............. : yes
XFree86 VidMode support .......... : yes
Using PowerPC emulator ........... : yes
Enable JIT compiler .............. : yes
Enable video on SEGV signals ..... : yes
ESD sound support ................ : yes
GTK user interface ............... : gtk2
mon debugger support ............. : no
Addressing mode .................. : real
Bad memory access recovery type .. : siginfo

Once the main SheepShaver program has been built, the following script builds the sheep_net.ko kernel module.



The following script installs the sheep_net.ko kernel module and creates the /dev/sheep_net network device with the right ownership:



Configure and run SheepShaver


I created a directory ~/sheepshaver.run/ and copied over the SheepShaver binary from the build location (~/sheepshaver.build/macemu/SheepShaver/src/Unix/SheepShaver). I then looked around the internet to locate a "New World" ROM (newworld86.rom) and a Mac OS 9 bootable installer image (Mac OS 9.toast). There are pointers to where they can be obtained from at "Setting up SheepShaver for Mac OS X". I placed both these items in the same directory as the SheepShaver binary.

I created a subdirectory called "shared" to share files between the Ubuntu host and SheepShaver's Mac desktop. This directory is configured to be the "Unix Root" on SheepShaver and shows up as the drive "Unix" on the virtual Mac desktop. It simplifies transfer of files between Ubuntu host and Mac OS 9 virtual machines guest; anything copied into "shared" shows up in the "Unix" drive on Mac OS desktop though they cannot be executed directly from there, requiring me to copy executable installers from "Unix" to a local place on Mac OS first.

Finally I fired up SheepShaver, added the boot disk image, created two disk drives of 250 MB each, disabled sound (I do not want audio!), set the network interface and launched the emulated PowerMac G4. Here is a series of pictures of the options I configured in each tab:

Supratim Sanyal's Blog: SheepShaver Mac OS 9 Disk Configuration on Ubuntu Linux
SheepShaver Mac OS 9 Disk Volume and Shared Directory configuration

Supratim Sanyal's Blog: SheepShaver Mac OS 9 Graphics and Sound configuration Ubuntu Linux
SheepShaver Mac OS 9 Graphics and Sound configuration

Supratim Sanyal's Blog: SheepShaver Mac OS 9 Keyboard and Mouse configuration Ubuntu Linux
SheepShaver Mac OS 9 Keyboard and Mouse configuration

Supratim Sanyal's Blog: SheepShaver Mac OS 9 Serial Ports and Network Adapter configuration AppleTalk Ubuntu Linux
SheepShaver Mac OS 9 Serial Ports and Network Adapter configuration
I used a port on a VDE (Virtual Distributed Ethernet)  switch already configured and used by my DECnet nodes

Supratim Sanyal's Blog: SheepShaver Mac OS 9 Memory and Misc configuration Ubuntu Linux
SheepShaver Mac OS 9 Memory and Misc. configuration

Supratim Sanyal's Blog: Supratim Sanyal's Blog: SheepShaver Mac OS 9 JIT Compiler configuration Linux Ubuntu
SheepShaver Mac OS 9 JIT Compiler configuration


When the "Start" button is clicked, SheepShaver saves the configuration out to a dotted (hidden) text file called ".sheepshaver_prefs" in the home directory, i.e. "~/.sheepshaver_prefs". It then launches the virtual Power Macintosh and boots from the CD image.

On examining ~/.sheepshaver_prefs I found a time-saving trick - setting "nogui" to "true" does not launch the heavy graphical configuration tool first but boots up the Mac OS 9 virtual machine directly. It is much easier to directly edit ~/.sheepshaver_prefs instead of having to deal with a GUI. Here is my  ~/.sheepshaver_prefs:

disk SANYALnet-MacOS9-Disk1.dsk
disk SANYALnet-MacOS9-Disk2.dsk
extfs shared
screen win/800/600
windowmodes 0
screenmodes 0
seriala /dev/null
serialb /dev/null
rom newworld86.rom
bootdrive 0
bootdriver 0
ramsize 536870912
frameskip 12
gfxaccel false
nocdrom true
nonet false
nosound true
nogui true
noclipconversion false
ignoresegv true
ignoreillegal true
jit true
jit68k false
keyboardtype 5
ether vde-decnet-tap2
keycodes false
mousewheelmode 1
mousewheellines 3
dsp /dev/dsp
mixer /dev/mixer
ignoresegv true
idlewait true


I use the following script to start the Mac OS 9 SheepShaver application with the X11 GUI going to a detached virtual X11 display screen using the "xpra" tool.



Install Mac OS 9 in SheepShaver


Supratim Sanyal's Blog: Mac OS 9 booting up from CD ROM installer image in SheepShaver on Ubuntu Linux
Mac OS 9 Installation CD Boot in SheepShaver
As expected for new disks, the installer asks to initialize them. I decided to initialize the two disks with "Mac OS Extended" file system instead of the default "Mac OS Standard". It appears from the literature around the internet that "Mac OS Extended" is actually a journaling file system with better performance for normal use.

More importantly, the "Update Apple Hard Disk Drivers" checkbox in the "Options" screen accessible via the "Options..." button needs to be unchecked (cleared) for successful SheepShaver installation; SheepShaver hangs if this button is checked.

Supratim Sanyal's Blog: Mac OS 9 installation options: "Update Apple Hard Disk Drivers" must be unchecked for SheepShaver
Mac OS 9 installation options: "Update Apple Hard Disk Drivers" must be unchecked for SheepShaver
As far as "Customize" is concerned, I pretty much selected everything except Speech-related features.

Supratim Sanyal's Blog: Mac OS 9 Customized Installation Example: Selecting "All" Internet Access Features
Mac OS 9 Customized Installation Example: Selecting "All" Internet Access Features

I then proceeded with the installation by clicking "Start".

Supratim Sanyal's Blog: Mac OS 9 on SheepShaver CD ROM image installation progress
Mac OS 9 on SheepShaver CD ROM image installation progress

Once installation completed (it takes about 7 - 8 minutes), I shut Mac OS 9 down and restarted SheepShaver to get back to the launcher options GUI. I then removed the CD ROM from the list of volumes and booted up Mac OS 9 from the hard disk.

Supratim Sanyal's Blog: Mac OS 9 SheepShaver Configuration for Hard-Disk only volumes (CD ROM volume removed)
Mac OS 9 SheepShaver Configuration for Hard-Disk only volumes (CD ROM volume removed)
On booting up the first time after installation, Mac OS 9 presents a "Mac OS Setup Assistant" window. It is very important the Setup Assistant be not used; all configuration can be done separately using the various Control Panels reachable via the Apple logo at the top left. Mac OS Setup Assistant hangs SheepShaver, close it immediately!

Supratim Sanyal's Blog: Mac OS 9 Setup Assistant in SheepShaver for Ubuntu Linux
The Mac OS 9 Setup Assistant: Close the Setup Assistant immediately; it hangs SheepShaver
That completes the base installation of Mac OS 9 on SheepShaver, ready to be configured for its networking features. Here are a couple of more screenshots.

Supratim Sanyal's Blog: Clean initial installation of Mac OS 9 on Power Macintosh emulated by SheepShaver for Ubuntu Linux

Supratim Sanyal's Blog: Clean initial installation of Mac OS 9 on Power Macintosh emulated by SheepShaver for Ubuntu Linux
Clean initial installation of Mac OS 9 on Power Macintosh emulated by SheepShaver for Ubuntu Linux

Get Mac OS 9 in SheepShaver Ready for AppleTalk


It took me a while and many SheepShaver freezes to figure this out:

Mac OS 9 in SheepShaver needs to have an IP address, netmask and gateway configured, and the configured Gateway needs to be reachable, to not freeze and stay up even if we are using only AppleTalk.

It does not matter if the configured IP Gateway actually connects to the internet or anything at all; as long as Mac OS 9 can see it, it is happy.

I used the TCP/IP control panel to configure a dummy IP address, subnet mask, router (Apple speak for Gateway) and Name server (DNS).

Supratim Sanyal's Blog: Mac OS 9 TCP/IP configuration using TCP/IP Control Panel
TCP/IP Control Panel on Mac OS 9

Then I assigned the router and DNS address configured in Mac OS 9 to a different plug on the same VDE switch on the Ubuntu host so that Mac OS 9 can see the  IP gateway. There is no IP traffic after a few initial startup packets.

$ ip addr show vde-decnet-tap3
13: vde-decnet-tap3: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 82:29:cd:e3:f6:56 brd ff:ff:ff:ff:ff:ff
    inet 192.168.217.1/27 brd 192.168.217.31 scope global vde-decnet-tap3
       valid_lft forever preferred_lft forever

I did not have to do much else in terms of preparing for AppleTalk; it did really work "automagically" as claimed once Netatalk was configured on the Ubuntu host.

Install and Configure Netatalk on Linux Ubuntu


Unfortunately my total ignorance of AppleTalk resulted in spending significant time in numerous false starts before everything fell into place. One of the bigger mistakes I made was to download and build Netatalk 3.0 from source, only to realize later that they completely took out support for AppleTalk in Netatalk 3.0 onwards.

There is no AppleTalk router in my setup. All AppleTalk nodes are plugged into the same VDE virtual switch. Also, there is no AppleTalk Zone Name required or specified; there is only one zone which is also the default zone.

Ultimately what worked was a straight-forward installation from standard Ubuntu repository which pulled in Netatalk version 2.2.5 (on Ubuntu 17), and edits to just four files.

/etc/default/netatalk

To use the AFP file server, I enabled both the cnid_metad and afpd daemons. Since I am only interested in AppleTalk, I enabled the atalkd, papd and timelord "legacy" daemons but left the a2boot daemon disabled because I have no need for netbooting. Here is /etc/default/netatalk configuration file from MOKSHA which is the Ubuntu 17.04 host machine for SheepShaver.




/etc/netatalk/atalkd.conf

The virtual Ethernet card on my SheepShaver configuration is connected to a plug on a Virtual Distributed Ethernet (VDE) switch running on MOKSHA which also happens to host four more virtual machines that communicate over DECnet. All I needed to do with atalkd.conf is stick in the name of a hitherto unused VDE plug network device, just by itself, on the last line. Netatalk actually modifies this file on startup with a startup AppleTalk net-range and a self-generated node number (which it decides on "automagically" based on what it can see on the network) and adds those items to the configuration itself. Here is my atalkd.conf from MOKSHA after being modified by Netatalk.




/etc/netatalk/afpd.conf

This file configures file-sharing between Ubuntu and Mac OS 9 over AppleTalk. Interested only in AppleTalk, I disabled TCP and enabled DDP ("Datagram Delivery Protocol") that is part of the AppleTalk stack. I also enabled guest access requiring no authentication and a "welcome" message that is displayed when a guest connection is established to Ubuntu from Mac OS 9.

The Ubuntu directory made available publicly to Mac OS 9 over AppleTalk is actually configured in the next file.

Supratim Sanyal's Blog: AppleTalk Remote Network File Share Login Welcome Message on Mac OS 9 accessing Ubuntu shared directory
AppleTalk Network File Share Login Message


Here is my afpd.conf file.




/etc/netatalk/AppleVolumes.default

This file defines the directories to be shared by Ubuntu over AppleTalk for Mac OS clients. I configured just one directory to be shared with Mac OS. (I have a lofty goal of making this directory available over the FAL service of DECnet as well, hence the name). Here is my AppleVolumes.default configuration file.



Of course, the netatalk service has to restarted using the standard Ubuntu systemctl (or service on Ubuntu 14) tool for configuration changes to take effect. Also, netatalk has to be enabled for starting up at boot using systemctl (or update-rc.d on Ubuntu 14).


More AppleTalk Nodes


With the Ubuntu 17 host and SheepShaver Mac OS 9 communicating successfully over AppleTalk at this point, I added two more Ubuntu 14 nodes FEDACH and FOMFOR into the AppleTalk mix. They were already bridged into the DECnet VDE switch that I am using for AppleTalk too.

Once again I simply used Ubuntu's standard apt-get command to install Netatalk from the repos.

FEDACH, FOMFOR and MOKSHA have identical /etc/default/netatalk and /etc/netatalk/AppleVolumes.default configuration files.

The network adapter on FEDACH and FOMFOR dedicated to non-IP protocols (i.e. DECnet and AppleTalk only) is eth1. I accordingly updated /etc/netatalk/atalkd.conf with a single item "eth1" and restarted the netatalk service. As expected, Netatalk looked around, negotiated with other AppleTalk nodes and "automagically" filled in additional parameters with the same net ranges but unique node addresses as follows:

FEDACH - /etc/netatalk/atalkd.conf:
eth1 -phase 2 -net 0-65534 -addr 65280.225


FOMFOR - /etc/netatalk/atalkd.conf:
eth1 -phase 2 -net 0-65534 -addr 65280.149

I edited the /etc/netatalk/afpd.conf files on the two nodes to reflect the correct node names and login (welcome) messages:

FEDACH - /etc/netatalk/afpd.conf:
"FEDACH" -ddp -notcp -uamlist uams_guest.so -loginmesg "Welcome to FEDACH over AppleTalk, a SANYALnet Labs Ubuntu 14.04 server also speaking DECnet Phase IV and Internet Protocol (IP)."


FOMFOR - /etc/netatalk/afpd.conf:
"FOMFOR" -ddp -notcp -uamlist uams_guest.so -loginmesg "Welcome to FOMFOR over AppleTalk, a SANYALnet Labs Ubuntu 14.04 server also speaking DECnet Phase IV and Internet Protocol (IP)."


Continuing fun with Mac OS 9 Non-TCP/IP Networking Protocols

Power Macintosh 9500 / PowerPC G4 CPU / Mac OS 9 communicating over both AppleTalk and DECnet (no IP)

Moving on from AppleTalk, I went ahead to install DEC Pathworks for Macintosh and added DECnet support to Mac OS 9, thus having Mac OS 9 talking both AppleTalk and DECnet. But DECnet for Macintosh and Pathworks for Macintosh are the subjects of a separate post that I will get to some time! If it is up, you can see this Mac OS 9 virtual machine on HECnet.

Comments welcome.