mirror of
https://github.com/systemd/systemd.git
synced 2025-01-14 23:24:38 +03:00
dhcp6-option: Add helper function for uncompressed domain names
Add a helper function containing a modified version of dns_packet_read_name() that does not use DnsPacket to extract a string array of domain names from the provided option data. The domain names are stored uncompressed as defined in Section 8. of RFC 3315.
This commit is contained in:
parent
b553817ccf
commit
f96ccab7e0
@ -71,6 +71,8 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
|
||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
struct in6_addr **addrs, size_t count,
|
||||
size_t *allocated);
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
|
||||
char ***str_arr);
|
||||
|
||||
int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
|
||||
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
|
||||
|
@ -26,9 +26,11 @@
|
||||
#include "sparse-endian.h"
|
||||
#include "unaligned.h"
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
|
||||
#include "dhcp6-internal.h"
|
||||
#include "dhcp6-protocol.h"
|
||||
#include "dns-domain.h"
|
||||
|
||||
#define DHCP6_OPTION_IA_NA_LEN 12
|
||||
#define DHCP6_OPTION_IA_TA_LEN 4
|
||||
@ -335,3 +337,83 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
|
||||
char ***str_arr)
|
||||
{
|
||||
size_t pos = 0, idx = 0;
|
||||
_cleanup_free_ char **names = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(optlen > 1, -ENODATA);
|
||||
assert_return(optval[optlen] == '\0', -EINVAL);
|
||||
|
||||
while (pos < optlen) {
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
bool first = true;
|
||||
|
||||
for (;;) {
|
||||
uint8_t c;
|
||||
|
||||
c = optval[pos++];
|
||||
|
||||
if (c == 0)
|
||||
/* End of name */
|
||||
break;
|
||||
else if (c <= 63) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
const char *label;
|
||||
|
||||
/* Literal label */
|
||||
label = (const char *)&optval[pos];
|
||||
pos += c;
|
||||
if (pos > optlen)
|
||||
return -EMSGSIZE;
|
||||
|
||||
r = dns_label_escape(label, c, &t);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (!GREEDY_REALLOC0(ret, allocated, n + !first + strlen(t) + 1)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
ret[n++] = '.';
|
||||
else
|
||||
first = false;
|
||||
|
||||
memcpy(ret + n, t, r);
|
||||
n += r;
|
||||
continue;
|
||||
} else {
|
||||
r = -EBADMSG;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret[n] = 0;
|
||||
|
||||
r = strv_extend(&names, ret);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
ret = NULL;
|
||||
idx++;
|
||||
}
|
||||
|
||||
*str_arr = names;
|
||||
names = NULL;
|
||||
|
||||
return idx;
|
||||
|
||||
fail:
|
||||
return r;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user