Skip to contentSkip to conversation

slirp: fix ICMP handling on macOS hosts

PATCH Applied [email protected] 2 participants 2 messages Jul 29, 2018

v2 of 3 Applied Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 slirp: fix ICMP handling on macOS hosts

From: Andrew Oates <[email protected]>

On Linux, SOCK_DGRAM+IPPROTO_ICMP sockets give only the ICMP packet when read from. On macOS, however, the socket acts like a SOCK_RAW socket and includes the IP header as well.

This change strips the extra IP header from the received packet on macOS before sending it to the guest.

---
v2: check validity of inner_hlen and update len appropriately

 slirp/ip_icmp.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
slirp/ip_icmp.c +15 -1
index 0b667a429a..76c6d54b11 100644
@@ -420,7 +420,21 @@ void icmp_receive(struct socket *so)
     icp = mtod(m, struct icmp *);
 
     id = icp->icmp_id;
-    len = qemu_recv(so->s, icp, m->m_len, 0);
+    len = qemu_recv(so->s, icp, M_ROOM(m), 0);
+#ifdef CONFIG_DARWIN
+    if (len > 0) {
+        /* Skip the IP header that OS X (unlike Linux) includes. */
+        struct ip *inner_ip = mtod(m, struct ip *);
+        int inner_hlen = inner_ip->ip_hl << 2;
+        if (inner_hlen > len) {
+            len = -1;
+            errno = -EINVAL;
+        } else {
+            len -= inner_hlen;
+            memmove(icp, (unsigned char *)icp + inner_hlen, len);
+        }
+    }
+#endif
     icp->icmp_id = id;
 
     m->m_data -= hlen;
Signature · 1 line
2.17.0
#1 lore raw

Hello,

[email protected], le sam. 28 juil. 2018 21:54:26 -0400, a ecrit:

Quoted 10 lines

From: Andrew Oates <[email protected]>

On Linux, SOCK_DGRAM+IPPROTO_ICMP sockets give only the ICMP packet when read from. On macOS, however, the socket acts like a SOCK_RAW socket and includes the IP header as well.

This change strips the extra IP header from the received packet on macOS before sending it to the guest.

Applied to my tree, thanks!

Quoted 36 lines

---
v2: check validity of inner_hlen and update len appropriately

 slirp/ip_icmp.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
slirp/ip_icmp.c +15 -1
index 0b667a429a..76c6d54b11 100644
@@ -420,7 +420,21 @@ void icmp_receive(struct socket *so)
     icp = mtod(m, struct icmp *);
 
     id = icp->icmp_id;
-    len = qemu_recv(so->s, icp, m->m_len, 0);
+    len = qemu_recv(so->s, icp, M_ROOM(m), 0);
+#ifdef CONFIG_DARWIN
+    if (len > 0) {
+        /* Skip the IP header that OS X (unlike Linux) includes. */
+        struct ip *inner_ip = mtod(m, struct ip *);
+        int inner_hlen = inner_ip->ip_hl << 2;
+        if (inner_hlen > len) {
+            len = -1;
+            errno = -EINVAL;
+        } else {
+            len -= inner_hlen;
+            memmove(icp, (unsigned char *)icp + inner_hlen, len);
+        }
+    }
+#endif
     icp->icmp_id = id;
 
     m->m_data -= hlen;
Signature · 1 line
2.17.0
Signature · 4 lines
Samuel
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and
the Ugly)."
(By Matt Welsh)