Skip to content

Commit

Permalink
Merge the two development histories
Browse files Browse the repository at this point in the history
  • Loading branch information
marcan committed Aug 20, 2009
2 parents f4854f3 + 79ca4d9 commit 1a0c58e
Show file tree
Hide file tree
Showing 23 changed files with 2,001 additions and 62 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -1 +1,3 @@
*~
build

5 changes: 5 additions & 0 deletions AUTHORS
@@ -0,0 +1,5 @@
Nikias Bassen
Hector Martin
Bastien Nocera
Paul Sladen
Martin Szulecki
10 changes: 10 additions & 0 deletions CMakeLists.txt
@@ -0,0 +1,10 @@
PROJECT(usbmuxd)

cmake_minimum_required(VERSION 2.6)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/Modules/")

add_subdirectory (libusbmuxd)
add_subdirectory (usbmuxd)
add_subdirectory (tools)
add_subdirectory (udev)
340 changes: 340 additions & 0 deletions COPYING.GPLv2

Large diffs are not rendered by default.

File renamed without changes.
502 changes: 502 additions & 0 deletions COPYING.LGPLv2.1

Large diffs are not rendered by default.

File renamed without changes.
File renamed without changes.
150 changes: 100 additions & 50 deletions README
@@ -1,27 +1,103 @@
This is an implementation of the iPhone/iPod Touch USB connection protocol.

The server should be mostly compatible with the original Apple usbmuxd
protocol. This means that a single client lib should be able to interoperate
with both. Apple has now introduced a new plist-based version of the protocol
which works in essentially the same way but uses XML-based plists as
command/response payloads instead of binary blobs. The outer binary protocol is
still the same used but now the only command/response format is 8 (plist).

The server is under the usbmuxd directory. You'll need CMake and libusb 1.0 to
build it. Due to a bug in zero-length packet handling, you'll need either the
git version of libusb or 1.0.3, whenever it comes out.

There is a Python client library in the python-client directory. It should be
compatible with Windows, Linux, and OSX (using the Apple usbmuxd on Win and OSX)
tcprelay.py implements a TCP connection forwarder that lets you pipe TCP
connections to localhost to the phone. Run it with --help for usage. The Python
client lib is also compatible with the new plist-based protocol and should
automatically select it if it sees such a server. However, you need Python 2.6
for Windows and Linux in this case, since the plistlib module doesn't come with
older versions under these OSes (not that you'll have a server that supports
this protocol under Linux. TODO: does Windows iTunes use this yet?)

ARCHITECTURE
Background
==========

'usbmuxd' stands for "USB multiplexing daemon". To the user/developer what it
actually does is to proxy requests over a USB cable on directly to a listening
TCP port on the iPhone.

Multiple connections to different TCP ports can happen in parallel. An example
(and useful) tool called 'iproxy' is included that allows you to forward
localhost ports to the device---allows SSH over USB on jailbroken devices, or
allowing access the lockdown daemon (and then to all of the file access, sync,
notification and backup services running on the device).

This higher-level layers are handled by libiphone. The version of libiphone
compatible with the 'usbmuxd' infrastructure is called 'libiphone-usbmuxd'.
'ifuse' is then able to sit on top of this.

There is also a Python implementation of the client library in the python-client
library, and an example tcprelay.py which performs a similar function to iproxy.
This implementation supports OSX and Windows and the new iTunes plist-based
usbmuxd protocol, so it is portable and will run on those operating systems with
no modification, using Apple's native usbmuxd. This is useful if you need to
tunnel to your phone from another OS in a pinch. Run python tcpclient.py --help
for usage information.

Building
========

mkdir build
cd build
cmake ..
make
sudo make install

Running (with magic)
====================

(Unplug + replug your iPhone)
./iproxy 2222 22 &
ssh -p 2222 root@localhost

Hopefully you get the normal SSH login prompt. You may still lots of debugging
output for the moment. If this is getting in the way of your ssh login, then
run the 'ssh' command from a different xterminal
or virtual console.


Running (without magic)
=======================

If 'udev' is _not_ automatically running on your machine and picking up the new
.rules file, you will need to start usbmuxd by hand first. Check it's running
and that there is only one copy with 'ps aux | grep
usbmuxd'.

sudo usbmuxd -U -v -v &
./iproxy 2222 22 &
ssh -p 2222 root@localhost


Tip: Starting SSH if disabled
=============================

If your iphone is rooted, but SSH isn't started and you _cannot_ (for instance,
cracked/broken screen) get to the Services control panel on the device, then you
can start the SSH service over the USB by
mounting the (jailbroken) filesystem.

You will need to mount it usbing 'ifuse --afc2' (to access the root directory of
the device), and then edit:

/Library/LaunchDaemons/com.openssh.sshd.plist

to _remove_ the lines:

<key>Diabled</key>
<true/>

Reboot the device and then sshd should be running.

TODO
====

The server currently assumes that the phone is well-behaved and does not do a
bunch of checks like looking for the expected SEQ and ACK numbers from it. This
is normally not an issue, but it's annoying for debugging because lost packets
(which shouldn't happen, but can happen if the code is buggy) mean that stuff
gets out of sync and then might crash and burn dozens of packets later.

The server needs more testing, and some optimizing.

Someone should probably do some edge-case testing on the TCP stuff.

The outgoing ACK handling on the server probably needs some thought. Currently,
when there's an outstanding ACK, we send it after a timeout (to avoid sending
a no-payload ACK packet for everything the phone sends us). However, there's
probably a better way of doing this.

Architecture information
========================

The iPhone / iPod Touch basically implements a rather strange USB networking
system that operates at a higher level. It is of course completely proprietary.
Expand Down Expand Up @@ -90,9 +166,6 @@ Note that all normal packets need to have flags set to ACK (and only ACK). There
is no support for, erm, not-acking. Keep the ack number field valid at all
times.


GOTCHAS AND ANNOYANCES

The usbmuxd CONNECT request port field is byte-swapped (network-endian). This is
even more annoying for the plist based protocol, since it's even true there
(where the field is plain text). So even for the plain text int, you need to
Expand Down Expand Up @@ -123,26 +196,3 @@ at non-16k boundaries that are multiples of 512, but that seems to work fine. I
guess the ZLPs might cause spurious 0-byte transfers to show up on RX if things
line up right, but we ignore those. By the way, the maximum packet/transfer size
is 65535 bytes due to the 16-bit length header of the usbmux protocol.

TODO

The server currently assumes that the phone is well-behaved and does not do a
bunch of checks like looking for the expected SEQ and ACK numbers from it. This
is normally not an issue, but it's annoying for debugging because lost packets
(which shouldn't happen, but can happen if the code is buggy) mean that stuff
gets out of sync and then might crash and burn dozens of packets later.

The server needs a proper front-end (i.e. daemonizing, commandline options,
etc), more testing, and some optimizing.

Someone should probably do some edge-case testing on the TCP stuff.

At some point we should probably write a C client lib.

The outgoing ACK handling on the server probably needs some thought. Currently,
when there's an outstanding ACK, we send it after a timeout (to avoid sending
a no-payload ACK packet for everything the phone sends us). However, there's
probably a better way of doing this.



50 changes: 50 additions & 0 deletions README.devel
@@ -0,0 +1,50 @@
Background
==========

'libusbmuxd' makes it really simple to talk to a running 'usbmuxd' and
hides all the details for you. There are two function calls:

usbmuxd_scan()
--------------

This returns a list of all available iPhone-like devices that are
available for talking to. The returned array contains the USB
product_id, hex formatted serial_number of any iPhones/iTouches and a
non-descript 'handle' for all those devices that are within range (as
of March 2009, that means a device directly plugged into the
computer's USB port).

Once you have found the device you want to communicate with, take its
'handle' and pass this to usbmuxd_connect().

usbmuxd_connect()
-----------------

This takes a handle, a destination port number and tries to setup
a proxy a connection. It returns a file-descriptor which you should
be able to read(), write() and select() on like any other active network
socket connection.


Technical details
=================

When usbmuxd is running (normally started, or stopped as a result of
'udev' auto-insertion messages), it provides a socket interface in
'/var/run/usbmuxd' that is designed to be compatible with the socket
interface that is provided on MacOSX.

The structures for communicating over this device are documented
in the 'usbmuxd-proto.h', but you shouldn't need to view them
directly if you are using the libusbmuxd.so library for easy access.


Example
=======

#include <usbmuxd.h>

...

gcc -o leetphone leetphone.c -lusbmuxd

12 changes: 12 additions & 0 deletions libusbmuxd/CMakeLists.txt
@@ -0,0 +1,12 @@
add_library (libusbmuxd libusbmuxd.c sock_stuff.c)

# 'lib' is a UNIXism, the proper CMake target is usbmuxd
# But we can't use that due to the conflict with the usbmuxd daemon,
# so instead change the library output base name to usbmuxd here
set_target_properties(libusbmuxd PROPERTIES OUTPUT_NAME usbmuxd)

install(TARGETS libusbmuxd
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
install(FILES usbmuxd.h usbmuxd-proto.h DESTINATION include)

0 comments on commit 1a0c58e

Please sign in to comment.