forked from libimobiledevice/libusbmuxd
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update README with latest information and project URLs
- Loading branch information
Showing
1 changed file
with
48 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,214 +1,63 @@ | ||
Background | ||
========== | ||
|
||
'usbmuxd' stands for "USB multiplexing daemon". This daemon is in charge of | ||
multiplexing connections over USB to an iPhone or iPod touch. To users, it means | ||
you can sync your music, contacts, photos, etc. over USB. To developers, it | ||
means you can connect to any listening localhost socket on the device. usbmuxd | ||
is not used for tethering data transfer, which uses a dedicated USB interface as | ||
a virtual network device. | ||
|
||
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). | ||
|
||
The higher-level layers are handled by libimobiledevice. 'ifuse' is then able | ||
to sit on top of this and mount your device's AFC filesystem share. | ||
|
||
This package contains the usbmuxd communication interface library 'libusbmuxd'. | ||
|
||
There is also a Python implementation of the client library in the python-client | ||
directory, 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 device from another OS in a pinch. Run python tcpclient.py --help | ||
for usage information. | ||
|
||
License | ||
======= | ||
About | ||
===== | ||
|
||
The contents of this package are licensed under the GNU Lesser General Public | ||
License, version 2.1 or, at your option, any later version (see COPYING.LGPLv2.1). | ||
If a more permissive license is specified at the top of a source file, it takes | ||
precedence over this. | ||
A client library to multiplex connections from and to iOS devices by connecting | ||
to a socket provided by a usbmuxd daemon. | ||
|
||
Legal | ||
===== | ||
Requirements | ||
============ | ||
|
||
Apple, iPhone, and iPod touch are trademarks of Apple Inc., registered in the | ||
U.S. and other countries. | ||
Development Packages of: | ||
libplist | ||
|
||
Building | ||
======== | ||
Software: | ||
usbmuxd (Windows and Mac OS X can use the one provided by iTunes) | ||
make | ||
autoheader | ||
automake | ||
autoconf | ||
libtool | ||
pkg-config | ||
gcc | ||
|
||
./autogen.sh | ||
make | ||
sudo make install | ||
Optional: | ||
inotify (Linux only) | ||
|
||
Running (with magic) | ||
==================== | ||
Installation | ||
============ | ||
|
||
(Unplug + replug your jailbroken device) | ||
./iproxy 2222 22 & | ||
ssh -p 2222 root@localhost | ||
To compile run: | ||
./autogen.sh | ||
make | ||
sudo make install | ||
|
||
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. Of course, | ||
you need to have OpenSSH installed on your jailbroken device for this to work. | ||
Who/What/Where? | ||
=============== | ||
|
||
If you have iFuse, you can run "ifuse <mountpoint">. This doesn't require | ||
iproxy and works on all devices, jailbroken or not. | ||
Home: | ||
http://www.libimobiledevice.org/ | ||
|
||
Running (without magic) | ||
======================= | ||
Code: | ||
git clone http://git.sukimashita.com/libusbmuxd.git | ||
|
||
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'. | ||
Code (Mirror): | ||
git clone https://github.com/libimobiledevice/libusbmuxd.git | ||
|
||
sudo usbmuxd -U -v -v & | ||
./iproxy 2222 22 & | ||
ssh -p 2222 root@localhost | ||
Tickets: | ||
http://github.com/libimobiledevice/libusbmuxd/issues | ||
|
||
Tip: Starting SSH if disabled | ||
============================= | ||
Mailing List: | ||
http://lists.libimobiledevice.org/mailman/listinfo/libimobiledevice-devel | ||
|
||
IRC: | ||
irc://irc.freenode.net#libimobiledevice | ||
|
||
Credits | ||
======= | ||
|
||
If your device 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. | ||
Apple, iPhone, iPod, and iPod Touch are trademarks of Apple Inc. | ||
libimobiledevice is an independent software library and has not been | ||
authorized, sponsored, or otherwise approved by Apple Inc. | ||
|
||
You will need to mount it using 'ifuse --afc2' (to access the root directory of | ||
the device), and then edit: | ||
|
||
/Library/LaunchDaemons/com.openssh.sshd.plist | ||
|
||
to _remove_ the lines: | ||
|
||
<key>Disabled</key> | ||
<true/> | ||
|
||
Reboot the device and then sshd should be running. | ||
|
||
TODO | ||
==== | ||
|
||
The server currently assumes that the device 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. | ||
Generally speaking, this is what goes on in a typical usage scenario: | ||
|
||
0. iTunes opens a connection to usbmuxd and asks it for device notifications | ||
1. User inserts phone into computer | ||
2. usbmuxd notices the phone and pings it with a version packet | ||
3. phone replies | ||
4. usbmuxd now considers the phone to be connected and tells iTunes | ||
5. iTunes opens another separate connection to usbmuxd and asks it to connect | ||
to, say, the afc port on the device | ||
6. usbmuxd sends a pseudo-TCP SYN packet to the phone | ||
7. the phone's kernel driver receives the SYN packet and itself opens a | ||
TCP connection to localhost on the afc port | ||
8. the phone replies with a pseudo-TCP SYN/ACK indicating that the port is open | ||
and the connection can proceed | ||
7. usbmuxd sends a final ACK to the phone | ||
8. usbmuxd replies to iTunes with a "connection successful" message | ||
9. any data that iTunes writes to the usbmuxd socket from now on is forwarded, | ||
through pseudo-TCP, through USB, back into a more regular TCP connection to | ||
localhost, to the afc daemon on the phone, and vice versa | ||
|
||
The usbmuxd protocol is a relatively simple binary message protocol documented | ||
here: | ||
|
||
http://wikee.iphwn.org/usb:usbmux | ||
|
||
Note that once a connection is established the UNIX socket essentially becomes | ||
a dedicated pipe to the TCP connction and no more high-level control is | ||
possible (closing the socket closes the TCP connection). Ditto for the "listen | ||
for devices" mode - usbmuxd will reject any commands in such mode, and the | ||
socket essentially becomes a dedicated device notification pipe. This means | ||
that you need, at minimum, TWO connections to usbmuxd to do anything useful. | ||
|
||
On Windows, usbmuxd works the same way but a TCP connection to localhost port | ||
27015 replaces the UNIX socket. On OSX, the UNIX socket is /var/run/usbmuxd. The | ||
server and client implemented here default the same /var/run/usbmuxd socket. | ||
|
||
The phone protocol operates over a pair of USB bulk endpoints. There is an outer | ||
layer used for packet size info and a "protocol" (version and TCP are the only | ||
two options), and that header is followed by TCP headers for actual data comms. | ||
However, the protocol isn't actual TCP, just a custom protocol which for some | ||
reason uses a standard TCP header and leaves most fields unused. | ||
|
||
There is no reordering or retransmission. There are no checksums, no URG, no | ||
PSH, no non-ACK, no FIN. What there *is* is the SEQ/ACK/window mechanism used | ||
for flow control, and RST is used as the only connection teardown mechanism (and | ||
also for "connection refused"), and the connection startup is SYN/SYNACK/ACK. | ||
|
||
Windows are constant-scaled by 8 bits. This is legal TCP as long as the | ||
corresponding option is negotiated. Of course, no such negotiation happens on | ||
this protocol. | ||
|
||
Note that, since there are no retransmissions, there is some overlap between ACK | ||
and window for flow control. For example, the server doesn't ever touch its | ||
window size, and just refuses to ACK stuff if its buffers are full and the | ||
client isn't reading data. The phone happily seems to stop sending stuff. | ||
|
||
Also, if the phone RSTs you out of nowhere, look at the packet payload for a | ||
textual error message. Note: if it claims to suffer from amnesia, that probably | ||
means you overflowed its input buffer by ignoring its flow control / window | ||
size. Go figure. Probably a logic bug in the kernel code. | ||
|
||
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. | ||
|
||
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 | ||
swap the bytes (port 22 becomes <integer>5632</integer>). I have no clue if this | ||
is the case on the new plist protocol on PPC macs (is the newer iTunes available | ||
for those?) | ||
|
||
There are a bunch of gotchas due to the USB framing, and this is even worse | ||
because implementations tend to get it wrong (i.e. libusb, and this is the | ||
reason for the patch). Basically, USB Bulk offers, at the low level, the ability | ||
to transfer packets from 0 to wMaxPacketSize (512 here) bytes, period. There is | ||
no other support for higher level framing of transfers. The way you do those is | ||
by breaking them up into packets, and the final shorter packet marks the end of | ||
the transfer. The critical bit is that, if the transfer happens to be divisible | ||
by 512, you send a zero-length packet (ZLP) to indicate the end of the transfer. | ||
Libusb doesn't set this option by default and the iPhone gets packets stuck to | ||
each other, which it doesn't like. Actually, this framing is sort of redundant | ||
because the usbmux packet header includes a length field, but the phone still | ||
wants the ZLPs or else it breaks. To make matters worse, usbdevfs imposes a max | ||
transfer size of 16k, so libusb breaks transfers into that size. This is okay | ||
for sending as long as the ZLP is only added to the last transfer (the patch | ||
does that), but it can easily cause nasty race conditions on RX due to libusb | ||
doing multiple outstanding reads at the same time and then cancelling the rest | ||
when shorter data arrives (but what if some data got into the other requests | ||
already?), so we only do 16k reads and stick them together ourselves by looking | ||
at the packet size header. We still depend on ZLPs being sent to end transfers | ||
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. | ||
README Updated on: | ||
2014-10-02 |