diff options
Diffstat (limited to 'src/usbmux.c')
-rw-r--r-- | src/usbmux.c | 188 |
1 files changed, 104 insertions, 84 deletions
diff --git a/src/usbmux.c b/src/usbmux.c index 35f2ef3..cf1a2d9 100644 --- a/src/usbmux.c +++ b/src/usbmux.c @@ -39,8 +39,9 @@ static int clients = 0; * * @return A USBMux packet */ -usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) { - usbmux_tcp_header *conn = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header)); +usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) +{ + usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); conn->type = htonl(6); conn->length = 28; conn->sport = htons(s_port); @@ -58,8 +59,9 @@ usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) { * * @return A USBMux header */ -usbmux_version_header *version_header() { - usbmux_version_header *version = (usbmux_version_header*)malloc(sizeof(usbmux_version_header)); +usbmux_version_header *version_header() +{ + usbmux_version_header *version = (usbmux_version_header *) malloc(sizeof(usbmux_version_header)); version->type = 0; version->length = htonl(20); version->major = htonl(1); @@ -76,11 +78,13 @@ usbmux_version_header *version_header() { * * @param connection The connection to delete from the tracking list. */ -void delete_connection(iphone_umux_client_t connection) { - iphone_umux_client_t *newlist = (iphone_umux_client_t*)malloc(sizeof(iphone_umux_client_t) * (clients - 1)); +void delete_connection(iphone_umux_client_t connection) +{ + iphone_umux_client_t *newlist = (iphone_umux_client_t *) malloc(sizeof(iphone_umux_client_t) * (clients - 1)); int i = 0, j = 0; for (i = 0; i < clients; i++) { - if (connlist[i] == connection) continue; + if (connlist[i] == connection) + continue; else { newlist[j] = connlist[i]; j++; @@ -89,8 +93,10 @@ void delete_connection(iphone_umux_client_t connection) { free(connlist); connlist = newlist; clients--; - if (connection->recv_buffer) free(connection->recv_buffer); - if (connection->header) free(connection->header); + if (connection->recv_buffer) + free(connection->recv_buffer); + if (connection->header) + free(connection->header); connection->r_len = 0; free(connection); } @@ -101,8 +107,10 @@ void delete_connection(iphone_umux_client_t connection) { * @param connection The connection to add to the global list of connections. */ -void add_connection(iphone_umux_client_t connection) { - iphone_umux_client_t* newlist = (iphone_umux_client_t*)realloc(connlist, sizeof(iphone_umux_client_t) * (clients+1)); +void add_connection(iphone_umux_client_t connection) +{ + iphone_umux_client_t *newlist = + (iphone_umux_client_t *) realloc(connlist, sizeof(iphone_umux_client_t) * (clients + 1)); newlist[clients] = connection; connlist = newlist; clients++; @@ -116,13 +124,15 @@ void add_connection(iphone_umux_client_t connection) { * @param client A mux TCP header for the connection which is used for tracking and data transfer. * @return IPHONE_E_SUCCESS on success, an error code otherwise. */ -iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client ){ +iphone_error_t iphone_mux_new_client(iphone_device_t device, uint16_t src_port, uint16_t dst_port, + iphone_umux_client_t * client) +{ if (!device || !src_port || !dst_port) return IPHONE_E_INVALID_ARG; int bytes = 0; // Initialize connection stuff - iphone_umux_client_t new_connection = (iphone_umux_client_t)malloc(sizeof(struct iphone_umux_client_int)); + iphone_umux_client_t new_connection = (iphone_umux_client_t) malloc(sizeof(struct iphone_umux_client_int)); new_connection->header = new_mux_packet(src_port, dst_port); // blargg @@ -130,18 +140,19 @@ iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port new_connection->header->tcp_flags = 0x02; new_connection->header->length = htonl(new_connection->header->length); new_connection->header->length16 = htons(new_connection->header->length16); - - if (send_to_phone(device, (char*)new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { + + if (send_to_phone(device, (char *) new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { usbmux_tcp_header *response; - response = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header)); - bytes = recv_from_phone(device, (char*)response, sizeof(*response)); + response = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); + bytes = recv_from_phone(device, (char *) response, sizeof(*response)); if (response->tcp_flags != 0x12) { free(response); return IPHONE_E_UNKNOWN_ERROR; } else { free(response); - if (debug) printf("mux_connect: connection success\n"); + if (debug) + printf("mux_connect: connection success\n"); new_connection->header->tcp_flags = 0x10; new_connection->header->scnt = 1; new_connection->header->ocnt = 1; @@ -156,7 +167,6 @@ iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port return IPHONE_E_NOT_ENOUGH_DATA; } } - // if we get to this point it's probably bad return IPHONE_E_UNKNOWN_ERROR; } @@ -168,22 +178,24 @@ iphone_error_t iphone_mux_new_client ( iphone_device_t device, uint16_t src_port * * @return IPHONE_E_SUCCESS on success. */ -iphone_error_t iphone_mux_free_client ( iphone_umux_client_t client ) { - if (!client || !client->phone) return; - +iphone_error_t iphone_mux_free_client(iphone_umux_client_t client) +{ + if (!client || !client->phone) + return; + client->header->tcp_flags = 0x04; client->header->scnt = htonl(client->header->scnt); client->header->ocnt = htonl(client->header->ocnt); int bytes = 0; - - bytes = usb_bulk_write(client->phone->device, BULKOUT, (char*)client->header, sizeof(usbmux_tcp_header), 800); - if(debug && bytes < 0) + + bytes = usb_bulk_write(client->phone->device, BULKOUT, (char *) client->header, sizeof(usbmux_tcp_header), 800); + if (debug && bytes < 0) printf("iphone_muxèfree_client(): when writing, libusb gave me the error: %s\n", usb_strerror()); - bytes = usb_bulk_read(client->phone->device, BULKIN, (char*)client->header, sizeof(usbmux_tcp_header), 800); - if(debug && bytes < 0) + bytes = usb_bulk_read(client->phone->device, BULKIN, (char *) client->header, sizeof(usbmux_tcp_header), 800); + if (debug && bytes < 0) printf("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); - + delete_connection(client); return IPHONE_E_SUCCESS; @@ -201,30 +213,35 @@ iphone_error_t iphone_mux_free_client ( iphone_umux_client_t client ) { * @return IPHONE_E_SUCCESS on success. */ -iphone_error_t iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t *sent_bytes ) { - if (!client->phone || !client || !data || datalen == 0 || !sent_bytes) return IPHONE_E_INVALID_ARG; +iphone_error_t iphone_mux_send(iphone_umux_client_t client, const char *data, uint32_t datalen, uint32_t * sent_bytes) +{ + if (!client->phone || !client || !data || datalen == 0 || !sent_bytes) + return IPHONE_E_INVALID_ARG; // client->scnt and client->ocnt should already be in host notation... // we don't need to change them juuuust yet. *sent_bytes = 0; - if (debug) printf("mux_send(): client wants to send %i bytes\n", datalen); - char *buffer = (char*)malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding + if (debug) + printf("mux_send(): client wants to send %i bytes\n", datalen); + char *buffer = (char *) malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding // Set the length and pre-emptively htonl/htons it client->header->length = htonl(sizeof(usbmux_tcp_header) + datalen); client->header->length16 = htons(sizeof(usbmux_tcp_header) + datalen); - + // Put scnt and ocnt into big-endian notation client->header->scnt = htonl(client->header->scnt); client->header->ocnt = htonl(client->header->ocnt); // Concatenation of stuff in the buffer. memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); - memcpy(buffer+sizeof(usbmux_tcp_header), data, datalen); - + memcpy(buffer + sizeof(usbmux_tcp_header), data, datalen); + // We have a buffer full of data, we should now send it to the phone. - if (debug) printf("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header)+datalen, buffer); + if (debug) + printf("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header) + datalen, buffer); + - - *sent_bytes = send_to_phone(client->phone, buffer, sizeof(usbmux_tcp_header)+datalen); - if (debug) printf("mux_send: sent %i bytes!\n", *sent_bytes); + *sent_bytes = send_to_phone(client->phone, buffer, sizeof(usbmux_tcp_header) + datalen); + if (debug) + printf("mux_send: sent %i bytes!\n", *sent_bytes); // Now that we've sent it off, we can clean up after our sloppy selves. if (debug) { FILE *packet = fopen("packet", "a+"); @@ -232,24 +249,25 @@ iphone_error_t iphone_mux_send ( iphone_umux_client_t client, const char *data, fclose(packet); printf("\n"); } - - if (buffer) free(buffer); + + if (buffer) + free(buffer); // Re-calculate scnt and ocnt client->header->scnt = ntohl(client->header->scnt) + datalen; client->header->ocnt = ntohl(client->header->ocnt); - + // Revert lengths client->header->length = ntohl(client->header->length); client->header->length16 = ntohs(client->header->length16); - + // Now return the bytes. - if (*sent_bytes < sizeof(usbmux_tcp_header)+datalen) { + if (*sent_bytes < sizeof(usbmux_tcp_header) + datalen) { *sent_bytes = 0; return IPHONE_E_NOT_ENOUGH_DATA; } else { - *sent_bytes = *sent_bytes - 28; // actual length sent. :/ + *sent_bytes = *sent_bytes - 28; // actual length sent. :/ } - + return IPHONE_E_SUCCESS; } @@ -261,7 +279,8 @@ iphone_error_t iphone_mux_send ( iphone_umux_client_t client, const char *data, * * @return How many bytes were read, or -1 if something bad happens. */ -iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t *recv_bytes ) { +iphone_error_t iphone_mux_recv(iphone_umux_client_t client, char *data, uint32_t datalen, uint32_t * recv_bytes) +{ if (!client || !data || datalen == 0 || !recv_bytes) return IPHONE_E_INVALID_ARG; @@ -269,18 +288,19 @@ iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32 * Order of operation: * 1.) Check if the client has a pre-received buffer. * 2.) If so, fill data with the buffer, as much as needed. - * a.) Return quickly if the buffer has enough - * b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return) + * a.) Return quickly if the buffer has enough + * b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return) * 3.) If not, receive directly from the phone. - * a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation. - * b.) If not, find the client the ports belong to and fill that client's buffer, then return mux_recv with the same args to try again. + * a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation. + * b.) If not, find the client the ports belong to and fill that client's buffer, then return mux_recv with the same args to try again. */ - if (debug) printf("mux_recv: datalen == %i\n", datalen); + if (debug) + printf("mux_recv: datalen == %i\n", datalen); int bytes = 0, i = 0, complex = 0, offset = 0; *recv_bytes = 0; char *buffer = NULL; usbmux_tcp_header *header = NULL; - + if (client->recv_buffer) { if (client->r_len >= datalen) { memcpy(data, client->recv_buffer, datalen); @@ -290,41 +310,42 @@ iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32 client->r_len = 0; client->recv_buffer = NULL; } else { - buffer = (char*)malloc(sizeof(char) * (client->r_len - datalen)); - memcpy(buffer, client->recv_buffer+datalen, (client->r_len - datalen)); + buffer = (char *) malloc(sizeof(char) * (client->r_len - datalen)); + memcpy(buffer, client->recv_buffer + datalen, (client->r_len - datalen)); client->r_len -= datalen; free(client->recv_buffer); client->recv_buffer = buffer; } - + // Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above. return datalen; } else { memcpy(data, client->recv_buffer, client->r_len); - free(client->recv_buffer); // don't need to deal with anymore, but... - offset = client->r_len; // see #2b, above + free(client->recv_buffer); // don't need to deal with anymore, but... + offset = client->r_len; // see #2b, above client->r_len = 0; } - } // End of what to do if we have a pre-buffer. See #1 and #2 above. - - buffer = (char*)malloc(sizeof(char) * 131072); // make sure we get enough ;) - + } // End of what to do if we have a pre-buffer. See #1 and #2 above. + + buffer = (char *) malloc(sizeof(char) * 131072); // make sure we get enough ;) + // See #3. bytes = recv_from_phone(client->phone, buffer, 131072); if (bytes < 28) { free(buffer); - if (debug) printf("mux_recv: Did not even get the header.\n"); + if (debug) + printf("mux_recv: Did not even get the header.\n"); return IPHONE_E_NOT_ENOUGH_DATA; } - - header = (usbmux_tcp_header*)buffer; + + header = (usbmux_tcp_header *) buffer; if (header->sport != client->header->dport || header->dport != client->header->sport) { // Ooooops -- we got someone else's packet. // We gotta stick it in their buffer. (Take that any old way you want ;) ) for (i = 0; i < clients; i++) { if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) { // we have a winner. - char *nfb = (char*)malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28))); + char *nfb = (char *) malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28))); if (connlist[i]->recv_buffer && connlist[i]->r_len) { memcpy(nfb, connlist[i]->recv_buffer, connlist[i]->r_len); free(connlist[i]->recv_buffer); @@ -332,45 +353,44 @@ iphone_error_t iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32 connlist[i]->r_len += bytes - 28; //connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * client->r_len); // grow their buffer connlist[i]->recv_buffer = nfb; - nfb = NULL; // A cookie for you if you can guess what "nfb" means. + nfb = NULL; // A cookie for you if you can guess what "nfb" means. complex = connlist[i]->r_len - (bytes - 28); - memcpy(connlist[i]->recv_buffer+complex, buffer+28, bytes-28); // paste into their buffer - connlist[i]->header->ocnt += bytes-28; + memcpy(connlist[i]->recv_buffer + complex, buffer + 28, bytes - 28); // paste into their buffer + connlist[i]->header->ocnt += bytes - 28; } } // If it wasn't ours, it's been handled by this point... or forgotten. // Free our buffer and continue. free(buffer); buffer = NULL; - return iphone_mux_recv(client, data, datalen, recv_bytes); // recurse back in to try again + return iphone_mux_recv(client, data, datalen, recv_bytes); // recurse back in to try again } - // The packet was absolutely meant for us if it hits this point. // The pre-buffer has been taken care of, so, again, if we're at this point we have to read from the phone. - - if ((bytes-28) > datalen) { + + if ((bytes - 28) > datalen) { // Copy what we need into the data, buffer the rest because we can. - memcpy(data+offset, buffer+28, datalen); // data+offset: see #2b, above - complex = client->r_len + (bytes-28) - datalen; - client->recv_buffer = (char*)realloc(client->recv_buffer, (sizeof(char) * complex)); + memcpy(data + offset, buffer + 28, datalen); // data+offset: see #2b, above + complex = client->r_len + (bytes - 28) - datalen; + client->recv_buffer = (char *) realloc(client->recv_buffer, (sizeof(char) * complex)); client->r_len = complex; - complex = client->r_len - (bytes-28) - datalen; - memcpy(client->recv_buffer+complex, buffer+28+datalen, (bytes-28) - datalen); + complex = client->r_len - (bytes - 28) - datalen; + memcpy(client->recv_buffer + complex, buffer + 28 + datalen, (bytes - 28) - datalen); free(buffer); - client->header->ocnt += bytes-28; + client->header->ocnt += bytes - 28; *recv_bytes = datalen; return IPHONE_E_SUCCESS; } else { // Fill the data with what we have, and just return. - memcpy(data+offset, buffer+28, bytes-28); // data+offset: see #2b, above - client->header->ocnt += bytes-28; + memcpy(data + offset, buffer + 28, bytes - 28); // data+offset: see #2b, above + client->header->ocnt += bytes - 28; free(buffer); *recv_bytes = bytes - 28; return IPHONE_E_SUCCESS; } - + // If we get to this point, 'tis probably bad. - if (debug) printf("mux_recv: Heisenbug: bytes and datalen not matching up\n"); + if (debug) + printf("mux_recv: Heisenbug: bytes and datalen not matching up\n"); return IPHONE_E_UNKNOWN_ERROR; } - |