network: DHCP server Add support to transmit SIP server

1. DHCP server trasmit
2. Client parses and saves in leases
Implements http://www.rfc-editor.org/rfc/rfc3361.txt

```
Frame 134: 348 bytes on wire (2784 bits), 348 bytes captured (2784 bits) on interface 0
Ethernet II, Src: 42:65:85:d6:4e:32 (42:65:85:d6:4e:32), Dst: 1e:04:f8:b8:2f:d4 (1e:04:f8:b8:2f:d4)
Internet Protocol Version 4, Src: 192.168.5.1, Dst: 192.168.5.11
User Datagram Protocol, Src Port: 67, Dst Port: 68
Dynamic Host Configuration Protocol (ACK)
    Message type: Boot Reply (2)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0x7cc87cb4
    Seconds elapsed: 0
    Bootp flags: 0x0000 (Unicast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 192.168.5.11
    Next server IP address: 0.0.0.0
    Relay agent IP address: 0.0.0.0
    Client MAC address: 1e:04:f8:b8:2f:d4 (1e:04:f8:b8:2f:d4)
    Client hardware address padding: 00000000000000000000
    Server host name not given
    Boot file name not given
    Magic cookie: DHCP
    Option: (53) DHCP Message Type (ACK)
        Length: 1
        DHCP: ACK (5)
    Option: (51) IP Address Lease Time
        Length: 4
        IP Address Lease Time: (3600s) 1 hour
    Option: (1) Subnet Mask (255.255.255.0)
        Length: 4
        Subnet Mask: 255.255.255.0
    Option: (3) Router
        Length: 4
        Router: 192.168.5.1
    Option: (6) Domain Name Server
        Length: 4
        Domain Name Server: 192.168.5.1
    Option: (42) Network Time Protocol Servers
        Length: 4
        Network Time Protocol Server: 192.168.1.1
    Option: (120) SIP Servers <=====here
        Length: 9
        SIP Server Encoding: IPv4 Address (1)
        SIP Server Address: 192.168.1.1
        SIP Server Address: 192.168.5.2
    Option: (101) TCode
        Length: 13
        TZ TCode: Europe/Berlin
    Option: (54) DHCP Server Identifier (192.168.5.1)
        Length: 4
        DHCP Server Identifier: 192.168.5.1
    Option: (255) End
        Option End: 255
```

```
cat /run/systemd/netif/state                                                                                                   ✔    3148  16:40:51
OPER_STATE=routable
CARRIER_STATE=carrier
ADDRESS_STATE=routable
DNS=192.168.94.2 192.168.5.1
NTP=192.168.5.1
SIP=192.168.1.1 192.168.5.2

```

aa
This commit is contained in:
Susant Sahani 2019-09-18 15:22:47 +02:00 committed by Yu Watanabe
parent 5bc945bec4
commit 299d578f7f
22 changed files with 370 additions and 11 deletions

View file

@ -1348,6 +1348,14 @@
and take precedence over any statically configured ones.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseSIP=</varname></term>
<listitem>
<para>When true (the default), the SIP servers received
from the DHCP server will be saved at the state files and can be
read via <function>sd_network_link_get_sip_servers()</function> function.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseMTU=</varname></term>
<listitem>
@ -1776,6 +1784,19 @@
<varname>DNS=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>EmitSIP=</varname></term>
<term><varname>SIP=</varname></term>
<listitem><para>Similar to the <varname>EmitDNS=</varname> and
<varname>DNS=</varname> settings described above, these
settings configure whether and what SIP server information
shall be emitted as part of the DHCP lease. The same syntax,
propagation semantics and defaults apply as for
<varname>EmitDNS=</varname> and
<varname>DNS=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>EmitRouter=</varname></term>

View file

@ -58,6 +58,9 @@ struct sd_dhcp_lease {
struct in_addr *ntp;
size_t ntp_size;
struct in_addr *sip;
size_t sip_size;
struct sd_dhcp_route *static_route;
size_t static_route_size, static_route_allocated;

View file

@ -65,6 +65,18 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
break;
}
case SD_DHCP_OPTION_SIP_SERVER:
if (*offset + 3 + optlen > size)
return -ENOBUFS;
options[*offset] = code;
options[*offset + 1] = optlen + 1;
options[*offset + 2] = 1;
memcpy_safe(&options[*offset + 3], optval, optlen);
*offset += 3 + optlen;
break;
default:
if (*offset + 2 + optlen > size)
return -ENOBUFS;

View file

@ -45,8 +45,8 @@ struct sd_dhcp_server {
char *timezone;
struct in_addr *ntp, *dns;
unsigned n_ntp, n_dns;
struct in_addr *ntp, *dns, *sip;
unsigned n_ntp, n_dns, n_sip;
bool emit_router;

View file

@ -120,6 +120,17 @@ int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
return (int) lease->ntp_size;
}
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
if (lease->sip_size <= 0)
return -ENODATA;
*addr = lease->sip;
return (int) lease->sip_size;
}
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
assert_return(lease, -EINVAL);
assert_return(domainname, -EINVAL);
@ -269,6 +280,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
free(lease->domainname);
free(lease->dns);
free(lease->ntp);
free(lease->sip);
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
@ -402,6 +414,36 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
return 0;
}
static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
assert(option);
assert(ret);
assert(n_ret);
if (len <= 0) {
*ret = mfree(*ret);
*n_ret = 0;
} else {
size_t n_addresses;
struct in_addr *addresses;
int l = len - 1;
if (l % 4 != 0)
return -EINVAL;
n_addresses = l / 4;
addresses = newdup(struct in_addr, option + 1, n_addresses);
if (!addresses)
return -ENOMEM;
free(*ret);
*ret = addresses;
*n_ret = n_addresses;
}
return 0;
}
static int lease_parse_routes(
const uint8_t *option, size_t len,
struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
@ -555,6 +597,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse NTP server, ignoring: %m");
break;
case SD_DHCP_OPTION_SIP_SERVER:
r = lease_parse_sip_server(option, len, &lease->sip, &lease->sip_size);
if (r < 0)
log_debug_errno(r, "Failed to parse SIP server, ignoring: %m");
break;
case SD_DHCP_OPTION_STATIC_ROUTE:
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
if (r < 0)
@ -893,6 +941,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
fputc('\n', f);
}
r = sd_dhcp_lease_get_sip(lease, &addresses);
if (r > 0) {
fputs("SIP=", f);
serialize_in_addrs(f, addresses, r, false, NULL);
fputc('\n', f);
}
r = sd_dhcp_lease_get_domainname(lease, &string);
if (r >= 0)
fprintf(f, "DOMAINNAME=%s\n", string);
@ -983,6 +1038,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*broadcast = NULL,
*dns = NULL,
*ntp = NULL,
*sip = NULL,
*mtu = NULL,
*routes = NULL,
*domains = NULL,
@ -1011,6 +1067,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"BROADCAST", &broadcast,
"DNS", &dns,
"NTP", &ntp,
"SIP", &sip,
"MTU", &mtu,
"DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname,
@ -1115,6 +1172,14 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
lease->ntp_size = r;
}
if (sip) {
r = deserialize_in_addrs(&lease->sip, sip);
if (r < 0)
log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", ntp);
else
lease->ntp_size = r;
}
if (mtu) {
r = safe_atou16(mtu, &lease->mtu);
if (r < 0)

View file

@ -139,6 +139,7 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
free(server->timezone);
free(server->dns);
free(server->ntp);
free(server->sip);
hashmap_free(server->leases_by_client_id);
@ -498,6 +499,15 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
return r;
}
if (server->n_sip > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_SIP_SERVER,
sizeof(struct in_addr) * server->n_sip, server->sip);
if (r < 0)
return r;
}
if (server->timezone) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
@ -1124,6 +1134,32 @@ int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], u
return 1;
}
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(sip || n <= 0, -EINVAL);
if (server->n_sip == n &&
memcmp(server->sip, sip, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->sip = mfree(server->sip);
server->n_sip = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, sip, n);
if (!c)
return -ENOMEM;
free(server->sip);
server->sip = c;
server->n_sip = n;
}
return 1;
}
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
assert_return(server, -EINVAL);

View file

@ -249,6 +249,10 @@ _public_ int sd_network_link_get_route_domains(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "ROUTE_DOMAINS", ret);
}
_public_ int sd_network_link_get_sip_servers(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "SIP", ret);
}
_public_ int sd_network_link_get_dns_default_route(int ifindex) {
char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
_cleanup_free_ char *s = NULL;

View file

@ -91,6 +91,38 @@ int config_parse_dhcp_use_dns(
return 0;
}
int config_parse_dhcp_use_sip(
const char* unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *network = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse UseSIP=%s, ignoring assignment: %m", rvalue);
return 0;
}
network->dhcp_use_sip = r;
return 0;
}
int config_parse_dhcp_use_ntp(
const char* unit,
const char *filename,

View file

@ -31,5 +31,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_ntp);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_sip);
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);

View file

@ -137,6 +137,55 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
return sd_dhcp_server_set_ntp(s, addresses, n_addresses);
}
static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
char **a;
if (!link->network)
return 0;
log_debug("Copying SIP server information from %s", link->ifname);
STRV_FOREACH(a, link->network->sip) {
union in_addr_union ia;
/* Only look for IPv4 addresses */
if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
continue;
/* Never propagate obviously borked data */
if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
addresses[n_addresses++] = ia.in;
}
if (link->network->dhcp_use_sip && link->dhcp_lease) {
const struct in_addr *da = NULL;
int j, n;
n = sd_dhcp_lease_get_sip(link->dhcp_lease, &da);
if (n > 0) {
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
return log_oom();
for (j = 0; j < n; j++)
if (in4_addr_is_non_local(&da[j]))
addresses[n_addresses++] = da[j];
}
}
if (n_addresses <= 0)
return 0;
return sd_dhcp_server_set_sip(s, addresses, n_addresses);
}
int dhcp4_server_configure(Link *link) {
Address *address;
Link *uplink = NULL;
@ -209,6 +258,24 @@ int dhcp4_server_configure(Link *link) {
log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m");
}
if (link->network->dhcp_server_emit_sip) {
if (link->network->n_dhcp_server_sip > 0)
r = sd_dhcp_server_set_sip(link->dhcp_server, link->network->dhcp_server_sip, link->network->n_dhcp_server_sip);
else {
if (!acquired_uplink)
uplink = manager_find_uplink(link->manager, link);
if (!uplink) {
log_link_debug(link, "Not emitting sip server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_uplink_sip_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to set SIP server for DHCP server, ignoring: %m");
}
r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to set router emission for DHCP server: %m");
@ -345,3 +412,55 @@ int config_parse_dhcp_server_ntp(
n->dhcp_server_ntp = m;
}
}
int config_parse_dhcp_server_sip(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
r = in_addr_from_string(AF_INET, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse SIP server address '%s', ignoring: %m", w);
continue;
}
m = reallocarray(n->dhcp_server_sip, n->n_dhcp_server_sip + 1, sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_sip++] = a.in;
n->dhcp_server_sip = m;
}
}

View file

@ -9,3 +9,4 @@ int dhcp4_server_configure(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip);

View file

@ -1159,6 +1159,12 @@ int dhcp4_configure(Link *link) {
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for NTP server: %m");
}
if (link->network->dhcp_use_sip) {
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_SIP_SERVER);
if (r < 0)
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for SIP server: %m");
}
if (link->network->dhcp_use_timezone) {
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE);
if (r < 0)

View file

@ -3597,6 +3597,22 @@ int link_save(Link *link) {
space = true;
}
fputc('\n', f);
fputs("SIP=", f);
space = false;
fputstrv(f, link->network->sip, NULL, &space);
if (link->network->dhcp_use_sip &&
link->dhcp_lease) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses);
if (r > 0)
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
space = true;
}
if (link->network->dhcp6_use_ntp && dhcp6_lease) {
struct in6_addr *in6_addrs;
char **hosts;

View file

@ -1333,16 +1333,16 @@ static int ordered_set_put_in4_addrv(OrderedSet *s,
}
static int manager_save(Manager *m) {
_cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *search_domains = NULL, *route_domains = NULL;
Link *link;
Iterator i;
_cleanup_free_ char *temp_path = NULL;
_cleanup_strv_free_ char **p = NULL;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
const char *operstate_str, *carrier_state_str, *address_state_str;
LinkOperationalState operstate = LINK_OPERSTATE_OFF;
LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
LinkAddressState address_state = LINK_ADDRESS_STATE_OFF;
const char *operstate_str, *carrier_state_str, *address_state_str;
_cleanup_free_ char *temp_path = NULL;
_cleanup_strv_free_ char **p = NULL;
_cleanup_fclose_ FILE *f = NULL;
Link *link;
Iterator i;
int r;
assert(m);
@ -1357,6 +1357,10 @@ static int manager_save(Manager *m) {
if (!ntp)
return -ENOMEM;
sip = ordered_set_new(&string_hash_ops);
if (!sip)
return -ENOMEM;
search_domains = ordered_set_new(&dns_name_hash_ops);
if (!search_domains)
return -ENOMEM;
@ -1426,6 +1430,18 @@ static int manager_save(Manager *m) {
return r;
}
if (link->network->dhcp_use_sip) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses);
if (r > 0) {
r = ordered_set_put_in4_addrv(sip, addresses, r, in4_addr_is_non_local);
if (r < 0)
return r;
} else if (r < 0 && r != -ENODATA)
return r;
}
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
const char *domainname;
char **domains = NULL;
@ -1476,6 +1492,7 @@ static int manager_save(Manager *m) {
ordered_set_print(f, "DNS=", dns);
ordered_set_print(f, "NTP=", ntp);
ordered_set_print(f, "SIP=", sip);
ordered_set_print(f, "DOMAINS=", search_domains);
ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);

View file

@ -145,6 +145,7 @@ DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier,
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)
DHCPv4.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_use_ntp)
DHCPv4.UseSIP, config_parse_bool, 0, offsetof(Network, dhcp_use_sip)
DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_use_mtu)
DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname)
DHCPv4.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains)
@ -182,6 +183,8 @@ DHCPServer.EmitDNS, config_parse_bool,
DHCPServer.DNS, config_parse_dhcp_server_dns, 0, 0
DHCPServer.EmitNTP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_ntp)
DHCPServer.NTP, config_parse_dhcp_server_ntp, 0, 0
DHCPServer.EmitSIP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_sip)
DHCPServer.SIP, config_parse_dhcp_server_sip, 0, 0
DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router)
DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone)
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)

View file

@ -363,6 +363,7 @@ int network_load_one(Manager *manager, const char *filename) {
.dhcp = ADDRESS_FAMILY_NO,
.dhcp_critical = -1,
.dhcp_use_ntp = true,
.dhcp_use_sip = true,
.dhcp_use_dns = true,
.dhcp_use_hostname = true,
.dhcp_use_routes = true,
@ -386,6 +387,7 @@ int network_load_one(Manager *manager, const char *filename) {
.dhcp_server_emit_dns = true,
.dhcp_server_emit_ntp = true,
.dhcp_server_emit_sip = true,
.dhcp_server_emit_router = true,
.dhcp_server_emit_timezone = true,
@ -546,6 +548,8 @@ static Network *network_free(Network *network) {
strv_free(network->ntp);
free(network->dns);
strv_free(network->sip);
free(network->sip);
ordered_set_free_free(network->search_domains);
ordered_set_free_free(network->route_domains);
strv_free(network->bind_carrier);
@ -608,6 +612,7 @@ static Network *network_free(Network *network) {
free(network->dhcp_server_timezone);
free(network->dhcp_server_dns);
free(network->dhcp_server_ntp);
free(network->dhcp_server_sip);
set_free_free(network->dnssec_negative_trust_anchors);

View file

@ -93,6 +93,7 @@ struct Network {
bool dhcp_use_dns;
bool dhcp_routes_to_dns;
bool dhcp_use_ntp;
bool dhcp_use_sip;
bool dhcp_use_mtu;
bool dhcp_use_routes;
bool dhcp_use_timezone;
@ -110,12 +111,19 @@ struct Network {
/* DHCP Server Support */
bool dhcp_server;
bool dhcp_server_emit_dns;
struct in_addr *dhcp_server_dns;
unsigned n_dhcp_server_dns;
bool dhcp_server_emit_ntp;
struct in_addr *dhcp_server_ntp;
unsigned n_dhcp_server_ntp;
bool dhcp_server_emit_sip;
struct in_addr *dhcp_server_sip;
unsigned n_dhcp_server_sip;
bool dhcp_server_emit_router;
bool dhcp_server_emit_timezone;
char *dhcp_server_timezone;
@ -257,6 +265,7 @@ struct Network {
Set *dnssec_negative_trust_anchors;
char **ntp;
char **sip;
char **bind_carrier;
};

View file

@ -87,6 +87,7 @@ enum {
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
SD_DHCP_OPTION_SIP_SERVER = 120,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
SD_DHCP_OPTION_PRIVATE_BASE = 224,
/* Windows 10 option to send when Anonymize=true */

View file

@ -44,6 +44,7 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);

View file

@ -46,8 +46,9 @@ int sd_dhcp_server_stop(sd_dhcp_server *server);
int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen, uint32_t offset, uint32_t size);
int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);

View file

@ -160,6 +160,9 @@ int sd_network_link_get_search_domains(int ifindex, char ***domains);
/* Get the route DNS domain names for a given link. */
int sd_network_link_get_route_domains(int ifindex, char ***domains);
/* Get the sip servers for a given link. */
int sd_network_link_get_sip_servers(int ifindex, char ***sip);
/* Get whether this link shall be used as 'default route' for DNS queries */
int sd_network_link_get_dns_default_route(int ifindex);

View file

@ -72,6 +72,7 @@ UseRoutes=
IAID=
UserClass=
UseNTP=
UseSIP=
UseMTU=
UseDomainName=
RouteMetric=
@ -245,6 +246,8 @@ PoolOffset=
Timezone=
EmitDNS=
NTP=
EmitSIP=
SIP=
EmitRouter=
MaxLeaseTimeSec=
DefaultLeaseTimeSec=