Example #1
0
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
	}
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
File: compat.c Project: mchf/wicked
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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
File: compat.c Project: mchf/wicked
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);
			}
		}
	}
}
Example #12
0
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;
}
Example #13
0
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);
}
Example #14
0
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;
}
Example #15
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;
}
Example #16
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;
}
Example #17
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;
}
Example #18
0
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;
}
Example #19
0
File: compat.c Project: mchf/wicked
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);
}