summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/idevice.c83
1 files changed, 76 insertions, 7 deletions
diff --git a/src/idevice.c b/src/idevice.c
index 0a62907..418ee86 100644
--- a/src/idevice.c
+++ b/src/idevice.c
@@ -421,7 +421,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t
return IDEVICE_E_INVALID_ARG;
}
- if (device->conn_type == CONNECTION_USBMUXD || device->conn_type == CONNECTION_NETWORK) {
+ if (device->conn_type == CONNECTION_USBMUXD) {
int sfd = usbmuxd_connect(device->mux_id, port);
if (sfd < 0) {
debug_info("ERROR: Connecting to usbmuxd failed: %d (%s)", sfd, strerror(-sfd));
@@ -434,6 +434,45 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t
new_connection->device = device;
*connection = new_connection;
return IDEVICE_E_SUCCESS;
+ } else if (device->conn_type == CONNECTION_NETWORK) {
+ unsigned char saddr_[32];
+ memset(saddr_, '\0', sizeof(saddr_));
+ struct sockaddr* saddr = (struct sockaddr*)&saddr_[0];
+ if (((char*)device->conn_data)[1] == 0x02) { // AF_INET
+ saddr->sa_family = AF_INET;
+ memcpy(&saddr->sa_data[0], (char*)device->conn_data+2, 14);
+ }
+ else if (((char*)device->conn_data)[1] == 0x1E) { //AF_INET6 (bsd)
+#ifdef AF_INET6
+ saddr->sa_family = AF_INET6;
+ memcpy(&saddr->sa_data[0], (char*)device->conn_data+2, 26);
+#else
+ debug_info("ERROR: Got an IPv6 address but this system doesn't support IPv6");
+ return IDEVICE_E_UNKNOWN_ERROR;
+#endif
+ }
+ else {
+ debug_info("Unsupported address family 0x%02x", ((char*)device->conn_data)[1]);
+ return IDEVICE_E_UNKNOWN_ERROR;
+ }
+ char addrtxt[48];
+ addrtxt[0] = '\0';
+ if (!socket_addr_to_string(saddr, addrtxt, sizeof(addrtxt))) {
+ debug_info("Failed to convert network address: %d (%s)", errno, strerror(errno));
+ }
+ debug_info("Connecting to %s port %d...", addrtxt, port);
+ int sfd = socket_connect_addr(saddr, port);
+ if (sfd < 0) {
+ debug_info("ERROR: Connecting to network device failed: %d (%s)", errno, strerror(errno));
+ return IDEVICE_E_NO_DEVICE;
+ }
+ idevice_connection_t new_connection = (idevice_connection_t)malloc(sizeof(struct idevice_connection_private));
+ new_connection->type = CONNECTION_NETWORK;
+ new_connection->data = (void*)(long)sfd;
+ new_connection->ssl_data = NULL;
+ new_connection->device = device;
+ *connection = new_connection;
+ return IDEVICE_E_SUCCESS;
} else {
debug_info("Unknown connection type %d", device->conn_type);
}
@@ -451,10 +490,14 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_disconnect(idevice_connection_t con
idevice_connection_disable_ssl(connection);
}
idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR;
- if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) {
+ if (connection->type == CONNECTION_USBMUXD) {
usbmuxd_disconnect((int)(long)connection->data);
connection->data = NULL;
result = IDEVICE_E_SUCCESS;
+ } else if (connection->type == CONNECTION_NETWORK) {
+ socket_close((int)(long)connection->data);
+ connection->data = NULL;
+ result = IDEVICE_E_SUCCESS;
} else {
debug_info("Unknown connection type %d", connection->type);
}
@@ -474,13 +517,21 @@ static idevice_error_t internal_connection_send(idevice_connection_t connection,
return IDEVICE_E_INVALID_ARG;
}
- if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) {
+ if (connection->type == CONNECTION_USBMUXD) {
int res = usbmuxd_send((int)(long)connection->data, data, len, sent_bytes);
if (res < 0) {
debug_info("ERROR: usbmuxd_send returned %d (%s)", res, strerror(-res));
return IDEVICE_E_UNKNOWN_ERROR;
}
return IDEVICE_E_SUCCESS;
+ } else if (connection->type == CONNECTION_NETWORK) {
+ int s = socket_send((int)(long)connection->data, (void*)data, len);
+ if (s < 0) {
+ *sent_bytes = 0;
+ return IDEVICE_E_UNKNOWN_ERROR;
+ }
+ *sent_bytes = s;
+ return IDEVICE_E_SUCCESS;
} else {
debug_info("Unknown connection type %d", connection->type);
}
@@ -545,7 +596,7 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t
return IDEVICE_E_INVALID_ARG;
}
- if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) {
+ if (connection->type == CONNECTION_USBMUXD) {
int conn_error = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout);
idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, *recv_bytes);
@@ -554,6 +605,14 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t
}
return error;
+ } else if (connection->type == CONNECTION_NETWORK) {
+ int res = socket_receive_timeout((int)(long)connection->data, data, len, 0, timeout);
+ if (res < 0) {
+ debug_info("ERROR: socket_receive_timeout failed: %d (%s)", res, strerror(-res));
+ return (res == -EAGAIN ? IDEVICE_E_NOT_ENOUGH_DATA : IDEVICE_E_UNKNOWN_ERROR);
+ }
+ *recv_bytes = (uint32_t)res;
+ return IDEVICE_E_SUCCESS;
} else {
debug_info("Unknown connection type %d", connection->type);
}
@@ -630,13 +689,20 @@ static idevice_error_t internal_connection_receive(idevice_connection_t connecti
return IDEVICE_E_INVALID_ARG;
}
- if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) {
+ if (connection->type == CONNECTION_USBMUXD) {
int res = usbmuxd_recv((int)(long)connection->data, data, len, recv_bytes);
if (res < 0) {
debug_info("ERROR: usbmuxd_recv returned %d (%s)", res, strerror(-res));
return IDEVICE_E_UNKNOWN_ERROR;
}
-
+ return IDEVICE_E_SUCCESS;
+ } else if (connection->type == CONNECTION_NETWORK) {
+ int res = socket_receive((int)(long)connection->data, data, len);
+ if (res < 0) {
+ debug_info("ERROR: socket_receive returned %d (%s)", res, strerror(-res));
+ return IDEVICE_E_UNKNOWN_ERROR;
+ }
+ *recv_bytes = (uint32_t)res;
return IDEVICE_E_SUCCESS;
} else {
debug_info("Unknown connection type %d", connection->type);
@@ -674,7 +740,10 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_get_fd(idevice_connectio
}
idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR;
- if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) {
+ if (connection->type == CONNECTION_USBMUXD) {
+ *fd = (int)(long)connection->data;
+ result = IDEVICE_E_SUCCESS;
+ } else if (connection->type == CONNECTION_NETWORK) {
*fd = (int)(long)connection->data;
result = IDEVICE_E_SUCCESS;
} else {