summary refs log tree commit diff stats
path: root/slirp/socket.c
diff options
context:
space:
mode:
authorGuillaume Subiron <maethor@subiron.org>2016-03-15 10:31:20 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-03-15 10:35:08 +0100
commit15d62af4b6068d1bac1806ca4625b6d4c475eb09 (patch)
tree17e76661234a309b56927de53f336a4e8bf8e598 /slirp/socket.c
parentfc6c9257c6dd47316a1c55d356bcd89bdc5fd642 (diff)
downloadfocaccia-qemu-15d62af4b6068d1bac1806ca4625b6d4c475eb09.tar.gz
focaccia-qemu-15d62af4b6068d1bac1806ca4625b6d4c475eb09.zip
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.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/slirp/socket.c b/slirp/socket.c
index 32b1ba3bd5..55150f5e5e 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 */