Many network devices are able to upload and download firmware and configurations via the TFTP protocol. I have found it useful to use this feature with Netopia ENT routers, as it enables me to make backups of client configurations, and update the firmware directly on my service laptop. OS X comes with tftpd preinstalled. On OS X Server, tftpd is utilized for NetBoot; however, on the standard client, the framework still exists.
In Tiger, most services that were previously configured using xinetd have been migrated to launchd. The new launchd service consults the settings located in /System » Library » LaunchDaemons and /Library » LaunchDaemons directories. By default, Tiger has tftp.plist installed, however, this should be modified to suit your needs.
First, back up the default tftp.plist as below:
The tftp.plist includes only one program argument: -i. This flag prohibits usage with realpath, which will translate relative links to a full path. I would recommend using this as well as the -s flag, which essentially chroots the environment. The entire contents of this modified file is as follows (note that there is no return within the <!DOCTYPE plist... statement):
cp /System/Library/LaunchDaemons/tftp.plist ~/Desktop/tftp.plist
You may also wish to add the -l flag in the ProgramArguments block to enable logging requests to syslog. Consult the tftpd man pages for additional arguments. In 10.4, the /private/tftpboot directory already exists, so no other changes are necessary. The service may be started with the following command:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>InitGroups</key> <true/> <key>Label</key> <string>com.apple.tftpd</string> <key>ProgramArguments</key> <array> <string>/usr/libexec/tftpd</string> <string>-i</string> <string>-s</string> <string>/private/tftpboot</string> </array> <key>Sockets</key> <dict> <key>Listeners</key> <dict> <key>SockServiceName</key> <string>tftp</string> <key>SockType</key> <string>dgram</string> </dict> </dict> <key>inetdCompatibility</key> <dict> <key>Wait</key> <true/> </dict> </dict> </plist>
And stopped with:
$ sudo launchctl load -w /System/Library/LaunchDaemons/tftp.plist
The TFTP protocol allows any user to read and write to files on your system, so keep this in mind when choosing the storage directory. As a minimal security measure, the files must already exist before writing to them, and must have write access by all users. In general usage, I will store firmware upgrades with read-only access. When capturing someone's firmware configuration, I then perform the following:
sudo launchctl unload -w /System/Library/LaunchDaemons/tftp.plist
At this point, you're ready to start using the service to store configurations as needed. For testing, you can perform the following:
$ cd /private/tftpboot $ sudo touch netopia.conf $ sudo chmod 666 netopia.conf
This will open a tftp connection and switch to an interactive tftp session. Now perform the following:
$ cd ~/Desktop $ echo "THIS IS A TEST" > netopia.conf $ tftp localhost
If there are no errors returned, all is working correctly. If not, check your firewall settings to ensure that UDP port 69 is open. Other issues may be due to syntax errors in the tftp.plist file.
tftp>verbose tftp>put netopia.conf tftp>quit
Mac OS X Hints