mirror of
https://passt.top/passt
synced 2025-06-11 18:15:34 +02:00
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>
This commit is contained in:
parent
0231ac1c86
commit
9010054ea4
6 changed files with 312 additions and 45 deletions
54
ndp.c
54
ndp.c
|
@ -14,6 +14,7 @@
|
|||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
|
@ -21,7 +22,6 @@
|
|||
#include <linux/udp.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "passt.h"
|
||||
#include "util.h"
|
||||
|
@ -76,6 +76,9 @@ int ndp(struct ctx *c, struct ethhdr *eh, size_t len)
|
|||
memcpy(p, c->mac, ETH_ALEN);
|
||||
p += 6;
|
||||
} else if (ih->icmp6_type == RS) {
|
||||
size_t len = 0;
|
||||
int i, n;
|
||||
|
||||
info("NDP: received RS, sending RA");
|
||||
ihr->icmp6_type = RA;
|
||||
ihr->icmp6_code = 0;
|
||||
|
@ -95,13 +98,48 @@ int ndp(struct ctx *c, struct ethhdr *eh, size_t len)
|
|||
memcpy(p, &c->addr6, 8); /* prefix */
|
||||
p += 16;
|
||||
|
||||
*p++ = 25; /* RDNS */
|
||||
*p++ = 3; /* length */
|
||||
p += 2;
|
||||
*(uint32_t *)p = htonl(60); /* lifetime */
|
||||
p += 4;
|
||||
memcpy(p, &c->dns6, 16); /* address */
|
||||
p += 16;
|
||||
for (n = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[n]); n++);
|
||||
if (n) {
|
||||
*p++ = 25; /* RDNSS */
|
||||
*p++ = 1 + 2 * n; /* length */
|
||||
p += 2; /* reserved */
|
||||
*(uint32_t *)p = htonl(60); /* lifetime */
|
||||
p += 4;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
memcpy(p, &c->dns6[i], 16); /* address */
|
||||
p += 16;
|
||||
}
|
||||
}
|
||||
|
||||
for (n = 0; *c->dns_search[n].n; n++)
|
||||
len += strlen(c->dns_search[n].n) + 2;
|
||||
if (len) {
|
||||
*p++ = 31; /* DNSSL */
|
||||
*p++ = 2 + (len + 8 - 1) / 8; /* length */
|
||||
p += 2; /* reserved */
|
||||
*(uint32_t *)p = htonl(60); /* lifetime */
|
||||
p += 4;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
char *dot;
|
||||
|
||||
*(p++) = '.';
|
||||
|
||||
strncpy((char *)p, c->dns_search[i].n,
|
||||
sizeof(buf) -
|
||||
((intptr_t)p - (intptr_t)buf));
|
||||
for (dot = (char *)p - 1; *dot; dot++) {
|
||||
if (*dot == '.')
|
||||
*dot = strcspn(dot + 1, ".");
|
||||
}
|
||||
p += strlen(c->dns_search[i].n);
|
||||
*(p++) = 0;
|
||||
}
|
||||
|
||||
memset(p, 0, len % 8); /* padding */
|
||||
p += len % 8;
|
||||
}
|
||||
|
||||
*p++ = 1; /* source ll */
|
||||
*p++ = 1; /* length */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue