static int __ni_dhcp6_lease_ia_addr_to_xml(const ni_dhcp6_ia_addr_t *iadr, uint16_t type, xml_node_t *node) { ni_sockaddr_t addr; char *tmp = NULL; ni_sockaddr_set_ipv6(&addr, iadr->addr, 0); switch (type) { case NI_DHCP6_OPTION_IA_TA: case NI_DHCP6_OPTION_IA_NA: xml_node_new_element("address", node, ni_sockaddr_print(&addr)); break; case NI_DHCP6_OPTION_IA_PD: ni_string_printf(&tmp, "%s/%u", ni_sockaddr_print(&addr), iadr->plen); xml_node_new_element("prefix", node, tmp); ni_string_free(&tmp); break; default: return -1; } xml_node_new_element_uint("preferred-lft", node, iadr->preferred_lft); xml_node_new_element_uint("valid-lft", node, iadr->valid_lft); /* xml_node_new_element_uint("flags", node, iadr->flags); */ __ni_dhcp6_lease_status_to_xml(&iadr->status, node); return 0; }
int __ni_dhcp4_build_msg_request_offer(const ni_dhcp4_device_t *dev, const ni_addrconf_lease_t *lease, ni_buffer_t *msgbuf) { const ni_dhcp4_config_t *options = dev->config; unsigned int msg_code = DHCP4_REQUEST; ni_dhcp4_message_t *message; ni_sockaddr_t addr; /* Request an offer provided by a server (id!) while discover */ ni_sockaddr_set_ipv4(&addr, lease->dhcp4.address, 0); if (!ni_sockaddr_is_ipv4_specified(&addr)) { ni_error("%s: not requesting this offer - no ip-address in lease", dev->ifname); return -1; } if (!(message = __ni_dhcp4_build_msg_init_head(dev, msg_code, msgbuf))) return -1; if (__ni_dhcp4_build_msg_put_hwspec(dev, message) < 0) return -1; if (__ni_dhcp4_build_msg_put_client_id(dev, msg_code, message, msgbuf) < 0) return -1; if (__ni_dhcp4_build_msg_put_server_id(dev, lease, msg_code, msgbuf) < 0) return -1; ni_dhcp4_option_put_ipv4(msgbuf, DHCP4_ADDRESS, lease->dhcp4.address); ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using offered ip-address: %s", dev->ifname, ni_sockaddr_print(&addr)); if (__ni_dhcp4_build_msg_put_our_hostname(dev, msgbuf) < 0) return -1; if (__ni_dhcp4_build_msg_put_option_request(dev, msg_code, msgbuf) < 0) return -1; ni_dhcp4_option_put16(msgbuf, DHCP4_MAXMESSAGESIZE, dev->system.mtu); if (lease->dhcp4.lease_time != 0) { ni_dhcp4_option_put32(msgbuf, DHCP4_LEASETIME, lease->dhcp4.lease_time); } if (options->userclass.len > 0) { ni_dhcp4_option_put(msgbuf, DHCP4_USERCLASS, options->userclass.data, options->userclass.len); } if (options->classid && options->classid[0]) { ni_dhcp4_option_puts(msgbuf, DHCP4_CLASSID, options->classid); } return 0; }
static int __ni_dhcp4_build_msg_release(const ni_dhcp4_device_t *dev, const ni_addrconf_lease_t *lease, ni_buffer_t *msgbuf) { unsigned int msg_code = DHCP4_RELEASE; ni_dhcp4_message_t *message; ni_sockaddr_t addr; /* Release an IP address from a lease we own */ ni_sockaddr_set_ipv4(&addr, lease->dhcp4.address, 0); if (!ni_sockaddr_is_ipv4_specified(&addr)) { ni_error("%s: cannot release - no ip-address in lease", dev->ifname); return -1; } if (!(message = __ni_dhcp4_build_msg_init_head(dev, msg_code, msgbuf))) return -1; message->ciaddr = lease->dhcp4.address.s_addr; ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using release ip-address: %s", dev->ifname, ni_sockaddr_print(&addr)); if (__ni_dhcp4_build_msg_put_hwspec(dev, message) < 0) return -1; if (__ni_dhcp4_build_msg_put_client_id(dev, msg_code, message, msgbuf) < 0) return -1; if (__ni_dhcp4_build_msg_put_server_id(dev, lease, msg_code, msgbuf) < 0) return -1; return 0; }
int main(void) { ni_ibft_nic_array_t nics = NI_IBFT_NIC_ARRAY_INIT; const char *root = NULL; unsigned int i; /* Use local directory */ if (!ni_file_exists("/sys/firmware/ibft")) root = "./ibft"; if(ni_sysfs_ibft_scan_nics(&nics, root) <= 0) return 0; for(i = 0; i < nics.count; ++i) { ni_ibft_nic_t *nic = nics.data[i]; printf("node: %s\n", nic->node); printf(" devpath : %s\n", nic->devpath); printf(" ifname : %s\n", nic->ifname); printf(" ifindex : %u\n", nic->ifindex); printf(" index : %u\n", nic->index); printf(" flags : %u\n", nic->flags); printf(" origin : %u\n", nic->origin); printf(" vlan : %u\n", nic->vlan); printf(" hwaddr : %s\n", ni_link_address_print(&nic->hwaddr)); printf(" ipaddr : %s/%u\n", ni_sockaddr_print(&nic->ipaddr), nic->prefix_len); printf(" dhcp : %s\n", ni_sockaddr_print(&nic->dhcp)); printf(" gateway : %s\n", ni_sockaddr_print(&nic->gateway)); printf(" pri_dns : %s\n", ni_sockaddr_print(&nic->primary_dns)); printf(" sec_dns : %s\n", ni_sockaddr_print(&nic->secondary_dns)); printf(" hostname : %s\n", nic->hostname); printf("\n"); } ni_ibft_nic_array_destroy(&nics); return 0; }
void ni_server_trace_interface_nduseropt_events(ni_netdev_t *dev, ni_event_t event) { ni_ipv6_devinfo_t *ipv6 = dev->ipv6; if (!ni_debug_guard(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS)) return; switch (event) { case NI_EVENT_RDNSS_UPDATE: if (ipv6 && ipv6->radv.rdnss) { ni_ipv6_ra_rdnss_t *rdnss; char buf[32] = {'\0'}; const char *rainfo; rainfo = ipv6->radv.managed_addr ? "managed" : ipv6->radv.other_config ? "config" : "unmanaged"; for (rdnss = ipv6->radv.rdnss; rdnss; rdnss = rdnss->next) { ni_stringbuf_t lft = NI_STRINGBUF_INIT_BUFFER(buf); ni_trace("%s: update IPv6 RA<%s> RDNSS<%s>[%s]", dev->name, rainfo, ni_sockaddr_print(&rdnss->server), ni_lifetime_print_valid(&lft, rdnss->lifetime)); ni_stringbuf_destroy(&lft); } } break; case NI_EVENT_DNSSL_UPDATE: if (ipv6 && ipv6->radv.dnssl) { ni_ipv6_ra_dnssl_t *dnssl; char buf[32] = {'\0'}; const char *rainfo; rainfo = ipv6->radv.managed_addr ? "managed" : ipv6->radv.other_config ? "config" : "unmanaged"; for (dnssl = ipv6->radv.dnssl; dnssl; dnssl = dnssl->next) { ni_stringbuf_t lft = NI_STRINGBUF_INIT_BUFFER(buf); ni_trace("%s: update IPv6 RA<%s> DNSSL<%s>[%s]", dev->name, rainfo, dnssl->domain, ni_lifetime_print_valid(&lft, dnssl->lifetime)); ni_stringbuf_destroy(&lft); } } break; default: ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS, "%s: IPv6 RA %s event: ", dev->name, ni_event_type_to_name(event)); break; } }
int ni_addrconf_lease_addrs_data_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node) { unsigned int count = 0; xml_node_t *anode; ni_address_t *ap; for (ap = lease->addrs; ap; ap = ap->next) { if (lease->family != ap->local_addr.ss_family || !ni_sockaddr_is_specified(&ap->local_addr)) continue; count++; anode = xml_node_new("address", node); xml_node_new_element("local", anode, ni_sockaddr_prefix_print (&ap->local_addr, ap->prefixlen)); if (ap->peer_addr.ss_family == ap->family) { xml_node_new_element("peer", anode, ni_sockaddr_print (&ap->peer_addr)); } if (ap->anycast_addr.ss_family == ap->family) { xml_node_new_element("anycast", anode, ni_sockaddr_print (&ap->anycast_addr)); } if (ap->bcast_addr.ss_family == ap->family) { xml_node_new_element("broadcast", anode, ni_sockaddr_print (&ap->bcast_addr)); } if (ap->family == AF_INET && ap->label) xml_node_new_element("label", anode, ap->label); if (ap->ipv6_cache_info.preferred_lft || ap->ipv6_cache_info.valid_lft) { xml_node_t *cnode = xml_node_new("cache-info", anode); xml_node_new_element_uint("preferred-lifetime", cnode, ap->ipv6_cache_info.preferred_lft); xml_node_new_element_uint("valid-lifetime", cnode, ap->ipv6_cache_info.valid_lft); } } return count ? 0 : 1; }
static int __ni_dhcp4_build_msg_discover(const ni_dhcp4_device_t *dev, const ni_addrconf_lease_t *lease, ni_buffer_t *msgbuf) { const ni_dhcp4_config_t *options = dev->config; unsigned int msg_code = DHCP4_DISCOVER; ni_dhcp4_message_t *message; ni_sockaddr_t addr; /* Discover server able to provide usable offer */ if (!(message = __ni_dhcp4_build_msg_init_head(dev, msg_code, msgbuf))) return -1; if (__ni_dhcp4_build_msg_put_hwspec(dev, message) < 0) return -1; if (__ni_dhcp4_build_msg_put_client_id(dev, msg_code, message, msgbuf) < 0) return -1; /* An optional hint that we've had this address in the past, * so the server __may__ assign it again to us. */ ni_sockaddr_set_ipv4(&addr, lease->dhcp4.address, 0); if (ni_sockaddr_is_ipv4_specified(&addr)) { ni_dhcp4_option_put_ipv4(msgbuf, DHCP4_ADDRESS, lease->dhcp4.address); ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using ip-address hint: %s", dev->ifname, ni_sockaddr_print(&addr)); } if (__ni_dhcp4_build_msg_put_option_request(dev, msg_code, msgbuf) < 0) return -1; ni_dhcp4_option_put16(msgbuf, DHCP4_MAXMESSAGESIZE, dev->system.mtu); if (lease->dhcp4.lease_time != 0) { ni_dhcp4_option_put32(msgbuf, DHCP4_LEASETIME, lease->dhcp4.lease_time); } if (options->userclass.len > 0) { ni_dhcp4_option_put(msgbuf, DHCP4_USERCLASS, options->userclass.data, options->userclass.len); } if (options->classid && options->classid[0]) { ni_dhcp4_option_puts(msgbuf, DHCP4_CLASSID, options->classid); } return 0; }
static xml_node_t * __ni_compat_generate_static_address_list(xml_node_t *ifnode, ni_address_t *addr_list, unsigned int af) { ni_address_t *ap; const char *afname; xml_node_t *aconf = NULL; afname = ni_addrfamily_type_to_name(af); if (!afname) { ni_error("%s: unknown address family %u", __func__, af); return NULL; } for (ap = addr_list; ap; ap = ap->next) { xml_node_t *anode; if (ap->family != af) continue; if (aconf == NULL) { char buffer[64]; snprintf(buffer, sizeof(buffer), "%s:static", afname); aconf = xml_node_create(ifnode, buffer); } anode = xml_node_new("address", aconf); xml_node_new_element("local", anode, ni_sockaddr_prefix_print(&ap->local_addr, ap->prefixlen)); if (ap->peer_addr.ss_family != AF_UNSPEC) xml_node_new_element("peer", anode, ni_sockaddr_print(&ap->peer_addr)); if (ap->bcast_addr.ss_family != AF_UNSPEC) xml_node_new_element("broadcast", anode, ni_sockaddr_print(&ap->bcast_addr)); if (ap->label) xml_node_new_element("label", anode, ap->label); } return aconf; }
static ni_bool_t __do_arp_validate_send(struct arp_handle *handle) { struct in_addr null = { 0 }; ni_bool_t ret = FALSE; if (!handle->hwaddr.len && handle->nprobes) { ni_debug_application("%s: arp validate: probing for %s", handle->ifname, ni_sockaddr_print(&handle->ipaddr)); handle->nprobes--; handle->replies = TRUE; if ((ret = ni_arp_send_request(handle->sock, null, handle->ipaddr.sin.sin_addr) > 0)) { __do_arp_validate_arm_timer(handle); } } else if (!handle->hwaddr.len && handle->nclaims) { ni_debug_application("%s: arp validate: claiming %s use", handle->ifname, ni_sockaddr_print(&handle->ipaddr)); handle->nclaims--; handle->replies = FALSE; if ((ret = ni_arp_send_grat_request(handle->sock, handle->ipaddr.sin.sin_addr) > 0)) { if (handle->nclaims) { __do_arp_validate_arm_timer(handle); } else if (handle->sock) { __do_arp_handle_close(handle); } } } return ret; }
int __ni_dhcp4_build_msg_inform(const ni_dhcp4_device_t *dev, const ni_addrconf_lease_t *lease, ni_buffer_t *msgbuf) { const ni_dhcp4_config_t *options = dev->config; unsigned int msg_code = DHCP4_INFORM; ni_dhcp4_message_t *message; ni_sockaddr_t addr; /* Inform server about IP address we use and request other config */ ni_sockaddr_set_ipv4(&addr, lease->dhcp4.address, 0); if (!ni_sockaddr_is_ipv4_specified(&addr)) { ni_error("%s: cannot inform - no ip-address set", dev->ifname); return -1; } if (!(message = __ni_dhcp4_build_msg_init_head(dev, msg_code, msgbuf))) return -1; message->ciaddr = lease->dhcp4.address.s_addr; ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using inform ip-address: %s", dev->ifname, ni_sockaddr_print(&addr)); if (__ni_dhcp4_build_msg_put_hwspec(dev, message) < 0) return -1; if (__ni_dhcp4_build_msg_put_client_id(dev, msg_code, message, msgbuf) < 0) return -1; if (__ni_dhcp4_build_msg_put_option_request(dev, msg_code, msgbuf) < 0) return -1; ni_dhcp4_option_put16(msgbuf, DHCP4_MAXMESSAGESIZE, dev->system.mtu); if (options->userclass.len > 0) { ni_dhcp4_option_put(msgbuf, DHCP4_USERCLASS, options->userclass.data, options->userclass.len); } if (options->classid && options->classid[0]) { ni_dhcp4_option_puts(msgbuf, DHCP4_CLASSID, options->classid); } return 0; }
static void __ni_compat_generate_static_route_hops(xml_node_t *rnode, const ni_route_nexthop_t *hops, const char *ifname) { const ni_route_nexthop_t *nh; for (nh = hops; nh; nh = nh->next) { xml_node_t *nhnode; if (nh->gateway.ss_family == AF_UNSPEC && !nh->device.name) continue; nhnode = xml_node_new("nexthop", rnode); if (nh->gateway.ss_family != AF_UNSPEC) { xml_node_new_element("gateway", nhnode, ni_sockaddr_print(&nh->gateway)); } if (nh->device.name && !ni_string_eq(ifname, nh->device.name)) { xml_node_new_element("device", nhnode, nh->device.name); } else if (ifname) { xml_node_new_element("device", nhnode, ifname); } if (!hops->next) continue; if (nh->weight > 0) { xml_node_new_element("weight", nhnode, ni_sprint_uint(nh->weight)); } if (nh->realm > 0) { /* Hmm.. */ xml_node_new_element("realm", nhnode, ni_sprint_uint(nh->realm)); } if (nh->flags > 0) { ni_string_array_t names = NI_STRING_ARRAY_INIT; xml_node_t *fnode = NULL; unsigned int i; ni_route_nh_flags_get_names(nh->flags, &names); for (i = 0; i < names.count; ++i) { if (fnode == NULL) fnode = xml_node_new("flags", nhnode); xml_node_new(names.data[i], fnode); } } } }
int ni_addrconf_lease_routes_data_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node) { ni_route_table_t *tab; ni_route_nexthop_t *nh; xml_node_t *route, *hop; ni_route_t *rp; unsigned int count = 0; unsigned int i; /* A very limitted view */ for (tab = lease->routes; tab; tab = tab->next) { if (tab->tid != 254) /* RT_TABLE_MAIN for now */ continue; for (i = 0; i < tab->routes.count; ++i) { if (!(rp = tab->routes.data[i])) continue; route = xml_node_new("route", NULL); if (ni_sockaddr_is_specified(&rp->destination)) { xml_node_new_element("destination", route, ni_sockaddr_prefix_print(&rp->destination, rp->prefixlen)); } for (nh = &rp->nh; nh; nh = nh->next) { if (!ni_sockaddr_is_specified(&nh->gateway)) continue; hop = xml_node_new("nexthop", route); xml_node_new_element("gateway", hop, ni_sockaddr_print(&nh->gateway)); } if (route->children) { xml_node_add_child(node, route); count++; } else { xml_node_free(route); } } } return count ? 0 : 1; }
void ni_server_trace_interface_prefix_events(ni_netdev_t *dev, ni_event_t event, const ni_ipv6_ra_pinfo_t *pi) { char vbuf[32] = {'\0'}, pbuf[32] = {'\0'}; ni_stringbuf_t vlft = NI_STRINGBUF_INIT_BUFFER(vbuf); ni_stringbuf_t plft = NI_STRINGBUF_INIT_BUFFER(pbuf); ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS, "%s: %s IPv6 RA<%s> Prefix<%s/%u %s,%s>[%s,%s]", dev->name, (event == NI_EVENT_PREFIX_UPDATE ? "update" : "delete"), (dev->ipv6 && dev->ipv6->radv.managed_addr ? "managed" : (dev->ipv6 && dev->ipv6->radv.other_config ? "config" : "unmanaged")), ni_sockaddr_print(&pi->prefix), pi->length, (pi->on_link ? "onlink" : "not-onlink"), (pi->autoconf ? "autoconf" : "no-autoconf"), ni_lifetime_print_valid(&vlft, pi->valid_lft), ni_lifetime_print_preferred(&plft, pi->preferred_lft)); ni_stringbuf_destroy(&vlft); ni_stringbuf_destroy(&plft); }
static int __ni_dhcp4_build_msg_put_server_id(const ni_dhcp4_device_t *dev, const ni_addrconf_lease_t *lease, unsigned int msg_code, ni_buffer_t *msgbuf) { ni_sockaddr_t addr; ni_sockaddr_set_ipv4(&addr, lease->dhcp4.server_id, 0); if (!ni_sockaddr_is_ipv4_specified(&addr)) { ni_error("%s: cannot construct %s without server-id", dev->ifname, ni_dhcp4_message_name(msg_code)); return -1; } ni_dhcp4_option_put_ipv4(msgbuf, DHCP4_SERVERIDENTIFIER, lease->dhcp4.server_id); ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using server-id: %s", dev->ifname, ni_sockaddr_print(&addr)); return 0; }
/* * dhcp6 lease data to xml */ static int __ni_dhcp6_lease_head_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node) { ni_sockaddr_t addr; xml_node_new_element("client-id", node, ni_duid_print_hex(&lease->dhcp6.client_id)); xml_node_new_element("server-id", node, ni_duid_print_hex(&lease->dhcp6.server_id)); ni_sockaddr_set_ipv6(&addr, lease->dhcp6.server_addr, 0); xml_node_new_element("server-address", node, ni_sockaddr_print(&addr)); xml_node_new_element_uint("server-preference", node, lease->dhcp6.server_pref); if (lease->dhcp6.rapid_commit) xml_node_new_element("rapid-commit", node, NULL); if (!ni_string_empty(lease->hostname)) xml_node_new_element("hostname", node, lease->hostname); return 0; }
static int __ni_dhcp4_build_msg_decline(const ni_dhcp4_device_t *dev, const ni_addrconf_lease_t *lease, ni_buffer_t *msgbuf) { unsigned int msg_code = DHCP4_DECLINE; ni_dhcp4_message_t *message; ni_sockaddr_t addr; /* Decline IP address the server offered to us; * we've found another host using it already. */ ni_sockaddr_set_ipv4(&addr, lease->dhcp4.address, 0); if (!ni_sockaddr_is_ipv4_specified(&addr)) { ni_error("%s: cannot decline - no ip-address in lease", dev->ifname); return -1; } if (!(message = __ni_dhcp4_build_msg_init_head(dev, msg_code, msgbuf))) return -1; if (__ni_dhcp4_build_msg_put_hwspec(dev, message) < 0) return -1; if (__ni_dhcp4_build_msg_put_client_id(dev, msg_code, message, msgbuf) < 0) return -1; if (__ni_dhcp4_build_msg_put_server_id(dev, lease, msg_code, msgbuf) < 0) return -1; ni_dhcp4_option_put_ipv4(msgbuf, DHCP4_ADDRESS, lease->dhcp4.address); ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_DHCP, "%s: using decline ip-address: %s", dev->ifname, ni_sockaddr_print(&addr)); return 0; }
/* * Install information from a lease, and remember that we did */ static ni_bool_t ni_system_updater_install(ni_updater_t *updater, const ni_addrconf_lease_t *lease, const char *ifname) { ni_string_array_t arguments = NI_STRING_ARRAY_INIT; const char *statedir = NULL; char *file = NULL; ni_bool_t result = FALSE; int rv = 0; ni_debug_ifconfig("Updating system %s settings from %s/%s lease", ni_updater_name(updater->kind), ni_addrconf_type_to_name(lease->type), ni_addrfamily_type_to_name(lease->family)); if (!updater->proc_install) return TRUE; if (!ifname || (!updater->have_backup && !ni_system_updater_backup(updater, ifname))) return FALSE; ni_string_array_append(&arguments, "-i"); ni_string_array_append(&arguments, ifname); ni_string_array_append(&arguments, "-t"); ni_string_array_append(&arguments, ni_addrconf_type_to_name(lease->type)); ni_string_array_append(&arguments, "-f"); ni_string_array_append(&arguments, ni_addrfamily_type_to_name(lease->family)); switch (updater->kind) { case NI_ADDRCONF_UPDATER_GENERIC: switch (updater->format) { case NI_ADDRCONF_UPDATER_FORMAT_INFO: ni_leaseinfo_dump(NULL, lease, ifname, NULL); if (!(file = ni_leaseinfo_path(ifname, lease->type, lease->family))) { ni_error("Unable to determine leaseinfo file path."); goto done; } ni_string_array_append(&arguments, file); break; default: ni_error("Unsupported %s updater data format.", ni_updater_name(updater->kind)); goto done; } ni_string_array_append(&arguments, ni_updater_format_name(updater->format)); break; case NI_ADDRCONF_UPDATER_RESOLVER: statedir = ni_extension_statedir(ni_updater_name(updater->kind)); if (!statedir) { ni_error("failed to get %s statedir", ni_updater_name(updater->kind)); goto done; } ni_string_printf(&file, "%s/resolv.conf.%s.%s.%s", statedir, ifname, ni_addrconf_type_to_name(lease->type), ni_addrfamily_type_to_name(lease->family)); ni_string_array_append(&arguments, file); if ((rv = ni_resolver_write_resolv_conf(file, lease->resolver, NULL)) < 0) { ni_error("failed to write resolver info to file: %s", ni_strerror(rv)); goto done; } break; case NI_ADDRCONF_UPDATER_HOSTNAME: if (!ni_string_empty(lease->hostname)) { ni_string_array_append(&arguments, lease->hostname); } else { const ni_address_t *ap; char *name = NULL; unsigned int count; /* bnc#861476 workaround */ if (!can_try_reverse_lookup(lease)) goto done; for (count = 0, ap = lease->addrs; ap; ap = ap->next) { if (!ni_sockaddr_is_specified(&ap->local_addr)) continue; if (!ni_resolve_reverse_timed(&ap->local_addr, &name, NI_UPDATER_REVERSE_TIMEOUT)) break; ni_info("Unable to resolve %s to hostname", ni_sockaddr_print(&ap->local_addr)); if (++count >= NI_UPDATER_REVERSE_MAX_CNT) break; } if (ni_string_empty(name)) { ni_note("Skipping hostname update, none available"); goto done; } ni_string_array_append(&arguments, name); ni_string_free(&name); } break; default: ni_error("cannot install new %s settings - file format not understood", ni_updater_name(updater->kind)); goto done; } if (!ni_system_updater_run(updater->proc_install, &arguments)) { ni_error("failed to install %s settings", ni_updater_name(updater->kind)); goto done; } result = TRUE; switch (updater->kind) { case NI_ADDRCONF_UPDATER_RESOLVER: if (ni_global.other_event) ni_global.other_event(NI_EVENT_RESOLVER_UPDATED); break; case NI_ADDRCONF_UPDATER_HOSTNAME: if (ni_global.other_event) ni_global.other_event(NI_EVENT_HOSTNAME_UPDATED); break; case NI_ADDRCONF_UPDATER_GENERIC: if (ni_global.other_event) ni_global.other_event(NI_EVENT_GENERIC_UPDATED); break; default: break; } done: if (file) free(file); ni_string_array_destroy(&arguments); return result; }
int ni_do_arp(int argc, char **argv) { static struct option options[] = { { "help", no_argument, NULL, OPT_HELP }, { "quiet", no_argument, NULL, OPT_QUIET }, { "verbose", no_argument, NULL, OPT_VERBOSE }, { "verify", required_argument, NULL, OPT_VERIFY }, { "notify", required_argument, NULL, OPT_NOTIFY }, { "interval", required_argument, NULL, OPT_TIMEOUT }, { NULL, no_argument, NULL, 0 } }; int c, status = NI_WICKED_RC_USAGE; unsigned int opt_verbose = OPT_VERBOSE; unsigned int opt_nprobes; unsigned int opt_nclaims; struct arp_handle handle; memset(&handle, 0, sizeof(handle)); handle.nprobes = opt_nprobes = 3; handle.nclaims = opt_nclaims = 0; handle.timeout = 200; optind = 1; while ((c = getopt_long(argc, argv, "", options, NULL)) != EOF) { switch (c) { case OPT_HELP: status = NI_WICKED_RC_SUCCESS; default: usage: fprintf(stderr, "wicked %s [options ...] <ifname> <IP address>\n" "\n" "Supported options:\n" " --help\n" " Show this help text.\n" " --quiet\n" " Return exit status only\n" " --verbose\n" " Show a result info (default)\n" "\n" " --verify <count>\n" " Verify IP for duplicates on the network (DAD);\n" " Returns 4, when duplicate IP address exists.\n" " --notify <count>\n" " Notify about IP address use (gratuitous ARP)\n" " --interval <msec>\n" " Packet sending interval in msec\n" , argv[0] ); goto cleanup; case OPT_QUIET: case OPT_VERBOSE: opt_verbose = c; break; case OPT_VERIFY: if (ni_parse_uint(optarg, &opt_nprobes, 10)) { ni_error("%s: Cannot parse verify count '%s'", argv[0], optarg); goto cleanup; } handle.nprobes = opt_nprobes; break; case OPT_NOTIFY: if (ni_parse_uint(optarg, &opt_nclaims, 10)) { ni_error("%s: Cannot parse notify count '%s'", argv[0], optarg); goto cleanup; } handle.nclaims = opt_nclaims; break; case OPT_TIMEOUT: if (ni_parse_uint(optarg, &handle.timeout, 10)) { ni_error("%s %s: Cannot parse interval '%s'", argv[0], argv[1], optarg); goto cleanup; } break; } } if (optind + 2 != argc) goto usage; if (!handle.nprobes && !handle.nclaims) { ni_error("%s: nothing to send", argv[0]); goto cleanup; } handle.ifname = argv[optind++]; if (ni_string_empty(handle.ifname)) goto cleanup; if (ni_sockaddr_parse(&handle.ipaddr, argv[optind], AF_INET) != 0) { ni_error("%s: cannot parse '%s' as IPv4 address", argv[0], argv[optind]); goto cleanup; } status = __do_arp_validate(&handle); if (opt_verbose) { if (handle.hwaddr.len) { printf("%s: IP address %s is in use by %s\n", handle.ifname, ni_sockaddr_print(&handle.ipaddr), ni_link_address_print(&handle.hwaddr)); } else { if (opt_nprobes) { printf("%s: No duplicates for IP address %s detected\n", handle.ifname, ni_sockaddr_print(&handle.ipaddr)); } if (opt_nclaims) { printf("%s: Notified neighbours about IP address %s\n", handle.ifname, ni_sockaddr_print(&handle.ipaddr)); } } } cleanup: return status; }
void __ni_compat_generate_static_route(xml_node_t *aconf, const ni_route_t *rp, const char *ifname) { xml_node_t *rnode, *mnode, *knode; char *tmp = NULL; const char *ptr; rnode = xml_node_new("route", aconf); if (rp->destination.ss_family != AF_UNSPEC && rp->prefixlen != 0) { xml_node_new_element("destination", rnode, ni_sockaddr_prefix_print(&rp->destination, rp->prefixlen)); } __ni_compat_generate_static_route_hops(rnode, &rp->nh, ifname); knode = NULL; if (rp->table != RT_TABLE_UNSPEC && rp->table != RT_TABLE_MAIN) { if (!(ptr = ni_route_table_type_to_name(rp->table))) ptr = ni_sprint_uint(rp->table); if (knode == NULL) knode = xml_node_new("kern", rnode); xml_node_new_element("table", knode, ptr); } if (rp->type != RTN_UNSPEC && rp->type != RTN_UNICAST) { if (!(ptr = ni_route_type_type_to_name(rp->type))) ptr = ni_sprint_uint(rp->type); if (knode == NULL) knode = xml_node_new("kern", rnode); xml_node_new_element("type", knode, ptr); } if (rp->scope != RT_SCOPE_UNIVERSE) { if (!(ptr = ni_route_scope_type_to_name(rp->scope))) ptr = ni_sprint_uint(rp->scope); if (knode == NULL) knode = xml_node_new("kern", rnode); xml_node_new_element("scope", knode, ptr); } if (rp->protocol != RTPROT_UNSPEC && rp->protocol != RTPROT_BOOT) { if (!(ptr = ni_route_protocol_type_to_name(rp->protocol))) ptr = ni_sprint_uint(rp->protocol); if (knode == NULL) knode = xml_node_new("kern", rnode); xml_node_new_element("protocol", knode, ptr); } if (rp->priority > 0) { xml_node_new_element("priority", rnode, ni_sprint_uint(rp->priority)); } if (ni_sockaddr_is_specified(&rp->pref_src)) { xml_node_new_element("source", rnode, ni_sockaddr_print(&rp->pref_src)); } if (rp->realm > 0) { /* Hmm */ xml_node_new_element("realm", rnode, ni_sprint_uint(rp->realm)); } if (rp->mark > 0 && ni_string_printf(&tmp, "0x%02x", rp->mark)) { xml_node_new_element("mark", rnode, tmp); ni_string_free(&tmp); } if (rp->flags > 0) { ni_string_array_t names = NI_STRING_ARRAY_INIT; xml_node_t *fnode = NULL; unsigned int i; ni_route_flags_get_names(rp->flags, &names); for (i = 0; i < names.count; ++i) { if (fnode == NULL) fnode = xml_node_new("flags", rnode); xml_node_new(names.data[i], fnode); } } if (rp->tos > 0 && ni_string_printf(&tmp, "0x%02x", rp->tos)) { xml_node_new_element("tos", rnode, tmp); ni_string_free(&tmp); } mnode = xml_node_new("metrics", NULL); __ni_compat_generate_static_route_metrics(mnode, rp); if (mnode->children || mnode->attrs.count || mnode->cdata) xml_node_add_child(rnode, mnode); else xml_node_free(mnode); }