Ejemplo n.º 1
0
static void test_discover_message(sd_event *e) {
        sd_dhcp_client *client;
        int res, r;

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        r = sd_dhcp_client_new(&client, false);
        assert_se(r >= 0);
        assert_se(client);

        r = sd_dhcp_client_attach_event(client, e, 0);
        assert_se(r >= 0);

        assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0);
        assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);

        assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);

        callback_recv = test_discover_message_verify;

        res = sd_dhcp_client_start(client);

        assert_se(IN_SET(res, 0, -EINPROGRESS));

        sd_event_run(e, (uint64_t) -1);

        sd_dhcp_client_stop(client);
        sd_dhcp_client_unref(client);

        test_fd[1] = safe_close(test_fd[1]);

        callback_recv = NULL;
}
Ejemplo n.º 2
0
static void test_addr_acq(sd_event *e) {
        usec_t time_now = now(CLOCK_MONOTONIC);
        sd_dhcp_client *client;
        int res, r;

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        r = sd_dhcp_client_new(&client);
        assert_se(r >= 0);
        assert_se(client);

        r = sd_dhcp_client_attach_event(client, e, 0);
        assert_se(r >= 0);

        assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
        assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);

        assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e)
                >= 0);

        callback_recv = test_addr_acq_recv_discover;

        assert_se(sd_event_add_time(e, &test_hangcheck,
                                    CLOCK_MONOTONIC,
                                    time_now + 2 * USEC_PER_SEC, 0,
                                    test_dhcp_hangcheck, NULL) >= 0);

        res = sd_dhcp_client_start(client);
        assert_se(res == 0 || res == -EINPROGRESS);

        sd_event_loop(e);

        test_hangcheck = sd_event_source_unref(test_hangcheck);

        sd_dhcp_client_set_callback(client, NULL, NULL);
        sd_dhcp_client_stop(client);
        sd_dhcp_client_unref(client);

        test_fd[1] = safe_close(test_fd[1]);

        callback_recv = NULL;
        xid = 0;
}
Ejemplo n.º 3
0
static void test_addr_acq(sd_event *e) {
        usec_t time_now = now(clock_boottime_or_monotonic());
        sd_dhcp_client *client;
        int res, r;

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        r = sd_dhcp_client_new(&client, false);
        assert_se(r >= 0);
        assert_se(client);

        r = sd_dhcp_client_attach_event(client, e, 0);
        assert_se(r >= 0);

        assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0);
        assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);

        assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0);

        callback_recv = test_addr_acq_recv_discover;

        assert_se(sd_event_add_time(e, &test_hangcheck,
                                    clock_boottime_or_monotonic(),
                                    time_now + 2 * USEC_PER_SEC, 0,
                                    test_dhcp_hangcheck, NULL) >= 0);

        res = sd_dhcp_client_start(client);
        assert_se(IN_SET(res, 0, -EINPROGRESS));

        assert_se(sd_event_loop(e) >= 0);

        test_hangcheck = sd_event_source_unref(test_hangcheck);

        assert_se(sd_dhcp_client_set_callback(client, NULL, NULL) >= 0);
        assert_se(sd_dhcp_client_stop(client) >= 0);
        sd_dhcp_client_unref(client);

        test_fd[1] = safe_close(test_fd[1]);

        callback_recv = NULL;
        xid = 0;
}
Ejemplo n.º 4
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);

        if (!link->dhcp_client) {
                r = sd_dhcp_client_new(&link->dhcp_client);
                if (r < 0)
                        return r;
        }

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return r;

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_use_mtu) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_INTERFACE_MTU);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_use_routes) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return r;
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                if (r < 0)
                        return r;
        }

        /* Always acquire the timezone and NTP */
        r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE);
        if (r < 0)
                return r;

        r = dhcp4_set_hostname(link);
        if (r < 0)
                return r;

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_client_port) {
                r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
                if (r < 0)
                        return r;
        }

        switch (link->network->dhcp_client_identifier) {
        case DHCP_CLIENT_ID_DUID: {
                /* If configured, apply user specified DUID and/or IAID */
                const DUID *duid = link_duid(link);

                r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
                                                 link->network->iaid,
                                                 duid->type,
                                                 duid->raw_data_len > 0 ? duid->raw_data : NULL,
                                                 duid->raw_data_len);
                if (r < 0)
                        return r;
                break;
        }
        case DHCP_CLIENT_ID_MAC:
                r = sd_dhcp_client_set_client_id(link->dhcp_client,
                                                 ARPHRD_ETHER,
                                                 (const uint8_t *) &link->mac,
                                                 sizeof(link->mac));
                if (r < 0)
                        return r;
                break;
        default:
                assert_not_reached("Unknown client identifier type.");
        }

        return 0;
}
Ejemplo n.º 5
0
static gboolean
ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address)
{
	NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client);
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);
	const char *iface = nm_dhcp_client_get_iface (client);
	const GByteArray *hwaddr;
	sd_dhcp_lease *lease = NULL;
	GBytes *override_client_id;
	const uint8_t *client_id = NULL;
	size_t client_id_len = 0;
	struct in_addr last_addr = { 0 };
	const char *hostname, *fqdn;
	int r, i;
	gboolean success = FALSE;
	guint16 arp_type;

	g_assert (priv->client4 == NULL);
	g_assert (priv->client6 == NULL);

	g_free (priv->lease_file);
	priv->lease_file = get_leasefile_path (iface, nm_dhcp_client_get_uuid (client), FALSE);

	r = sd_dhcp_client_new (&priv->client4);
	if (r < 0) {
		_LOGW ("failed to create client (%d)", r);
		return FALSE;
	}

	_LOGT ("dhcp-client4: set %p", priv->client4);

	r = sd_dhcp_client_attach_event (priv->client4, NULL, 0);
	if (r < 0) {
		_LOGW ("failed to attach event (%d)", r);
		goto error;
	}

	hwaddr = nm_dhcp_client_get_hw_addr (client);
	if (hwaddr) {
		arp_type= get_arp_type (hwaddr);
		if (arp_type == ARPHRD_NONE) {
			_LOGW ("failed to determine ARP type");
			goto error;
		}

		r = sd_dhcp_client_set_mac (priv->client4,
		                            hwaddr->data,
		                            hwaddr->len,
		                            arp_type);
		if (r < 0) {
			_LOGW ("failed to set MAC address (%d)", r);
			goto error;
		}
	}

	r = sd_dhcp_client_set_index (priv->client4, nm_dhcp_client_get_ifindex (client));
	if (r < 0) {
		_LOGW ("failed to set ifindex (%d)", r);
		goto error;
	}

	r = sd_dhcp_client_set_callback (priv->client4, dhcp_event_cb, client);
	if (r < 0) {
		_LOGW ("failed to set callback (%d)", r);
		goto error;
	}

	r = sd_dhcp_client_set_request_broadcast (priv->client4, true);
	if (r < 0) {
		_LOGW ("failed to enable broadcast mode (%d)", r);
		goto error;
	}

	dhcp_lease_load (&lease, priv->lease_file);

	if (last_ip4_address)
		inet_pton (AF_INET, last_ip4_address, &last_addr);
	else if (lease)
		sd_dhcp_lease_get_address (lease, &last_addr);

	if (last_addr.s_addr) {
		r = sd_dhcp_client_set_request_address (priv->client4, &last_addr);
		if (r < 0) {
			_LOGW ("failed to set last IPv4 address (%d)", r);
			goto error;
		}
	}

	override_client_id = nm_dhcp_client_get_client_id (client);
	if (override_client_id) {
		client_id = g_bytes_get_data (override_client_id, &client_id_len);
		g_assert (client_id && client_id_len);
		sd_dhcp_client_set_client_id (priv->client4,
		                              client_id[0],
		                              client_id + 1,
		                              client_id_len - 1);
	} else if (lease) {
		r = sd_dhcp_lease_get_client_id (lease, (const void **) &client_id, &client_id_len);
		if (r == 0 && client_id_len) {
			sd_dhcp_client_set_client_id (priv->client4,
			                              client_id[0],
			                              client_id + 1,
			                              client_id_len - 1);
			_save_client_id (NM_DHCP_SYSTEMD (client),
			                 client_id[0],
			                 client_id + 1,
			                 client_id_len - 1);
		}
	}


	/* Add requested options */
	for (i = 0; dhcp4_requests[i].name; i++) {
		if (dhcp4_requests[i].include)
			sd_dhcp_client_set_request_option (priv->client4, dhcp4_requests[i].num);
	}

	hostname = nm_dhcp_client_get_hostname (client);
	if (hostname) {
		char *prefix, *dot;

		prefix = strdup (hostname);
		dot = strchr (prefix, '.');
		/* get rid of the domain */
		if (dot)
			*dot = '\0';

		r = sd_dhcp_client_set_hostname (priv->client4, prefix);
		free (prefix);

		if (r < 0) {
			_LOGW ("failed to set DHCP hostname (%d)", r);
			goto error;
		}
	}

	fqdn = nm_dhcp_client_get_fqdn (client);
	if (fqdn) {
		r = sd_dhcp_client_set_hostname (priv->client4, fqdn);
		if (r < 0) {
			_LOGW ("failed to set DHCP FQDN (%d)", r);
			goto error;
		}
	}

	r = sd_dhcp_client_start (priv->client4);
	if (r < 0) {
		_LOGW ("failed to start client (%d)", r);
		goto error;
	}

	nm_dhcp_client_start_timeout (client);

	success = TRUE;

error:
	sd_dhcp_lease_unref (lease);
	if (!success)
		priv->client4 = sd_dhcp_client_unref (priv->client4);
	return success;
}
Ejemplo n.º 6
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);

        r = sd_dhcp_client_new(&link->dhcp_client);
        if (r < 0)
                return r;

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return r;

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_mtu) {
             r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                   DHCP_OPTION_INTERFACE_MTU);
             if (r < 0)
                return r;
        }

        if (link->network->dhcp_routes) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return r;
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_sendhost) {
                _cleanup_free_ char *hostname = NULL;
                const char *hn = NULL;

                if (!link->network->hostname)  {
                        hostname = gethostname_malloc();
                        if (!hostname)
                                return -ENOMEM;

                        hn = hostname;
                } else
                        hn = link->network->hostname;

                if (!is_localhost(hn)) {
                        r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
                        if (r < 0)
                                return r;
                }
        }

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return r;
        }

        switch (link->network->dhcp_client_identifier) {
        case DHCP_CLIENT_ID_DUID:
                /* Library defaults to this. */
                break;
        case DHCP_CLIENT_ID_MAC:
                r = sd_dhcp_client_set_client_id(link->dhcp_client,
                                                 ARPHRD_ETHER,
                                                 (const uint8_t *) &link->mac,
                                                 sizeof (link->mac));
                if (r < 0)
                        return r;
                break;
        default:
                assert_not_reached("Unknown client identifier type.");
        }

        return 0;
}
Ejemplo n.º 7
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);

        if (!link->dhcp_client) {
                r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
                if (r == -ENOMEM)
                        return log_oom();
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to create DHCP4 client: %m");
        }

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to attach event: %m");

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m");

        r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex);
        if (r < 0)
                return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set ifindex: %m");

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set callback: %m");

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for broadcast: %m");

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MTU: %m");
        }

        if (link->network->dhcp_use_mtu) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_INTERFACE_MTU);
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for MTU: %m");
        }

        /* NOTE: even if this variable is called "use", it also "sends" PRL
         * options, maybe there should be a different configuration variable
         * to send or not route options?. */
        /* NOTE: when using Anonymize=yes, routes PRL options are sent
         * by default, so they don't need to be added here. */
        if (link->network->dhcp_use_routes && !link->network->dhcp_anonymize) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for static route: %m");

                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for classless static route: %m");
        }

        if (link->network->dhcp_use_ntp) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER);
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for NTP 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)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for timezone: %m");
        }

        r = dhcp4_set_hostname(link);
        if (r < 0)
                return r;

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set vendor class identifier: %m");
        }

        if (link->network->dhcp_user_class) {
                r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class);
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m");
        }

        if (link->network->dhcp_client_port) {
                r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
                if (r < 0)
                        return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set listen port: %m");
        }

        return dhcp4_set_client_identifier(link);
}
Ejemplo n.º 8
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);

        if (!link->dhcp_client) {
                r = sd_dhcp_client_new(&link->dhcp_client);
                if (r < 0)
                        return r;
        }

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return r;

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_use_mtu) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_INTERFACE_MTU);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_use_routes) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return r;
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                if (r < 0)
                        return r;
        }

        /* Always acquire the timezone and NTP */
        r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE);
        if (r < 0)
                return r;

        if (link->network->dhcp_send_hostname) {
                _cleanup_free_ char *hostname = NULL;
                const char *hn = NULL;

                if (!link->network->dhcp_hostname) {
                        hostname = gethostname_malloc();
                        if (!hostname)
                                return -ENOMEM;

                        hn = hostname;
                } else
                        hn = link->network->dhcp_hostname;

                if (!is_localhost(hn)) {
                        r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
                        if (r < 0)
                                return r;
                }
        }

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return r;
        }

        switch (link->network->dhcp_client_identifier) {
        case DHCP_CLIENT_ID_DUID:
                /* If configured, apply user specified DUID and/or IAID */
                r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
                                                 link->network->iaid_value,
                                                 link->manager->dhcp_duid_len,
                                                 &link->manager->dhcp_duid);
                if (r < 0)
                        return r;
                break;
        case DHCP_CLIENT_ID_MAC:
                r = sd_dhcp_client_set_client_id(link->dhcp_client,
                                                 ARPHRD_ETHER,
                                                 (const uint8_t *) &link->mac,
                                                 sizeof (link->mac));
                if (r < 0)
                        return r;
                break;
        default:
                assert_not_reached("Unknown client identifier type.");
        }

        return 0;
}
Ejemplo n.º 9
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4));

        r = sd_dhcp_client_new(&link->dhcp_client);
        if (r < 0)
                return r;

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return r;

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_mtu) {
             r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                   DHCP_OPTION_INTERFACE_MTU);
             if (r < 0)
                return r;
        }

        if (link->network->dhcp_routes) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return r;
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                        if (r < 0)
                                return r;
        }

        if (link->network->dhcp_sendhost) {
                _cleanup_free_ char *hostname = NULL;

                hostname = gethostname_malloc();
                if (!hostname)
                        return -ENOMEM;

                if (!is_localhost(hostname)) {
                        r = sd_dhcp_client_set_hostname(link->dhcp_client,
                                                        hostname);
                        if (r < 0)
                                return r;
                }
        }

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return r;
        }

        return 0;
}
Ejemplo n.º 10
0
static gboolean
ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address)
{
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (client);
	const char *iface = nm_dhcp_client_get_iface (client);
	const GByteArray *hwaddr;
	sd_dhcp_lease *lease = NULL;
	GBytes *override_client_id;
	const uint8_t *client_id = NULL;
	size_t client_id_len = 0;
	struct in_addr last_addr = { 0 };
	const char *hostname;
	int r, i;
	gboolean success = FALSE;

	g_assert (priv->client4 == NULL);
	g_assert (priv->client6 == NULL);

	g_free (priv->lease_file);
	priv->lease_file = get_leasefile_path (iface, nm_dhcp_client_get_uuid (client), FALSE);

	r = sd_dhcp_client_new (&priv->client4);
	if (r < 0) {
		nm_log_warn (LOGD_DHCP4, "(%s): failed to create DHCPv4 client (%d)", iface, r);
		return FALSE;
	}

	r = sd_dhcp_client_attach_event (priv->client4, NULL, 0);
	if (r < 0) {
		nm_log_warn (LOGD_DHCP4, "(%s): failed to attach DHCP event (%d)", iface, r);
		goto error;
	}

	hwaddr = nm_dhcp_client_get_hw_addr (client);
	if (hwaddr) {
		r = sd_dhcp_client_set_mac (priv->client4,
		                            hwaddr->data,
		                            hwaddr->len,
		                            get_arp_type (hwaddr));
		if (r < 0) {
			nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP MAC address (%d)", iface, r);
			goto error;
		}
	}

	r = sd_dhcp_client_set_index (priv->client4, nm_dhcp_client_get_ifindex (client));
	if (r < 0) {
		nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP ifindex (%d)", iface, r);
		goto error;
	}

	r = sd_dhcp_client_set_callback (priv->client4, dhcp_event_cb, client);
	if (r < 0) {
		nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP callback (%d)", iface, r);
		goto error;
	}

	r = sd_dhcp_client_set_request_broadcast (priv->client4, true);
	if (r < 0) {
		nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP broadcast (%d)", iface, r);
		goto error;
	}

	dhcp_lease_load (&lease, priv->lease_file);

	if (last_ip4_address)
		inet_pton (AF_INET, last_ip4_address, &last_addr);
	else if (lease)
		sd_dhcp_lease_get_address (lease, &last_addr);

	if (last_addr.s_addr) {
		r = sd_dhcp_client_set_request_address (priv->client4, &last_addr);
		if (r < 0) {
			nm_log_warn (LOGD_DHCP4, "(%s): failed to set last IPv4 address (%d)", iface, r);
			goto error;
		}
	}

	override_client_id = nm_dhcp_client_get_client_id (client);
	if (override_client_id) {
		client_id = g_bytes_get_data (override_client_id, &client_id_len);
		g_assert (client_id && client_id_len);
		sd_dhcp_client_set_client_id (priv->client4,
		                              client_id[0],
		                              client_id + 1,
		                              client_id_len - 1);
	} else if (lease) {
		r = sd_dhcp_lease_get_client_id (lease, (const void **) &client_id, &client_id_len);
		if (r == 0 && client_id_len) {
			sd_dhcp_client_set_client_id (priv->client4,
			                              client_id[0],
			                              client_id + 1,
			                              client_id_len - 1);
			_save_client_id (NM_DHCP_SYSTEMD (client),
			                 client_id[0],
			                 client_id + 1,
			                 client_id_len - 1);
		}
	}


	/* Add requested options */
	for (i = 0; dhcp4_requests[i].name; i++) {
		if (dhcp4_requests[i].include)
			sd_dhcp_client_set_request_option (priv->client4, dhcp4_requests[i].num);
	}

	hostname = nm_dhcp_client_get_hostname (client);
	if (hostname) {
		r = sd_dhcp_client_set_hostname (priv->client4, hostname);
		if (r < 0) {
			nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP hostname (%d)", iface, r);
			goto error;
		}
	}

	r = sd_dhcp_client_start (priv->client4);
	if (r < 0) {
		nm_log_warn (LOGD_DHCP4, "(%s): failed to start DHCP (%d)", iface, r);
		goto error;
	}

	success = TRUE;

error:
	sd_dhcp_lease_unref (lease);
	if (!success)
		priv->client4 = sd_dhcp_client_unref (priv->client4);
	return success;
}
Ejemplo n.º 11
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);

        if (!link->dhcp_client) {
                r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
                if (r < 0)
                        return r;
        }

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return r;

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_use_mtu) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_INTERFACE_MTU);
                if (r < 0)
                        return r;
        }

        /* NOTE: even if this variable is called "use", it also "sends" PRL
         * options, maybe there should be a different configuration variable
         * to send or not route options?. */
        /* NOTE: when using Anonymize=yes, routes PRL options are sent
         * by default, so they don't need to be added here. */
        if (link->network->dhcp_use_routes && !link->network->dhcp_anonymize) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return r;
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_use_ntp) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER);
                if (r < 0)
                        return r;
        }

        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)
                        return r;
        }

        r = dhcp4_set_hostname(link);
        if (r < 0)
                return r;

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_client_port) {
                r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
                if (r < 0)
                        return r;
        }

        switch (link->network->dhcp_client_identifier) {
        case DHCP_CLIENT_ID_DUID: {
                /* If configured, apply user specified DUID and/or IAID */
                const DUID *duid = link_duid(link);

                r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
                                                 link->network->iaid,
                                                 duid->type,
                                                 duid->raw_data_len > 0 ? duid->raw_data : NULL,
                                                 duid->raw_data_len);
                if (r < 0)
                        return r;
                break;
        }
        case DHCP_CLIENT_ID_DUID_ONLY: {
                /* If configured, apply user specified DUID */
                const DUID *duid = link_duid(link);

                r = sd_dhcp_client_set_duid(link->dhcp_client,
                                            duid->type,
                                            duid->raw_data_len > 0 ? duid->raw_data : NULL,
                                            duid->raw_data_len);
                if (r < 0)
                        return r;
                break;
        }
        case DHCP_CLIENT_ID_MAC:
                r = sd_dhcp_client_set_client_id(link->dhcp_client,
                                                 ARPHRD_ETHER,
                                                 (const uint8_t *) &link->mac,
                                                 sizeof(link->mac));
                if (r < 0)
                        return r;
                break;
        default:
                assert_not_reached("Unknown client identifier type.");
        }

        return 0;
}