aboutgitcodebugslistschat
path: root/passt.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-05-21 11:14:47 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-05-21 11:14:47 +0200
commit9010054ea4ceee9105aa938f15b79a3a91ec5969 (patch)
treef9f1ca6a2b506d6b4b2f1fdb210e702d016fecf8 /passt.c
parent0231ac1c86578a8dac2ae6531d30c71ba89688e1 (diff)
downloadpasst-9010054ea4ceee9105aa938f15b79a3a91ec5969.tar
passt-9010054ea4ceee9105aa938f15b79a3a91ec5969.tar.gz
passt-9010054ea4ceee9105aa938f15b79a3a91ec5969.tar.bz2
passt-9010054ea4ceee9105aa938f15b79a3a91ec5969.tar.lz
passt-9010054ea4ceee9105aa938f15b79a3a91ec5969.tar.xz
passt-9010054ea4ceee9105aa938f15b79a3a91ec5969.tar.zst
passt-9010054ea4ceee9105aa938f15b79a3a91ec5969.zip
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero, from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations. Introduce support for domain search list for DHCP (RFC 3397), NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from /etc/resolv.conf. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'passt.c')
-rw-r--r--passt.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/passt.c b/passt.c
index c2c630e..d0dcb26 100644
--- a/passt.c
+++ b/passt.c
@@ -299,30 +299,49 @@ out:
*/
static void get_dns(struct ctx *c)
{
+ struct in6_addr *dns6 = &c->dns6[0];
+ struct fqdn *s = c->dns_search;
+ uint32_t *dns4 = &c->dns4[0];
char buf[BUFSIZ], *p, *end;
- int dns4 = 0, dns6 = 0;
FILE *r;
r = fopen("/etc/resolv.conf", "r");
- while (fgets(buf, BUFSIZ, r) && !(dns4 && dns6)) {
- if (!strstr(buf, "nameserver "))
- continue;
- p = strrchr(buf, ' ');
- end = strpbrk(buf, "%\n");
- if (end)
- *end = 0;
- if (p && inet_pton(AF_INET, p + 1, &c->dns4))
- dns4 = 1;
- if (p && inet_pton(AF_INET6, p + 1, &c->dns6))
- dns6 = 1;
+ while (fgets(buf, BUFSIZ, r)) {
+ if (strstr(buf, "nameserver ") == buf) {
+ p = strrchr(buf, ' ');
+ if (!p)
+ continue;
+
+ end = strpbrk(buf, "%\n");
+ if (end)
+ *end = 0;
+
+ if (dns4 - &c->dns4[0] < ARRAY_SIZE(c->dns4) &&
+ inet_pton(AF_INET, p + 1, dns4))
+ dns4++;
+
+ if (dns6 - &c->dns6[0] < ARRAY_SIZE(c->dns6) &&
+ inet_pton(AF_INET6, p + 1, dns6))
+ dns6++;
+ } else if (strstr(buf, "search ") == buf &&
+ s == c->dns_search) {
+ end = strpbrk(buf, "\n");
+ if (end)
+ *end = 0;
+
+ p = strtok(buf, " \t");
+ while ((p = strtok(NULL, " \t")) &&
+ s - c->dns_search < ARRAY_SIZE(c->dns_search)) {
+ strncpy(s->n, p, sizeof(c->dns_search[0]));
+ s++;
+ }
+ }
}
fclose(r);
- if (dns4 || dns6)
- return;
- err("Couldn't get any nameserver address");
- exit(EXIT_FAILURE);
+ if (dns4 == c->dns4 && dns6 == c->dns6)
+ warn("Couldn't get any nameserver address");
}
/**
@@ -785,8 +804,17 @@ int main(int argc, char **argv)
inet_ntop(AF_INET, &c.mask4, buf4, sizeof(buf4)));
info(" router: %s",
inet_ntop(AF_INET, &c.gw4, buf4, sizeof(buf4)));
- info(" DNS: %s",
- inet_ntop(AF_INET, &c.dns4, buf4, sizeof(buf4)));
+ for (i = 0; c.dns4[i]; i++) {
+ if (!i)
+ info(" DNS:");
+ inet_ntop(AF_INET, &c.dns4[i], buf4, sizeof(buf4));
+ info(" %s", buf4);
+ }
+ for (i = 0; *c.dns_search[i].n; i++) {
+ if (!i)
+ info(" search:");
+ info(" %s", c.dns_search[i].n);
+ }
}
if (c.v6) {
info("NDP/DHCPv6:");
@@ -794,8 +822,17 @@ int main(int argc, char **argv)
inet_ntop(AF_INET6, &c.addr6, buf6, sizeof(buf6)));
info(" router: %s",
inet_ntop(AF_INET6, &c.gw6, buf6, sizeof(buf6)));
- info(" DNS: %s",
- inet_ntop(AF_INET6, &c.dns6, buf6, sizeof(buf6)));
+ for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c.dns6[i]); i++) {
+ if (!i)
+ info(" DNS:");
+ inet_ntop(AF_INET6, &c.dns6[i], buf6, sizeof(buf6));
+ info(" %s", buf6);
+ }
+ for (i = 0; *c.dns_search[i].n; i++) {
+ if (!i)
+ info(" search:");
+ info(" %s", c.dns_search[i].n);
+ }
}
listen: