aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author5eraph <bcervenka@protonmail.com>2020-02-12 18:52:23 +0100
committer5eraph <bcervenka@protonmail.com>2020-03-02 20:17:27 +0100
commit5eb4fc45dc87717fc9c2e26afb602119006d5dd4 (patch)
tree25a8e89ede65d0e3de0b6f3915235732e06747b0
parent296faab4cfd1955bc37fff885985a5b2c0a1fc40 (diff)
downloadslirp-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.c7
-rw-r--r--src/libslirp.h4
-rw-r--r--src/misc.c20
-rw-r--r--src/misc.h2
-rw-r--r--src/slirp.c7
-rw-r--r--src/slirp.h3
-rw-r--r--src/tcp_subr.c10
-rw-r--r--src/udp.c6
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,
diff --git a/src/misc.c b/src/misc.c
index ddbe43d..e6bc0a2 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -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
diff --git a/src/misc.h b/src/misc.h
index 841b0a7..81b370c 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -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;
diff --git a/src/udp.c b/src/udp.c
index 35218a9..6bde20f 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -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);
}