summaryrefslogtreecommitdiffstats
path: root/README
diff options
context:
space:
mode:
Diffstat (limited to 'README')
-rw-r--r--README185
1 files changed, 155 insertions, 30 deletions
diff --git a/README b/README
index ff28e19..0490e1f 100644
--- a/README
+++ b/README
@@ -1,31 +1,37 @@
1Background 1Background
2========== 2==========
3 3
4'usbmuxd' stands for "USB multiplexing daemon". To the user/developer 4'usbmuxd' stands for "USB multiplexing daemon". To the user/developer what it
5what it actually does is to proxy requests over a USB cable on directly 5actually does is to proxy requests over a USB cable on directly to a listening
6to a listening TCP port on the iPhone. 6TCP port on the iPhone.
7 7
8Multiple connections to different TCP ports can happen in parallel. 8Multiple connections to different TCP ports can happen in parallel. An example
9An example (and useful) tool called 'iproxy' is included that allows 9(and useful) tool called 'iproxy' is included that allows you to forward
10you to forward localhost ports to the device---allows SSH over USB on 10localhost ports to the device---allows SSH over USB on jailbroken devices, or
11jailbroken devices, or allowing access the lockdown daemon (and then 11allowing access the lockdown daemon (and then to all of the file access, sync,
12to all of the file access, sync, notification and backup services 12notification and backup services running on the device).
13running on the device). 13
14 14This higher-level layers are handled by libiphone. The version of libiphone
15This higher-level layers are handled by libiphone. The version of 15compatible with the 'usbmuxd' infrastructure is called 'libiphone-usbmuxd'.
16libiphone compatible with the 'usbmuxd' infrastructure is called 16'ifuse' is then able to sit on top of this.
17'libiphone-usbmuxd'. 'ifuse' is then able to sit on top of this. 17
18 18There is also a Python implementation of the client library in the python-client
19library, and an example tcprelay.py which performs a similar function to iproxy.
20This implementation supports OSX and Windows and the new iTunes plist-based
21usbmuxd protocol, so it is portable and will run on those operating systems with
22no modification, using Apple's native usbmuxd. This is useful if you need to
23tunnel to your phone from another OS in a pinch. Run python tcpclient.py --help
24for usage information.
19 25
20Building 26Building
21======== 27========
22 28
23 ./autogen.sh 29 mkdir build
24 ./configure --sysconfdir=/etc 30 cd build
31 cmake ..
25 make 32 make
26 sudo make install 33 sudo make install
27 34
28
29Running (with magic) 35Running (with magic)
30==================== 36====================
31 37
@@ -33,21 +39,21 @@ Running (with magic)
33 ./iproxy 2222 22 & 39 ./iproxy 2222 22 &
34 ssh -p 2222 root@localhost 40 ssh -p 2222 root@localhost
35 41
36Hopefully you get the normal SSH login prompt. You may still lots of 42Hopefully you get the normal SSH login prompt. You may still lots of debugging
37debugging output for the moment. If this is getting in the way of 43output for the moment. If this is getting in the way of your ssh login, then
38your ssh login, then run the 'ssh' command from a different xterminal 44run the 'ssh' command from a different xterminal
39or virtual console. 45or virtual console.
40 46
41 47
42Running (without magic) 48Running (without magic)
43======================= 49=======================
44 50
45If 'udev' is _not_ automatically running on your machine and picking 51If 'udev' is _not_ automatically running on your machine and picking up the new
46up the new .rules file, you will need to start usbmuxd by hand first. 52.rules file, you will need to start usbmuxd by hand first. Check it's running
47Check it's running and that there is only one copy with 'ps aux | grep 53and that there is only one copy with 'ps aux | grep
48usbmuxd'. 54usbmuxd'.
49 55
50 sudo usbmuxd & 56 sudo usbmuxd -U -v -v &
51 ./iproxy 2222 22 & 57 ./iproxy 2222 22 &
52 ssh -p 2222 root@localhost 58 ssh -p 2222 root@localhost
53 59
@@ -55,13 +61,13 @@ usbmuxd'.
55Tip: Starting SSH if disabled 61Tip: Starting SSH if disabled
56============================= 62=============================
57 63
58If your iphone is rooted, but SSH isn't started and you _cannot_ (for 64If your iphone is rooted, but SSH isn't started and you _cannot_ (for instance,
59instance, cracked/broken screen) get to the Services control panel on 65cracked/broken screen) get to the Services control panel on the device, then you
60the device, then you can start the SSH service over the USB by 66can start the SSH service over the USB by
61mounting the (jailbroken) filesystem. 67mounting the (jailbroken) filesystem.
62 68
63You will need to mount it usbing 'ifuse --afc2' (to access the root 69You will need to mount it usbing 'ifuse --afc2' (to access the root directory of
64directory of the device), and then edit: 70the device), and then edit:
65 71
66 /Library/LaunchDaemons/com.openssh.sshd.plist 72 /Library/LaunchDaemons/com.openssh.sshd.plist
67 73
@@ -71,3 +77,122 @@ to _remove_ the lines:
71 <true/> 77 <true/>
72 78
73Reboot the device and then sshd should be running. 79Reboot the device and then sshd should be running.
80
81TODO
82====
83
84The server currently assumes that the phone is well-behaved and does not do a
85bunch of checks like looking for the expected SEQ and ACK numbers from it. This
86is normally not an issue, but it's annoying for debugging because lost packets
87(which shouldn't happen, but can happen if the code is buggy) mean that stuff
88gets out of sync and then might crash and burn dozens of packets later.
89
90The server needs more testing, and some optimizing.
91
92Someone should probably do some edge-case testing on the TCP stuff.
93
94The outgoing ACK handling on the server probably needs some thought. Currently,
95when there's an outstanding ACK, we send it after a timeout (to avoid sending
96a no-payload ACK packet for everything the phone sends us). However, there's
97probably a better way of doing this.
98
99Architecture information
100========================
101
102The iPhone / iPod Touch basically implements a rather strange USB networking
103system that operates at a higher level. It is of course completely proprietary.
104Generally speaking, this is what goes on in a typical usage scenario:
105
1060. iTunes opens a connection to usbmuxd and asks it for device notifications
1071. User inserts phone into computer
1082. usbmuxd notices the phone and pings it with a version packet
1093. phone replies
1104. usbmuxd now considers the phone to be connected and tells iTunes
1115. iTunes opens another separate connection to usbmuxd and asks it to connect
112 to, say, the afc port on the device
1136. usbmuxd sends a pseudo-TCP SYN packet to the phone
1147. the phone's kernel driver receives the SYN packet and itself opens a
115 TCP connection to localhost on the afc port
1168. the phone replies with a pseudo-TCP SYN/ACK indicating that the port is open
117 and the connection can proceed
1187. usbmuxd sends a final ACK to the phone
1198. usbmuxd replies to iTunes with a "connection successful" message
1209. any data that iTunes writes to the usbmuxd socket from now on is forwarded,
121 through pseudo-TCP, through USB, back into a more regular TCP connection to
122 localhost, to the afc daemon on the phone, and vice versa
123
124The usbmuxd protocol is a relatively simple binary message protocol documented
125here:
126
127http://wikee.iphwn.org/usb:usbmux
128
129Note that once a connection is established the UNIX socket essentially becomes
130a dedicated pipe to the TCP connction and no more high-level control is
131possible (closing the socket closes the TCP connection). Ditto for the "listen
132for devices" mode - usbmuxd will reject any commands in such mode, and the
133socket essentially becomes a dedicated device notification pipe. This means
134that you need, at minimum, TWO connections to usbmuxd to do anything useful.
135
136On Windows, usbmuxd works the same way but a TCP connection to localhost port
13727015 replaces the UNIX socket. On OSX, the UNIX socket is /var/run/usbmuxd. The
138server and client implemented here default to /tmp/usbmuxd at the moment.
139
140The phone protocol operates over a pair of USB bulk endpoints. There is an outer
141layer used for packet size info and a "protocol" (version and TCP are the only
142two options), and that header is followed by TCP headers for actual data comms.
143However, the protocol isn't actual TCP, just a custom protocol which for some
144reason uses a standard TCP header and leaves most fields unused.
145
146There is no reordering or retransmission. There are no checksums, no URG, no
147PSH, no non-ACK, no FIN. What there *is* is the SEQ/ACK/window mechanism used
148for flow control, and RST is used as the only connection teardown mechanism (and
149also for "connection refused"), and the connection startup is SYN/SYNACK/ACK.
150
151Windows are constant-scaled by 8 bits. This is legal TCP as long as the
152corresponding option is negotiated. Of course, no such negotiation happens on
153this protocol.
154
155Note that, since there are no retransmissions, there is some overlap between ACK
156and window for flow control. For example, the server doesn't ever touch its
157window size, and just refuses to ACK stuff if its buffers are full and the
158client isn't reading data. The phone happily seems to stop sending stuff.
159
160Also, if the phone RSTs you out of nowhere, look at the packet payload for a
161textual error message. Note: if it claims to suffer from amnesia, that probably
162means you overflowed its input buffer by ignoring its flow control / window
163size. Go figure. Probably a logic bug in the kernel code.
164
165Note that all normal packets need to have flags set to ACK (and only ACK). There
166is no support for, erm, not-acking. Keep the ack number field valid at all
167times.
168
169The usbmuxd CONNECT request port field is byte-swapped (network-endian). This is
170even more annoying for the plist based protocol, since it's even true there
171(where the field is plain text). So even for the plain text int, you need to
172swap the bytes (port 22 becomes <integer>5632</integer>). I have no clue if this
173is the case on the new plist protocol on PPC macs (is the newer iTunes available
174for those?)
175
176There are a bunch of gotchas due to the USB framing, and this is even worse
177because implementations tend to get it wrong (i.e. libusb, and this is the
178reason for the patch). Basically, USB Bulk offers, at the low level, the ability
179to transfer packets from 0 to wMaxPacketSize (512 here) bytes, period. There is
180no other support for higher level framing of transfers. The way you do those is
181by breaking them up into packets, and the final shorter packet marks the end of
182the transfer. The critical bit is that, if the transfer happens to be divisible
183by 512, you send a zero-length packet (ZLP) to indicate the end of the transfer.
184Libusb doesn't set this option by default and the iPhone gets packets stuck to
185each other, which it doesn't like. Actually, this framing is sort of redundant
186because the usbmux packet header includes a length field, but the phone still
187wants the ZLPs or else it breaks. To make matters worse, usbdevfs imposes a max
188transfer size of 16k, so libusb breaks transfers into that size. This is okay
189for sending as long as the ZLP is only added to the last transfer (the patch
190does that), but it can easily cause nasty race conditions on RX due to libusb
191doing multiple outstanding reads at the same time and then cancelling the rest
192when shorter data arrives (but what if some data got into the other requests
193already?), so we only do 16k reads and stick them together ourselves by looking
194at the packet size header. We still depend on ZLPs being sent to end transfers
195at non-16k boundaries that are multiples of 512, but that seems to work fine. I
196guess the ZLPs might cause spurious 0-byte transfers to show up on RX if things
197line up right, but we ignore those. By the way, the maximum packet/transfer size
198is 65535 bytes due to the 16-bit length header of the usbmux protocol.