slirp: fix ICMP handling on macOS hosts
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
@@ -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
Samuel Thibault
AppliedHello,
[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_RAWsocket 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.
Signed-off-by Andrew Oates <[email protected]>
Applied to my tree, thanks!
Quoted 36 lines
---
v2: check validity ofinner_hlenand update len appropriatelyslirp/ip_icmp.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)slirp/ip_icmp.c +15
-1@@ -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)