diff options
author | Guillaume Subiron <maethor@subiron.org> | 2016-03-15 10:31:20 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2016-03-15 10:35:08 +0100 |
commit | 15d62af4b6068d1bac1806ca4625b6d4c475eb09 (patch) | |
tree | 17e76661234a309b56927de53f336a4e8bf8e598 /slirp/socket.c | |
parent | fc6c9257c6dd47316a1c55d356bcd89bdc5fd642 (diff) | |
download | qemu-15d62af4b6068d1bac1806ca4625b6d4c475eb09.zip qemu-15d62af4b6068d1bac1806ca4625b6d4c475eb09.tar.gz qemu-15d62af4b6068d1bac1806ca4625b6d4c475eb09.tar.bz2 |
slirp: Adding IPv6 UDP support
This adds the sin6 case in the fhost and lhost unions and related macros.
It adds udp6_input() and udp6_output().
It adds the IPv6 case in sorecvfrom().
Finally, udp_input() is called by ip6_input().
Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'slirp/socket.c')
-rw-r--r-- | slirp/socket.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/slirp/socket.c b/slirp/socket.c index 32b1ba3..55150f5 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -505,13 +505,37 @@ sorecvfrom(struct socket *so) DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", m->m_len, errno,strerror(errno))); if(m->m_len<0) { - u_char code=ICMP_UNREACH_PORT; - - if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; - - DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); - icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno)); + /* Report error as ICMP */ + switch (so->so_lfamily) { + uint8_t code; + case AF_INET: + code = ICMP_UNREACH_PORT; + + if (errno == EHOSTUNREACH) { + code = ICMP_UNREACH_HOST; + } else if (errno == ENETUNREACH) { + code = ICMP_UNREACH_NET; + } + + DEBUG_MISC((dfd, " rx error, tx icmp ICMP_UNREACH:%i\n", code)); + icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno)); + break; + case AF_INET6: + code = ICMP6_UNREACH_PORT; + + if (errno == EHOSTUNREACH) { + code = ICMP6_UNREACH_ADDRESS; + } else if (errno == ENETUNREACH) { + code = ICMP6_UNREACH_NO_ROUTE; + } + + DEBUG_MISC((dfd, " rx error, tx icmp6 ICMP_UNREACH:%i\n", code)); + icmp6_send_error(so->so_m, ICMP6_UNREACH, code); + break; + default: + g_assert_not_reached(); + break; + } m_free(m); } else { /* @@ -541,7 +565,12 @@ sorecvfrom(struct socket *so) (struct sockaddr_in *) &daddr, so->so_iptos); break; + case AF_INET6: + udp6_output(so, m, (struct sockaddr_in6 *) &saddr, + (struct sockaddr_in6 *) &daddr); + break; default: + g_assert_not_reached(); break; } } /* rx error */ |