@@ -366,3 +366,51 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
return so;
}
+
+struct socket *
+udp6_listen(Slirp *slirp, struct in6_addr haddr, u_int hport,
+ struct in6_addr laddr, u_int lport, int flags)
+{
+ struct sockaddr_in6 addr;
+ struct socket *so;
+ socklen_t addrlen = sizeof(addr);
+
+ memset(&addr, 0, sizeof(addr));
+
+ so = socreate(slirp);
+ if (!so) {
+ return NULL;
+ }
+ so->s = qemu_socket(AF_INET6, SOCK_DGRAM, 0);
+ if (so->s < 0) {
+ sofree(so);
+ return NULL;
+ }
+ so->so_expire = curtime + SO_EXPIRE;
+ insque(so, &slirp->udb);
+
+ addr.sin6_family = AF_INET6;
+ addr.sin6_addr = haddr;
+ addr.sin6_port = hport;
+
+ if (bind(so->s, (struct sockaddr *)&addr, addrlen) < 0) {
+ udp_detach(so);
+ return NULL;
+ }
+ socket_set_fast_reuse(so->s);
+
+ getsockname(so->s, (struct sockaddr *)&addr, &addrlen);
+ so->fhost.sin6 = addr;
+ sotranslate_accept(so);
+ so->so_lfamily = AF_INET6;
+ so->so_lport = lport;
+ so->so_laddr6 = laddr;
+ if (flags != SS_FACCEPTONCE) {
+ so->so_expire = 0;
+ }
+
+ so->so_state &= SS_PERSISTENT_MASK;
+ so->so_state |= SS_ISFCONNECTED | flags;
+
+ return so;
+}
@@ -80,6 +80,8 @@ int udp_attach(struct socket *, unsigned short af);
void udp_detach(struct socket *);
struct socket * udp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
int);
+struct socket *udp6_listen(Slirp *slirp, struct in6_addr, u_int,
+ struct in6_addr, u_int, int);
int udp_output(struct socket *so, struct mbuf *m,
struct sockaddr_in *saddr, struct sockaddr_in *daddr,
int iptos);
Signed-off-by: Maxim Samoylov <max7255@yandex-team.ru> --- slirp/udp.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ slirp/udp.h | 2 ++ 2 files changed, 50 insertions(+)