diff options
author | 5eraph <bcervenka@protonmail.com> | 2020-02-12 18:52:23 +0100 |
---|---|---|
committer | 5eraph <bcervenka@protonmail.com> | 2020-03-02 20:17:27 +0100 |
commit | 5eb4fc45dc87717fc9c2e26afb602119006d5dd4 (patch) | |
tree | 25a8e89ede65d0e3de0b6f3915235732e06747b0 | |
parent | 296faab4cfd1955bc37fff885985a5b2c0a1fc40 (diff) | |
download | slirp-5eb4fc45dc87717fc9c2e26afb602119006d5dd4.zip slirp-5eb4fc45dc87717fc9c2e26afb602119006d5dd4.tar.gz slirp-5eb4fc45dc87717fc9c2e26afb602119006d5dd4.tar.bz2 |
Use specific outbound IP address
Fixes #14
Signed-off-by: 5eraph <bcervenka@protonmail.com>
-rw-r--r-- | src/ip_icmp.c | 7 | ||||
-rw-r--r-- | src/libslirp.h | 4 | ||||
-rw-r--r-- | src/misc.c | 20 | ||||
-rw-r--r-- | src/misc.h | 2 | ||||
-rw-r--r-- | src/slirp.c | 7 | ||||
-rw-r--r-- | src/slirp.h | 3 | ||||
-rw-r--r-- | src/tcp_subr.c | 10 | ||||
-rw-r--r-- | src/udp.c | 6 |
8 files changed, 58 insertions, 1 deletions
diff --git a/src/ip_icmp.c b/src/ip_icmp.c index 58e35a5..fe0add4 100644 --- a/src/ip_icmp.c +++ b/src/ip_icmp.c @@ -90,6 +90,13 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen) return -1; } + if (slirp_bind_outbound(so, AF_INET) != 0) { + // bind failed - close socket + closesocket(so->s); + so->s = -1; + return -1; + } + so->so_m = m; so->so_faddr = ip->ip_dst; so->so_laddr = ip->ip_src; diff --git a/src/libslirp.h b/src/libslirp.h index ad93edf..fb4c7e8 100644 --- a/src/libslirp.h +++ b/src/libslirp.h @@ -67,7 +67,7 @@ typedef struct SlirpCb { } SlirpCb; #define SLIRP_CONFIG_VERSION_MIN 1 -#define SLIRP_CONFIG_VERSION_MAX 1 +#define SLIRP_CONFIG_VERSION_MAX 2 typedef struct SlirpConfig { /* Version must be provided */ @@ -107,6 +107,8 @@ typedef struct SlirpConfig { /* * Fields introduced in SlirpConfig version 2 begin */ + struct sockaddr_in *outbound_addr; + struct sockaddr_in6 *outbound_addr6; } SlirpConfig; Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, @@ -368,3 +368,23 @@ char *slirp_connection_info(Slirp *slirp) return g_string_free(str, FALSE); } + +int slirp_bind_outbound(struct socket *so, unsigned short af) +{ + int ret = 0; + struct sockaddr *addr = NULL; + int addr_size = 0; + + if (af == AF_INET && so->slirp->outbound_addr != NULL) { + addr = (struct sockaddr *)so->slirp->outbound_addr; + addr_size = sizeof(struct sockaddr_in); + } else if (af == AF_INET6 && so->slirp->outbound_addr6 != NULL) { + addr = (struct sockaddr *)so->slirp->outbound_addr6; + addr_size = sizeof(struct sockaddr_in6); + } + + if (addr != NULL) { + ret = bind(so->s, addr, addr_size); + } + return ret; +}
\ No newline at end of file @@ -67,4 +67,6 @@ struct gfwd_list *add_unix(struct gfwd_list **ex_ptr, const char *unixsock, int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port); +int slirp_bind_outbound(struct socket *so, unsigned short af); + #endif diff --git a/src/slirp.c b/src/slirp.c index e0b53a7..4967475 100644 --- a/src/slirp.c +++ b/src/slirp.c @@ -326,6 +326,13 @@ Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque) slirp->disable_host_loopback = cfg->disable_host_loopback; slirp->enable_emu = cfg->enable_emu; + if (cfg->version >= 2) { + slirp->outbound_addr = cfg->outbound_addr; + slirp->outbound_addr6 = cfg->outbound_addr6; + } else { + slirp->outbound_addr = NULL; + slirp->outbound_addr6 = NULL; + } return slirp; } diff --git a/src/slirp.h b/src/slirp.h index a231eb2..32634bc 100644 --- a/src/slirp.h +++ b/src/slirp.h @@ -199,6 +199,9 @@ struct Slirp { const SlirpCb *cb; void *opaque; + + struct sockaddr_in *outbound_addr; + struct sockaddr_in6 *outbound_addr6; }; void if_start(Slirp *); diff --git a/src/tcp_subr.c b/src/tcp_subr.c index 9dc541a..a1016d9 100644 --- a/src/tcp_subr.c +++ b/src/tcp_subr.c @@ -407,6 +407,16 @@ int tcp_fconnect(struct socket *so, unsigned short af) ret = so->s = slirp_socket(af, SOCK_STREAM, 0); if (ret >= 0) { + ret = slirp_bind_outbound(so, af); + if (ret < 0) { + // bind failed - close socket + closesocket(so->s); + so->s = -1; + return (ret); + } + } + + if (ret >= 0) { int opt, s = so->s; struct sockaddr_storage addr; @@ -279,6 +279,12 @@ int udp_attach(struct socket *so, unsigned short af) { so->s = slirp_socket(af, SOCK_DGRAM, 0); if (so->s != -1) { + if (slirp_bind_outbound(so, af) != 0) { + // bind failed - close socket + closesocket(so->s); + so->s = -1; + return -1; + } so->so_expire = curtime + SO_EXPIRE; insque(so, &so->slirp->udb); } |