diff options
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | iphone.c | 16 | ||||
-rw-r--r-- | iproxy.c | 160 | ||||
-rw-r--r-- | libusbmuxd.c | 170 | ||||
-rw-r--r-- | libusbmuxd.h | 27 | ||||
-rw-r--r-- | main.c | 18 | ||||
-rw-r--r-- | testclient.c | 146 | ||||
-rw-r--r-- | usbmuxd.h | 5 |
8 files changed, 253 insertions, 303 deletions
@@ -1,5 +1,5 @@ -TARGETS=usbmuxd iproxy testclient -CFLAGS=-Wall -g -DDEBUG +TARGETS=usbmuxd iproxy +CFLAGS=-I. -Wall -g -DDEBUG LIBS=-lpthread -lusb -lrt LDFLAGS= INSTALL_PREFIX=/usr @@ -7,9 +7,10 @@ INSTALL_PREFIX=/usr all: $(TARGETS) main.o: main.c usbmuxd.h sock_stuff.h iphone.h -iphone.o: iproxy.c iphone.h usbmuxd.h sock_stuff.h +iphone.o: iphone.c iphone.h usbmuxd.h sock_stuff.h sock_stuff.o: sock_stuff.c sock_stuff.h -testclient.o: testclient.c sock_stuff.h +libusbmuxd.o: libusbmuxd.c libusbmuxd.h usbmuxd.h +iproxy.o: iproxy.c sock_stuff.h %.o: %.c $(CC) -o $@ $(CFLAGS) -c $< @@ -17,10 +18,7 @@ testclient.o: testclient.c sock_stuff.h usbmuxd: main.o sock_stuff.o iphone.o $(CC) -o $@ $(LDFLAGS) $^ $(LIBS) -testclient: testclient.o sock_stuff.o - $(CC) -o $@ $(LDFLAGS) $^ $(LIBS) - -iproxy: iproxy.o sock_stuff.o +iproxy: iproxy.o libusbmuxd.o sock_stuff.o $(CC) -o $@ $(LDFLAGS) $^ $(LIBS) clean: @@ -114,7 +114,7 @@ static int clients = 0; /** */ -int toto_debug = 0; +int toto_debug = 1; void log_debug_msg(const char *format, ...) { #ifndef STRIP_DEBUG_CODE @@ -124,7 +124,7 @@ void log_debug_msg(const char *format, ...) va_start(args, format); if (toto_debug) - fprintf(stderr, format, args); + vfprintf(stderr, format, args); va_end(args); @@ -215,6 +215,12 @@ static iphone_error_t iphone_config_usb_device(iphone_device_t phone) int bytes; char buf[512]; + log_debug_msg("checking configuration...\n"); + if (phone->__device->config->bConfigurationValue != 3) { + log_debug_msg("WARNING: usb device configuration is not 3 as expected!\n"); + } + +#if 0 log_debug_msg("setting configuration...\n"); ret = usb_set_configuration(phone->device, 3); if (ret != 0) { @@ -242,6 +248,7 @@ static iphone_error_t iphone_config_usb_device(iphone_device_t phone) } else { log_debug_msg("done.\n"); } +#endif log_debug_msg("claiming interface... "); ret = usb_claim_interface(phone->device, 1); @@ -307,8 +314,9 @@ iphone_error_t iphone_get_specific_device(int bus_n, int dev_n, iphone_device_t if (dev->devnum == dev_n) { phone->__device = dev; phone->device = usb_open(phone->__device); - iphone_config_usb_device(phone); - goto found; + if (iphone_config_usb_device(phone) == IPHONE_E_SUCCESS) { + goto found; + } } iphone_free_device(phone); @@ -31,8 +31,9 @@ #include <errno.h> #include <arpa/inet.h> #include <pthread.h> -#include "usbmuxd.h" +#include <usbmuxd.h> #include "sock_stuff.h" +#include "libusbmuxd.h" static uint16_t listen_port = 0; static uint16_t device_port = 0; @@ -46,43 +47,6 @@ struct client_data { volatile int stop_stoc; }; -int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t *result) -{ - struct usbmuxd_result res; - int recv_len; - int i; - uint32_t rrr[5]; - - if (!result) { - return -EINVAL; - } - - if ((recv_len = recv_buf(sfd, &res, sizeof(res))) <= 0) { - perror("recv"); - return -errno; - } else { - memcpy(&rrr, &res, recv_len); - for (i = 0; i < recv_len/4; i++) { - fprintf(stderr, "%08x ", rrr[i]); - } - fprintf(stderr, "\n"); - if ((recv_len == sizeof(res)) - && (res.header.length == recv_len) - && (res.header.reserved == 0) - && (res.header.type == USBMUXD_RESULT) - ) { - *result = res.result; - if (res.header.tag == tag) { - return 1; - } else { - return 0; - } - } - } - - return -1; -} - void *run_stoc_loop(void *arg) { struct client_data *cdata = (struct client_data*)arg; @@ -178,13 +142,7 @@ void *run_ctos_loop(void *arg) void *acceptor_thread(void *arg) { struct client_data *cdata; - int recv_len = 0; - int scan_done; - int connected; - uint32_t pktlen; - unsigned char *buf; - struct usbmuxd_scan_request scan; - struct am_device_info device_info; + usbmuxd_device_t *dev_list = NULL; pthread_t ctos; if (!arg) { @@ -194,102 +152,36 @@ void *acceptor_thread(void *arg) cdata = (struct client_data*)arg; - cdata->sfd = connect_unix_socket(USBMUXD_SOCKET_FILE); - if (cdata->sfd < 0) { - printf("error opening socket, terminating.\n"); + if (usbmuxd_scan(&dev_list) != 0) { + printf("Connecting to usbmuxd failed, terminating.\n"); + free(dev_list); return NULL; } - // send scan - scan.header.length = sizeof(struct usbmuxd_scan_request); - scan.header.reserved = 0; - scan.header.type = USBMUXD_SCAN; - scan.header.tag = 2; - - scan_done = 0; - connected = 0; - - fprintf(stdout, "sending scan packet\n"); - if (send(cdata->sfd, &scan, scan.header.length, 0) == scan.header.length) { - uint32_t res = -1; - // get response - if (usbmuxd_get_result(cdata->sfd, scan.header.tag, &res) && (res==0)) { - fprintf(stdout, "Got response to scan request!\n"); - scan_done = 1; - } else { - fprintf(stderr, "Did not get response to scan request (with result=0)...\n"); - close(cdata->sfd); - cdata->sfd = -1; - return NULL; - } - - device_info.device_id = 0; - - if (scan_done) { - // get all devices - while (1) { - if (recv_buf_timeout(cdata->sfd, &pktlen, 4, MSG_PEEK, 1000) == 4) { - buf = (unsigned char*)malloc(pktlen); - if (!buf) { - exit(-ENOMEM); - } - recv_len = recv_buf(cdata->sfd, buf, pktlen); - if (recv_len < pktlen) { - fprintf(stdout, "received less data than specified in header!\n"); - } - fprintf(stdout, "Received device data\n"); - //log_debug_buffer(stdout, (char*)buf, pktlen); - memcpy(&device_info, buf + sizeof(struct usbmuxd_header), sizeof(device_info)); - free(buf); - } else { - // we _should_ have all of them now. - // or perhaps an error occured. - break; - } - } - } - - if (device_info.device_id > 0) { - struct usbmuxd_connect_request c_req; - - fprintf(stdout, "Requesting connecion to device %d port %d\n", device_info.device_id, device_port); + if (!dev_list || dev_list[0].device_id == 0) { + printf("No connected device found, terminating.\n"); + free(dev_list); + return NULL; + } - // try to connect to last device found - c_req.header.length = sizeof(c_req); - c_req.header.reserved = 0; - c_req.header.type = USBMUXD_CONNECT; - c_req.header.tag = 3; - c_req.device_id = device_info.device_id; - c_req.tcp_dport = htons(device_port); - c_req.reserved = 0; + fprintf(stdout, "Requesting connecion to device %d port %d\n", dev_list[0].device_id, device_port); - if (send_buf(cdata->sfd, &c_req, sizeof(c_req)) < 0) { - perror("send"); - } else { - // read ACK - res = -1; - fprintf(stdout, "Reading connect result...\n"); - if (usbmuxd_get_result(cdata->sfd, c_req.header.tag, &res)) { - if (res == 0) { - fprintf(stdout, "Connect success!\n"); - connected = 1; - } else { - fprintf(stderr, "Connect failed, Error code=%d\n", res); - } - } - } - } + cdata->sfd = usbmuxd_connect(dev_list[0].device_id, device_port); + free(dev_list); + if (cdata->sfd < 0) { + fprintf(stderr, "Error connecting to device!\n"); + } else { + cdata->stop_ctos = 0; + pthread_create(&ctos, NULL, run_ctos_loop, cdata); + pthread_join(ctos, NULL); + } - if (connected) { - cdata->stop_ctos = 0; - pthread_create(&ctos, NULL, run_ctos_loop, cdata); - pthread_join(ctos, NULL); - } else { - fprintf(stderr, "Error connecting to device!\n"); - } + if (cdata->fd > 0) { + close(cdata->fd); + } + if (cdata->sfd > 0) { + close(cdata->sfd); } - close(cdata->fd); - close(cdata->sfd); return NULL; } diff --git a/libusbmuxd.c b/libusbmuxd.c new file mode 100644 index 0000000..4e4ec10 --- /dev/null +++ b/libusbmuxd.c @@ -0,0 +1,170 @@ +#include <stdint.h> +#include <stdlib.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <unistd.h> + +#include <usbmuxd.h> +#include "sock_stuff.h" + +static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t *result) +{ + struct usbmuxd_result res; + int recv_len; + + if (!result) { + return -EINVAL; + } + + if ((recv_len = recv_buf(sfd, &res, sizeof(res))) <= 0) { + perror("recv"); + return -errno; + } else { + if ((recv_len == sizeof(res)) + && (res.header.length == recv_len) + && (res.header.reserved == 0) + && (res.header.type == USBMUXD_RESULT) + ) { + *result = res.result; + if (res.header.tag == tag) { + return 1; + } else { + return 0; + } + } + } + + return -1; +} + +int usbmuxd_scan(usbmuxd_device_t **devices) +{ + struct usbmuxd_scan_request s_req; + int sfd; + int scan_success = 0; + uint32_t res; + uint32_t pktlen; + int recv_len; + usbmuxd_device_t *newlist = NULL; + struct usbmuxd_device_info_record dev_info_pkt; + int dev_cnt = 0; + + sfd = connect_unix_socket(USBMUXD_SOCKET_FILE); + if (sfd < 0) { + fprintf(stderr, "%s: error opening socket!\n", __func__); + return sfd; + } + + s_req.header.length = sizeof(struct usbmuxd_scan_request); + s_req.header.reserved = 0; + s_req.header.type = USBMUXD_SCAN; + s_req.header.tag = 2; + + // send scan request packet + if (send_buf(sfd, &s_req, s_req.header.length) == s_req.header.length) { + res = -1; + // get response + if (usbmuxd_get_result(sfd, s_req.header.tag, &res) && (res == 0)) { + scan_success = 1; + } else { + fprintf(stderr, "%s: Did not get response to scan request (with result=0)...\n", __func__); + close(sfd); + return res; + } + } + + if (!scan_success) { + fprintf(stderr, "%s: Could not send scan request!\n", __func__); + return -1; + } + + *devices = NULL; + // receive device list + while (1) { + if (recv_buf_timeout(sfd, &pktlen, 4, MSG_PEEK, 500) == 4) { + if (pktlen != sizeof(dev_info_pkt)) { + // invalid packet size received! + fprintf(stderr, "%s: Invalid packet size (%d) received when expecting a device info record.\n", __func__, pktlen); + break; + } + + recv_len = recv_buf(sfd, &dev_info_pkt, pktlen); + if (recv_len <= 0) { + fprintf(stderr, "%s: Error when receiving device info record\n", __func__); + break; + } else if (recv_len < pktlen) { + fprintf(stderr, "%s: received less data than specified in header!\n", __func__); + } else { + //fprintf(stderr, "%s: got device record with id %d, UUID=%s\n", __func__, dev_info_pkt.device_info.device_id, dev_info_pkt.device_info.serial_number); + newlist = (usbmuxd_device_t*)realloc(*devices, sizeof(usbmuxd_device_t) * (dev_cnt+1)); + if (newlist) { + memcpy(newlist+dev_cnt, &dev_info_pkt.device, sizeof(usbmuxd_device_t)); + *devices = newlist; + dev_cnt++; + } else { + fprintf(stderr, "%s: ERROR: out of memory when trying to realloc!\n", __func__); + break; + } + } + } else { + // we _should_ have all of them now. + // or perhaps an error occured. + break; + } + } + + // terminating zero record + newlist = (usbmuxd_device_t*)realloc(*devices, sizeof(usbmuxd_device_t) * (dev_cnt+1)); + memset(newlist+dev_cnt, 0, sizeof(usbmuxd_device_t)); + *devices = newlist; + + return 0; +} + +int usbmuxd_connect(uint32_t device_id, uint16_t port) +{ + int sfd; + struct usbmuxd_connect_request c_req; + int connected = 0; + uint32_t res = -1; + + sfd = connect_unix_socket(USBMUXD_SOCKET_FILE); + if (sfd < 0) { + fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(errno)); + return sfd; + } + + c_req.header.length = sizeof(c_req); + c_req.header.reserved = 0; + c_req.header.type = USBMUXD_CONNECT; + c_req.header.tag = 3; + c_req.device_id = device_id; + c_req.tcp_dport = htons(port); + c_req.reserved = 0; + + if (send_buf(sfd, &c_req, sizeof(c_req)) < 0) { + perror("send"); + } else { + // read ACK + fprintf(stderr, "%s: Reading connect result...\n", __func__); + if (usbmuxd_get_result(sfd, c_req.header.tag, &res)) { + if (res == 0) { + fprintf(stderr, "%s: Connect success!\n", __func__); + connected = 1; + } else { + fprintf(stderr, "%s: Connect failed, Error code=%d\n", __func__, res); + } + } + } + + if (connected) { + return sfd; + } + + close(sfd); + + return -1; +} diff --git a/libusbmuxd.h b/libusbmuxd.h new file mode 100644 index 0000000..82f9a47 --- /dev/null +++ b/libusbmuxd.h @@ -0,0 +1,27 @@ +#ifndef __LIBUSBMUXD_H +#define __LIBUSBMUXD_H + +#include <usbmuxd.h> + +/** + * Contacts usbmuxd via it's unix domain socket and performs a scan for + * connected devices. + * + * @param devices Pointer to an array of usbmuxd_device_t. + * Assumed initially NULL, will be allocated by this function. + * + * @return number of devices found, negative on error + */ +int usbmuxd_scan(usbmuxd_device_t **devices); + +/** + * Performs the connect procedure via usbmuxd. + * + * @param device_id USB device number of the device to connect to + * @param port Port number to connect to + * + * @return socket of the connection, negative on error + */ +int usbmuxd_connect(uint32_t device_id, uint16_t port); + +#endif /* __LIBUSBMUXD_H */ @@ -92,10 +92,10 @@ static void print_buffer(FILE *fp, const char *data, const int length) if (verbose >= 4) fprintf(fp, "%04x: ", i); for (j=0;j<16;j++) { if (i+j >= length) { - printf(" "); + if (verbose >= 4) fprintf(fp, " "); continue; } - if (verbose >= 4) printf("%02hhx ", *(data+i+j)); + if (verbose >= 4) fprintf(fp, "%02hhx ", *(data+i+j)); } if (verbose >= 4) fprintf(fp, " | "); for(j=0;j<16;j++) { @@ -103,7 +103,7 @@ static void print_buffer(FILE *fp, const char *data, const int length) break; c = *(data+i+j); if ((c < 32) || (c > 127)) { - printf("."); + if (verbose >= 4) fprintf(fp, "."); continue; } if (verbose >= 4) fprintf(fp, "%c", c); @@ -491,14 +491,14 @@ static void *usbmuxd_client_init_thread(void *arg) if (verbose >= 2) fprintf(stderr, "%s: started (fd=%d)\n", __func__, cdata->socket); if ((recv_len = usbmuxd_get_request(cdata->socket, (void**)&s_req, 0)) <= 0) { - if (verbose >= 2) fprintf(stderr, "%s: No Hello packet received, error %s\n", __func__, strerror(errno)); + if (verbose >= 2) fprintf(stderr, "%s: No scan packet received, error %s\n", __func__, strerror(errno)); goto leave; } if ((recv_len == sizeof(struct usbmuxd_scan_request)) && (s_req->header.length == sizeof(struct usbmuxd_scan_request)) && (s_req->header.reserved == 0) && (s_req->header.type == USBMUXD_SCAN)) { // send success response - if (verbose >= 3) fprintf(stderr, "%s: Got Hello packet!\n", __func__); + if (verbose >= 3) fprintf(stderr, "%s: Got scan packet!\n", __func__); usbmuxd_send_result(cdata->socket, s_req->header.tag, 0); } else if ((recv_len == sizeof(struct usbmuxd_connect_request)) && (s_req->header.type == USBMUXD_CONNECT)) { c_req = (struct usbmuxd_connect_request*)s_req; @@ -506,7 +506,7 @@ static void *usbmuxd_client_init_thread(void *arg) goto connect; } else { // send error response and exit - if (verbose >= 2) fprintf(stderr, "%s: Invalid Hello packet received.\n", __func__); + if (verbose >= 2) fprintf(stderr, "%s: Invalid scan packet received.\n", __func__); // TODO is this required?! usbmuxd_send_result(cdata->socket, s_req->header.tag, EINVAL); goto leave; @@ -537,14 +537,14 @@ static void *usbmuxd_client_init_thread(void *arg) memset(&dev_info_rec, 0, sizeof(dev_info_rec)); dev_info_rec.header.length = sizeof(dev_info_rec); dev_info_rec.header.type = USBMUXD_DEVICE_INFO; - dev_info_rec.device_info.device_id = dev->devnum; - dev_info_rec.device_info.product_id = dev->descriptor.idProduct; + dev_info_rec.device.device_id = dev->devnum; + dev_info_rec.device.product_id = dev->descriptor.idProduct; if (dev->descriptor.iSerialNumber) { usb_dev_handle *udev; //pthread_mutex_lock(&usbmux_mutex); udev = usb_open(dev); if (udev) { - usb_get_string_simple(udev, dev->descriptor.iSerialNumber, dev_info_rec.device_info.serial_number, sizeof(dev_info_rec.device_info.serial_number)+1); + usb_get_string_simple(udev, dev->descriptor.iSerialNumber, dev_info_rec.device.serial_number, sizeof(dev_info_rec.device.serial_number)+1); usb_close(udev); } //pthread_mutex_unlock(&usbmux_mutex); diff --git a/testclient.c b/testclient.c deleted file mode 100644 index dc2dd28..0000000 --- a/testclient.c +++ /dev/null @@ -1,146 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <stddef.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> -#include <errno.h> -#include <arpa/inet.h> -#include "usbmuxd.h" -#include "sock_stuff.h" - -int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t *result) -{ - struct usbmuxd_result res; - int recv_len; - - if (!result) { - return -EINVAL; - } - - if ((recv_len = recv_buf(sfd, &res, sizeof(res))) <= 0) { - perror("recv"); - return -errno; - } else { - if ((recv_len == sizeof(res)) - && (res.header.length == recv_len) - && (res.header.reserved == 0) - && (res.header.type == USBMUXD_RESULT) - ) { - *result = res.result; - if (res.header.tag == tag) { - return 1; - } else { - return 0; - } - } - } - - return -1; -} - -int main(int argc, char **argv) -{ - int sfd; - int recv_len = 0; - int scan_done; - int connected; - uint32_t pktlen; - unsigned char *buf; - struct usbmuxd_scan_request scan; - struct am_device_info device_info; - - sfd = connect_unix_socket(USBMUXD_SOCKET_FILE); - if (sfd < 0) { - printf("error opening socket, terminating.\n"); - return -1; - } - - // send scan - scan.header.length = sizeof(struct usbmuxd_scan_request); - scan.header.reserved = 0; - scan.header.type = USBMUXD_SCAN; - scan.header.tag = 2; - - scan_done = 0; - connected = 0; - - fprintf(stdout, "sending scan packet\n"); - if (send(sfd, &scan, scan.header.length, 0) == scan.header.length) { - uint32_t res = -1; - // get response - if (usbmuxd_get_result(sfd, scan.header.tag, &res) && (res==0)) { - fprintf(stdout, "Got response to scan request!\n"); - scan_done = 1; - } else { - fprintf(stderr, "Did not get response to scan request (with result=0)...\n"); - close(sfd); - return -1; - } - - device_info.device_id = 0; - - if (scan_done) { - // get all devices - while (1) { - if (recv_buf_timeout(sfd, &pktlen, 4, MSG_PEEK, 1000) == 4) { - buf = (unsigned char*)malloc(pktlen); - if (!buf) { - exit(-ENOMEM); - } - recv_len = recv_buf(sfd, buf, pktlen); - if (recv_len < pktlen) { - fprintf(stdout, "received less data than specified in header!\n"); - } - fprintf(stdout, "got device data:\n"); - //log_debug_buffer(stdout, (char*)buf, pktlen); - memcpy(&device_info, buf + sizeof(struct usbmuxd_header), sizeof(device_info)); - free(buf); - } else { - // we _should_ have all of them now. - // or perhaps an error occured. - break; - } - } - } - - if (device_info.device_id > 0) { - struct usbmuxd_connect_request c_req; - - // try to connect to last device found - c_req.header.length = sizeof(c_req); - c_req.header.reserved = 0; - c_req.header.type = USBMUXD_CONNECT; - c_req.header.tag = 3; - c_req.device_id = device_info.device_id; - c_req.tcp_dport = htons(22); - c_req.reserved = 0; - - if (send_buf(sfd, &c_req, sizeof(c_req)) < 0) { - perror("send"); - } else { - // read ACK - res = -1; - if (usbmuxd_get_result(sfd, c_req.header.tag, &res)) { - if (res == 0) { - fprintf(stdout, "Connect success!\n"); - connected = 1; - } else { - fprintf(stderr, "Connect failed, Error code=%d\n", res); - } - } - } - } - - if (connected) { - - - // do communication now. - sleep(10); - } - } - close(sfd); - - return 0; -} @@ -24,15 +24,16 @@ struct usbmuxd_connect_request { uint16_t reserved; // set to zero } __attribute__((__packed__)); -struct am_device_info { +struct usbmuxd_device { uint32_t device_id; uint16_t product_id; char serial_number[40]; } __attribute__((__packed__)); +typedef struct usbmuxd_device usbmuxd_device_t; struct usbmuxd_device_info_record { struct usbmuxd_header header; - struct am_device_info device_info; + struct usbmuxd_device device; char padding[222]; } __attribute__((__packed__)); |