aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--arp.c2
-rw-r--r--conf.c184
-rw-r--r--dhcp.c22
-rw-r--r--dhcpv6.c18
-rw-r--r--ndp.c16
-rw-r--r--passt.c2
-rw-r--r--passt.h68
-rw-r--r--pasta.c10
-rw-r--r--tap.c22
-rw-r--r--tcp.c34
-rw-r--r--udp.c62
-rw-r--r--util.c4
12 files changed, 232 insertions, 212 deletions
diff --git a/arp.c b/arp.c
index e8f21b5..0ad97af 100644
--- a/arp.c
+++ b/arp.c
@@ -66,7 +66,7 @@ int arp(const struct ctx *c, const struct pool *p)
return 1;
/* Don't resolve our own address, either. */
- if (!memcmp(am->tip, &c->addr4, sizeof(am->tip)))
+ if (!memcmp(am->tip, &c->ip4.addr, sizeof(am->tip)))
return 1;
ah->ar_op = htons(ARPOP_REPLY);
diff --git a/conf.c b/conf.c
index 735b722..83b2fe5 100644
--- a/conf.c
+++ b/conf.c
@@ -404,9 +404,9 @@ overlap:
static void get_dns(struct ctx *c)
{
int dns4_set, dns6_set, dnss_set, dns_set, fd;
- struct in6_addr *dns6 = &c->dns6[0];
+ struct in6_addr *dns6 = &c->ip6.dns[0];
struct fqdn *s = c->dns_search;
- uint32_t *dns4 = &c->dns4[0];
+ uint32_t *dns4 = &c->ip4.dns[0];
struct lineread resolvconf;
int line_len;
char *line, *p, *end;
@@ -434,7 +434,7 @@ static void get_dns(struct ctx *c)
*end = 0;
if (!dns4_set &&
- dns4 - &c->dns4[0] < ARRAY_SIZE(c->dns4) - 1 &&
+ dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) - 1 &&
inet_pton(AF_INET, p + 1, dns4)) {
/* We can only access local addresses via the gw redirect */
if (ntohl(*dns4) >> IN_CLASSA_NSHIFT == IN_LOOPBACKNET) {
@@ -442,14 +442,14 @@ static void get_dns(struct ctx *c)
*dns4 = 0;
continue;
}
- *dns4 = c->gw4;
+ *dns4 = c->ip4.gw;
}
dns4++;
*dns4 = 0;
}
if (!dns6_set &&
- dns6 - &c->dns6[0] < ARRAY_SIZE(c->dns6) - 1 &&
+ dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) - 1 &&
inet_pton(AF_INET6, p + 1, dns6)) {
/* We can only access local addresses via the gw redirect */
if (IN6_IS_ADDR_LOOPBACK(dns6)) {
@@ -457,7 +457,7 @@ static void get_dns(struct ctx *c)
memset(dns6, 0, sizeof(*dns6));
continue;
}
- memcpy(dns6, &c->gw6, sizeof(*dns6));
+ memcpy(dns6, &c->ip6.gw, sizeof(*dns6));
}
dns6++;
memset(dns6, 0, sizeof(*dns6));
@@ -485,7 +485,7 @@ static void get_dns(struct ctx *c)
close(fd);
out:
- if (!dns_set && dns4 == c->dns4 && dns6 == c->dns6)
+ if (!dns_set && dns4 == c->ip4.dns && dns6 == c->ip6.dns)
warn("Couldn't get any nameserver address");
}
@@ -612,12 +612,14 @@ static int conf_ns_opt(struct ctx *c,
/**
* conf_ip4() - Verify or detect IPv4 support, get relevant addresses
- * @c: Execution context
* @ifi: Host interface to attempt (0 to determine one)
+ * @ip4: IPv4 context (will be written)
+ * @mac: MAC address to use (written if unset)
*
* Return: Interface index for IPv4, or 0 on failure.
*/
-static unsigned int conf_ip4(struct ctx *c, unsigned int ifi)
+static unsigned int conf_ip4(unsigned int ifi,
+ struct ip4_ctx *ip4, unsigned char *mac)
{
if (!ifi)
ifi = nl_get_ext_if(AF_INET);
@@ -627,33 +629,33 @@ static unsigned int conf_ip4(struct ctx *c, unsigned int ifi)
return 0;
}
- if (!c->gw4)
- nl_route(0, ifi, AF_INET, &c->gw4);
+ if (!ip4->gw)
+ nl_route(0, ifi, AF_INET, &ip4->gw);
- if (!c->addr4) {
+ if (!ip4->addr) {
int mask_len = 0;
- nl_addr(0, ifi, AF_INET, &c->addr4, &mask_len, NULL);
- c->mask4 = htonl(0xffffffff << (32 - mask_len));
+ nl_addr(0, ifi, AF_INET, &ip4->addr, &mask_len, NULL);
+ ip4->mask = htonl(0xffffffff << (32 - mask_len));
}
- if (!c->mask4) {
- if (IN_CLASSA(ntohl(c->addr4)))
- c->mask4 = htonl(IN_CLASSA_NET);
- else if (IN_CLASSB(ntohl(c->addr4)))
- c->mask4 = htonl(IN_CLASSB_NET);
- else if (IN_CLASSC(ntohl(c->addr4)))
- c->mask4 = htonl(IN_CLASSC_NET);
+ if (!ip4->mask) {
+ if (IN_CLASSA(ntohl(ip4->addr)))
+ ip4->mask = htonl(IN_CLASSA_NET);
+ else if (IN_CLASSB(ntohl(ip4->addr)))
+ ip4->mask = htonl(IN_CLASSB_NET);
+ else if (IN_CLASSC(ntohl(ip4->addr)))
+ ip4->mask = htonl(IN_CLASSC_NET);
else
- c->mask4 = 0xffffffff;
+ ip4->mask = 0xffffffff;
}
- memcpy(&c->addr4_seen, &c->addr4, sizeof(c->addr4_seen));
+ memcpy(&ip4->addr_seen, &ip4->addr, sizeof(ip4->addr_seen));
- if (MAC_IS_ZERO(c->mac))
- nl_link(0, ifi, c->mac, 0, 0);
+ if (MAC_IS_ZERO(mac))
+ nl_link(0, ifi, mac, 0, 0);
- if (!c->gw4 || !c->addr4 || MAC_IS_ZERO(c->mac))
+ if (!ip4->gw || !ip4->addr || MAC_IS_ZERO(mac))
return 0;
return ifi;
@@ -661,12 +663,14 @@ static unsigned int conf_ip4(struct ctx *c, unsigned int ifi)
/**
* conf_ip6() - Verify or detect IPv6 support, get relevant addresses
- * @c: Execution context
* @ifi: Host interface to attempt (0 to determine one)
+ * @ip6: IPv6 context (will be written)
+ * @mac: MAC address to use (written if unset)
*
* Return: Interface index for IPv6, or 0 on failure.
*/
-static unsigned int conf_ip6(struct ctx *c, unsigned int ifi)
+static unsigned int conf_ip6(unsigned int ifi,
+ struct ip6_ctx *ip6, unsigned char *mac)
{
int prefix_len = 0;
@@ -678,23 +682,23 @@ static unsigned int conf_ip6(struct ctx *c, unsigned int ifi)
return 0;
}
- if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6))
- nl_route(0, ifi, AF_INET6, &c->gw6);
+ if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw))
+ nl_route(0, ifi, AF_INET6, &ip6->gw);
nl_addr(0, ifi, AF_INET6,
- IN6_IS_ADDR_UNSPECIFIED(&c->addr6) ? &c->addr6 : NULL,
- &prefix_len, &c->addr6_ll);
+ IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL,
+ &prefix_len, &ip6->addr_ll);
- memcpy(&c->addr6_seen, &c->addr6, sizeof(c->addr6));
- memcpy(&c->addr6_ll_seen, &c->addr6_ll, sizeof(c->addr6_ll));
+ memcpy(&ip6->addr_seen, &ip6->addr, sizeof(ip6->addr));
+ memcpy(&ip6->addr_ll_seen, &ip6->addr_ll, sizeof(ip6->addr_ll));
- if (MAC_IS_ZERO(c->mac))
- nl_link(0, ifi, c->mac, 0, 0);
+ if (MAC_IS_ZERO(mac))
+ nl_link(0, ifi, mac, 0, 0);
- if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6) ||
- IN6_IS_ADDR_UNSPECIFIED(&c->addr6) ||
- IN6_IS_ADDR_UNSPECIFIED(&c->addr6_ll) ||
- MAC_IS_ZERO(c->mac))
+ if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw) ||
+ IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ||
+ IN6_IS_ADDR_UNSPECIFIED(&ip6->addr_ll) ||
+ MAC_IS_ZERO(mac))
return 0;
return ifi;
@@ -899,17 +903,17 @@ static void conf_print(const struct ctx *c)
if (!c->no_dhcp) {
info("DHCP:");
info(" assign: %s",
- inet_ntop(AF_INET, &c->addr4, buf4, sizeof(buf4)));
+ inet_ntop(AF_INET, &c->ip4.addr, buf4, sizeof(buf4)));
info(" mask: %s",
- inet_ntop(AF_INET, &c->mask4, buf4, sizeof(buf4)));
+ inet_ntop(AF_INET, &c->ip4.mask, buf4, sizeof(buf4)));
info(" router: %s",
- inet_ntop(AF_INET, &c->gw4, buf4, sizeof(buf4)));
+ inet_ntop(AF_INET, &c->ip4.gw, buf4, sizeof(buf4)));
}
- for (i = 0; c->dns4[i]; i++) {
+ for (i = 0; c->ip4.dns[i]; i++) {
if (!i)
info("DNS:");
- inet_ntop(AF_INET, &c->dns4[i], buf4, sizeof(buf4));
+ inet_ntop(AF_INET, &c->ip4.dns[i], buf4, sizeof(buf4));
info(" %s", buf4);
}
@@ -933,17 +937,17 @@ static void conf_print(const struct ctx *c)
goto dns6;
info(" assign: %s",
- inet_ntop(AF_INET6, &c->addr6, buf6, sizeof(buf6)));
+ inet_ntop(AF_INET6, &c->ip6.addr, buf6, sizeof(buf6)));
info(" router: %s",
- inet_ntop(AF_INET6, &c->gw6, buf6, sizeof(buf6)));
+ inet_ntop(AF_INET6, &c->ip6.gw, buf6, sizeof(buf6)));
info(" our link-local: %s",
- inet_ntop(AF_INET6, &c->addr6_ll, buf6, sizeof(buf6)));
+ inet_ntop(AF_INET6, &c->ip6.addr_ll, buf6, sizeof(buf6)));
dns6:
- for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) {
+ for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[i]); i++) {
if (!i)
info("DNS:");
- inet_ntop(AF_INET6, &c->dns6[i], buf6, sizeof(buf6));
+ inet_ntop(AF_INET6, &c->ip6.dns[i], buf6, sizeof(buf6));
info(" %s", buf6);
}
@@ -1065,10 +1069,10 @@ void conf(struct ctx *c, int argc, char **argv)
enum conf_port_type tcp_tap = 0, tcp_init = 0;
enum conf_port_type udp_tap = 0, udp_init = 0;
bool v4_only = false, v6_only = false;
+ struct in6_addr *dns6 = c->ip6.dns;
struct fqdn *dnss = c->dns_search;
- struct in6_addr *dns6 = c->dns6;
+ uint32_t *dns4 = c->ip4.dns;
int name, ret, mask, b, i;
- uint32_t *dns4 = c->dns4;
unsigned int ifi = 0;
if (c->mode == MODE_PASTA)
@@ -1167,17 +1171,17 @@ void conf(struct ctx *c, int argc, char **argv)
c->no_dhcp_dns_search = 1;
break;
case 9:
- if (IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) &&
- inet_pton(AF_INET6, optarg, &c->dns6_fwd) &&
- !IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) &&
- !IN6_IS_ADDR_LOOPBACK(&c->dns6_fwd))
+ if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) &&
+ inet_pton(AF_INET6, optarg, &c->ip6.dns_fwd) &&
+ !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) &&
+ !IN6_IS_ADDR_LOOPBACK(&c->ip6.dns_fwd))
break;
- if (c->dns4_fwd == INADDR_ANY &&
- inet_pton(AF_INET, optarg, &c->dns4_fwd) &&
- c->dns4_fwd != INADDR_ANY &&
- c->dns4_fwd != INADDR_BROADCAST &&
- c->dns4_fwd != INADDR_LOOPBACK)
+ if (c->ip4.dns_fwd == INADDR_ANY &&
+ inet_pton(AF_INET, optarg, &c->ip4.dns_fwd) &&
+ c->ip4.dns_fwd != INADDR_ANY &&
+ c->ip4.dns_fwd != INADDR_BROADCAST &&
+ c->ip4.dns_fwd != INADDR_LOOPBACK)
break;
err("Invalid DNS forwarding address: %s", optarg);
@@ -1334,34 +1338,34 @@ void conf(struct ctx *c, int argc, char **argv)
}
break;
case 'a':
- if (IN6_IS_ADDR_UNSPECIFIED(&c->addr6) &&
- inet_pton(AF_INET6, optarg, &c->addr6) &&
- !IN6_IS_ADDR_UNSPECIFIED(&c->addr6) &&
- !IN6_IS_ADDR_LOOPBACK(&c->addr6) &&
- !IN6_IS_ADDR_V4MAPPED(&c->addr6) &&
- !IN6_IS_ADDR_V4COMPAT(&c->addr6) &&
- !IN6_IS_ADDR_MULTICAST(&c->addr6))
+ if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr) &&
+ inet_pton(AF_INET6, optarg, &c->ip6.addr) &&
+ !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr) &&
+ !IN6_IS_ADDR_LOOPBACK(&c->ip6.addr) &&
+ !IN6_IS_ADDR_V4MAPPED(&c->ip6.addr) &&
+ !IN6_IS_ADDR_V4COMPAT(&c->ip6.addr) &&
+ !IN6_IS_ADDR_MULTICAST(&c->ip6.addr))
break;
- if (c->addr4 == INADDR_ANY &&
- inet_pton(AF_INET, optarg, &c->addr4) &&
- c->addr4 != INADDR_ANY &&
- c->addr4 != INADDR_BROADCAST &&
- c->addr4 != INADDR_LOOPBACK &&
- !IN_MULTICAST(c->addr4))
+ if (c->ip4.addr == INADDR_ANY &&
+ inet_pton(AF_INET, optarg, &c->ip4.addr) &&
+ c->ip4.addr != INADDR_ANY &&
+ c->ip4.addr != INADDR_BROADCAST &&
+ c->ip4.addr != INADDR_LOOPBACK &&
+ !IN_MULTICAST(c->ip4.addr))
break;
err("Invalid address: %s", optarg);
usage(argv[0]);
break;
case 'n':
- if (inet_pton(AF_INET, optarg, &c->mask4))
+ if (inet_pton(AF_INET, optarg, &c->ip4.mask))
break;
errno = 0;
mask = strtol(optarg, NULL, 0);
if (mask > 0 && mask <= 32 && !errno) {
- c->mask4 = htonl(0xffffffff << (32 - mask));
+ c->ip4.mask = htonl(0xffffffff << (32 - mask));
break;
}
@@ -1380,17 +1384,17 @@ void conf(struct ctx *c, int argc, char **argv)
}
break;
case 'g':
- if (IN6_IS_ADDR_UNSPECIFIED(&c->gw6) &&
- inet_pton(AF_INET6, optarg, &c->gw6) &&
- !IN6_IS_ADDR_UNSPECIFIED(&c->gw6) &&
- !IN6_IS_ADDR_LOOPBACK(&c->gw6))
+ if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.gw) &&
+ inet_pton(AF_INET6, optarg, &c->ip6.gw) &&
+ !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.gw) &&
+ !IN6_IS_ADDR_LOOPBACK(&c->ip6.gw))
break;
- if (c->gw4 == INADDR_ANY &&
- inet_pton(AF_INET, optarg, &c->gw4) &&
- c->gw4 != INADDR_ANY &&
- c->gw4 != INADDR_BROADCAST &&
- c->gw4 != INADDR_LOOPBACK)
+ if (c->ip4.gw == INADDR_ANY &&
+ inet_pton(AF_INET, optarg, &c->ip4.gw) &&
+ c->ip4.gw != INADDR_ANY &&
+ c->ip4.gw != INADDR_BROADCAST &&
+ c->ip4.gw != INADDR_LOOPBACK)
break;
err("Invalid gateway address: %s", optarg);
@@ -1410,7 +1414,7 @@ void conf(struct ctx *c, int argc, char **argv)
break;
case 'D':
if (c->no_dns ||
- (!optarg && (dns4 - c->dns4 || dns6 - c->dns6))) {
+ (!optarg && (dns4 - c->ip4.dns || dns6 - c->ip6.dns))) {
err("Empty and non-empty DNS options given");
usage(argv[0]);
}
@@ -1420,13 +1424,13 @@ void conf(struct ctx *c, int argc, char **argv)
break;
}
- if (dns4 - &c->dns4[0] < ARRAY_SIZE(c->dns4) &&
+ if (dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) &&
inet_pton(AF_INET, optarg, dns4)) {
dns4++;
break;
}
- if (dns6 - &c->dns6[0] < ARRAY_SIZE(c->dns6) &&
+ if (dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) &&
inet_pton(AF_INET6, optarg, dns6)) {
dns6++;
break;
@@ -1511,9 +1515,9 @@ void conf(struct ctx *c, int argc, char **argv)
usage(argv[0]);
}
if (!v6_only)
- c->ifi4 = conf_ip4(c, ifi);
+ c->ifi4 = conf_ip4(ifi, &c->ip4, c->mac);
if (!v4_only)
- c->ifi6 = conf_ip6(c, ifi);
+ c->ifi6 = conf_ip6(ifi, &c->ip6, c->mac);
if (!c->ifi4 && !c->ifi6) {
err("External interface not usable");
exit(EXIT_FAILURE);
diff --git a/dhcp.c b/dhcp.c
index 32dee56..7ad1319 100644
--- a/dhcp.c
+++ b/dhcp.c
@@ -332,20 +332,20 @@ int dhcp(const struct ctx *c, const struct pool *p)
m->chaddr[0], m->chaddr[1], m->chaddr[2],
m->chaddr[3], m->chaddr[4], m->chaddr[5]);
- m->yiaddr = c->addr4;
- memcpy(opts[1].s, &c->mask4, sizeof(c->mask4));
- memcpy(opts[3].s, &c->gw4, sizeof(c->gw4));
- memcpy(opts[54].s, &c->gw4, sizeof(c->gw4));
+ m->yiaddr = c->ip4.addr;
+ memcpy(opts[1].s, &c->ip4.mask, sizeof(c->ip4.mask));
+ memcpy(opts[3].s, &c->ip4.gw, sizeof(c->ip4.gw));
+ memcpy(opts[54].s, &c->ip4.gw, sizeof(c->ip4.gw));
/* If the gateway is not on the assigned subnet, send an option 121
* (Classless Static Routing) adding a dummy route to it.
*/
- if ((c->addr4 & c->mask4) != (c->gw4 & c->mask4)) {
+ if ((c->ip4.addr & c->ip4.mask) != (c->ip4.gw & c->ip4.mask)) {
/* a.b.c.d/32:0.0.0.0, 0:a.b.c.d */
opts[121].slen = 14;
opts[121].s[0] = 32;
- memcpy(opts[121].s + 1, &c->gw4, sizeof(c->gw4));
- memcpy(opts[121].s + 10, &c->gw4, sizeof(c->gw4));
+ memcpy(opts[121].s + 1, &c->ip4.gw, sizeof(c->ip4.gw));
+ memcpy(opts[121].s + 10, &c->ip4.gw, sizeof(c->ip4.gw));
}
if (c->mtu != -1) {
@@ -354,8 +354,8 @@ int dhcp(const struct ctx *c, const struct pool *p)
opts[26].s[1] = c->mtu % 256;
}
- for (i = 0, opts[6].slen = 0; !c->no_dhcp_dns && c->dns4[i]; i++) {
- ((uint32_t *)opts[6].s)[i] = c->dns4[i];
+ for (i = 0, opts[6].slen = 0; !c->no_dhcp_dns && c->ip4.dns[i]; i++) {
+ ((uint32_t *)opts[6].s)[i] = c->ip4.dns[i];
opts[6].slen += sizeof(uint32_t);
}
@@ -368,8 +368,8 @@ int dhcp(const struct ctx *c, const struct pool *p)
uh->dest = htons(68);
iph->tot_len = htons(len += sizeof(*iph));
- iph->daddr = c->addr4;
- iph->saddr = c->gw4;
+ iph->daddr = c->ip4.addr;
+ iph->saddr = c->ip4.gw;
iph->check = 0;
iph->check = csum_unaligned(iph, (intptr_t)(iph->ihl * 4), 0);
diff --git a/dhcpv6.c b/dhcpv6.c
index 4124a3e..fbae88d 100644
--- a/dhcpv6.c
+++ b/dhcpv6.c
@@ -390,7 +390,7 @@ static size_t dhcpv6_dns_fill(const struct ctx *c, char *buf, int offset)
if (c->no_dhcp_dns)
goto search;
- for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) {
+ for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[i]); i++) {
if (!i) {
srv = (struct opt_dns_servers *)(buf + offset);
offset += sizeof(struct opt_hdr);
@@ -398,7 +398,7 @@ static size_t dhcpv6_dns_fill(const struct ctx *c, char *buf, int offset)
srv->hdr.l = 0;
}
- memcpy(&srv->addr[i], &c->dns6[i], sizeof(srv->addr[i]));
+ memcpy(&srv->addr[i], &c->ip6.dns[i], sizeof(srv->addr[i]));
srv->hdr.l += sizeof(srv->addr[i]);
offset += sizeof(srv->addr[i]);
}
@@ -473,12 +473,12 @@ int dhcpv6(struct ctx *c, const struct pool *p,
if (mlen + sizeof(*uh) != ntohs(uh->len) || mlen < sizeof(*mh))
return -1;
- c->addr6_ll_seen = *saddr;
+ c->ip6.addr_ll_seen = *saddr;
- if (IN6_IS_ADDR_LINKLOCAL(&c->gw6))
- src = &c->gw6;
+ if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw))
+ src = &c->ip6.gw;
else
- src = &c->addr6_ll;
+ src = &c->ip6.addr_ll;
mh = packet_get(p, 0, sizeof(*uh), sizeof(*mh), NULL);
if (!mh)
@@ -508,7 +508,7 @@ int dhcpv6(struct ctx *c, const struct pool *p,
if (mh->type == TYPE_CONFIRM && server_id)
return -1;
- if ((bad_ia = dhcpv6_ia_notonlink(p, &c->addr6))) {
+ if ((bad_ia = dhcpv6_ia_notonlink(p, &c->ip6.addr))) {
info("DHCPv6: received CONFIRM with inappropriate IA,"
" sending NotOnLink status in REPLY");
@@ -580,7 +580,7 @@ int dhcpv6(struct ctx *c, const struct pool *p,
resp.hdr.xid = mh->xid;
tap_ip_send(c, src, IPPROTO_UDP, (char *)&resp, n, mh->xid);
- c->addr6_seen = c->addr6;
+ c->ip6.addr_seen = c->ip6.addr;
return 1;
}
@@ -602,5 +602,5 @@ void dhcpv6_init(const struct ctx *c)
memcpy(resp.server_id.duid_lladdr, c->mac, sizeof(c->mac));
memcpy(resp_not_on_link.server_id.duid_lladdr, c->mac, sizeof(c->mac));
- resp.ia_addr.addr = c->addr6;
+ resp.ia_addr.addr = c->ip6.addr;
}
diff --git a/ndp.c b/ndp.c
index 4d13be3..29c4b14 100644
--- a/ndp.c
+++ b/ndp.c
@@ -107,7 +107,7 @@ int ndp(struct ctx *c, const struct icmp6hdr *ih,
p += 4;
*(uint32_t *)p = htonl(3600); /* preferred lifetime */
p += 8;
- memcpy(p, &c->addr6, 8); /* prefix */
+ memcpy(p, &c->ip6.addr, 8); /* prefix */
p += 16;
if (c->mtu != -1) {
@@ -121,7 +121,7 @@ int ndp(struct ctx *c, const struct icmp6hdr *ih,
if (c->no_dhcp_dns)
goto dns_done;
- for (n = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[n]); n++);
+ for (n = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[n]); n++);
if (n) {
*p++ = 25; /* RDNSS */
*p++ = 1 + 2 * n; /* length */
@@ -130,7 +130,7 @@ int ndp(struct ctx *c, const struct icmp6hdr *ih,
p += 4;
for (i = 0; i < n; i++) {
- memcpy(p, &c->dns6[i], 16); /* address */
+ memcpy(p, &c->ip6.dns[i], 16); /* address */
p += 16;
}
@@ -177,15 +177,15 @@ dns_done:
len = (uintptr_t)p - (uintptr_t)ihr - sizeof(*ihr);
if (IN6_IS_ADDR_LINKLOCAL(saddr))
- c->addr6_ll_seen = *saddr;
+ c->ip6.addr_ll_seen = *saddr;
else
- c->addr6_seen = *saddr;
+ c->ip6.addr_seen = *saddr;
ip6hr->daddr = *saddr;
- if (IN6_IS_ADDR_LINKLOCAL(&c->gw6))
- ip6hr->saddr = c->gw6;
+ if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw))
+ ip6hr->saddr = c->ip6.gw;
else
- ip6hr->saddr = c->addr6_ll;
+ ip6hr->saddr = c->ip6.addr_ll;
ip6hr->payload_len = htons(sizeof(*ihr) + len);
ip6hr->hop_limit = IPPROTO_ICMPV6;
diff --git a/passt.c b/passt.c
index 5d0b3cd..0113002 100644
--- a/passt.c
+++ b/passt.c
@@ -363,7 +363,7 @@ int main(int argc, char **argv)
if ((!c.no_udp && udp_init(&c)) || (!c.no_tcp && tcp_init(&c)))
exit(EXIT_FAILURE);
- proto_update_l2_buf(c.mac_guest, c.mac, &c.addr4);
+ proto_update_l2_buf(c.mac_guest, c.mac, &c.ip4.addr);
if (c.ifi4 && !c.no_dhcp)
dhcp_init();
diff --git a/passt.h b/passt.h
index a8d5992..347e7c1 100644
--- a/passt.h
+++ b/passt.h
@@ -95,6 +95,44 @@ enum passt_modes {
};
/**
+ * struct ip4_ctx - IPv4 execution context
+ * @addr: IPv4 address for external, routable interface
+ * @addr_seen: Latest IPv4 address seen as source from tap
+ * @mask: IPv4 netmask, network order
+ * @gw: Default IPv4 gateway, network order
+ * @dns: IPv4 DNS addresses, zero-terminated, network order
+ * @dns_fwd: Address forwarded (UDP) to first IPv4 DNS, network order
+ */
+struct ip4_ctx {
+ uint32_t addr;
+ uint32_t addr_seen;
+ uint32_t mask;
+ uint32_t gw;
+ uint32_t dns[MAXNS + 1];
+ uint32_t dns_fwd;
+};
+
+/**
+ * struct ip6_ctx - IPv6 execution context
+ * @addr: IPv6 address for external, routable interface
+ * @addr_ll: Link-local IPv6 address on external, routable interface
+ * @addr_seen: Latest IPv6 global/site address seen as source from tap
+ * @addr_ll_seen: Latest IPv6 link-local address seen as source from tap
+ * @gw: Default IPv6 gateway
+ * @dns: IPv6 DNS addresses, zero-terminated
+ * @dns_fwd: Address forwarded (UDP) to first IPv6 DNS, network order
+ */
+struct ip6_ctx {
+ struct in6_addr addr;
+ struct in6_addr addr_ll;
+ struct in6_addr addr_seen;
+ struct in6_addr addr_ll_seen;
+ struct in6_addr gw;
+ struct in6_addr dns[MAXNS + 1];
+ struct in6_addr dns_fwd;
+};
+
+/**
* struct ctx - Execution context
* @mode: Operation mode, qemu/UNIX domain socket or namespace/tap
* @debug: Enable debug mode
@@ -122,21 +160,10 @@ enum passt_modes {
* @mac: Host MAC address
* @mac_guest: MAC address of guest or namespace, seen or configured
* @ifi4: Index of routable interface for IPv4, 0 if IPv4 disabled
- * @addr4: IPv4 address for external, routable interface
- * @addr4_seen: Latest IPv4 address seen as source from tap
- * @mask4: IPv4 netmask, network order
- * @gw4: Default IPv4 gateway, network order
- * @dns4: IPv4 DNS addresses, zero-terminated, network order
- * @dns4_fwd: Address forwarded (UDP) to first IPv4 DNS, network order
+ * @ip: IPv4 configuration
* @dns_search: DNS search list
* @ifi6: Index of routable interface for IPv6, 0 if IPv6 disabled
- * @addr6: IPv6 address for external, routable interface
- * @addr6_ll: Link-local IPv6 address on external, routable interface
- * @addr6_seen: Latest IPv6 global/site address seen as source from tap
- * @addr6_ll_seen: Latest IPv6 link-local address seen as source from tap
- * @gw6: Default IPv6 gateway
- * @dns6: IPv6 DNS addresses, zero-terminated
- * @dns6_fwd: Address forwarded (UDP) to first IPv6 DNS, network order
+ * @ip6: IPv6 configuration
* @pasta_ifn: Name of namespace interface for pasta
* @pasta_ifn: Index of namespace interface for pasta
* @pasta_conf_ns: Configure namespace interface after creating it
@@ -192,23 +219,12 @@ struct ctx {
unsigned char mac_guest[ETH_ALEN];
unsigned int ifi4;
- uint32_t addr4;
- uint32_t addr4_seen;
- uint32_t mask4;
- uint32_t gw4;
- uint32_t dns4[MAXNS + 1];
- uint32_t dns4_fwd;
+ struct ip4_ctx ip4;
struct fqdn dns_search[MAXDNSRCH];
unsigned int ifi6;
- struct in6_addr addr6;
- struct in6_addr addr6_ll;
- struct in6_addr addr6_seen;
- struct in6_addr addr6_ll_seen;
- struct in6_addr gw6;
- struct in6_addr dns6[MAXNS + 1];
- struct in6_addr dns6_fwd;
+ struct ip6_ctx ip6;
char pasta_ifn[IF_NAMESIZE];
unsigned int pasta_ifi;
diff --git a/pasta.c b/pasta.c
index 2d7b5a1..5a78065 100644
--- a/pasta.c
+++ b/pasta.c
@@ -196,17 +196,17 @@ void pasta_ns_conf(struct ctx *c)
nl_link(1, c->pasta_ifi, c->mac_guest, 1, c->mtu);
if (c->ifi4) {
- prefix_len = __builtin_popcount(c->mask4);
- nl_addr(1, c->pasta_ifi, AF_INET, &c->addr4,
+ prefix_len = __builtin_popcount(c->ip4.mask);
+ nl_addr(1, c->pasta_ifi, AF_INET, &c->ip4.addr,
&prefix_len, NULL);
- nl_route(1, c->pasta_ifi, AF_INET, &c->gw4);
+ nl_route(1, c->pasta_ifi, AF_INET, &c->ip4.gw);
}
if (c->ifi6) {
prefix_len = 64;
- nl_addr(1, c->pasta_ifi, AF_INET6, &c->addr6,
+ nl_addr(1, c->pasta_ifi, AF_INET6, &c->ip6.addr,
&prefix_len, NULL);
- nl_route(1, c->pasta_ifi, AF_INET6, &c->gw6);
+ nl_route(1, c->pasta_ifi, AF_INET6, &c->ip6.gw);
}
} else {
nl_link(1, c->pasta_ifi, c->mac_guest, 0, 0);
diff --git a/tap.c b/tap.c
index 8d552e9..3231da7 100644
--- a/tap.c
+++ b/tap.c
@@ -130,7 +130,7 @@ void tap_ip_send(const struct ctx *c, const struct in6_addr *src, uint8_t proto,
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = proto;
- iph->daddr = c->addr4_seen;
+ iph->daddr = c->ip4.addr_seen;
memcpy(&iph->saddr, &src->s6_addr[12], 4);
iph->check = 0;
@@ -165,9 +165,9 @@ void tap_ip_send(const struct ctx *c, const struct in6_addr *src, uint8_t proto,
ip6h->saddr = *src;
if (IN6_IS_ADDR_LINKLOCAL(src))
- ip6h->daddr = c->addr6_ll_seen;
+ ip6h->daddr = c->ip6.addr_ll_seen;
else
- ip6h->daddr = c->addr6_seen;
+ ip6h->daddr = c->ip6.addr_seen;
memcpy(data, in, len);
@@ -354,9 +354,9 @@ resume:
l4_len = l3_len - hlen;
- if (iph->saddr && c->addr4_seen != iph->saddr) {
- c->addr4_seen = iph->saddr;
- proto_update_l2_buf(NULL, NULL, &c->addr4_seen);
+ if (iph->saddr && c->ip4.addr_seen != iph->saddr) {
+ c->ip4.addr_seen = iph->saddr;
+ proto_update_l2_buf(NULL, NULL, &c->ip4.addr_seen);
}
l4h = packet_get(in, i, sizeof(*eh) + hlen, l4_len, NULL);
@@ -504,13 +504,13 @@ resume:
continue;
if (IN6_IS_ADDR_LINKLOCAL(saddr)) {
- c->addr6_ll_seen = *saddr;
+ c->ip6.addr_ll_seen = *saddr;
- if (IN6_IS_ADDR_UNSPECIFIED(&c->addr6_seen)) {
- c->addr6_seen = *saddr;
+ if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.addr_seen)) {
+ c->ip6.addr_seen = *saddr;
}
} else {
- c->addr6_seen = *saddr;
+ c->ip6.addr_seen = *saddr;
}
if (proto == IPPROTO_ICMPV6) {
@@ -545,7 +545,7 @@ resume:
continue;
}
- *saddr = c->addr6;
+ *saddr = c->ip6.addr;
if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
tap_packet_debug(NULL, ip6h, NULL, proto, NULL, 1);
diff --git a/tcp.c b/tcp.c
index 3382dfd..ec8c32e 100644
--- a/tcp.c
+++ b/tcp.c
@@ -1700,9 +1700,9 @@ do { \
b->ip6h.payload_len = htons(plen + sizeof(struct tcphdr));
b->ip6h.saddr = conn->a.a6;
if (IN6_IS_ADDR_LINKLOCAL(&b->ip6h.saddr))
- b->ip6h.daddr = c->addr6_ll_seen;
+ b->ip6h.daddr = c->ip6.addr_ll_seen;
else
- b->ip6h.daddr = c->addr6_seen;
+ b->ip6h.daddr = c->ip6.addr_seen;
memset(b->ip6h.flow_lbl, 0, 3);
@@ -1723,7 +1723,7 @@ do { \
ip_len = plen + sizeof(struct iphdr) + sizeof(struct tcphdr);
b->iph.tot_len = htons(ip_len);
b->iph.saddr = conn->a.a4.a.s_addr;
- b->iph.daddr = c->addr4_seen;
+ b->iph.daddr = c->ip4.addr_seen;
if (check)
b->iph.check = *check;
@@ -2069,7 +2069,7 @@ static uint32_t tcp_seq_init(const struct ctx *c, int af, const void *addr,
} __attribute__((__packed__)) in = {
.src = *(struct in_addr *)addr,
.srcport = srcport,
- .dst = { c->addr4 },
+ .dst = { c->ip4.addr },
.dstport = dstport,
};
@@ -2083,7 +2083,7 @@ static uint32_t tcp_seq_init(const struct ctx *c, int af, const void *addr,
} __attribute__((__packed__)) in = {
.src = *(struct in6_addr *)addr,
.srcport = srcport,
- .dst = c->addr6,
+ .dst = c->ip6.addr,
.dstport = dstport,
};
@@ -2197,16 +2197,16 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr,
return;
if (!c->no_map_gw) {
- if (af == AF_INET && addr4.sin_addr.s_addr == c->gw4)
+ if (af == AF_INET && addr4.sin_addr.s_addr == c->ip4.gw)
addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- if (af == AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->gw6))
+ if (af == AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->ip6.gw))
addr6.sin6_addr = in6addr_loopback;
}
if (af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr)) {
struct sockaddr_in6 addr6_ll = {
.sin6_family = AF_INET6,
- .sin6_addr = c->addr6_ll,
+ .sin6_addr = c->ip6.addr_ll,
.sin6_scope_id = c->ifi6,
};
if (bind(s, (struct sockaddr *)&addr6_ll, sizeof(addr6_ll))) {
@@ -2894,14 +2894,14 @@ static void tcp_conn_from_sock(struct ctx *c, union epoll_ref ref,
memcpy(&sa6, &sa, sizeof(sa6));
if (IN6_IS_ADDR_LOOPBACK(&sa6.sin6_addr) ||
- IN6_ARE_ADDR_EQUAL(&sa6.sin6_addr, &c->addr6_seen) ||
- IN6_ARE_ADDR_EQUAL(&sa6.sin6_addr, &c->addr6)) {
+ IN6_ARE_ADDR_EQUAL(&sa6.sin6_addr, &c->ip6.addr_seen) ||
+ IN6_ARE_ADDR_EQUAL(&sa6.sin6_addr, &c->ip6.addr)) {
struct in6_addr *src;
- if (IN6_IS_ADDR_LINKLOCAL(&c->gw6))
- src = &c->gw6;
+ if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw))
+ src = &c->ip6.gw;
else
- src = &c->addr6_ll;
+ src = &c->ip6.addr_ll;
memcpy(&sa6.sin6_addr, src, sizeof(*src));
}
@@ -2928,8 +2928,8 @@ static void tcp_conn_from_sock(struct ctx *c, union epoll_ref ref,
memset(&conn->a.a4.one, 0xff, sizeof(conn->a.a4.one));
if (s_addr >> IN_CLASSA_NSHIFT == IN_LOOPBACKNET ||
- s_addr == INADDR_ANY || htonl(s_addr) == c->addr4_seen)
- s_addr = ntohl(c->gw4);
+ s_addr == INADDR_ANY || htonl(s_addr) == c->ip4.addr_seen)
+ s_addr = ntohl(c->ip4.gw);
s_addr = htonl(s_addr);
memcpy(&conn->a.a4.a, &s_addr, sizeof(conn->a.a4.a));
@@ -3118,7 +3118,7 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_family_t af,
if (af == AF_INET || af == AF_UNSPEC) {
if (!addr && c->mode == MODE_PASTA)
- bind_addr = &c->addr4;
+ bind_addr = &c->ip4.addr;
else
bind_addr = addr;
@@ -3159,7 +3159,7 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_family_t af,
if (af == AF_INET6 || af == AF_UNSPEC) {
if (!addr && c->mode == MODE_PASTA)
- bind_addr = &c->addr6;
+ bind_addr = &c->ip6.addr;
else
bind_addr = addr;
diff --git a/udp.c b/udp.c
index 856429f..c4ebecc 100644
--- a/udp.c
+++ b/udp.c
@@ -690,20 +690,20 @@ static void udp_sock_fill_data_v4(const struct ctx *c, int n,
src_port = htons(b->s_in.sin_port);
if (src >> IN_CLASSA_NSHIFT == IN_LOOPBACKNET ||
- src == INADDR_ANY || src == ntohl(c->addr4_seen)) {
- b->iph.saddr = c->gw4;
+ src == INADDR_ANY || src == ntohl(c->ip4.addr_seen)) {
+ b->iph.saddr = c->ip4.gw;
udp_tap_map[V4][src_port].ts = now->tv_sec;
udp_tap_map[V4][src_port].flags |= PORT_LOCAL;
- if (b->s_in.sin_addr.s_addr == c->addr4_seen)
+ if (b->s_in.sin_addr.s_addr == c->ip4.addr_seen)
udp_tap_map[V4][src_port].flags &= ~PORT_LOOPBACK;
else
udp_tap_map[V4][src_port].flags |= PORT_LOOPBACK;
bitmap_set(udp_act[V4][UDP_ACT_TAP], src_port);
- } else if (c->dns4_fwd &&
- src == ntohl(c->dns4[0]) && ntohs(src_port) == 53) {
- b->iph.saddr = c->dns4_fwd;
+ } else if (c->ip4.dns_fwd &&
+ src == ntohl(c->ip4.dns[0]) && ntohs(src_port) == 53) {
+ b->iph.saddr = c->ip4.dns_fwd;
} else {
b->iph.saddr = b->s_in.sin_addr.s_addr;
}
@@ -768,17 +768,17 @@ static void udp_sock_fill_data_v6(const struct ctx *c, int n,
b->ip6h.payload_len = htons(udp6_l2_mh_sock[n].msg_len + sizeof(b->uh));
if (IN6_IS_ADDR_LINKLOCAL(src)) {
- b->ip6h.daddr = c->addr6_ll_seen;
+ b->ip6h.daddr = c->ip6.addr_ll_seen;
b->ip6h.saddr = b->s_in6.sin6_addr;
} else if (IN6_IS_ADDR_LOOPBACK(src) ||
- IN6_ARE_ADDR_EQUAL(src, &c->addr6_seen) ||
- IN6_ARE_ADDR_EQUAL(src, &c->addr6)) {
- b->ip6h.daddr = c->addr6_ll_seen;
+ IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr_seen) ||
+ IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr)) {
+ b->ip6h.daddr = c->ip6.addr_ll_seen;
- if (IN6_IS_ADDR_LINKLOCAL(&c->gw6))
- b->ip6h.saddr = c->gw6;
+ if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.gw))
+ b->ip6h.saddr = c->ip6.gw;
else
- b->ip6h.saddr = c->addr6_ll;
+ b->ip6h.saddr = c->ip6.addr_ll;
udp_tap_map[V6][src_port].ts = now->tv_sec;
udp_tap_map[V6][src_port].flags |= PORT_LOCAL;
@@ -788,18 +788,18 @@ static void udp_sock_fill_data_v6(const struct ctx *c, int n,
else
udp_tap_map[V6][src_port].flags &= ~PORT_LOOPBACK;
- if (IN6_ARE_ADDR_EQUAL(src, &c->addr6))
+ if (IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr))
udp_tap_map[V6][src_port].flags |= PORT_GUA;
else
udp_tap_map[V6][src_port].flags &= ~PORT_GUA;
bitmap_set(udp_act[V6][UDP_ACT_TAP], src_port);
- } else if (!IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) &&
- IN6_ARE_ADDR_EQUAL(src, &c->dns6_fwd) && src_port == 53) {
- b->ip6h.daddr = c->addr6_seen;
- b->ip6h.saddr = c->dns6_fwd;
+ } else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) &&
+ IN6_ARE_ADDR_EQUAL(src, &c->ip6.dns_fwd) && src_port == 53) {
+ b->ip6h.daddr = c->ip6.addr_seen;
+ b->ip6h.saddr = c->ip6.dns_fwd;
} else {
- b->ip6h.daddr = c->addr6_seen;
+ b->ip6h.daddr = c->ip6.addr_seen;
b->ip6h.saddr = b->s_in6.sin6_addr;
}
@@ -1015,15 +1015,15 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
udp_tap_map[V4][src].ts = now->tv_sec;
- if (s_in.sin_addr.s_addr == c->gw4 && !c->no_map_gw) {
+ if (s_in.sin_addr.s_addr == c->ip4.gw && !c->no_map_gw) {
if (!(udp_tap_map[V4][dst].flags & PORT_LOCAL) ||
(udp_tap_map[V4][dst].flags & PORT_LOOPBACK))
s_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
else
- s_in.sin_addr.s_addr = c->addr4_seen;
- } else if (s_in.sin_addr.s_addr == c->dns4_fwd &&
+ s_in.sin_addr.s_addr = c->ip4.addr_seen;
+ } else if (s_in.sin_addr.s_addr == c->ip4.dns_fwd &&
ntohs(s_in.sin_port) == 53) {
- s_in.sin_addr.s_addr = c->dns4[0];
+ s_in.sin_addr.s_addr = c->ip4.dns[0];
}
} else {
s_in6 = (struct sockaddr_in6) {
@@ -1036,19 +1036,19 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
sa = (struct sockaddr *)&s_in6;
sl = sizeof(s_in6);
- if (IN6_ARE_ADDR_EQUAL(addr, &c->gw6) && !c->no_map_gw) {
+ if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.gw) && !c->no_map_gw) {
if (!(udp_tap_map[V6][dst].flags & PORT_LOCAL) ||
(udp_tap_map[V6][dst].flags & PORT_LOOPBACK))
s_in6.sin6_addr = in6addr_loopback;
else if (udp_tap_map[V6][dst].flags & PORT_GUA)
- s_in6.sin6_addr = c->addr6;
+ s_in6.sin6_addr = c->ip6.addr;
else
- s_in6.sin6_addr = c->addr6_seen;
- } else if (IN6_ARE_ADDR_EQUAL(addr, &c->dns6_fwd) &&
+ s_in6.sin6_addr = c->ip6.addr_seen;
+ } else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_fwd) &&
ntohs(s_in6.sin6_port) == 53) {
- s_in6.sin6_addr = c->dns6[0];
+ s_in6.sin6_addr = c->ip6.dns[0];
} else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) {
- bind_addr = &c->addr6_ll;
+ bind_addr = &c->ip6.addr_ll;
}
if (!(s = udp_tap_map[V6][src].sock)) {
@@ -1122,7 +1122,7 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
if (af == AF_INET || af == AF_UNSPEC) {
if (!addr && c->mode == MODE_PASTA)
- bind_addr = &c->addr4;
+ bind_addr = &c->ip4.addr;
else
bind_addr = addr;
@@ -1155,7 +1155,7 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
if (af == AF_INET6 || af == AF_UNSPEC) {
if (!addr && c->mode == MODE_PASTA)
- bind_addr = &c->addr6;
+ bind_addr = &c->ip6.addr;
else
bind_addr = addr;
diff --git a/util.c b/util.c
index f4ec102..9b87b65 100644
--- a/util.c
+++ b/util.c
@@ -278,8 +278,8 @@ int sock_l4(const struct ctx *c, int af, uint8_t proto,
if (bind_addr) {
addr6.sin6_addr = *(struct in6_addr *)bind_addr;
- if (!memcmp(bind_addr, &c->addr6_ll,
- sizeof(c->addr6_ll)))
+ if (!memcmp(bind_addr, &c->ip6.addr_ll,
+ sizeof(c->ip6.addr_ll)))
addr6.sin6_scope_id = c->ifi6;
} else {
addr6.sin6_addr = in6addr_any;