static int __ni_dhcp4_build_msg_put_client_id(const ni_dhcp4_device_t *dev, unsigned int msg_code, ni_dhcp4_message_t *message, ni_buffer_t *msgbuf) { const ni_dhcp4_config_t *options = dev->config; if (options->client_id.len) { ni_dhcp4_option_put(msgbuf, DHCP4_CLIENTID, options->client_id.data, options->client_id.len); ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using client-id: %s", dev->ifname, ni_print_hex(options->client_id.data, options->client_id.len)); } else if (!message->hwlen) { ni_error("%s: cannot construct %s without usable hw-addr and client-id", dev->ifname, ni_dhcp4_message_name(msg_code)); return -1; } else { return 1; /* skipped client-id */ } return 0; }
static int __ni_dhcp4_build_msg_put_hwspec(const ni_dhcp4_device_t *dev, ni_dhcp4_message_t *message) { switch (dev->system.hwaddr.type) { case ARPHRD_ETHER: case ARPHRD_IEEE802: if (dev->system.hwaddr.len && dev->system.hwaddr.len <= sizeof(message->chaddr)) { message->hwlen = dev->system.hwaddr.len; memcpy(&message->chaddr, dev->system.hwaddr.data, dev->system.hwaddr.len); } break; case ARPHRD_IEEE1394: case ARPHRD_INFINIBAND: /* See http://tools.ietf.org/html/rfc4390 * * Note: set the ciaddr before if needed. */ message->hwlen = 0; if (message->ciaddr == 0) message->flags = htons(BROADCAST_FLAG); break; default: ni_error("%s: dhcp4 unsupported hardware type %s (0x%x)", dev->ifname, ni_arphrd_type_to_name(dev->system.hwaddr.type), dev->system.hwaddr.type); return -1; } if (message->hwlen) { ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using hw-address[%u]: %s", dev->ifname, message->hwtype, ni_print_hex(message->chaddr, message->hwlen)); } if (message->flags & htons(BROADCAST_FLAG)) { ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using broadcast response flag", dev->ifname); } return 0; }
/* * Process a request to reconfigure the device (ie rebind a lease, or discover * a new lease). */ int ni_dhcp4_acquire(ni_dhcp4_device_t *dev, const ni_dhcp4_request_t *info) { ni_dhcp4_config_t *config; const char *classid; size_t len; int rv; if ((rv = ni_dhcp4_device_refresh(dev)) < 0) return rv; config = xcalloc(1, sizeof(*config)); config->dry_run = info->dry_run; config->resend_timeout = NI_DHCP4_RESEND_TIMEOUT_INIT; config->request_timeout = info->acquire_timeout?: NI_DHCP4_REQUEST_TIMEOUT; config->initial_discovery_timeout = NI_DHCP4_DISCOVERY_TIMEOUT; config->uuid = info->uuid; config->flags = info->flags; config->update = info->update; config->route_priority = info->route_priority; config->start_delay = info->start_delay; config->recover_lease = info->recover_lease; config->release_lease = info->release_lease; config->max_lease_time = ni_dhcp4_config_max_lease_time(); if (config->max_lease_time == 0) config->max_lease_time = ~0U; if (info->lease_time && info->lease_time < config->max_lease_time) config->max_lease_time = info->lease_time; if ((len = ni_string_len(info->hostname)) > 0) { if (ni_check_domain_name(info->hostname, len, 0)) { strncpy(config->hostname, info->hostname, sizeof(config->hostname) - 1); } else { ni_debug_dhcp("Discarded request to use suspect hostname: '%s'", ni_print_suspect(info->hostname, len)); } } if (info->clientid) { ni_dhcp4_parse_client_id(&config->client_id, dev->system.hwaddr.type, info->clientid); } else { /* Set client ID from interface hwaddr */ ni_dhcp4_set_client_id(&config->client_id, &dev->system.hwaddr); } if ((classid = info->vendor_class) == NULL) classid = ni_dhcp4_config_vendor_class(); if (classid) strncpy(config->classid, classid, sizeof(config->classid) - 1); config->doflags = DHCP4_DO_DEFAULT; config->doflags |= ni_dhcp4_do_bits(info->update); if (ni_debug & NI_TRACE_DHCP) { ni_trace("Received request:"); ni_trace(" acquire-timeout %u", config->request_timeout); ni_trace(" lease-time %u", config->max_lease_time); ni_trace(" start-delay %u", config->start_delay); ni_trace(" hostname %s", config->hostname[0]? config->hostname : "<none>"); ni_trace(" vendor-class %s", config->classid[0]? config->classid : "<none>"); ni_trace(" client-id %s", ni_print_hex(config->client_id.data, config->client_id.len)); ni_trace(" uuid %s", ni_uuid_print(&config->uuid)); ni_trace(" update-flags %s", __ni_dhcp4_print_doflags(config->doflags)); ni_trace(" recover_lease %s", config->recover_lease ? "true" : "false"); ni_trace(" release_lease %s", config->release_lease ? "true" : "false"); } ni_dhcp4_device_set_config(dev, config); if (!dev->lease) ni_dhcp4_recover_lease(dev); if (dev->lease) { if (!ni_addrconf_lease_is_valid(dev->lease) || (config->client_id.len && !ni_opaque_eq(&config->client_id, &dev->lease->dhcp4.client_id))) { ni_debug_dhcp("%s: lease doesn't match request", dev->ifname); ni_dhcp4_device_drop_lease(dev); dev->notify = 1; } } ni_note("%s: Request to acquire DHCPv4 lease with UUID %s", dev->ifname, ni_uuid_print(&config->uuid)); if (ni_dhcp4_device_start(dev) < 0) return -1; return 1; }