summaryrefslogtreecommitdiff
path: root/src/dhcp/nm-dhcp-nettools.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dhcp/nm-dhcp-nettools.c')
-rw-r--r--src/dhcp/nm-dhcp-nettools.c2434
1 files changed, 1204 insertions, 1230 deletions
diff --git a/src/dhcp/nm-dhcp-nettools.c b/src/dhcp/nm-dhcp-nettools.c
index e7ae502d87..5b9300846f 100644
--- a/src/dhcp/nm-dhcp-nettools.c
+++ b/src/dhcp/nm-dhcp-nettools.c
@@ -32,51 +32,55 @@
/*****************************************************************************/
-#define NM_TYPE_DHCP_NETTOOLS (nm_dhcp_nettools_get_type ())
-#define NM_DHCP_NETTOOLS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_NETTOOLS, NMDhcpNettools))
-#define NM_DHCP_NETTOOLS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_NETTOOLS, NMDhcpNettoolsClass))
-#define NM_IS_DHCP_NETTOOLS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_NETTOOLS))
-#define NM_IS_DHCP_NETTOOLS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_NETTOOLS))
-#define NM_DHCP_NETTOOLS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_NETTOOLS, NMDhcpNettoolsClass))
-
-typedef struct _NMDhcpNettools NMDhcpNettools;
+#define NM_TYPE_DHCP_NETTOOLS (nm_dhcp_nettools_get_type())
+#define NM_DHCP_NETTOOLS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_NETTOOLS, NMDhcpNettools))
+#define NM_DHCP_NETTOOLS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_NETTOOLS, NMDhcpNettoolsClass))
+#define NM_IS_DHCP_NETTOOLS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_NETTOOLS))
+#define NM_IS_DHCP_NETTOOLS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_NETTOOLS))
+#define NM_DHCP_NETTOOLS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_NETTOOLS, NMDhcpNettoolsClass))
+
+typedef struct _NMDhcpNettools NMDhcpNettools;
typedef struct _NMDhcpNettoolsClass NMDhcpNettoolsClass;
/*****************************************************************************/
typedef struct {
- NDhcp4Client *client;
- NDhcp4ClientProbe *probe;
- NDhcp4ClientLease *lease;
- GSource *event_source;
- char *lease_file;
+ NDhcp4Client * client;
+ NDhcp4ClientProbe *probe;
+ NDhcp4ClientLease *lease;
+ GSource * event_source;
+ char * lease_file;
} NMDhcpNettoolsPrivate;
struct _NMDhcpNettools {
- NMDhcpClient parent;
- NMDhcpNettoolsPrivate _priv;
+ NMDhcpClient parent;
+ NMDhcpNettoolsPrivate _priv;
};
struct _NMDhcpNettoolsClass {
- NMDhcpClientClass parent;
+ NMDhcpClientClass parent;
};
-G_DEFINE_TYPE (NMDhcpNettools, nm_dhcp_nettools, NM_TYPE_DHCP_CLIENT)
+G_DEFINE_TYPE(NMDhcpNettools, nm_dhcp_nettools, NM_TYPE_DHCP_CLIENT)
-#define NM_DHCP_NETTOOLS_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDhcpNettools, NM_IS_DHCP_NETTOOLS)
+#define NM_DHCP_NETTOOLS_GET_PRIVATE(self) \
+ _NM_GET_PRIVATE(self, NMDhcpNettools, NM_IS_DHCP_NETTOOLS)
/*****************************************************************************/
static void
-set_error_nettools (GError **error, int r, const char *message)
+set_error_nettools(GError **error, int r, const char *message)
{
- /* the error code returned from n_dhcp4_* API is either a negative
+ /* the error code returned from n_dhcp4_* API is either a negative
* errno, or a positive internal error code. Generate different messages
* for these. */
- if (r < 0)
- nm_utils_error_set_errno (error, r, "%s: %s", message);
- else
- nm_utils_error_set (error, r, "%s (code %d)", message, r);
+ if (r < 0)
+ nm_utils_error_set_errno(error, r, "%s: %s", message);
+ else
+ nm_utils_error_set(error, r, "%s (code %d)", message, r);
}
/*****************************************************************************/
@@ -84,147 +88,146 @@ set_error_nettools (GError **error, int r, const char *message)
#define DHCP_MAX_FQDN_LENGTH 255
enum {
- NM_IN_ADDR_CLASS_A,
- NM_IN_ADDR_CLASS_B,
- NM_IN_ADDR_CLASS_C,
- NM_IN_ADDR_CLASS_INVALID,
+ NM_IN_ADDR_CLASS_A,
+ NM_IN_ADDR_CLASS_B,
+ NM_IN_ADDR_CLASS_C,
+ NM_IN_ADDR_CLASS_INVALID,
};
static int
-in_addr_class (struct in_addr addr)
+in_addr_class(struct in_addr addr)
{
- switch (ntohl (addr.s_addr) >> 24) {
- case 0 ... 127:
- return NM_IN_ADDR_CLASS_A;
- case 128 ... 191:
- return NM_IN_ADDR_CLASS_B;
- case 192 ... 223:
- return NM_IN_ADDR_CLASS_C;
- default:
- return NM_IN_ADDR_CLASS_INVALID;
- }
+ switch (ntohl(addr.s_addr) >> 24) {
+ case 0 ... 127:
+ return NM_IN_ADDR_CLASS_A;
+ case 128 ... 191:
+ return NM_IN_ADDR_CLASS_B;
+ case 192 ... 223:
+ return NM_IN_ADDR_CLASS_C;
+ default:
+ return NM_IN_ADDR_CLASS_INVALID;
+ }
}
static gboolean
-lease_option_consume (void *out,
- size_t n_out,
- uint8_t **datap,
- size_t *n_datap)
+lease_option_consume(void *out, size_t n_out, uint8_t **datap, size_t *n_datap)
{
- if (*n_datap < n_out)
- return FALSE;
+ if (*n_datap < n_out)
+ return FALSE;
- memcpy (out, *datap, n_out);
- *datap += n_out;
- *n_datap -= n_out;
- return TRUE;
+ memcpy(out, *datap, n_out);
+ *datap += n_out;
+ *n_datap -= n_out;
+ return TRUE;
}
static gboolean
-lease_option_next_in_addr (struct in_addr *addrp,
- uint8_t **datap,
- size_t *n_datap)
+lease_option_next_in_addr(struct in_addr *addrp, uint8_t **datap, size_t *n_datap)
{
- return lease_option_consume (addrp, sizeof (struct in_addr), datap, n_datap);
+ return lease_option_consume(addrp, sizeof(struct in_addr), datap, n_datap);
}
static gboolean
-lease_option_next_route (struct in_addr *destp,
- uint8_t *plenp,
- struct in_addr *gatewayp,
- gboolean classless,
- uint8_t **datap,
- size_t *n_datap)
+lease_option_next_route(struct in_addr *destp,
+ uint8_t * plenp,
+ struct in_addr *gatewayp,
+ gboolean classless,
+ uint8_t ** datap,
+ size_t * n_datap)
{
- struct in_addr dest = {}, gateway;
- uint8_t *data = *datap;
- size_t n_data = *n_datap;
- uint8_t plen;
- uint8_t bytes;
-
- if (classless) {
- if (!lease_option_consume (&plen, sizeof (plen), &data, &n_data))
- return FALSE;
-
- if (plen > 32)
- return FALSE;
-
- bytes = plen == 0 ? 0 : ((plen - 1) / 8) + 1;
-
- if (!lease_option_consume (&dest, bytes, &data, &n_data))
- return FALSE;
- } else {
- if (!lease_option_next_in_addr (&dest, &data, &n_data))
- return FALSE;
-
- switch (in_addr_class (dest)) {
- case NM_IN_ADDR_CLASS_A:
- plen = 8;
- break;
- case NM_IN_ADDR_CLASS_B:
- plen = 16;
- break;
- case NM_IN_ADDR_CLASS_C:
- plen = 24;
- break;
- case NM_IN_ADDR_CLASS_INVALID:
- return FALSE;
- }
- }
-
- dest.s_addr = nm_utils_ip4_address_clear_host_address (dest.s_addr, plen);
-
- if (!lease_option_next_in_addr (&gateway, &data, &n_data))
- return FALSE;
-
- *destp = dest;
- *plenp = plen;
- *gatewayp = gateway;
- *datap = data;
- *n_datap = n_data;
- return TRUE;
+ struct in_addr dest = {}, gateway;
+ uint8_t * data = *datap;
+ size_t n_data = *n_datap;
+ uint8_t plen;
+ uint8_t bytes;
+
+ if (classless) {
+ if (!lease_option_consume(&plen, sizeof(plen), &data, &n_data))
+ return FALSE;
+
+ if (plen > 32)
+ return FALSE;
+
+ bytes = plen == 0 ? 0 : ((plen - 1) / 8) + 1;
+
+ if (!lease_option_consume(&dest, bytes, &data, &n_data))
+ return FALSE;
+ } else {
+ if (!lease_option_next_in_addr(&dest, &data, &n_data))
+ return FALSE;
+
+ switch (in_addr_class(dest)) {
+ case NM_IN_ADDR_CLASS_A:
+ plen = 8;
+ break;
+ case NM_IN_ADDR_CLASS_B:
+ plen = 16;
+ break;
+ case NM_IN_ADDR_CLASS_C:
+ plen = 24;
+ break;
+ case NM_IN_ADDR_CLASS_INVALID:
+ return FALSE;
+ }
+ }
+
+ dest.s_addr = nm_utils_ip4_address_clear_host_address(dest.s_addr, plen);
+
+ if (!lease_option_next_in_addr(&gateway, &data, &n_data))
+ return FALSE;
+
+ *destp = dest;
+ *plenp = plen;
+ *gatewayp = gateway;
+ *datap = data;
+ *n_datap = n_data;
+ return TRUE;
}
static gboolean
-lease_option_print_label (GString *str, size_t n_label, uint8_t **datap, size_t *n_datap)
+lease_option_print_label(GString *str, size_t n_label, uint8_t **datap, size_t *n_datap)
{
- for (size_t i = 0; i < n_label; ++i) {
- uint8_t c;
-
- if (!lease_option_consume(&c, sizeof (c), datap, n_datap))
- return FALSE;
-
- switch (c) {
- case 'a' ... 'z':
- case 'A' ... 'Z':
- case '0' ... '9':
- case '-':
- case '_':
- g_string_append_c(str, c);
- break;
- case '.':
- case '\\':
- g_string_append_printf(str, "\\%c", c);
- break;
- default:
- g_string_append_printf(str, "\\%3d", c);
- }
- }
-
- return TRUE;
+ for (size_t i = 0; i < n_label; ++i) {
+ uint8_t c;
+
+ if (!lease_option_consume(&c, sizeof(c), datap, n_datap))
+ return FALSE;
+
+ switch (c) {
+ case 'a' ... 'z':
+ case 'A' ... 'Z':
+ case '0' ... '9':
+ case '-':
+ case '_':
+ g_string_append_c(str, c);
+ break;
+ case '.':
+ case '\\':
+ g_string_append_printf(str, "\\%c", c);
+ break;
+ default:
+ g_string_append_printf(str, "\\%3d", c);
+ }
+ }
+
+ return TRUE;
}
static gboolean
-lease_option_print_domain_name (GString *str, uint8_t *cache, size_t *n_cachep, uint8_t **datap, size_t *n_datap)
+lease_option_print_domain_name(GString * str,
+ uint8_t * cache,
+ size_t * n_cachep,
+ uint8_t **datap,
+ size_t * n_datap)
{
- uint8_t *domain;
- size_t n_domain, n_cache = *n_cachep;
- uint8_t **domainp = datap;
- size_t *n_domainp = n_datap;
- gboolean first = TRUE;
- uint8_t c;
-
- /*
+ uint8_t * domain;
+ size_t n_domain, n_cache = *n_cachep;
+ uint8_t **domainp = datap;
+ size_t * n_domainp = n_datap;
+ gboolean first = TRUE;
+ uint8_t c;
+
+ /*
* We are given two adjacent memory regions. The @cache contains alreday parsed
* domain names, and the @datap contains the remaining data to parse.
*
@@ -240,1320 +243,1291 @@ lease_option_print_domain_name (GString *str, uint8_t *cache, size_t *n_cachep,
* Note, that each time a jump to an offset is performed, the size of the
* cache shrinks, so this is guaranteed to terminate.
*/
- if (cache + n_cache != *datap)
- return FALSE;
+ if (cache + n_cache != *datap)
+ return FALSE;
- for (;;) {
- if (!lease_option_consume(&c, sizeof (c), domainp, n_domainp))
- return FALSE;
+ for (;;) {
+ if (!lease_option_consume(&c, sizeof(c), domainp, n_domainp))
+ return FALSE;
- switch (c & 0xC0) {
- case 0x00: /* label length */
- {
- size_t n_label = c;
+ switch (c & 0xC0) {
+ case 0x00: /* label length */
+ {
+ size_t n_label = c;
- if (n_label == 0) {
- /*
+ if (n_label == 0) {
+ /*
* We reached the final label of the domain name. Adjust
* the cache to include the consumed data, and return.
*/
- *n_cachep = *datap - cache;
- return TRUE;
- }
+ *n_cachep = *datap - cache;
+ return TRUE;
+ }
- if (!first)
- g_string_append_c(str, '.');
- else
- first = FALSE;
+ if (!first)
+ g_string_append_c(str, '.');
+ else
+ first = FALSE;
- if (!lease_option_print_label (str, n_label, domainp, n_domainp))
- return FALSE;
+ if (!lease_option_print_label(str, n_label, domainp, n_domainp))
+ return FALSE;
- break;
- }
- case 0xC0: /* back pointer */
- {
- size_t offset = (c & 0x3F) << 16;
+ break;
+ }
+ case 0xC0: /* back pointer */
+ {
+ size_t offset = (c & 0x3F) << 16;
- /*
+ /*
* The offset is given as two bytes (in big endian), where the
* two high bits are masked out.
*/
- if (!lease_option_consume (&c, sizeof (c), domainp, n_domainp))
- return FALSE;
+ if (!lease_option_consume(&c, sizeof(c), domainp, n_domainp))
+ return FALSE;
- offset += c;
+ offset += c;
- if (offset >= n_cache)
- return FALSE;
+ if (offset >= n_cache)
+ return FALSE;
- domain = cache + offset;
- n_domain = n_cache - offset;
- n_cache = offset;
+ domain = cache + offset;
+ n_domain = n_cache - offset;
+ n_cache = offset;
- domainp = &domain;
- n_domainp = &n_domain;
+ domainp = &domain;
+ n_domainp = &n_domain;
- break;
- }
- default:
- return FALSE;
- }
- }
+ break;
+ }
+ default:
+ return FALSE;
+ }
+ }
}
static gboolean
-lease_get_in_addr (NDhcp4ClientLease *lease,
- guint8 option,
- struct in_addr *addrp) {
- struct in_addr addr;
- uint8_t *data;
- size_t n_data;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, option, &data, &n_data);
- if (r)
- return FALSE;
-
- if (!lease_option_next_in_addr (&addr, &data, &n_data))
- return FALSE;
-
- if (n_data != 0)
- return FALSE;
-
- *addrp = addr;
- return TRUE;
+lease_get_in_addr(NDhcp4ClientLease *lease, guint8 option, struct in_addr *addrp)
+{
+ struct in_addr addr;
+ uint8_t * data;
+ size_t n_data;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease, option, &data, &n_data);
+ if (r)
+ return FALSE;
+
+ if (!lease_option_next_in_addr(&addr, &data, &n_data))
+ return FALSE;
+
+ if (n_data != 0)
+ return FALSE;
+
+ *addrp = addr;
+ return TRUE;
}
static gboolean
-lease_get_u16 (NDhcp4ClientLease *lease,
- uint8_t option,
- uint16_t *u16p)
+lease_get_u16(NDhcp4ClientLease *lease, uint8_t option, uint16_t *u16p)
{
- uint8_t *data;
- size_t n_data;
- uint16_t be16;
- int r;
+ uint8_t *data;
+ size_t n_data;
+ uint16_t be16;
+ int r;
- r = n_dhcp4_client_lease_query (lease, option, &data, &n_data);
- if (r)
- return FALSE;
+ r = n_dhcp4_client_lease_query(lease, option, &data, &n_data);
+ if (r)
+ return FALSE;
- if (n_data != sizeof (be16))
- return FALSE;
+ if (n_data != sizeof(be16))
+ return FALSE;
- memcpy (&be16, data, sizeof (be16));
+ memcpy(&be16, data, sizeof(be16));
- *u16p = ntohs(be16);
- return TRUE;
+ *u16p = ntohs(be16);
+ return TRUE;
}
static gboolean
-lease_parse_address (NDhcp4ClientLease *lease,
- NMIP4Config *ip4_config,
- GHashTable *options,
- GError **error)
+lease_parse_address(NDhcp4ClientLease *lease,
+ NMIP4Config * ip4_config,
+ GHashTable * options,
+ GError ** error)
{
- char addr_str[NM_UTILS_INET_ADDRSTRLEN];
- struct in_addr a_address;
- struct in_addr a_netmask;
- struct in_addr a_next_server;
- guint32 a_plen;
- guint64 nettools_lifetime;
- guint32 a_lifetime;
- guint32 a_timestamp;
- guint64 a_expiry;
-
- n_dhcp4_client_lease_get_yiaddr (lease, &a_address);
- if (a_address.s_addr == INADDR_ANY) {
- nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "could not get address from lease");
- return FALSE;
- }
-
- n_dhcp4_client_lease_get_lifetime (lease, &nettools_lifetime);
-
- if (nettools_lifetime == G_MAXUINT64) {
- a_timestamp = 0;
- a_lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
- a_expiry = G_MAXUINT64;
- } else {
- guint64 nettools_basetime;
- guint64 lifetime;
- gint64 ts;
-
- n_dhcp4_client_lease_get_basetime (lease, &nettools_basetime);
-
- /* usually we shouldn't assert against external libraries like n-dhcp4.
+ char addr_str[NM_UTILS_INET_ADDRSTRLEN];
+ struct in_addr a_address;
+ struct in_addr a_netmask;
+ struct in_addr a_next_server;
+ guint32 a_plen;
+ guint64 nettools_lifetime;
+ guint32 a_lifetime;
+ guint32 a_timestamp;
+ guint64 a_expiry;
+
+ n_dhcp4_client_lease_get_yiaddr(lease, &a_address);
+ if (a_address.s_addr == INADDR_ANY) {
+ nm_utils_error_set_literal(error,
+ NM_UTILS_ERROR_UNKNOWN,
+ "could not get address from lease");
+ return FALSE;
+ }
+
+ n_dhcp4_client_lease_get_lifetime(lease, &nettools_lifetime);
+
+ if (nettools_lifetime == G_MAXUINT64) {
+ a_timestamp = 0;
+ a_lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
+ a_expiry = G_MAXUINT64;
+ } else {
+ guint64 nettools_basetime;
+ guint64 lifetime;
+ gint64 ts;
+
+ n_dhcp4_client_lease_get_basetime(lease, &nettools_basetime);
+
+ /* usually we shouldn't assert against external libraries like n-dhcp4.
* Here we still do it... it seems safe enough. */
- nm_assert (nettools_basetime > 0);
- nm_assert (nettools_lifetime >= nettools_basetime);
- nm_assert (((nettools_lifetime - nettools_basetime) % NM_UTILS_NSEC_PER_SEC) == 0);
- nm_assert ((nettools_lifetime - nettools_basetime) / NM_UTILS_NSEC_PER_SEC <= G_MAXUINT32);
-
- if (nettools_lifetime <= nettools_basetime) {
- /* A lease time of 0 is allowed on some dhcp servers, so, let's accept it. */
- lifetime = 0;
- } else {
- lifetime = nettools_lifetime - nettools_basetime;
-
- /* we "ceil" the value to the next second. In practice, we don't expect any sub-second values
+ nm_assert(nettools_basetime > 0);
+ nm_assert(nettools_lifetime >= nettools_basetime);
+ nm_assert(((nettools_lifetime - nettools_basetime) % NM_UTILS_NSEC_PER_SEC) == 0);
+ nm_assert((nettools_lifetime - nettools_basetime) / NM_UTILS_NSEC_PER_SEC <= G_MAXUINT32);
+
+ if (nettools_lifetime <= nettools_basetime) {
+ /* A lease time of 0 is allowed on some dhcp servers, so, let's accept it. */
+ lifetime = 0;
+ } else {
+ lifetime = nettools_lifetime - nettools_basetime;
+
+ /* we "ceil" the value to the next second. In practice, we don't expect any sub-second values
* from n-dhcp4 anyway, so this should have no effect. */
- lifetime += NM_UTILS_NSEC_PER_SEC - 1;
- }
+ lifetime += NM_UTILS_NSEC_PER_SEC - 1;
+ }
- ts = nm_utils_monotonic_timestamp_from_boottime (nettools_basetime, 1);
+ ts = nm_utils_monotonic_timestamp_from_boottime(nettools_basetime, 1);
- /* the timestamp must be positive, because we only started nettools DHCP client
+ /* the timestamp must be positive, because we only started nettools DHCP client
* after obtaining the first monotonic timestamp. Hence, the lease must have been
* received afterwards. */
- nm_assert (ts >= NM_UTILS_NSEC_PER_SEC);
-
- a_timestamp = ts / NM_UTILS_NSEC_PER_SEC;
- a_lifetime = NM_MIN (lifetime / NM_UTILS_NSEC_PER_SEC, NM_PLATFORM_LIFETIME_PERMANENT - 1);
- a_expiry = time (NULL) + ((lifetime - (nm_utils_clock_gettime_nsec (CLOCK_BOOTTIME) - nettools_basetime)) / NM_UTILS_NSEC_PER_SEC);
- }
-
- if (!lease_get_in_addr (lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, &a_netmask)) {
- nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "could not get netmask from lease");
- return FALSE;
- }
-
- _nm_utils_inet4_ntop (a_address.s_addr, addr_str);
- a_plen = nm_utils_ip4_netmask_to_prefix (a_netmask.s_addr);
-
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS,
- addr_str);
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_SUBNET_MASK,
- _nm_utils_inet4_ntop (a_netmask.s_addr, addr_str));
-
- nm_dhcp_option_add_option_u64 (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME,
- (guint64) a_lifetime);
-
- if (a_expiry != G_MAXUINT64) {
- nm_dhcp_option_add_option_u64 (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_NM_EXPIRY,
- a_expiry);
- }
-
-
- n_dhcp4_client_lease_get_siaddr (lease, &a_next_server);
- if (a_next_server.s_addr != INADDR_ANY) {
- _nm_utils_inet4_ntop (a_next_server.s_addr, addr_str);
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER,
- addr_str);
- }
-
- nm_ip4_config_add_address (ip4_config,
- &((const NMPlatformIP4Address) {
- .address = a_address.s_addr,
- .peer_address = a_address.s_addr,
- .plen = a_plen,
- .addr_source = NM_IP_CONFIG_SOURCE_DHCP,
- .timestamp = a_timestamp,
- .lifetime = a_lifetime,
- .preferred = a_lifetime,
- }));
-
- return TRUE;
+ nm_assert(ts >= NM_UTILS_NSEC_PER_SEC);
+
+ a_timestamp = ts / NM_UTILS_NSEC_PER_SEC;
+ a_lifetime = NM_MIN(lifetime / NM_UTILS_NSEC_PER_SEC, NM_PLATFORM_LIFETIME_PERMANENT - 1);
+ a_expiry = time(NULL)
+ + ((lifetime - (nm_utils_clock_gettime_nsec(CLOCK_BOOTTIME) - nettools_basetime))
+ / NM_UTILS_NSEC_PER_SEC);
+ }
+
+ if (!lease_get_in_addr(lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, &a_netmask)) {
+ nm_utils_error_set_literal(error,
+ NM_UTILS_ERROR_UNKNOWN,
+ "could not get netmask from lease");
+ return FALSE;
+ }
+
+ _nm_utils_inet4_ntop(a_address.s_addr, addr_str);
+ a_plen = nm_utils_ip4_netmask_to_prefix(a_netmask.s_addr);
+
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS,
+ addr_str);
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_SUBNET_MASK,
+ _nm_utils_inet4_ntop(a_netmask.s_addr, addr_str));
+
+ nm_dhcp_option_add_option_u64(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME,
+ (guint64) a_lifetime);
+
+ if (a_expiry != G_MAXUINT64) {
+ nm_dhcp_option_add_option_u64(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_NM_EXPIRY,
+ a_expiry);
+ }
+
+ n_dhcp4_client_lease_get_siaddr(lease, &a_next_server);
+ if (a_next_server.s_addr != INADDR_ANY) {
+ _nm_utils_inet4_ntop(a_next_server.s_addr, addr_str);
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER,
+ addr_str);
+ }
+
+ nm_ip4_config_add_address(ip4_config,
+ &((const NMPlatformIP4Address){
+ .address = a_address.s_addr,
+ .peer_address = a_address.s_addr,
+ .plen = a_plen,
+ .addr_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .timestamp = a_timestamp,
+ .lifetime = a_lifetime,
+ .preferred = a_lifetime,
+ }));
+
+ return TRUE;
}
static void
-lease_parse_address_list (NDhcp4ClientLease *lease,
- NMIP4Config *ip4_config,
- NMDhcpOptionDhcp4Options option,
- GHashTable *options)
+lease_parse_address_list(NDhcp4ClientLease * lease,
+ NMIP4Config * ip4_config,
+ NMDhcpOptionDhcp4Options option,
+ GHashTable * options)
{
- nm_auto_free_gstring GString *str = NULL;
- char addr_str[NM_UTILS_INET_ADDRSTRLEN];
- struct in_addr addr;
- uint8_t *data;
- size_t n_data;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, option, &data, &n_data);
- if (r)
- return;
-
- nm_gstring_prepare (&str);
-
- while (lease_option_next_in_addr (&addr, &data, &n_data)) {
-
- _nm_utils_inet4_ntop (addr.s_addr, addr_str);
- g_string_append (nm_gstring_add_space_delimiter (str), addr_str);
-
- switch (option) {
- case NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER:
- if ( addr.s_addr == 0
- || nm_ip4_addr_is_localhost (addr.s_addr)) {
- /* Skip localhost addresses, like also networkd does.
+ nm_auto_free_gstring GString *str = NULL;
+ char addr_str[NM_UTILS_INET_ADDRSTRLEN];
+ struct in_addr addr;
+ uint8_t * data;
+ size_t n_data;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease, option, &data, &n_data);
+ if (r)
+ return;
+
+ nm_gstring_prepare(&str);
+
+ while (lease_option_next_in_addr(&addr, &data, &n_data)) {
+ _nm_utils_inet4_ntop(addr.s_addr, addr_str);
+ g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
+
+ switch (option) {
+ case NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER:
+ if (addr.s_addr == 0 || nm_ip4_addr_is_localhost(addr.s_addr)) {
+ /* Skip localhost addresses, like also networkd does.
* See https://github.com/systemd/systemd/issues/4524. */
- continue;
- }
- nm_ip4_config_add_nameserver (ip4_config, addr.s_addr);
- break;
- case NM_DHCP_OPTION_DHCP4_NIS_SERVERS:
- nm_ip4_config_add_nis_server (ip4_config, addr.s_addr);
- break;
- case NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER:
- nm_ip4_config_add_wins (ip4_config, addr.s_addr);
- break;
- default:
- nm_assert_not_reached ();
- }
- }
-
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- option,
- str->str);
+ continue;
+ }
+ nm_ip4_config_add_nameserver(ip4_config, addr.s_addr);
+ break;
+ case NM_DHCP_OPTION_DHCP4_NIS_SERVERS:
+ nm_ip4_config_add_nis_server(ip4_config, addr.s_addr);
+ break;
+ case NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER:
+ nm_ip4_config_add_wins(ip4_config, addr.s_addr);
+ break;
+ default:
+ nm_assert_not_reached();
+ }
+ }
+
+ nm_dhcp_option_add_option(options, _nm_dhcp_option_dhcp4_options, option, str->str);
}
static void
-lease_parse_routes (NDhcp4ClientLease *lease,
- NMIP4Config *ip4_config,
- GHashTable *options,
- guint32 route_table,
- guint32 route_metric)
+lease_parse_routes(NDhcp4ClientLease *lease,
+ NMIP4Config * ip4_config,
+ GHashTable * options,
+ guint32 route_table,
+ guint32 route_metric)
{
- nm_auto_free_gstring GString *str = NULL;
- char dest_str[NM_UTILS_INET_ADDRSTRLEN];
- char gateway_str[NM_UTILS_INET_ADDRSTRLEN];
- const char *s;
- struct in_addr dest, gateway;
- uint8_t plen;
- guint32 m;
- gboolean has_router_from_classless = FALSE, has_classless = FALSE;
- guint32 default_route_metric = route_metric;
- uint8_t *data;
- size_t n_data;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE, &data, &n_data);
- if (!r) {
- nm_gstring_prepare (&str);
-
- has_classless = TRUE;
-
- while (lease_option_next_route (&dest, &plen, &gateway, TRUE, &data, &n_data)) {
-
- _nm_utils_inet4_ntop (dest.s_addr, dest_str);
- _nm_utils_inet4_ntop (gateway.s_addr, gateway_str);
-
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "%s/%d %s",
- dest_str,
- (int) plen,
- gateway_str);
-
- if (plen == 0) {
- /* if there are multiple default routes, we add them with differing
+ nm_auto_free_gstring GString *str = NULL;
+ char dest_str[NM_UTILS_INET_ADDRSTRLEN];
+ char gateway_str[NM_UTILS_INET_ADDRSTRLEN];
+ const char * s;
+ struct in_addr dest, gateway;
+ uint8_t plen;
+ guint32 m;
+ gboolean has_router_from_classless = FALSE, has_classless = FALSE;
+ guint32 default_route_metric = route_metric;
+ uint8_t * data;
+ size_t n_data;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease,
+ NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
+ &data,
+ &n_data);
+ if (!r) {
+ nm_gstring_prepare(&str);
+
+ has_classless = TRUE;
+
+ while (lease_option_next_route(&dest, &plen, &gateway, TRUE, &data, &n_data)) {
+ _nm_utils_inet4_ntop(dest.s_addr, dest_str);
+ _nm_utils_inet4_ntop(gateway.s_addr, gateway_str);
+
+ g_string_append_printf(nm_gstring_add_space_delimiter(str),
+ "%s/%d %s",
+ dest_str,
+ (int) plen,
+ gateway_str);
+
+ if (plen == 0) {
+ /* if there are multiple default routes, we add them with differing
* metrics. */
- m = default_route_metric;
- if (default_route_metric < G_MAXUINT32)
- default_route_metric++;
-
- has_router_from_classless = TRUE;
- } else {
- m = route_metric;
- }
-
- nm_ip4_config_add_route (ip4_config,
- &((const NMPlatformIP4Route) {
- .network = dest.s_addr,
- .plen = plen,
- .gateway = gateway.s_addr,
- .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
- .metric = m,
- .table_coerced = nm_platform_route_table_coerce (route_table),
- }),
- NULL);
- }
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
- str->str);
- }
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, &data, &n_data);
- if (!r) {
- nm_gstring_prepare (&str);
-
- while (lease_option_next_route (&dest, &plen, &gateway, FALSE, &data, &n_data)) {
-
- _nm_utils_inet4_ntop (dest.s_addr, dest_str);
- _nm_utils_inet4_ntop (gateway.s_addr, gateway_str);
-
- g_string_append_printf (nm_gstring_add_space_delimiter (str),
- "%s/%d %s",
- dest_str,
- (int) plen,
- gateway_str);
-
- if (has_classless) {
- /* RFC 3443: if the DHCP server returns both a Classless Static Routes
+ m = default_route_metric;
+ if (default_route_metric < G_MAXUINT32)
+ default_route_metric++;
+
+ has_router_from_classless = TRUE;
+ } else {
+ m = route_metric;
+ }
+
+ nm_ip4_config_add_route(
+ ip4_config,
+ &((const NMPlatformIP4Route){
+ .network = dest.s_addr,
+ .plen = plen,
+ .gateway = gateway.s_addr,
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .metric = m,
+ .table_coerced = nm_platform_route_table_coerce(route_table),
+ }),
+ NULL);
+ }
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
+ str->str);
+ }
+
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, &data, &n_data);
+ if (!r) {
+ nm_gstring_prepare(&str);
+
+ while (lease_option_next_route(&dest, &plen, &gateway, FALSE, &data, &n_data)) {
+ _nm_utils_inet4_ntop(dest.s_addr, dest_str);
+ _nm_utils_inet4_ntop(gateway.s_addr, gateway_str);
+
+ g_string_append_printf(nm_gstring_add_space_delimiter(str),
+ "%s/%d %s",
+ dest_str,
+ (int) plen,
+ gateway_str);
+
+ if (has_classless) {
+ /* RFC 3443: if the DHCP server returns both a Classless Static Routes
* option and a Static Routes option, the DHCP client MUST ignore the
* Static Routes option. */
- continue;
- }
+ continue;
+ }
- if (plen == 0) {
- /* for option 33 (static route), RFC 2132 says:
+ if (plen == 0) {
+ /* for option 33 (static route), RFC 2132 says:
*
* The default route (0.0.0.0) is an illegal destination for a static
* route. */
- continue;
- }
-
- nm_ip4_config_add_route (ip4_config,
- &((const NMPlatformIP4Route) {
- .network = dest.s_addr,
- .plen = plen,
- .gateway = gateway.s_addr,
- .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
- .metric = route_metric,
- .table_coerced = nm_platform_route_table_coerce (route_table),
- }),
- NULL);
- }
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
- str->str);
- }
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_ROUTER, &data, &n_data);
- if (!r) {
- nm_gstring_prepare (&str);
-
- while (lease_option_next_in_addr (&gateway, &data, &n_data)) {
- s = _nm_utils_inet4_ntop (gateway.s_addr, gateway_str);
- g_string_append (nm_gstring_add_space_delimiter (str), s);
-
- if (gateway.s_addr == 0) {
- /* silently skip 0.0.0.0 */
- continue;
- }
-
- if (has_router_from_classless) {
- /* If the DHCP server returns both a Classless Static Routes option and a
+ continue;
+ }
+
+ nm_ip4_config_add_route(
+ ip4_config,
+ &((const NMPlatformIP4Route){
+ .network = dest.s_addr,
+ .plen = plen,
+ .gateway = gateway.s_addr,
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .metric = route_metric,
+ .table_coerced = nm_platform_route_table_coerce(route_table),
+ }),
+ NULL);
+ }
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
+ str->str);
+ }
+
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROUTER, &data, &n_data);
+ if (!r) {
+ nm_gstring_prepare(&str);
+
+ while (lease_option_next_in_addr(&gateway, &data, &n_data)) {
+ s = _nm_utils_inet4_ntop(gateway.s_addr, gateway_str);
+ g_string_append(nm_gstring_add_space_delimiter(str), s);
+
+ if (gateway.s_addr == 0) {
+ /* silently skip 0.0.0.0 */
+ continue;
+ }
+
+ if (has_router_from_classless) {
+ /* If the DHCP server returns both a Classless Static Routes option and a
* Router option, the DHCP client MUST ignore the Router option [RFC 3442].
*
* Be more lenient and ignore the Router option only if Classless Static
* Routes contain a default gateway (as other DHCP backends do).
*/
- continue;
- }
+ continue;
+ }
- /* if there are multiple default routes, we add them with differing
+ /* if there are multiple default routes, we add them with differing
* metrics. */
- m = default_route_metric;
- if (default_route_metric < G_MAXUINT32)
- default_route_metric++;
-
- nm_ip4_config_add_route (ip4_config,
- &((const NMPlatformIP4Route) {
- .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
- .gateway = gateway.s_addr,
- .table_coerced = nm_platform_route_table_coerce (route_table),
- .metric = m,
- }),
- NULL);
- }
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_ROUTER,
- str->str);
- }
+ m = default_route_metric;
+ if (default_route_metric < G_MAXUINT32)
+ default_route_metric++;
+
+ nm_ip4_config_add_route(
+ ip4_config,
+ &((const NMPlatformIP4Route){
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .gateway = gateway.s_addr,
+ .table_coerced = nm_platform_route_table_coerce(route_table),
+ .metric = m,
+ }),
+ NULL);
+ }
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_ROUTER,
+ str->str);
+ }
}
static void
-lease_parse_mtu (NDhcp4ClientLease *lease,
- NMIP4Config *ip4_config,
- GHashTable *options)
+lease_parse_mtu(NDhcp4ClientLease *lease, NMIP4Config *ip4_config, GHashTable *options)
{
- uint16_t mtu;
+ uint16_t mtu;
- if (!lease_get_u16 (lease, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, &mtu))
- return;
+ if (!lease_get_u16(lease, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, &mtu))
+ return;
- if (mtu < 68)
- return;
+ if (mtu < 68)
+ return;
- nm_dhcp_option_add_option_u64 (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_INTERFACE_MTU,
- mtu);
- nm_ip4_config_set_mtu (ip4_config, mtu, NM_IP_CONFIG_SOURCE_DHCP);
+ nm_dhcp_option_add_option_u64(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_INTERFACE_MTU,
+ mtu);
+ nm_ip4_config_set_mtu(ip4_config, mtu, NM_IP_CONFIG_SOURCE_DHCP);
}
static void
-lease_parse_metered (NDhcp4ClientLease *lease,
- NMIP4Config *ip4_config,
- GHashTable *options)
+lease_parse_metered(NDhcp4ClientLease *lease, NMIP4Config *ip4_config, GHashTable *options)
{
- gboolean metered = FALSE;
- uint8_t *data;
- size_t n_data;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_VENDOR_SPECIFIC, &data, &n_data);
- if (r)
- metered = FALSE;
- else
- metered = !!memmem (data, n_data, "ANDROID_METERED", NM_STRLEN ("ANDROID_METERED"));
-
- /* TODO: expose the vendor specific option when present */
- nm_ip4_config_set_metered (ip4_config, metered);
+ gboolean metered = FALSE;
+ uint8_t *data;
+ size_t n_data;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_VENDOR_SPECIFIC, &data, &n_data);
+ if (r)
+ metered = FALSE;
+ else
+ metered = !!memmem(data, n_data, "ANDROID_METERED", NM_STRLEN("ANDROID_METERED"));
+
+ /* TODO: expose the vendor specific option when present */
+ nm_ip4_config_set_metered(ip4_config, metered);
}
static void
-lease_parse_ntps (NDhcp4ClientLease *lease,
- GHashTable *options)
+lease_parse_ntps(NDhcp4ClientLease *lease, GHashTable *options)
{
- nm_auto_free_gstring GString *str = NULL;
- char addr_str[NM_UTILS_INET_ADDRSTRLEN];
- struct in_addr addr;
- uint8_t *data;
- size_t n_data;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_NTP_SERVER, &data, &n_data);
- if (r)
- return;
-
- nm_gstring_prepare (&str);
-
- while (lease_option_next_in_addr (&addr, &data, &n_data)) {
- _nm_utils_inet4_ntop (addr.s_addr, addr_str);
- g_string_append (nm_gstring_add_space_delimiter (str), addr_str);
- }
-
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_NTP_SERVER,
- str->str);
+ nm_auto_free_gstring GString *str = NULL;
+ char addr_str[NM_UTILS_INET_ADDRSTRLEN];
+ struct in_addr addr;
+ uint8_t * data;
+ size_t n_data;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_NTP_SERVER, &data, &n_data);
+ if (r)
+ return;
+
+ nm_gstring_prepare(&str);
+
+ while (lease_option_next_in_addr(&addr, &data, &n_data)) {
+ _nm_utils_inet4_ntop(addr.s_addr, addr_str);
+ g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
+ }
+
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_NTP_SERVER,
+ str->str);
}
static void
-lease_parse_hostname (NDhcp4ClientLease *lease,
- GHashTable *options)
+lease_parse_hostname(NDhcp4ClientLease *lease, GHashTable *options)
{
- nm_auto_free_gstring GString *str = NULL;
- uint8_t *data;
- size_t n_data;
- int r;
+ nm_auto_free_gstring GString *str = NULL;
+ uint8_t * data;
+ size_t n_data;
+ int r;
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_HOST_NAME, &data, &n_data);
- if (r)
- return;
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_HOST_NAME, &data, &n_data);
+ if (r)
+ return;
- str = g_string_new_len ((char *)data, n_data);
+ str = g_string_new_len((char *) data, n_data);
- if (nm_utils_is_localhost (str->str))
- return;
+ if (nm_utils_is_localhost(str->str))
+ return;
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_HOST_NAME,
- str->str);
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_HOST_NAME,
+ str->str);
}
static void
-lease_parse_domainname (NDhcp4ClientLease *lease,
- NMIP4Config *ip4_config,
- GHashTable *options)
+lease_parse_domainname(NDhcp4ClientLease *lease, NMIP4Config *ip4_config, GHashTable *options)
{
- nm_auto_free_gstring GString *str = NULL;
- gs_strfreev char **domains = NULL;
- uint8_t *data;
- size_t n_data;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, &data, &n_data);
- if (r)
- return;
-
- str = g_string_new_len ((char *)data, n_data);
-
- /* Multiple domains sometimes stuffed into option 15 "Domain Name". */
- domains = g_strsplit (str->str, " ", 0);
- nm_gstring_prepare (&str);
-
- for (char **d = domains; *d; d++) {
- if (nm_utils_is_localhost (*d))
- return;
-
- g_string_append (nm_gstring_add_space_delimiter (str), *d);
- nm_ip4_config_add_domain (ip4_config, *d);
- }
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_DOMAIN_NAME,
- str->str);
+ nm_auto_free_gstring GString *str = NULL;
+ gs_strfreev char ** domains = NULL;
+ uint8_t * data;
+ size_t n_data;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, &data, &n_data);
+ if (r)
+ return;
+
+ str = g_string_new_len((char *) data, n_data);
+
+ /* Multiple domains sometimes stuffed into option 15 "Domain Name". */
+ domains = g_strsplit(str->str, " ", 0);
+ nm_gstring_prepare(&str);
+
+ for (char **d = domains; *d; d++) {
+ if (nm_utils_is_localhost(*d))
+ return;
+
+ g_string_append(nm_gstring_add_space_delimiter(str), *d);
+ nm_ip4_config_add_domain(ip4_config, *d);
+ }
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_DOMAIN_NAME,
+ str->str);
}
char **
-nm_dhcp_parse_search_list (guint8 *data, size_t n_data)
+nm_dhcp_parse_search_list(guint8 *data, size_t n_data)
{
- GPtrArray *array = NULL;
- guint8 *cache = data;
- size_t n_cache = 0;
+ GPtrArray *array = NULL;
+ guint8 * cache = data;
+ size_t n_cache = 0;
- for (;;) {
- nm_auto_free_gstring GString *domain = NULL;
+ for (;;) {
+ nm_auto_free_gstring GString *domain = NULL;
- nm_gstring_prepare (&domain);
+ nm_gstring_prepare(&domain);
- if (!lease_option_print_domain_name (domain, cache, &n_cache, &data, &n_data))
- break;
+ if (!lease_option_print_domain_name(domain, cache, &n_cache, &data, &n_data))
+ break;
- if (!array)
- array = g_ptr_array_new ();
+ if (!array)
+ array = g_ptr_array_new();
- g_ptr_array_add (array, g_string_free (domain, FALSE));
- domain = NULL;
- }
+ g_ptr_array_add(array, g_string_free(domain, FALSE));
+ domain = NULL;
+ }
- if (array) {
- g_ptr_array_add (array, NULL);
- return (char **) g_ptr_array_free (array, FALSE);
- } else
- return NULL;
+ if (array) {
+ g_ptr_array_add(array, NULL);
+ return (char **) g_ptr_array_free(array, FALSE);
+ } else
+ return NULL;
}
static void
-lease_parse_search_domains (NDhcp4ClientLease *lease,
- NMIP4Config *ip4_config,
- GHashTable *options)
+lease_parse_search_domains(NDhcp4ClientLease *lease, NMIP4Config *ip4_config, GHashTable *options)
{
- nm_auto_free_gstring GString *str = NULL;
- uint8_t *data;
- size_t n_data;
- gs_strfreev char **domains = NULL;
- guint i;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST, &data, &n_data);
- if (r)
- return;
-
- domains = nm_dhcp_parse_search_list (data, n_data);
- nm_gstring_prepare (&str);
-
- for (i = 0; domains && domains[i]; i++) {
- g_string_append (nm_gstring_add_space_delimiter (str), domains[i]);
- nm_ip4_config_add_search (ip4_config, domains[i]);
- }
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST,
- str->str);
+ nm_auto_free_gstring GString *str = NULL;
+ uint8_t * data;
+ size_t n_data;
+ gs_strfreev char ** domains = NULL;
+ guint i;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST, &data, &n_data);
+ if (r)
+ return;
+
+ domains = nm_dhcp_parse_search_list(data, n_data);
+ nm_gstring_prepare(&str);
+
+ for (i = 0; domains && domains[i]; i++) {
+ g_string_append(nm_gstring_add_space_delimiter(str), domains[i]);
+ nm_ip4_config_add_search(ip4_config, domains[i]);
+ }
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST,
+ str->str);
}
static void
-lease_parse_root_path (NDhcp4ClientLease *lease,
- GHashTable *options)
+lease_parse_root_path(NDhcp4ClientLease *lease, GHashTable *options)
{
- nm_auto_free_gstring GString *str = NULL;
- uint8_t *data;
- size_t n_data;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_ROOT_PATH, &data, &n_data);
- if (r)
- return;
-
- str = g_string_new_len ((char *)data, n_data);
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_ROOT_PATH,
- str->str);
+ nm_auto_free_gstring GString *str = NULL;
+ uint8_t * data;
+ size_t n_data;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROOT_PATH, &data, &n_data);
+ if (r)
+ return;
+
+ str = g_string_new_len((char *) data, n_data);
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_ROOT_PATH,
+ str->str);
}
static void
-lease_parse_wpad (NDhcp4ClientLease *lease,
- GHashTable *options)
+lease_parse_wpad(NDhcp4ClientLease *lease, GHashTable *options)
{
- gs_free char *wpad = NULL;
- uint8_t *data;
- size_t n_data;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, &data, &n_data);
- if (r)
- return;
-
- nm_utils_buf_utf8safe_escape ((char *)data, n_data, 0, &wpad);
- if (wpad == NULL)
- wpad = g_strndup ((char *)data, n_data);
-
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
- wpad);
+ gs_free char *wpad = NULL;
+ uint8_t * data;
+ size_t n_data;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
+ &data,
+ &n_data);
+ if (r)
+ return;
+
+ nm_utils_buf_utf8safe_escape((char *) data, n_data, 0, &wpad);
+ if (wpad == NULL)
+ wpad = g_strndup((char *) data, n_data);
+
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
+ wpad);
}
static void
-lease_parse_nis_domain (NDhcp4ClientLease *lease,
- NMIP4Config *ip4_config,
- GHashTable *options)
+lease_parse_nis_domain(NDhcp4ClientLease *lease, NMIP4Config *ip4_config, GHashTable *options)
{
- gs_free char *str_free = NULL;
- const char *str;
- uint8_t *data;
- size_t n_data;
- guint i;
- int r;
-
- r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, &data, &n_data);
- if (r)
- return;
-
- for (i = 0; i < n_data; i++) {
- if (!nm_is_ascii ((char) data[i]))
- return;
- }
-
- str = nm_strndup_a (300, (const char *) data, n_data, &str_free);
- nm_dhcp_option_add_option (options,
- _nm_dhcp_option_dhcp4_options,
- NM_DHCP_OPTION_DHCP4_NIS_DOMAIN,
- str);
- nm_ip4_config_set_nis_domain (ip4_config, str);
+ gs_free char *str_free = NULL;
+ const char * str;
+ uint8_t * data;
+ size_t n_data;
+ guint i;
+ int r;
+
+ r = n_dhcp4_client_lease_query(lease, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, &data, &n_data);
+ if (r)
+ return;
+
+ for (i = 0; i < n_data; i++) {
+ if (!nm_is_ascii((char) data[i]))
+ return;
+ }
+
+ str = nm_strndup_a(300, (const char *) data, n_data, &str_free);
+ nm_dhcp_option_add_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_NIS_DOMAIN,
+ str);
+ nm_ip4_config_set_nis_domain(ip4_config, str);
}
static void
-lease_parse_private_options (NDhcp4ClientLease *lease,
- GHashTable *options)
+lease_parse_private_options(NDhcp4ClientLease *lease, GHashTable *options)
{
- int i;
+ int i;
- for (i = NM_DHCP_OPTION_DHCP4_PRIVATE_224; i <= NM_DHCP_OPTION_DHCP4_PRIVATE_254; i++) {
- gs_free char *option_string = NULL;
- guint8 *data;
- gsize n_data;
- int r;
+ for (i = NM_DHCP_OPTION_DHCP4_PRIVATE_224; i <= NM_DHCP_OPTION_DHCP4_PRIVATE_254; i++) {
+ gs_free char *option_string = NULL;
+ guint8 * data;
+ gsize n_data;
+ int r;
- /* We manage private options 249 (private classless static route) and 252 (wpad) in a special
+ /* We manage private options 249 (private classless static route) and 252 (wpad) in a special
* way, so skip them as we here just manage all (the other) private options as raw data */
- if (NM_IN_SET (i, NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE,
- NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY))
- continue;
-
- r = n_dhcp4_client_lease_query (lease, i, &data, &n_data);
- if (r)
- continue;
-
- option_string = nm_utils_bin2hexstr_full (data, n_data, ':', FALSE, NULL);
- nm_dhcp_option_take_option (options,
- _nm_dhcp_option_dhcp4_options,
- i,
- g_steal_pointer (&option_string));
- }
+ if (NM_IN_SET(i,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY))
+ continue;
+
+ r = n_dhcp4_client_lease_query(lease, i, &data, &n_data);
+ if (r)
+ continue;
+
+ option_string = nm_utils_bin2hexstr_full(data, n_data, ':', FALSE, NULL);
+ nm_dhcp_option_take_option(options,
+ _nm_dhcp_option_dhcp4_options,
+ i,
+ g_steal_pointer(&option_string));
+ }
}
static NMIP4Config *
-lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
- const char *iface,
- int ifindex,
- NDhcp4ClientLease *lease,
- guint32 route_table,
- guint32 route_metric,
- GHashTable **out_options,
- GError **error)
+lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
+ const char * iface,
+ int ifindex,
+ NDhcp4ClientLease *lease,
+ guint32 route_table,
+ guint32 route_metric,
+ GHashTable ** out_options,
+ GError ** error)
{
- gs_unref_object NMIP4Config *ip4_config = NULL;
- gs_unref_hashtable GHashTable *options = NULL;
-
- g_return_val_if_fail (lease != NULL, NULL);
-
- ip4_config = nm_ip4_config_new (multi_idx, ifindex);
- options = nm_dhcp_option_create_options_dict ();
-
- if (!lease_parse_address (lease, ip4_config, options, error))
- return NULL;
-
- lease_parse_routes (lease, ip4_config, options, route_table, route_metric);
- lease_parse_address_list (lease, ip4_config, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, options);
- lease_parse_domainname (lease, ip4_config, options);
- lease_parse_search_domains (lease, ip4_config, options);
- lease_parse_mtu (lease, ip4_config, options);
- lease_parse_metered (lease, ip4_config, options);
-
- lease_parse_hostname (lease, options);
- lease_parse_ntps (lease, options);
- lease_parse_root_path (lease, options);
- lease_parse_wpad (lease, options);
- lease_parse_nis_domain (lease, ip4_config, options);
- lease_parse_address_list (lease, ip4_config, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options);
- lease_parse_address_list (lease, ip4_config, NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER, options);
- lease_parse_private_options (lease, options);
-
- NM_SET_OUT (out_options, g_steal_pointer (&options));
- return g_steal_pointer (&ip4_config);
+ gs_unref_object NMIP4Config *ip4_config = NULL;
+ gs_unref_hashtable GHashTable *options = NULL;
+
+ g_return_val_if_fail(lease != NULL, NULL);
+
+ ip4_config = nm_ip4_config_new(multi_idx, ifindex);
+ options = nm_dhcp_option_create_options_dict();
+
+ if (!lease_parse_address(lease, ip4_config, options, error))
+ return NULL;
+
+ lease_parse_routes(lease, ip4_config, options, route_table, route_metric);
+ lease_parse_address_list(lease, ip4_config, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, options);
+ lease_parse_domainname(lease, ip4_config, options);
+ lease_parse_search_domains(lease, ip4_config, options);
+ lease_parse_mtu(lease, ip4_config, options);
+ lease_parse_metered(lease, ip4_config, options);
+
+ lease_parse_hostname(lease, options);
+ lease_parse_ntps(lease, options);
+ lease_parse_root_path(lease, options);
+ lease_parse_wpad(lease, options);
+ lease_parse_nis_domain(lease, ip4_config, options);
+ lease_parse_address_list(lease, ip4_config, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options);
+ lease_parse_address_list(lease, ip4_config, NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER, options);
+ lease_parse_private_options(lease, options);
+
+ NM_SET_OUT(out_options, g_steal_pointer(&options));
+ return g_steal_pointer(&ip4_config);
}
/*****************************************************************************/
static void
-lease_save (NMDhcpNettools *self, NDhcp4ClientLease *lease, const char *lease_file)
+lease_save(NMDhcpNettools *self, NDhcp4ClientLease *lease, const char *lease_file)
{
- struct in_addr a_address;
- nm_auto_free_gstring GString *new_contents = NULL;
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
- gs_free_error GError *error = NULL;
+ struct in_addr a_address;
+ nm_auto_free_gstring GString *new_contents = NULL;
+ char sbuf[NM_UTILS_INET_ADDRSTRLEN];
+ gs_free_error GError *error = NULL;
- nm_assert (lease);
- nm_assert (lease_file);
+ nm_assert(lease);
+ nm_assert(lease_file);
- new_contents = g_string_new ("# This is private data. Do not parse.\n");
+ new_contents = g_string_new("# This is private data. Do not parse.\n");
- n_dhcp4_client_lease_get_yiaddr (lease, &a_address);
- if (a_address.s_addr == INADDR_ANY)
- return;
+ n_dhcp4_client_lease_get_yiaddr(lease, &a_address);
+ if (a_address.s_addr == INADDR_ANY)
+ return;
- g_string_append_printf (new_contents,
- "ADDRESS=%s\n", _nm_utils_inet4_ntop (a_address.s_addr, sbuf));
+ g_string_append_printf(new_contents,
+ "ADDRESS=%s\n",
+ _nm_utils_inet4_ntop(a_address.s_addr, sbuf));
- if (!g_file_set_contents (lease_file,
- new_contents->str,
- -1,
- &error))
- _LOGW ("error saving lease to %s: %s", lease_file, error->message);
+ if (!g_file_set_contents(lease_file, new_contents->str, -1, &error))
+ _LOGW("error saving lease to %s: %s", lease_file, error->message);
}
static void
-bound4_handle (NMDhcpNettools *self, NDhcp4ClientLease *lease, gboolean extended)
+bound4_handle(NMDhcpNettools *self, NDhcp4ClientLease *lease, gboolean extended)
{
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self);
- const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self));
- gs_unref_object NMIP4Config *ip4_config = NULL;
- gs_unref_hashtable GHashTable *options = NULL;
- GError *error = NULL;
-
- _LOGT ("lease available (%s)", extended ? "extended" : "new");
-
- ip4_config = lease_to_ip4_config (nm_dhcp_client_get_multi_idx (NM_DHCP_CLIENT (self)),
- iface,
- nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)),
- lease,
- nm_dhcp_client_get_route_table (NM_DHCP_CLIENT (self)),
- nm_dhcp_client_get_route_metric (NM_DHCP_CLIENT (self)),
- &options,
- &error);
- if (!ip4_config) {
- _LOGW ("%s", error->message);
- g_clear_error (&error);
- nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL);
- return;
- }
-
- nm_dhcp_option_add_requests_to_options (options, _nm_dhcp_option_dhcp4_options);
- lease_save (self, lease, priv->lease_file);
-
- nm_dhcp_client_set_state (NM_DHCP_CLIENT (self),
- extended ? NM_DHCP_STATE_EXTENDED : NM_DHCP_STATE_BOUND,
- NM_IP_CONFIG_CAST (ip4_config),
- options);
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
+ const char * iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
+ gs_unref_object NMIP4Config *ip4_config = NULL;
+ gs_unref_hashtable GHashTable *options = NULL;
+ GError * error = NULL;
+
+ _LOGT("lease available (%s)", extended ? "extended" : "new");
+
+ ip4_config = lease_to_ip4_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
+ iface,
+ nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
+ lease,
+ nm_dhcp_client_get_route_table(NM_DHCP_CLIENT(self)),
+ nm_dhcp_client_get_route_metric(NM_DHCP_CLIENT(self)),
+ &options,
+ &error);
+ if (!ip4_config) {
+ _LOGW("%s", error->message);
+ g_clear_error(&error);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ return;
+ }
+
+ nm_dhcp_option_add_requests_to_options(options, _nm_dhcp_option_dhcp4_options);
+ lease_save(self, lease, priv->lease_file);
+
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self),
+ extended ? NM_DHCP_STATE_EXTENDED : NM_DHCP_STATE_BOUND,
+ NM_IP_CONFIG_CAST(ip4_config),
+ options);
}
static void
-dhcp4_event_handle (NMDhcpNettools *self,
- NDhcp4ClientEvent *event)
+dhcp4_event_handle(NMDhcpNettools *self, NDhcp4ClientEvent *event)
{
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self);
- struct in_addr server_id;
- char addr_str[INET_ADDRSTRLEN];
- int r;
-
- _LOGT ("client event %d", event->event);
-
- switch (event->event) {
- case N_DHCP4_CLIENT_EVENT_OFFER:
- r = n_dhcp4_client_lease_get_server_identifier (event->offer.lease, &server_id);
- if (r) {
- _LOGW ("selecting lease failed: %d", r);
- return;
- }
-
- if (nm_dhcp_client_server_id_is_rejected (NM_DHCP_CLIENT (self), &server_id)) {
- _LOGD ("server-id %s is in the reject-list, ignoring",
- nm_utils_inet_ntop (AF_INET, &server_id, addr_str));
- return;
- }
-
- r = n_dhcp4_client_lease_select (event->offer.lease);
- if (r) {
- _LOGW ("selecting lease failed: %d", r);
- return;
- }
- break;
- case N_DHCP4_CLIENT_EVENT_RETRACTED:
- case N_DHCP4_CLIENT_EVENT_EXPIRED:
- nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_EXPIRE, NULL, NULL);
- break;
- case N_DHCP4_CLIENT_EVENT_CANCELLED:
- nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL);
- break;
- case N_DHCP4_CLIENT_EVENT_GRANTED:
- priv->lease = n_dhcp4_client_lease_ref (event->granted.lease);
- bound4_handle (self, event->granted.lease, FALSE);
- break;
- case N_DHCP4_CLIENT_EVENT_EXTENDED:
- bound4_handle (self, event->extended.lease, TRUE);
- break;
- case N_DHCP4_CLIENT_EVENT_DOWN:
- /* ignore down events, they are purely informational */
- break;
- case N_DHCP4_CLIENT_EVENT_LOG: {
- NMLogLevel nm_level;
-
- nm_level = nm_log_level_from_syslog (event->log.level);
- if (nm_logging_enabled (nm_level, LOGD_DHCP4)) {
- nm_log (nm_level, LOGD_DHCP4, NULL , NULL,
- "dhcp4 (%s): %s",
- nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)),
- event->log.message);
- }
- }
- break;
- default:
- _LOGW ("unhandled DHCP event %d", event->event);
- break;
- }
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
+ struct in_addr server_id;
+ char addr_str[INET_ADDRSTRLEN];
+ int r;
+
+ _LOGT("client event %d", event->event);
+
+ switch (event->event) {
+ case N_DHCP4_CLIENT_EVENT_OFFER:
+ r = n_dhcp4_client_lease_get_server_identifier(event->offer.lease, &server_id);
+ if (r) {
+ _LOGW("selecting lease failed: %d", r);
+ return;
+ }
+
+ if (nm_dhcp_client_server_id_is_rejected(NM_DHCP_CLIENT(self), &server_id)) {
+ _LOGD("server-id %s is in the reject-list, ignoring",
+ nm_utils_inet_ntop(AF_INET, &server_id, addr_str));
+ return;
+ }
+
+ r = n_dhcp4_client_lease_select(event->offer.lease);
+ if (r) {
+ _LOGW("selecting lease failed: %d", r);
+ return;
+ }
+ break;
+ case N_DHCP4_CLIENT_EVENT_RETRACTED:
+ case N_DHCP4_CLIENT_EVENT_EXPIRED:
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_EXPIRE, NULL, NULL);
+ break;
+ case N_DHCP4_CLIENT_EVENT_CANCELLED:
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ break;
+ case N_DHCP4_CLIENT_EVENT_GRANTED:
+ priv->lease = n_dhcp4_client_lease_ref(event->granted.lease);
+ bound4_handle(self, event->granted.lease, FALSE);
+ break;
+ case N_DHCP4_CLIENT_EVENT_EXTENDED:
+ bound4_handle(self, event->extended.lease, TRUE);
+ break;
+ case N_DHCP4_CLIENT_EVENT_DOWN:
+ /* ignore down events, they are purely informational */
+ break;
+ case N_DHCP4_CLIENT_EVENT_LOG:
+ {
+ NMLogLevel nm_level;
+
+ nm_level = nm_log_level_from_syslog(event->log.level);
+ if (nm_logging_enabled(nm_level, LOGD_DHCP4)) {
+ nm_log(nm_level,
+ LOGD_DHCP4,
+ NULL,
+ NULL,
+ "dhcp4 (%s): %s",
+ nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self)),
+ event->log.message);
+ }
+ } break;
+ default:
+ _LOGW("unhandled DHCP event %d", event->event);
+ break;
+ }
}
static gboolean
-dhcp4_event_cb (int fd,
- GIOCondition condition,
- gpointer data)
+dhcp4_event_cb(int fd, GIOCondition condition, gpointer data)
{
- NMDhcpNettools *self = data;
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self);
- NDhcp4ClientEvent *event;
- int r;
-
- r = n_dhcp4_client_dispatch (priv->client);
- if (r < 0) {
- /* FIXME: if any operation (e.g. send()) fails during the
+ NMDhcpNettools * self = data;
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
+ NDhcp4ClientEvent * event;
+ int r;
+
+ r = n_dhcp4_client_dispatch(priv->client);
+ if (r < 0) {
+ /* FIXME: if any operation (e.g. send()) fails during the
* dispatch, n-dhcp4 returns an error without arming timers
* or progressing state, so the only reasonable thing to do
* is to move to failed state so that the client will be
* restarted. Ideally n-dhcp4 should retry failed operations
* a predefined number of times (possibly infinite).
*/
- _LOGE ("error %d dispatching events", r);
- nm_clear_g_source_inst (&priv->event_source);
- nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL);
- return G_SOURCE_REMOVE;
- }
+ _LOGE("error %d dispatching events", r);
+ nm_clear_g_source_inst(&priv->event_source);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ return G_SOURCE_REMOVE;
+ }
- while (!n_dhcp4_client_pop_event (priv->client, &event) && event) {
- dhcp4_event_handle (self, event);
- }
+ while (!n_dhcp4_client_pop_event(priv->client, &event) && event) {
+ dhcp4_event_handle(self, event);
+ }
- return G_SOURCE_CONTINUE;
+ return G_SOURCE_CONTINUE;
}
static gboolean
-nettools_create (NMDhcpNettools *self,
- const char *dhcp_anycast_addr,
- GError **error)
+nettools_create(NMDhcpNettools *self, const char *dhcp_anycast_addr, GError **error)
{
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self);
- nm_auto (n_dhcp4_client_config_freep) NDhcp4ClientConfig *config = NULL;
- nm_auto (n_dhcp4_client_unrefp) NDhcp4Client *client = NULL;
- GBytes *hwaddr;
- GBytes *bcast_hwaddr;
- const uint8_t *hwaddr_arr;
- const uint8_t *bcast_hwaddr_arr;
- gsize hwaddr_len;
- gsize bcast_hwaddr_len;
- GBytes *client_id;
- gs_unref_bytes GBytes *client_id_new = NULL;
- const uint8_t *client_id_arr;
- size_t client_id_len;
- int r, fd, arp_type, transport;
-
- g_return_val_if_fail (!priv->client, FALSE);
-
- hwaddr = nm_dhcp_client_get_hw_addr (NM_DHCP_CLIENT (self));
- if ( !hwaddr
- || !(hwaddr_arr = g_bytes_get_data (hwaddr, &hwaddr_len))
- || (arp_type = nm_utils_arp_type_detect_from_hwaddrlen (hwaddr_len)) < 0) {
- nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "invalid MAC address");
- return FALSE;
- }
-
- bcast_hwaddr = nm_dhcp_client_get_broadcast_hw_addr (NM_DHCP_CLIENT (self));
- bcast_hwaddr_arr = g_bytes_get_data (bcast_hwaddr, &bcast_hwaddr_len);
-
- switch (arp_type) {
- case ARPHRD_ETHER:
- transport = N_DHCP4_TRANSPORT_ETHERNET;
- break;
- case ARPHRD_INFINIBAND:
- transport = N_DHCP4_TRANSPORT_INFINIBAND;
- break;
- default:
- nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "unsupported ARP type");
- return FALSE;
- }
-
- /* Note that we always set a client-id. In particular for infiniband that is necessary,
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
+ nm_auto(n_dhcp4_client_config_freep) NDhcp4ClientConfig *config = NULL;
+ nm_auto(n_dhcp4_client_unrefp) NDhcp4Client * client = NULL;
+ GBytes * hwaddr;
+ GBytes * bcast_hwaddr;
+ const uint8_t * hwaddr_arr;
+ const uint8_t * bcast_hwaddr_arr;
+ gsize hwaddr_len;
+ gsize bcast_hwaddr_len;
+ GBytes * client_id;
+ gs_unref_bytes GBytes *client_id_new = NULL;
+ const uint8_t * client_id_arr;
+ size_t client_id_len;
+ int r, fd, arp_type, transport;
+
+ g_return_val_if_fail(!priv->client, FALSE);
+
+ hwaddr = nm_dhcp_client_get_hw_addr(NM_DHCP_CLIENT(self));
+ if (!hwaddr || !(hwaddr_arr = g_bytes_get_data(hwaddr, &hwaddr_len))
+ || (arp_type = nm_utils_arp_type_detect_from_hwaddrlen(hwaddr_len)) < 0) {
+ nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "invalid MAC address");
+ return FALSE;
+ }
+
+ bcast_hwaddr = nm_dhcp_client_get_broadcast_hw_addr(NM_DHCP_CLIENT(self));
+ bcast_hwaddr_arr = g_bytes_get_data(bcast_hwaddr, &bcast_hwaddr_len);
+
+ switch (arp_type) {
+ case ARPHRD_ETHER:
+ transport = N_DHCP4_TRANSPORT_ETHERNET;
+ break;
+ case ARPHRD_INFINIBAND:
+ transport = N_DHCP4_TRANSPORT_INFINIBAND;
+ break;
+ default:
+ nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "unsupported ARP type");
+ return FALSE;
+ }
+
+ /* Note that we always set a client-id. In particular for infiniband that is necessary,
* see https://tools.ietf.org/html/rfc4390#section-2.1 . */
- client_id = nm_dhcp_client_get_client_id (NM_DHCP_CLIENT (self));
- if (!client_id) {
- client_id_new = nm_utils_dhcp_client_id_mac (arp_type, hwaddr_arr, hwaddr_len);
- client_id = client_id_new;
- }
-
- if ( !(client_id_arr = g_bytes_get_data (client_id, &client_id_len))
- || client_id_len < 2) {
-
- /* invalid client-ids are not expected. */
- nm_assert_not_reached ();
-
- nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "no valid IPv4 client-id");
- return FALSE;
- }
-
- r = n_dhcp4_client_config_new (&config);
- if (r) {
- set_error_nettools (error, r, "failed to create client-config");
- return FALSE;
- }
-
- n_dhcp4_client_config_set_ifindex (config, nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)));
- n_dhcp4_client_config_set_transport (config, transport);
- n_dhcp4_client_config_set_mac (config, hwaddr_arr, hwaddr_len);
- n_dhcp4_client_config_set_broadcast_mac (config, bcast_hwaddr_arr, bcast_hwaddr_len);
- r = n_dhcp4_client_config_set_client_id (config,
- client_id_arr,
- NM_MIN (client_id_len, 1 + _NM_SD_MAX_CLIENT_ID_LEN));
- if (r) {
- set_error_nettools (error, r, "failed to set client-id");
- return FALSE;
- }
-
- r = n_dhcp4_client_new (&client, config);
- if (r) {
- set_error_nettools (error, r, "failed to create client");
- return FALSE;
- }
-
- priv->client = client;
- client = NULL;
-
- n_dhcp4_client_set_log_level (priv->client, nm_log_level_to_syslog (nm_logging_get_level (LOGD_DHCP4)));
-
- n_dhcp4_client_get_fd (priv->client, &fd);
-
- priv->event_source = nm_g_unix_fd_source_new (fd,
- G_IO_IN,
- G_PRIORITY_DEFAULT,
- dhcp4_event_cb,
- self,
- NULL);
- g_source_attach (priv->event_source, NULL);
-
- return TRUE;
+ client_id = nm_dhcp_client_get_client_id(NM_DHCP_CLIENT(self));
+ if (!client_id) {
+ client_id_new = nm_utils_dhcp_client_id_mac(arp_type, hwaddr_arr, hwaddr_len);
+ client_id = client_id_new;
+ }
+
+ if (!(client_id_arr = g_bytes_get_data(client_id, &client_id_len)) || client_id_len < 2) {
+ /* invalid client-ids are not expected. */
+ nm_assert_not_reached();
+
+ nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "no valid IPv4 client-id");
+ return FALSE;
+ }
+
+ r = n_dhcp4_client_config_new(&config);
+ if (r) {
+ set_error_nettools(error, r, "failed to create client-config");
+ return FALSE;
+ }
+
+ n_dhcp4_client_config_set_ifindex(config, nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)));
+ n_dhcp4_client_config_set_transport(config, transport);
+ n_dhcp4_client_config_set_mac(config, hwaddr_arr, hwaddr_len);
+ n_dhcp4_client_config_set_broadcast_mac(config, bcast_hwaddr_arr, bcast_hwaddr_len);
+ r = n_dhcp4_client_config_set_client_id(config,
+ client_id_arr,
+ NM_MIN(client_id_len, 1 + _NM_SD_MAX_CLIENT_ID_LEN));
+ if (r) {
+ set_error_nettools(error, r, "failed to set client-id");
+ return FALSE;
+ }
+
+ r = n_dhcp4_client_new(&client, config);
+ if (r) {
+ set_error_nettools(error, r, "failed to create client");
+ return FALSE;
+ }
+
+ priv->client = client;
+ client = NULL;
+
+ n_dhcp4_client_set_log_level(priv->client,
+ nm_log_level_to_syslog(nm_logging_get_level(LOGD_DHCP4)));
+
+ n_dhcp4_client_get_fd(priv->client, &fd);
+
+ priv->event_source =
+ nm_g_unix_fd_source_new(fd, G_IO_IN, G_PRIORITY_DEFAULT, dhcp4_event_cb, self, NULL);
+ g_source_attach(priv->event_source, NULL);
+
+ return TRUE;
}
static gboolean
-_accept (NMDhcpClient *client,
- GError **error)
+_accept(NMDhcpClient *client, GError **error)
{
- NMDhcpNettools *self = NM_DHCP_NETTOOLS (client);
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self);
- int r;
+ NMDhcpNettools * self = NM_DHCP_NETTOOLS(client);
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
+ int r;
- g_return_val_if_fail (priv->lease, FALSE);
+ g_return_val_if_fail(priv->lease, FALSE);
- _LOGT ("accept");
+ _LOGT("accept");
- r = n_dhcp4_client_lease_accept (priv->lease);
- if (r) {
- set_error_nettools (error, r, "failed to accept lease");
- return FALSE;
- }
+ r = n_dhcp4_client_lease_accept(priv->lease);
+ if (r) {
+ set_error_nettools(error, r, "failed to accept lease");
+ return FALSE;
+ }
- priv->lease = n_dhcp4_client_lease_unref (priv->lease);
+ priv->lease = n_dhcp4_client_lease_unref(priv->lease);
- return TRUE;
+ return TRUE;
}
static gboolean
-decline (NMDhcpClient *client,
- const char *error_message,
- GError **error)
+decline(NMDhcpClient *client, const char *error_message, GError **error)
{
- NMDhcpNettools *self = NM_DHCP_NETTOOLS (client);
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self);
- int r;
+ NMDhcpNettools * self = NM_DHCP_NETTOOLS(client);
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
+ int r;
- g_return_val_if_fail (priv->lease, FALSE);
+ g_return_val_if_fail(priv->lease, FALSE);
- _LOGT ("dhcp4-client: decline");
+ _LOGT("dhcp4-client: decline");
- r = n_dhcp4_client_lease_decline (priv->lease, error_message);
- if (r) {
- set_error_nettools (error, r, "failed to decline lease");
- return FALSE;
- }
+ r = n_dhcp4_client_lease_decline(priv->lease, error_message);
+ if (r) {
+ set_error_nettools(error, r, "failed to decline lease");
+ return FALSE;
+ }
- priv->lease = n_dhcp4_client_lease_unref (priv->lease);
+ priv->lease = n_dhcp4_client_lease_unref(priv->lease);
- return TRUE;
+ return TRUE;
}
static guint8
-fqdn_flags_to_wire (NMDhcpHostnameFlags flags)
+fqdn_flags_to_wire(NMDhcpHostnameFlags flags)
{
- guint r = 0;
+ guint r = 0;
- /* RFC 4702 section 2.1 */
- if (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE)
- r |= (1 << 0);
- if (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED)
- r |= (1 << 2);
- if (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE)
- r |= (1 << 3);
+ /* RFC 4702 section 2.1 */
+ if (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE)
+ r |= (1 << 0);
+ if (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED)
+ r |= (1 << 2);
+ if (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE)
+ r |= (1 << 3);
- return r;
+ return r;
}
static gboolean
-ip4_start (NMDhcpClient *client,
- const char *dhcp_anycast_addr,
- const char *last_ip4_address,
- GError **error)
+ip4_start(NMDhcpClient *client,
+ const char * dhcp_anycast_addr,
+ const char * last_ip4_address,
+ GError ** error)
{
- nm_auto (n_dhcp4_client_probe_config_freep) NDhcp4ClientProbeConfig *config = NULL;
- NMDhcpNettools *self = NM_DHCP_NETTOOLS (client);
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self);
- gs_free char *lease_file = NULL;
- struct in_addr last_addr = { 0 };
- const char *hostname;
- const char *mud_url;
- GBytes *vendor_class_identifier;
- int r, i;
-
- g_return_val_if_fail (!priv->probe, FALSE);
-
- if (!nettools_create (self, dhcp_anycast_addr, error))
- return FALSE;
-
- r = n_dhcp4_client_probe_config_new (&config);
- if (r) {
- set_error_nettools (error, r, "failed to create dhcp-client-probe-config");
- return FALSE;
- }
-
- /*
+ nm_auto(n_dhcp4_client_probe_config_freep) NDhcp4ClientProbeConfig *config = NULL;
+ NMDhcpNettools * self = NM_DHCP_NETTOOLS(client);
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
+ gs_free char * lease_file = NULL;
+ struct in_addr last_addr = {0};
+ const char * hostname;
+ const char * mud_url;
+ GBytes * vendor_class_identifier;
+ int r, i;
+
+ g_return_val_if_fail(!priv->probe, FALSE);
+
+ if (!nettools_create(self, dhcp_anycast_addr, error))
+ return FALSE;
+
+ r = n_dhcp4_client_probe_config_new(&config);
+ if (r) {
+ set_error_nettools(error, r, "failed to create dhcp-client-probe-config");
+ return FALSE;
+ }
+
+ /*
* FIXME:
* Select, or configure, a reasonable start delay, to protect poor servers being flooded.
*/
- n_dhcp4_client_probe_config_set_start_delay (config, 1);
-
- nm_dhcp_utils_get_leasefile_path (AF_INET,
- "internal",
- nm_dhcp_client_get_iface (client),
- nm_dhcp_client_get_uuid (client),
- &lease_file);
-
- if (last_ip4_address)
- inet_pton (AF_INET, last_ip4_address, &last_addr);
- else {
- /*
+ n_dhcp4_client_probe_config_set_start_delay(config, 1);
+
+ nm_dhcp_utils_get_leasefile_path(AF_INET,
+ "internal",
+ nm_dhcp_client_get_iface(client),
+ nm_dhcp_client_get_uuid(client),
+ &lease_file);
+
+ if (last_ip4_address)
+ inet_pton(AF_INET, last_ip4_address, &last_addr);
+ else {
+ /*
* TODO: we stick to the systemd-networkd lease file format. Quite easy for now to
* just use the functions in systemd code. Anyway, as in the end we just use the
* ip address from all the options found in the lease, write a function that parses
* the lease file just for the assigned address and returns it in &last_address.
* Then drop reference to systemd-networkd structures and functions.
*/
- nm_auto (sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
-
- dhcp_lease_load (&lease, lease_file);
- if (lease)
- sd_dhcp_lease_get_address (lease, &last_addr);
- }
-
- if (last_addr.s_addr) {
- n_dhcp4_client_probe_config_set_requested_ip (config, last_addr);
- n_dhcp4_client_probe_config_set_init_reboot (config, TRUE);
- }
-
- /* Add requested options */
- for (i = 0; _nm_dhcp_option_dhcp4_options[i].name; i++) {
- if (_nm_dhcp_option_dhcp4_options[i].include) {
- nm_assert (_nm_dhcp_option_dhcp4_options[i].option_num <= 255);
- n_dhcp4_client_probe_config_request_option (config,
- _nm_dhcp_option_dhcp4_options[i].option_num);
- }
- }
-
- mud_url = nm_dhcp_client_get_mud_url (client);
- if (mud_url) {
- r = n_dhcp4_client_probe_config_append_option (config,
- NM_DHCP_OPTION_DHCP4_MUD_URL,
- mud_url,
- strlen (mud_url));
- if (r) {
- set_error_nettools (error, r, "failed to set MUD URL");
- return FALSE;
- }
- }
- hostname = nm_dhcp_client_get_hostname (client);
- if (hostname) {
- if (nm_dhcp_client_get_use_fqdn (client)) {
- uint8_t buffer[255];
- NMDhcpHostnameFlags flags;
- size_t fqdn_len;
-
- flags = nm_dhcp_client_get_hostname_flags (client);
- buffer[0] = fqdn_flags_to_wire (flags);
- buffer[1] = 0; /* RCODE1 (deprecated) */
- buffer[2] = 0; /* RCODE2 (deprecated) */
-
- if (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED) {
- r = nm_sd_dns_name_to_wire_format (hostname,
- buffer + 3,
- sizeof (buffer) - 3,
- FALSE);
- if (r <= 0) {
- if (r < 0)
- nm_utils_error_set_errno (error, r, "failed to convert DHCP FQDN: %s");
- else
- nm_utils_error_set (error, r, "failed to convert DHCP FQDN");
- return FALSE;
- }
- fqdn_len = r;
- } else {
- fqdn_len = strlen (hostname);
- if (fqdn_len > sizeof (buffer) - 3) {
- nm_utils_error_set (error, r, "failed to set DHCP FQDN: name too long");
- return FALSE;
- }
- memcpy (buffer + 3, hostname, fqdn_len);
- }
-
- r = n_dhcp4_client_probe_config_append_option (config,
- NM_DHCP_OPTION_DHCP4_CLIENT_FQDN,
- buffer,
- 3 + fqdn_len);
- if (r) {
- set_error_nettools (error, r, "failed to set DHCP FQDN");
- return FALSE;
- }
- } else {
- r = n_dhcp4_client_probe_config_append_option (config,
- NM_DHCP_OPTION_DHCP4_HOST_NAME,
- hostname,
- strlen (hostname));
- if (r) {
- set_error_nettools (error, r, "failed to set DHCP hostname");
- return FALSE;
- }
- }
- }
-
- vendor_class_identifier = nm_dhcp_client_get_vendor_class_identifier (client);
- if (vendor_class_identifier) {
- const void *option_data;
- gsize option_size;
-
- option_data = g_bytes_get_data (vendor_class_identifier, &option_size);
- nm_assert (option_data);
- nm_assert (option_size <= 255);
-
- r = n_dhcp4_client_probe_config_append_option (config,
- NM_DHCP_OPTION_DHCP4_VENDOR_CLASS_IDENTIFIER,
- option_data,
- option_size);
- if (r) {
- set_error_nettools (error, r, "failed to set vendor class identifier");
- return FALSE;
- }
- }
-
- g_free (priv->lease_file);
- priv->lease_file = g_steal_pointer (&lease_file);
-
- r = n_dhcp4_client_probe (priv->client, &priv->probe, config);
- if (r) {
- set_error_nettools (error, r, "failed to start DHCP client");
- return FALSE;
- }
-
- _LOGT ("dhcp-client4: start %p", (gpointer) priv->client);
-
- nm_dhcp_client_start_timeout (client);
- return TRUE;
+ nm_auto(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
+
+ dhcp_lease_load(&lease, lease_file);
+ if (lease)
+ sd_dhcp_lease_get_address(lease, &last_addr);
+ }
+
+ if (last_addr.s_addr) {
+ n_dhcp4_client_probe_config_set_requested_ip(config, last_addr);
+ n_dhcp4_client_probe_config_set_init_reboot(config, TRUE);
+ }
+
+ /* Add requested options */
+ for (i = 0; _nm_dhcp_option_dhcp4_options[i].name; i++) {
+ if (_nm_dhcp_option_dhcp4_options[i].include) {
+ nm_assert(_nm_dhcp_option_dhcp4_options[i].option_num <= 255);
+ n_dhcp4_client_probe_config_request_option(config,
+ _nm_dhcp_option_dhcp4_options[i].option_num);
+ }
+ }
+
+ mud_url = nm_dhcp_client_get_mud_url(client);
+ if (mud_url) {
+ r = n_dhcp4_client_probe_config_append_option(config,
+ NM_DHCP_OPTION_DHCP4_MUD_URL,
+ mud_url,
+ strlen(mud_url));
+ if (r) {
+ set_error_nettools(error, r, "failed to set MUD URL");
+ return FALSE;
+ }
+ }
+ hostname = nm_dhcp_client_get_hostname(client);
+ if (hostname) {
+ if (nm_dhcp_client_get_use_fqdn(client)) {
+ uint8_t buffer[255];
+ NMDhcpHostnameFlags flags;
+ size_t fqdn_len;
+
+ flags = nm_dhcp_client_get_hostname_flags(client);
+ buffer[0] = fqdn_flags_to_wire(flags);
+ buffer[1] = 0; /* RCODE1 (deprecated) */
+ buffer[2] = 0; /* RCODE2 (deprecated) */
+
+ if (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED) {
+ r = nm_sd_dns_name_to_wire_format(hostname, buffer + 3, sizeof(buffer) - 3, FALSE);
+ if (r <= 0) {
+ if (r < 0)
+ nm_utils_error_set_errno(error, r, "failed to convert DHCP FQDN: %s");
+ else
+ nm_utils_error_set(error, r, "failed to convert DHCP FQDN");
+ return FALSE;
+ }
+ fqdn_len = r;
+ } else {
+ fqdn_len = strlen(hostname);
+ if (fqdn_len > sizeof(buffer) - 3) {
+ nm_utils_error_set(error, r, "failed to set DHCP FQDN: name too long");
+ return FALSE;
+ }
+ memcpy(buffer + 3, hostname, fqdn_len);
+ }
+
+ r = n_dhcp4_client_probe_config_append_option(config,
+ NM_DHCP_OPTION_DHCP4_CLIENT_FQDN,
+ buffer,
+ 3 + fqdn_len);
+ if (r) {
+ set_error_nettools(error, r, "failed to set DHCP FQDN");
+ return FALSE;
+ }
+ } else {
+ r = n_dhcp4_client_probe_config_append_option(config,
+ NM_DHCP_OPTION_DHCP4_HOST_NAME,
+ hostname,
+ strlen(hostname));
+ if (r) {
+ set_error_nettools(error, r, "failed to set DHCP hostname");
+ return FALSE;
+ }
+ }
+ }
+
+ vendor_class_identifier = nm_dhcp_client_get_vendor_class_identifier(client);
+ if (vendor_class_identifier) {
+ const void *option_data;
+ gsize option_size;
+
+ option_data = g_bytes_get_data(vendor_class_identifier, &option_size);
+ nm_assert(option_data);
+ nm_assert(option_size <= 255);
+
+ r = n_dhcp4_client_probe_config_append_option(config,
+ NM_DHCP_OPTION_DHCP4_VENDOR_CLASS_IDENTIFIER,
+ option_data,
+ option_size);
+ if (r) {
+ set_error_nettools(error, r, "failed to set vendor class identifier");
+ return FALSE;
+ }
+ }
+
+ g_free(priv->lease_file);
+ priv->lease_file = g_steal_pointer(&lease_file);
+
+ r = n_dhcp4_client_probe(priv->client, &priv->probe, config);
+ if (r) {
+ set_error_nettools(error, r, "failed to start DHCP client");
+ return FALSE;
+ }
+
+ _LOGT("dhcp-client4: start %p", (gpointer) priv->client);
+
+ nm_dhcp_client_start_timeout(client);
+ return TRUE;
}
static void
-stop (NMDhcpClient *client,
- gboolean release)
+stop(NMDhcpClient *client, gboolean release)
{
- NMDhcpNettools *self = NM_DHCP_NETTOOLS (client);
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self);
+ NMDhcpNettools * self = NM_DHCP_NETTOOLS(client);
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
- NM_DHCP_CLIENT_CLASS (nm_dhcp_nettools_parent_class)->stop (client, release);
+ NM_DHCP_CLIENT_CLASS(nm_dhcp_nettools_parent_class)->stop(client, release);
- _LOGT ("dhcp-client4: stop %p",
- (gpointer) priv->client);
+ _LOGT("dhcp-client4: stop %p", (gpointer) priv->client);
- priv->probe = n_dhcp4_client_probe_free (priv->probe);
+ priv->probe = n_dhcp4_client_probe_free(priv->probe);
}
/*****************************************************************************/
static void
-nm_dhcp_nettools_init (NMDhcpNettools *self)
-{
-}
+nm_dhcp_nettools_init(NMDhcpNettools *self)
+{}
static void
-dispose (GObject *object)
+dispose(GObject *object)
{
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (object);
+ NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(object);
- nm_clear_g_free (&priv->lease_file);
- nm_clear_g_source_inst (&priv->event_source);
- nm_clear_pointer (&priv->lease, n_dhcp4_client_lease_unref);
- nm_clear_pointer (&priv->probe, n_dhcp4_client_probe_free);
- nm_clear_pointer (&priv->client, n_dhcp4_client_unref);
+ nm_clear_g_free(&priv->lease_file);
+ nm_clear_g_source_inst(&priv->event_source);
+ nm_clear_pointer(&priv->lease, n_dhcp4_client_lease_unref);
+ nm_clear_pointer(&priv->probe, n_dhcp4_client_probe_free);
+ nm_clear_pointer(&priv->client, n_dhcp4_client_unref);
- G_OBJECT_CLASS (nm_dhcp_nettools_parent_class)->dispose (object);
+ G_OBJECT_CLASS(nm_dhcp_nettools_parent_class)->dispose(object);
}
static void
-nm_dhcp_nettools_class_init (NMDhcpNettoolsClass *class)
+nm_dhcp_nettools_class_init(NMDhcpNettoolsClass *class)
{
- NMDhcpClientClass *client_class = NM_DHCP_CLIENT_CLASS (class);
- GObjectClass *object_class = G_OBJECT_CLASS (class);
+ NMDhcpClientClass *client_class = NM_DHCP_CLIENT_CLASS(class);
+ GObjectClass * object_class = G_OBJECT_CLASS(class);
- object_class->dispose = dispose;
+ object_class->dispose = dispose;
- client_class->ip4_start = ip4_start;
- client_class->accept = _accept;
- client_class->decline = decline;
- client_class->stop = stop;
+ client_class->ip4_start = ip4_start;
+ client_class->accept = _accept;
+ client_class->decline = decline;
+ client_class->stop = stop;
}
const NMDhcpClientFactory _nm_dhcp_client_factory_nettools = {
- .name = "nettools",
- .get_type = nm_dhcp_nettools_get_type,
- .experimental = TRUE,
+ .name = "nettools",
+ .get_type = nm_dhcp_nettools_get_type,
+ .experimental = TRUE,
};