diff options
author | Jan Kiszka <jan.kiszka@web.de> | 2009-06-24 14:42:28 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-06-29 08:52:45 -0500 |
commit | f7479d388c09982958b5026f50164e8bb3857448 (patch) | |
tree | 53ef642f8baac03fe0d8518bd263da3ded64987b /slirp | |
parent | 082ffb01f5c1c00dbc9f126fa420a1d723707deb (diff) | |
download | qemu-f7479d388c09982958b5026f50164e8bb3857448.tar.gz qemu-f7479d388c09982958b5026f50164e8bb3857448.tar.bz2 qemu-f7479d388c09982958b5026f50164e8bb3857448.zip |
slirp: Bind support for host forwarding rules
Extend the hostfwd rule format so that the user can specify on which
host interface qemu should listen for incoming connections. If omitted,
binding will takes place against all interfaces.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'slirp')
-rw-r--r-- | slirp/libslirp.h | 5 | ||||
-rw-r--r-- | slirp/slirp.c | 11 | ||||
-rw-r--r-- | slirp/socket.c | 10 | ||||
-rw-r--r-- | slirp/socket.h | 2 | ||||
-rw-r--r-- | slirp/tcp_subr.c | 15 | ||||
-rw-r--r-- | slirp/udp.c | 7 | ||||
-rw-r--r-- | slirp/udp.h | 2 |
7 files changed, 27 insertions, 25 deletions
diff --git a/slirp/libslirp.h b/slirp/libslirp.h index e4c9c99c3b..9be4425bb6 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -22,10 +22,9 @@ void slirp_input(const uint8_t *pkt, int pkt_len); int slirp_can_output(void); void slirp_output(const uint8_t *pkt, int pkt_len); -int slirp_add_hostfwd(int is_udp, int host_port, +int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port, struct in_addr guest_addr, int guest_port); -int slirp_remove_hostfwd(int is_udp, int host_port); - +int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port); int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr, int guest_port); diff --git a/slirp/slirp.c b/slirp/slirp.c index ad88121c2c..ab0a8548aa 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -757,7 +757,7 @@ void if_encap(const uint8_t *ip_data, int ip_data_len) /* Unlistens a redirection * * Return value: number of redirs removed */ -int slirp_remove_hostfwd(int is_udp, int host_port) +int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port) { struct socket *so; struct socket *head = (is_udp ? &udb : &tcb); @@ -770,6 +770,7 @@ int slirp_remove_hostfwd(int is_udp, int host_port) for (so = head->so_next; so != head; so = so->so_next) { addr_len = sizeof(addr); if (getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 && + addr.sin_addr.s_addr == host_addr.s_addr && addr.sin_port == port) { close(so->s); sofree(so); @@ -781,19 +782,19 @@ int slirp_remove_hostfwd(int is_udp, int host_port) return n; } -int slirp_add_hostfwd(int is_udp, int host_port, +int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port, struct in_addr guest_addr, int guest_port) { if (!guest_addr.s_addr) { guest_addr = vdhcp_startaddr; } if (is_udp) { - if (!udp_listen(htons(host_port), guest_addr.s_addr, + if (!udp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr, htons(guest_port), 0)) return -1; } else { - if (!solisten(htons(host_port), guest_addr.s_addr, - htons(guest_port), 0)) + if (!tcp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr, + htons(guest_port), 0)) return -1; } return 0; diff --git a/slirp/socket.c b/slirp/socket.c index 9f13f03cc6..936021e84d 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -586,17 +586,17 @@ sosendto(struct socket *so, struct mbuf *m) } /* - * XXX This should really be tcp_listen + * Listen for incoming TCP connections */ struct socket * -solisten(u_int port, u_int32_t laddr, u_int lport, int flags) +tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags) { struct sockaddr_in addr; struct socket *so; int s, opt = 1; socklen_t addrlen = sizeof(addr); - DEBUG_CALL("solisten"); + DEBUG_CALL("tcp_listen"); DEBUG_ARG("port = %d", port); DEBUG_ARG("laddr = %x", laddr); DEBUG_ARG("lport = %d", lport); @@ -625,8 +625,8 @@ solisten(u_int port, u_int32_t laddr, u_int lport, int flags) so->so_laddr.s_addr = laddr; /* Ditto */ addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = port; + addr.sin_addr.s_addr = haddr; + addr.sin_port = hport; if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) || (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || diff --git a/slirp/socket.h b/slirp/socket.h index f5adaba6e7..ac36aaa4b5 100644 --- a/slirp/socket.h +++ b/slirp/socket.h @@ -82,7 +82,7 @@ int sosendoob _P((struct socket *)); int sowrite _P((struct socket *)); void sorecvfrom _P((struct socket *)); int sosendto _P((struct socket *, struct mbuf *)); -struct socket * solisten _P((u_int, u_int32_t, u_int, int)); +struct socket * tcp_listen _P((u_int32_t, u_int, u_int32_t, u_int, int)); void soisfconnecting _P((register struct socket *)); void soisfconnected _P((register struct socket *)); void soisfdisconnected _P((struct socket *)); diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index 858d1ae59c..6fa4223a4e 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -970,7 +970,7 @@ do_prompt: laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); lport = htons((n5 << 8) | (n6)); - if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) + if ((so = tcp_listen(INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL) return 1; n6 = ntohs(so->so_fport); @@ -1002,7 +1002,7 @@ do_prompt: laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); lport = htons((n5 << 8) | (n6)); - if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) + if ((so = tcp_listen(INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL) return 1; n6 = ntohs(so->so_fport); @@ -1042,7 +1042,7 @@ do_prompt: lport += m->m_data[i] - '0'; } if (m->m_data[m->m_len-1] == '\0' && lport != 0 && - (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) + (so = tcp_listen(INADDR_ANY, 0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d", ntohs(so->so_fport)) + 1; return 1; @@ -1057,7 +1057,7 @@ do_prompt: /* The %256s is for the broken mIRC */ if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) + if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) return 1; m->m_len = bptr - m->m_data; /* Adjust length */ @@ -1066,7 +1066,7 @@ do_prompt: (unsigned long)ntohl(so->so_faddr.s_addr), ntohs(so->so_fport), 1); } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) + if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) return 1; m->m_len = bptr - m->m_data; /* Adjust length */ @@ -1075,7 +1075,7 @@ do_prompt: (unsigned long)ntohl(so->so_faddr.s_addr), ntohs(so->so_fport), n1, 1); } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { - if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) + if ((so = tcp_listen(INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) return 1; m->m_len = bptr - m->m_data; /* Adjust length */ @@ -1190,7 +1190,8 @@ do_prompt: /* try to get udp port between 6970 - 7170 */ for (p = 6970; p < 7071; p++) { - if (udp_listen( htons(p), + if (udp_listen(INADDR_ANY, + htons(p), so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) { diff --git a/slirp/udp.c b/slirp/udp.c index ff3a39fb21..d675ad3e66 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -627,7 +627,8 @@ struct cu_header { } struct socket * -udp_listen(u_int port, u_int32_t laddr, u_int lport, int flags) +udp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, + int flags) { struct sockaddr_in addr; struct socket *so; @@ -642,8 +643,8 @@ udp_listen(u_int port, u_int32_t laddr, u_int lport, int flags) insque(so,&udb); addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = port; + addr.sin_addr.s_addr = haddr; + addr.sin_port = hport; if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) { udp_detach(so); diff --git a/slirp/udp.h b/slirp/udp.h index 51a07a2fcc..d4c2bea60e 100644 --- a/slirp/udp.h +++ b/slirp/udp.h @@ -101,7 +101,7 @@ void udp_input _P((register struct mbuf *, int)); int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *)); int udp_attach _P((struct socket *)); void udp_detach _P((struct socket *)); -struct socket * udp_listen _P((u_int, u_int32_t, u_int, int)); +struct socket * udp_listen _P((u_int32_t, u_int, u_int32_t, u_int, int)); int udp_output2(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr, struct sockaddr_in *daddr, int iptos); |