Skip to content

Commit 963aa39

Browse files
handle macOS's IPv4 length byte
1 parent 7d41fdb commit 963aa39

1 file changed

Lines changed: 46 additions & 38 deletions

File tree

idevice/src/usbmuxd/des.rs

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,40 @@ impl TryFrom<DeviceListResponse> for UsbmuxdDevice {
6363
));
6464
}
6565

66-
match addr[0] as _ {
67-
AF_INET => {
66+
// macOS sets the first byte as the len, which are:
67+
// 0x10 -> IPv4
68+
// 0x1C -> IPv6
69+
//
70+
// either way, IPv4 is always 16 bytes and IPv6 is always 28 bytes
71+
match addr.as_slice() {
72+
// it's an IPv4 address, but the len is short
73+
[family, ..] | [0x10, family, ..]
74+
if *family == AF_INET as u8 && addr.len() < 0x10 =>
75+
{
76+
warn!("IPv4 address is less than 16 bytes");
77+
return Err(IdeviceError::UnexpectedResponse(
78+
"IPv4 network address too short, expected 16 bytes".into(),
79+
));
80+
}
81+
82+
[family, ..] | [0x10, family, ..] if *family == AF_INET as u8 => {
6883
// IPv4
6984
Connection::Network(IpAddr::V4(Ipv4Addr::new(
7085
addr[4], addr[5], addr[6], addr[7],
7186
)))
7287
}
73-
AF_INET6 => {
74-
// IPv6
75-
if addr.len() < 24 {
76-
warn!("IPv6 address is less than 24 bytes");
77-
return Err(IdeviceError::UnexpectedResponse(
78-
"IPv6 network address too short, expected at least 24 bytes"
79-
.into(),
80-
));
81-
}
8288

89+
[family, ..] | [0x1C, family, ..]
90+
if *family == AF_INET6 as u8 && addr.len() < 28 =>
91+
{
92+
warn!("IPv6 address is less than 28 bytes");
93+
return Err(IdeviceError::UnexpectedResponse(
94+
"IPv6 network address too short, expected 28 bytes".into(),
95+
));
96+
}
97+
98+
[family, ..] | [0x1C, family, ..] if *family == AF_INET6 as u8 => {
99+
// IPv6
83100
Connection::Network(IpAddr::V6(Ipv6Addr::new(
84101
u16::from_be_bytes([addr[8], addr[9]]),
85102
u16::from_be_bytes([addr[10], addr[11]]),
@@ -91,34 +108,25 @@ impl TryFrom<DeviceListResponse> for UsbmuxdDevice {
91108
u16::from_be_bytes([addr[22], addr[23]]),
92109
)))
93110
}
94-
0x1C => {
95-
if addr.len() < 28 {
96-
warn!("IPv6 sockaddr_in6 data too short (len {})", addr.len());
97-
return Err(IdeviceError::UnexpectedResponse(
98-
"IPv6 sockaddr_in6 data too short, expected at least 28 bytes"
99-
.into(),
100-
));
101-
}
102-
if addr[1] == AF_INET6 as u8 {
103-
// IPv6 address starts at offset 8 in sockaddr_in6
104-
Connection::Network(IpAddr::V6(Ipv6Addr::new(
105-
u16::from_be_bytes([addr[8], addr[9]]),
106-
u16::from_be_bytes([addr[10], addr[11]]),
107-
u16::from_be_bytes([addr[12], addr[13]]),
108-
u16::from_be_bytes([addr[14], addr[15]]),
109-
u16::from_be_bytes([addr[16], addr[17]]),
110-
u16::from_be_bytes([addr[18], addr[19]]),
111-
u16::from_be_bytes([addr[20], addr[21]]),
112-
u16::from_be_bytes([addr[22], addr[23]]),
113-
)))
114-
} else {
115-
warn!(
116-
"Expected IPv6 family (0x1E) but got {:02X} for length 0x1C",
117-
addr[1]
118-
);
119-
Connection::Unknown(format!("Network {:02X}", addr[1]))
120-
}
111+
112+
// starts with IPv6 len, but it's not IPv6
113+
[0x1C, addr_family, ..] if *addr_family != AF_INET6 as u8 => {
114+
warn!(
115+
"Expected IPv6 family ({:02X}) but got {:02X} for length 0x1C",
116+
AF_INET6, addr_family
117+
);
118+
Connection::Unknown(format!("Network {:02X}", addr_family))
121119
}
120+
121+
// starts with IPv4 len, but it's not IPv4
122+
[0x10, addr_family, ..] if *addr_family != AF_INET as u8 => {
123+
warn!(
124+
"Expected IPv4 family ({:02X}) but got {:02X} for length 0x10",
125+
AF_INET, addr_family
126+
);
127+
Connection::Unknown(format!("Network {:02X}", addr_family))
128+
}
129+
122130
_ => {
123131
warn!("Unknown IP address protocol: {:02X}", addr[0]);
124132
Connection::Unknown(format!("Network {:02X}", addr[0]))

0 commit comments

Comments
 (0)