Copyright © 2013 Intel Corporation. All rights reserved.
***/
-#include <arpa/inet.h>
#include <sys/stat.h>
#include "sd-dhcp-lease.h"
#include "dns-def.h"
#include "dns-domain.h"
#include "dns-resolver-internal.h"
-#include "env-file.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "hexdecoct.h"
#include "hostname-util.h"
#include "in-addr-util.h"
#include "ip-util.h"
#include "network-common.h"
-#include "network-internal.h"
-#include "parse-util.h"
#include "set.h"
#include "sort-util.h"
-#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
-#include "tmpfile-util.h"
#include "unaligned.h"
void dhcp_lease_set_timestamp(sd_dhcp_lease *lease, const triple_timestamp *timestamp) {
return 0;
}
-int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
- _cleanup_(unlink_and_freep) char *temp_path = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- struct in_addr address;
- const struct in_addr *addresses;
- const void *data;
- size_t data_len;
- const char *string;
- uint16_t mtu;
- _cleanup_free_ sd_dhcp_route **routes = NULL;
- char **search_domains;
- usec_t t;
- int r;
-
- assert(lease);
- assert(lease_file);
-
- r = fopen_temporary(lease_file, &f, &temp_path);
- if (r < 0)
- return r;
-
- (void) fchmod(fileno(f), 0644);
-
- fprintf(f,
- "# This is private data. Do not parse.\n");
-
- r = sd_dhcp_lease_get_address(lease, &address);
- if (r >= 0)
- fprintf(f, "ADDRESS=%s\n", IN4_ADDR_TO_STRING(&address));
-
- r = sd_dhcp_lease_get_netmask(lease, &address);
- if (r >= 0)
- fprintf(f, "NETMASK=%s\n", IN4_ADDR_TO_STRING(&address));
-
- r = sd_dhcp_lease_get_router(lease, &addresses);
- if (r > 0) {
- fputs("ROUTER=", f);
- serialize_in_addrs(f, addresses, r, NULL, NULL);
- fputc('\n', f);
- }
-
- r = sd_dhcp_lease_get_server_identifier(lease, &address);
- if (r >= 0)
- fprintf(f, "SERVER_ADDRESS=%s\n", IN4_ADDR_TO_STRING(&address));
-
- r = sd_dhcp_lease_get_next_server(lease, &address);
- if (r >= 0)
- fprintf(f, "NEXT_SERVER=%s\n", IN4_ADDR_TO_STRING(&address));
-
- r = sd_dhcp_lease_get_broadcast(lease, &address);
- if (r >= 0)
- fprintf(f, "BROADCAST=%s\n", IN4_ADDR_TO_STRING(&address));
-
- r = sd_dhcp_lease_get_mtu(lease, &mtu);
- if (r >= 0)
- fprintf(f, "MTU=%" PRIu16 "\n", mtu);
-
- r = sd_dhcp_lease_get_t1(lease, &t);
- if (r >= 0)
- fprintf(f, "T1=%s\n", FORMAT_TIMESPAN(t, USEC_PER_SEC));
-
- r = sd_dhcp_lease_get_t2(lease, &t);
- if (r >= 0)
- fprintf(f, "T2=%s\n", FORMAT_TIMESPAN(t, USEC_PER_SEC));
-
- r = sd_dhcp_lease_get_lifetime(lease, &t);
- if (r >= 0)
- fprintf(f, "LIFETIME=%s\n", FORMAT_TIMESPAN(t, USEC_PER_SEC));
-
- r = sd_dhcp_lease_get_dns(lease, &addresses);
- if (r > 0) {
- fputs("DNS=", f);
- serialize_in_addrs(f, addresses, r, NULL, NULL);
- fputc('\n', f);
- }
-
- sd_dns_resolver *resolvers;
- r = sd_dhcp_lease_get_dnr(lease, &resolvers);
- if (r > 0) {
- fputs("DNR=", f);
- serialize_dnr(f, resolvers, r, NULL);
- fputc('\n', f);
- }
-
- r = sd_dhcp_lease_get_ntp(lease, &addresses);
- if (r > 0) {
- fputs("NTP=", f);
- serialize_in_addrs(f, addresses, r, NULL, NULL);
- fputc('\n', f);
- }
-
- r = sd_dhcp_lease_get_sip(lease, &addresses);
- if (r > 0) {
- fputs("SIP=", f);
- serialize_in_addrs(f, addresses, r, NULL, NULL);
- fputc('\n', f);
- }
-
- r = sd_dhcp_lease_get_domainname(lease, &string);
- if (r >= 0)
- fprintf(f, "DOMAINNAME=%s\n", string);
-
- r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
- if (r > 0) {
- fputs("DOMAIN_SEARCH_LIST=", f);
- fputstrv(f, search_domains, NULL, NULL);
- fputc('\n', f);
- }
-
- r = sd_dhcp_lease_get_hostname(lease, &string);
- if (r >= 0)
- fprintf(f, "HOSTNAME=%s\n", string);
-
- r = sd_dhcp_lease_get_root_path(lease, &string);
- if (r >= 0)
- fprintf(f, "ROOT_PATH=%s\n", string);
-
- r = sd_dhcp_lease_get_static_routes(lease, &routes);
- if (r > 0)
- serialize_dhcp_routes(f, "STATIC_ROUTES", routes, r);
-
- routes = mfree(routes);
- r = sd_dhcp_lease_get_classless_routes(lease, &routes);
- if (r > 0)
- serialize_dhcp_routes(f, "CLASSLESS_ROUTES", routes, r);
-
- r = sd_dhcp_lease_get_timezone(lease, &string);
- if (r >= 0)
- fprintf(f, "TIMEZONE=%s\n", string);
-
- if (sd_dhcp_client_id_is_set(&lease->client_id)) {
- _cleanup_free_ char *client_id_hex = NULL;
-
- client_id_hex = hexmem(lease->client_id.raw, lease->client_id.size);
- if (!client_id_hex)
- return -ENOMEM;
- fprintf(f, "CLIENTID=%s\n", client_id_hex);
- }
-
- r = sd_dhcp_lease_get_vendor_specific(lease, &data, &data_len);
- if (r >= 0) {
- _cleanup_free_ char *option_hex = NULL;
-
- option_hex = hexmem(data, data_len);
- if (!option_hex)
- return -ENOMEM;
- fprintf(f, "VENDOR_SPECIFIC=%s\n", option_hex);
- }
-
- LIST_FOREACH(options, option, lease->private_options) {
- char key[STRLEN("OPTION_000")+1];
-
- xsprintf(key, "OPTION_%" PRIu8, option->tag);
- r = serialize_dhcp_option(f, key, option->data, option->length);
- if (r < 0)
- return r;
- }
-
- r = fflush_and_check(f);
- if (r < 0)
- return r;
-
- r = conservative_rename(temp_path, lease_file);
- if (r < 0)
- return r;
-
- temp_path = mfree(temp_path);
-
- return 0;
-}
-
-static char **private_options_free(char **options) {
- if (!options)
- return NULL;
-
- free_many_charp(options, SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1);
-
- return mfree(options);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(char**, private_options_free);
-
-int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
- _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
- _cleanup_free_ char
- *address = NULL,
- *router = NULL,
- *netmask = NULL,
- *server_address = NULL,
- *next_server = NULL,
- *broadcast = NULL,
- *dns = NULL,
- *dnr = NULL,
- *ntp = NULL,
- *sip = NULL,
- *pop3 = NULL,
- *smtp = NULL,
- *lpr = NULL,
- *mtu = NULL,
- *static_routes = NULL,
- *classless_routes = NULL,
- *domains = NULL,
- *client_id_hex = NULL,
- *vendor_specific_hex = NULL,
- *lifetime = NULL,
- *t1 = NULL,
- *t2 = NULL;
- _cleanup_(private_options_freep) char **options = NULL;
-
- int r, i;
-
- assert(lease_file);
- assert(ret);
-
- r = dhcp_lease_new(&lease);
- if (r < 0)
- return r;
-
- options = new0(char*, SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1);
- if (!options)
- return -ENOMEM;
-
- r = parse_env_file(NULL, lease_file,
- "ADDRESS", &address,
- "ROUTER", &router,
- "NETMASK", &netmask,
- "SERVER_ADDRESS", &server_address,
- "NEXT_SERVER", &next_server,
- "BROADCAST", &broadcast,
- "DNS", &dns,
- "DNR", &dnr,
- "NTP", &ntp,
- "SIP", &sip,
- "POP3", &pop3,
- "SMTP", &smtp,
- "LPR", &lpr,
- "MTU", &mtu,
- "DOMAINNAME", &lease->domainname,
- "HOSTNAME", &lease->hostname,
- "DOMAIN_SEARCH_LIST", &domains,
- "ROOT_PATH", &lease->root_path,
- "STATIC_ROUTES", &static_routes,
- "CLASSLESS_ROUTES", &classless_routes,
- "CLIENTID", &client_id_hex,
- "TIMEZONE", &lease->timezone,
- "VENDOR_SPECIFIC", &vendor_specific_hex,
- "LIFETIME", &lifetime,
- "T1", &t1,
- "T2", &t2,
- "OPTION_224", &options[0],
- "OPTION_225", &options[1],
- "OPTION_226", &options[2],
- "OPTION_227", &options[3],
- "OPTION_228", &options[4],
- "OPTION_229", &options[5],
- "OPTION_230", &options[6],
- "OPTION_231", &options[7],
- "OPTION_232", &options[8],
- "OPTION_233", &options[9],
- "OPTION_234", &options[10],
- "OPTION_235", &options[11],
- "OPTION_236", &options[12],
- "OPTION_237", &options[13],
- "OPTION_238", &options[14],
- "OPTION_239", &options[15],
- "OPTION_240", &options[16],
- "OPTION_241", &options[17],
- "OPTION_242", &options[18],
- "OPTION_243", &options[19],
- "OPTION_244", &options[20],
- "OPTION_245", &options[21],
- "OPTION_246", &options[22],
- "OPTION_247", &options[23],
- "OPTION_248", &options[24],
- "OPTION_249", &options[25],
- "OPTION_250", &options[26],
- "OPTION_251", &options[27],
- "OPTION_252", &options[28],
- "OPTION_253", &options[29],
- "OPTION_254", &options[30]);
- if (r < 0)
- return r;
-
- if (address) {
- r = inet_pton(AF_INET, address, &lease->address);
- if (r <= 0)
- log_debug("Failed to parse address %s, ignoring.", address);
- }
-
- if (router) {
- r = deserialize_in_addrs(&lease->router, router);
- if (r < 0)
- log_debug_errno(r, "Failed to deserialize router addresses %s, ignoring: %m", router);
- else
- lease->router_size = r;
- }
-
- if (netmask) {
- r = inet_pton(AF_INET, netmask, &lease->subnet_mask);
- if (r <= 0)
- log_debug("Failed to parse netmask %s, ignoring.", netmask);
- }
-
- if (server_address) {
- r = inet_pton(AF_INET, server_address, &lease->server_address);
- if (r <= 0)
- log_debug("Failed to parse server address %s, ignoring.", server_address);
- }
-
- if (next_server) {
- r = inet_pton(AF_INET, next_server, &lease->next_server);
- if (r <= 0)
- log_debug("Failed to parse next server %s, ignoring.", next_server);
- }
-
- if (broadcast) {
- r = inet_pton(AF_INET, broadcast, &lease->broadcast);
- if (r <= 0)
- log_debug("Failed to parse broadcast address %s, ignoring.", broadcast);
- }
-
- if (dns) {
- r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_DNS].addr, dns);
- if (r < 0)
- log_debug_errno(r, "Failed to deserialize DNS servers %s, ignoring: %m", dns);
- else
- lease->servers[SD_DHCP_LEASE_DNS].size = r;
- }
-
- if (dnr) {
- r = deserialize_dnr(&lease->dnr, dnr);
- if (r < 0)
- log_debug_errno(r, "Failed to deserialize DNR servers %s, ignoring: %m", dnr);
- else
- lease->n_dnr = r;
- }
-
- if (ntp) {
- r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_NTP].addr, ntp);
- if (r < 0)
- log_debug_errno(r, "Failed to deserialize NTP servers %s, ignoring: %m", ntp);
- else
- lease->servers[SD_DHCP_LEASE_NTP].size = r;
- }
-
- if (sip) {
- r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_SIP].addr, sip);
- if (r < 0)
- log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip);
- else
- lease->servers[SD_DHCP_LEASE_SIP].size = r;
- }
-
- if (pop3) {
- r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_POP3].addr, pop3);
- if (r < 0)
- log_debug_errno(r, "Failed to deserialize POP3 server %s, ignoring: %m", pop3);
- else
- lease->servers[SD_DHCP_LEASE_POP3].size = r;
- }
-
- if (smtp) {
- r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_SMTP].addr, smtp);
- if (r < 0)
- log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp);
- else
- lease->servers[SD_DHCP_LEASE_SMTP].size = r;
- }
-
- if (lpr) {
- r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_LPR].addr, lpr);
- if (r < 0)
- log_debug_errno(r, "Failed to deserialize LPR server %s, ignoring: %m", lpr);
- else
- lease->servers[SD_DHCP_LEASE_LPR].size = r;
- }
-
- if (mtu) {
- r = safe_atou16(mtu, &lease->mtu);
- if (r < 0)
- log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu);
- }
-
- if (domains) {
- _cleanup_strv_free_ char **a = NULL;
- a = strv_split(domains, " ");
- if (!a)
- return -ENOMEM;
-
- if (!strv_isempty(a))
- lease->search_domains = TAKE_PTR(a);
- }
-
- if (static_routes) {
- r = deserialize_dhcp_routes(
- &lease->static_routes,
- &lease->n_static_routes,
- static_routes);
- if (r < 0)
- log_debug_errno(r, "Failed to parse DHCP static routes %s, ignoring: %m", static_routes);
- }
-
- if (classless_routes) {
- r = deserialize_dhcp_routes(
- &lease->classless_routes,
- &lease->n_classless_routes,
- classless_routes);
- if (r < 0)
- log_debug_errno(r, "Failed to parse DHCP classless routes %s, ignoring: %m", classless_routes);
- }
-
- if (lifetime) {
- r = parse_sec(lifetime, &lease->lifetime);
- if (r < 0)
- log_debug_errno(r, "Failed to parse lifetime %s, ignoring: %m", lifetime);
- }
-
- if (t1) {
- r = parse_sec(t1, &lease->t1);
- if (r < 0)
- log_debug_errno(r, "Failed to parse T1 %s, ignoring: %m", t1);
- }
-
- if (t2) {
- r = parse_sec(t2, &lease->t2);
- if (r < 0)
- log_debug_errno(r, "Failed to parse T2 %s, ignoring: %m", t2);
- }
-
- if (client_id_hex) {
- _cleanup_free_ void *data = NULL;
- size_t data_size;
-
- r = unhexmem(client_id_hex, &data, &data_size);
- if (r < 0)
- log_debug_errno(r, "Failed to parse client ID %s, ignoring: %m", client_id_hex);
-
- r = sd_dhcp_client_id_set_raw(&lease->client_id, data, data_size);
- if (r < 0)
- log_debug_errno(r, "Failed to assign client ID, ignoring: %m");
- }
-
- if (vendor_specific_hex) {
- r = unhexmem(vendor_specific_hex, &lease->vendor_specific, &lease->vendor_specific_len);
- if (r < 0)
- log_debug_errno(r, "Failed to parse vendor specific data %s, ignoring: %m", vendor_specific_hex);
- }
-
- for (i = 0; i <= SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE; i++) {
- _cleanup_free_ void *data = NULL;
- size_t len;
-
- if (!options[i])
- continue;
-
- r = unhexmem(options[i], &data, &len);
- if (r < 0) {
- log_debug_errno(r, "Failed to parse private DHCP option %s, ignoring: %m", options[i]);
- continue;
- }
-
- r = dhcp_lease_insert_private_option(lease, SD_DHCP_OPTION_PRIVATE_BASE + i, data, len);
- if (r < 0)
- return r;
- }
-
- *ret = TAKE_PTR(lease);
-
- return 0;
-}
-
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
struct in_addr address, mask;
int r;