Exemple #1
0
static ni_netdev_t *
__ni_objectmodel_dummy_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev_ifp = NULL;
	int rv;

	if (ni_string_empty(ifname)) {
		if (ni_string_empty(cfg_ifp->name) &&
		    (ifname = ni_netdev_make_name(nc, "dummy", 0))) {
			ni_string_dup(&cfg_ifp->name, ifname);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Unable to create dummy interface: "
				"name argument missed");
			goto out;
		}
		ifname = NULL;
	} else if(!ni_string_eq(cfg_ifp->name, ifname)) {
		ni_string_dup(&cfg_ifp->name, ifname);
	}

	if (cfg_ifp->link.hwaddr.len) {
		if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID)
			cfg_ifp->link.hwaddr.type = ARPHRD_ETHER;
		if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER ||
		    cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot create dummy interface: "
				"invalid ethernet address '%s'",
				ni_link_address_print(&cfg_ifp->link.hwaddr));
			return NULL;
		}
	}

	if ((rv = ni_system_dummy_create(nc, cfg_ifp, &dev_ifp)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || dev_ifp == NULL
		|| (ifname && dev_ifp && !ni_string_eq(dev_ifp->name, ifname))) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
					"Unable to create dummy interface: %s",
					ni_strerror(rv));
			dev_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("dummy interface exists (and name matches)");
	}

	if (dev_ifp->link.type != NI_IFTYPE_DUMMY) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create dummy interface: "
				"new interface is of type %s",
				ni_linktype_type_to_name(dev_ifp->link.type));
		dev_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return dev_ifp;
}
Exemple #2
0
static ni_netdev_t *
__ni_objectmodel_team_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	int rv;

	ni_netdev_get_team(cfg_ifp);
	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "team", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface - too many interfaces");
		goto out;
	}
	ni_string_dup(&cfg_ifp->name, ifname);

	if (cfg_ifp->link.hwaddr.len) {
		if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID)
			cfg_ifp->link.hwaddr.type = ARPHRD_ETHER;

		if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER ||
		    cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
					"Cannot create team interface: invalid ethernet address '%s'",
					ni_link_address_print(&cfg_ifp->link.hwaddr));
			goto out;
		}
	}

	if ((rv = ni_system_team_create(nc, cfg_ifp, &new_ifp)) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create team interface '%s'", cfg_ifp->name);
		new_ifp = NULL;
		goto out;
#if 0
		if (rv != -NI_ERROR_DEVICE_EXISTS
		 && (ifname != NULL && strcmp(ifname, new_ifp->name))) {
			dbus_set_error(error,
					DBUS_ERROR_FAILED,
					"Unable to create team interface: %s",
					ni_strerror(rv));
			goto out;
		}
		ni_debug_dbus("Bonding interface exists (and name matches)");
#endif
	}

	if (new_ifp->link.type != NI_IFTYPE_TEAM) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create team interface: new interface is of type %s",
				ni_linktype_type_to_name(new_ifp->link.type));
		new_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
Exemple #3
0
void
ni_dhcp4_fsm_process_arp_packet(ni_arp_socket_t *arph, const ni_arp_packet_t *pkt, void *user_data)
{
	ni_dhcp4_device_t *dev = user_data;
	ni_netconfig_t *nc = ni_global_state_handle(0);
	const ni_netdev_t *ifp;
	ni_bool_t false_alarm = FALSE;
	ni_bool_t found_addr = FALSE;

	if (!pkt || pkt->op != ARPOP_REPLY || !dev || !dev->lease)
		return;

	/* Is it about the address we're validating at all? */
	if (pkt->sip.s_addr != dev->lease->dhcp4.address.s_addr)
		return;

	/* Ignore any ARP replies that seem to come from our own
	 * MAC address. Some helpful switches seem to generate
	 * these. */
	if (ni_link_address_equal(&dev->system.hwaddr, &pkt->sha))
		return;

	/* As well as ARP replies that seem to come from our own
	 * host: dup if same address, not a dup if there are two
	 * interfaces connected to the same broadcast domain.
	 */
	for (ifp = ni_netconfig_devlist(nc); ifp; ifp = ifp->next) {
		if (ifp->link.ifindex == dev->link.ifindex)
			continue;

		if (!ni_netdev_link_is_up(ifp))
			continue;

		if (!ni_link_address_equal(&ifp->link.hwaddr, &pkt->sha))
			continue;

		/* OK, we have an interface matching the hwaddr,
		 * which will answer arp requests when it is on
		 * the same broadcast domain and causes a false
		 * alarm, except it really has the IP assigned.
		 */
		false_alarm = TRUE;
		if (__ni_dhcp4_address_on_device(ifp, pkt->sip))
			found_addr = TRUE;
	}
	if (false_alarm && !found_addr)
		return;

	ni_debug_dhcp("%s: address %s already in use by %s",
			dev->ifname, inet_ntoa(pkt->sip),
			ni_link_address_print(&pkt->sha));
	ni_dhcp4_device_arp_close(dev);
	ni_dhcp4_fsm_decline(dev);
}
Exemple #4
0
/*
 * Functions for generating XML
 */
static ni_bool_t
__ni_compat_generate_ethernet(xml_node_t *ifnode, const ni_compat_netdev_t *compat)
{
	const ni_netdev_t *dev = compat->dev;
	xml_node_t *child;

	child = xml_node_new("ethernet", ifnode);
	if (dev->link.hwaddr.len)
		xml_node_new_element("address", child, ni_link_address_print(&dev->link.hwaddr));

	/* generate offload and other information */

	return TRUE;
}
Exemple #5
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;
}
Exemple #6
0
static xml_node_t *
ni_compat_generate_ifcfg(const ni_compat_netdev_t *compat, xml_document_t *doc)
{
	xml_node_t *ifnode, *namenode;

	ifnode = xml_node_new("interface", doc->root);

	namenode = xml_node_new("name", ifnode);
	if (compat->identify.hwaddr.type == NI_IFTYPE_ETHERNET) {
		xml_node_add_attr(namenode, "namespace", "ethernet");
		xml_node_new_element("permanent-address", namenode,
				ni_link_address_print(&compat->identify.hwaddr));
	} else {
		xml_node_set_cdata(namenode, compat->dev->name);
	}

	__ni_compat_generate_ifcfg(ifnode, compat);
	return ifnode;
}
Exemple #7
0
static ni_bool_t
ni_objectmodel_ether_describe(const ni_objectmodel_ns_t *ns, const ni_dbus_object_t *object, xml_node_t *parent)
{
	ni_netdev_t *dev;
	ni_ethernet_t *eth;
	xml_node_t *node;

	if (!(dev = ni_objectmodel_unwrap_netif(object, NULL)))
		return FALSE;

	if (!(eth = dev->ethernet))
		return FALSE;

	if (eth->permanent_address.len) {
		node = __describe(ns, parent);
		xml_node_new_element("permanent-address", node,
				ni_link_address_print(&eth->permanent_address));
	}

	return TRUE;
}
Exemple #8
0
static void
__do_arp_validate_process(ni_arp_socket_t *sock, const ni_arp_packet_t *pkt,
		void *user_data)
{
	struct arp_handle *handle = user_data;
	ni_netconfig_t *nc = ni_global_state_handle(0);
	const ni_netdev_t *ifp;
	ni_bool_t false_alarm = FALSE;
	ni_bool_t found_addr = FALSE;
	const ni_address_t *ap;
	ni_sockaddr_t addr;

	if (!pkt || pkt->op != ARPOP_REPLY || !handle->replies)
		return;

	/* Is it about the address we're validating at all? */
	if (pkt->sip.s_addr != handle->ipaddr.sin.sin_addr.s_addr) {
		ni_debug_application("%s: report about different address",
				handle->ifname);
		return;
	}

	/* Ignore any ARP replies that seem to come from our own
	 * MAC address. Some helpful switches seem to generate
	 * these. */
	if (ni_link_address_equal(&sock->dev_info.hwaddr, &pkt->sha)) {
		ni_debug_application("%s: adress in use by ourself",
				handle->ifname);
		return;
	}

	/* As well as ARP replies that seem to come from our own
	 * host: dup if same address, not a dup if there are two
	 * interfaces connected to the same broadcast domain.
	 */
	ni_sockaddr_set_ipv4(&addr, pkt->sip, 0);
	for (ifp = ni_netconfig_devlist(nc); ifp; ifp = ifp->next) {
		if (ifp->link.ifindex == sock->dev_info.ifindex)
			continue;

		if (!ni_netdev_link_is_up(ifp))
			continue;

		if (!ni_link_address_equal(&ifp->link.hwaddr, &pkt->sha))
			continue;

		/* OK, we have an interface matching the hwaddr,
		 * which will answer arp requests when it is on
		 * the same broadcast domain and causes a false
		 * alarm, except it really has the IP assigned.
		 */
		false_alarm = TRUE;
		for (ap = ifp->addrs; !found_addr && ap; ap = ap->next) {
			if (ap->family != AF_INET)
				continue;
			if (ni_sockaddr_equal(&ap->local_addr, &addr))
				found_addr = TRUE;
		}
	}
	if (false_alarm && !found_addr) {
		ni_debug_application("%s: reply from one of our interfaces",
				handle->ifname);
		return;
	}

	ni_info("%s: adress %s in use by %s reported",
			handle->ifname,
			inet_ntoa(pkt->sip),
			ni_link_address_print(&pkt->sha));
	handle->hwaddr = pkt->sha;
}
Exemple #9
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;
}
Exemple #10
0
static ni_netdev_t *
__ni_objectmodel_macvlan_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev_ifp = NULL;
	const ni_macvlan_t *macvlan;
	const char *err;
	const char *cfg_ifp_iftype = NULL;
	int rv;

	cfg_ifp_iftype = ni_linktype_type_to_name(cfg_ifp->link.type);

	if (ni_string_empty(cfg_ifp->link.lowerdev.name)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Incomplete arguments: need a lower device name");
		return NULL;
	} else
	if (!ni_netdev_ref_bind_ifindex(&cfg_ifp->link.lowerdev, nc)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
			"Unable to find %s lower device %s by name",
			cfg_ifp_iftype,
			cfg_ifp->link.lowerdev.name);
		return NULL;
	}

	macvlan = ni_netdev_get_macvlan(cfg_ifp);
	if ((err = ni_macvlan_validate(macvlan))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		goto out;
	}

	if (ni_string_empty(ifname)) {
		if (ni_string_empty(cfg_ifp->name) &&
			(ifname = ni_netdev_make_name(
				nc,
				cfg_ifp_iftype,
				0))) {
			ni_string_dup(&cfg_ifp->name, ifname);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Unable to create %s interface: "
				"name argument missed",
				cfg_ifp_iftype);
			goto out;
		}
		ifname = NULL;
	} else if(!ni_string_eq(cfg_ifp->name, ifname)) {
		ni_string_dup(&cfg_ifp->name, ifname);
	}
	if (ni_string_eq(cfg_ifp->name, cfg_ifp->link.lowerdev.name)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
			"Cannot create %s interface: "
			"macvlan name %s equal with lower device name",
			cfg_ifp_iftype,
			cfg_ifp->name);
		return NULL;
	}

	if (cfg_ifp->link.hwaddr.len) {
		if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID)
			cfg_ifp->link.hwaddr.type = ARPHRD_ETHER;
		if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER ||
		    cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot create %s interface: "
				"invalid ethernet address '%s'",
				cfg_ifp_iftype,
				ni_link_address_print(&cfg_ifp->link.hwaddr));
			return NULL;
		}
	}

	if ((rv = ni_system_macvlan_create(nc, cfg_ifp, &dev_ifp)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || dev_ifp == NULL
		|| (ifname && dev_ifp && !ni_string_eq(dev_ifp->name, ifname))) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
					"Unable to create %s interface: %s",
				cfg_ifp_iftype,
				ni_strerror(rv));
			dev_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("%s interface exists (and name matches)",
			cfg_ifp_iftype);
	}

	if (dev_ifp->link.type != cfg_ifp->link.type) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create %s interface: "
				"new interface is of type %s",
			cfg_ifp_iftype,
			ni_linktype_type_to_name(dev_ifp->link.type));
		dev_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return dev_ifp;
}
Exemple #11
0
static ni_netdev_t *
__ni_objectmodel_gre_create(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_gre_t *gre = NULL;
	ni_netdev_t *dev = NULL;
	const char *err = NULL;
	int rv;

	gre = ni_netdev_get_gre(cfg_ifp);
	if ((err = ni_gre_validate(gre))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		goto out;
	}

	if (ni_string_empty(ifname)) {
		if (ni_string_empty(cfg_ifp->name) &&
			(ifname = ni_netdev_make_name(nc, "gre", 1))) {
			ni_string_dup(&cfg_ifp->name, ifname);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Unable to create gre tunnel: "
				"name argument missed");
			goto out;
		}
		ifname = NULL;
	} else if(!ni_string_eq(cfg_ifp->name, ifname)) {
		ni_string_dup(&cfg_ifp->name, ifname);
	}

	if (!ni_string_empty(cfg_ifp->link.lowerdev.name) &&
	    !ni_objectmodel_bind_netdev_ref_index(cfg_ifp->name, "gre tunnel",
					&cfg_ifp->link.lowerdev, nc, error))
		goto out;

	if (cfg_ifp->link.hwaddr.len) {
		if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID)
			cfg_ifp->link.hwaddr.type = ARPHRD_IPGRE;

		if (cfg_ifp->link.hwaddr.type != ARPHRD_IPGRE ||
		    cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_IPGRE)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot create gre tunnel interface: "
				"invalid local address '%s'",
				ni_link_address_print(&cfg_ifp->link.hwaddr));
			return NULL;
		}
	}

	if (cfg_ifp->link.hwpeer.len) {
		if (cfg_ifp->link.hwpeer.type == ARPHRD_VOID)
			cfg_ifp->link.hwpeer.type = ARPHRD_IPGRE;

		if (cfg_ifp->link.hwpeer.type != ARPHRD_IPGRE ||
		    cfg_ifp->link.hwpeer.len != ni_link_address_length(ARPHRD_IPGRE)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot create gre tunnel interface: "
				"invalid remote address '%s'",
				ni_link_address_print(&cfg_ifp->link.hwpeer));
			return NULL;
		}
	}

	if ((rv = ni_system_tunnel_create(nc, cfg_ifp, &dev, NI_IFTYPE_GRE) < 0)) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || dev == NULL
			|| (ifname && dev && !ni_string_eq(dev->name, ifname))) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create gre tunnel: %s", cfg_ifp->name);
			dev = NULL;
			goto out;
		}
		ni_debug_dbus("gre tunnel exists (and name matches)");
	}

	if (dev->link.type != NI_IFTYPE_GRE) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			"Unable to create gre tunnel: "
			"new interface is of type %s",
			ni_linktype_type_to_name(dev->link.type));
		dev = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return dev;
}
Exemple #12
0
static ni_bool_t
__ni_compat_generate_wireless(xml_node_t *ifnode, const ni_compat_netdev_t *compat)
{
	ni_wireless_t *wlan;
	ni_wireless_network_t *net;
	xml_node_t *wireless, *network, *wep, *wpa_psk, *wpa_eap;
	ni_wireless_blob_t *cert;
	char *tmp = NULL;
	const char *value;
	int i, count, key_i;

	wlan = ni_netdev_get_wireless(compat->dev);

	if (!(wireless = xml_node_create(ifnode, "wireless"))) {
		return FALSE;
	}

	if (ni_string_len(wlan->conf.country) == 2) {
		xml_node_new_element("country", wireless, wlan->conf.country);
	}

	if (wlan->conf.ap_scan <= NI_WIRELESS_AP_SCAN_SUPPLICANT_EXPLICIT_MATCH &&
		ni_string_printf(&tmp, "%u", wlan->conf.ap_scan)) {
		xml_node_new_element("ap-scan", wireless, tmp);
		ni_string_free(&tmp);
	}

	if (!ni_string_empty(wlan->conf.driver))
		xml_node_new_element("wpa-driver", wireless, wlan->conf.driver);

	count = wlan->conf.networks.count;

	for (i = 0; i < count; i++) {
		net = wlan->conf.networks.data[i];
		if (!(network = xml_node_new("network", wireless)))
			return FALSE;

		if (net->essid.len > 0) {
			ni_string_set(&tmp, (const char *) net->essid.data, net->essid.len);
			xml_node_new_element("essid", network, tmp);
			ni_string_free(&tmp);
		}

		xml_node_new_element("scan-ssid", network, net->scan_ssid?"true":"false");

		if (net->priority > 0 &&
			ni_string_printf(&tmp, "%u", net->priority)) {
			xml_node_new_element("priority", network, tmp);
			ni_string_free(&tmp);
		}

		if ((value = ni_wireless_mode_to_name(net->mode))) {
			xml_node_new_element("mode", network, value);
		}

		if (net->access_point.len > 0) {
			xml_node_new_element("access-point", network,
				ni_link_address_print(&net->access_point));
		}

		if (net->channel > 0 &&
			ni_string_printf(&tmp, "%u", net->channel)) {
			xml_node_new_element("channel", network, tmp);
			ni_string_free(&tmp);
		}

		if (net->fragment_size > 0 &&
			ni_string_printf(&tmp, "%u", net->fragment_size)) {
			xml_node_new_element("fragment-size", network, tmp);
			ni_string_free(&tmp);
		}

		if ((value = ni_wireless_key_management_to_name(net->keymgmt_proto))) {
			xml_node_new_element("key-management", network, value);
		}

		switch (net->keymgmt_proto) {
		case NI_WIRELESS_KEY_MGMT_NONE:
			if (!(wep = xml_node_new("wep", network))) {
				return FALSE;
			}

			if ((value = ni_wireless_auth_algo_to_name(net->auth_algo))) {
				xml_node_new_element("auth-algo", wep, value);
			}

			if (net->default_key < NI_WIRELESS_WEP_KEY_COUNT &&
				ni_string_printf(&tmp, "%u", net->default_key)) {
				xml_node_new_element("default-key", wep, tmp);
				ni_string_free(&tmp);
			}

			for (key_i = 0; key_i < NI_WIRELESS_WEP_KEY_COUNT; key_i++) {
				if (!ni_string_empty(net->wep_keys[key_i])) {
					/* To be secured */
					xml_node_new_element("key", wep, net->wep_keys[key_i]);
				}
			}

			break;
		case NI_WIRELESS_KEY_MGMT_PSK:
			if (!(wpa_psk = xml_node_new("wpa-psk", network))) {
				return FALSE;
			}

			if (!ni_string_empty(net->wpa_psk.passphrase)) {
				/* To be secured */
				xml_node_new_element("passphrase", wpa_psk,
					net->wpa_psk.passphrase);
			}

			if ((value = ni_wireless_auth_mode_to_name(net->auth_proto))) {
				xml_node_new_element("auth-proto", wpa_psk, value);
			}

			if ((value = ni_wireless_cipher_to_name(net->pairwise_cipher))) {
				xml_node_new_element("pairwise-cipher", wpa_psk, value);
			}

			if ((value = ni_wireless_cipher_to_name(net->group_cipher))) {
				xml_node_new_element("group-cipher", wpa_psk, value);
			}

			break;

		case NI_WIRELESS_KEY_MGMT_EAP:
			if (!(wpa_eap = xml_node_new("wpa-eap", network))) {
				return FALSE;
			}

			if ((value = ni_wireless_eap_method_to_name(net->wpa_eap.method))) {
				xml_node_new_element("method", wpa_eap, value);
			}

			if ((value = ni_wireless_auth_mode_to_name(net->auth_proto))) {
				xml_node_new_element("auth-proto", wpa_eap, value);
			}

			if ((value = ni_wireless_cipher_to_name(net->pairwise_cipher))) {
				xml_node_new_element("pairwise-cipher", wpa_eap, value);
			}

			if ((value = ni_wireless_cipher_to_name(net->group_cipher))) {
				xml_node_new_element("group-cipher", wpa_eap, value);
			}

			if (!ni_string_empty(net->wpa_eap.identity)) {
				xml_node_new_element("identity", wpa_eap, net->wpa_eap.identity);
			}

			xml_node_t *phase1 = xml_node_new("phase1", wpa_eap);

			if (ni_string_printf(&tmp, "%u", net->wpa_eap.phase1.peapver)) {
				xml_node_new_element("peap-version", phase1, tmp);
				ni_string_free(&tmp);
			}

			xml_node_t *phase2 = xml_node_new("phase2", wpa_eap);

			if ((value = ni_wireless_eap_method_to_name(net->wpa_eap.phase2.method))) {
				xml_node_new_element("method", phase2, value);
			}

			if (!ni_string_empty(net->wpa_eap.phase2.password)) {
				/* To be secured */
				xml_node_new_element("password", phase2,
						net->wpa_eap.phase2.password);
			}

			if (!ni_string_empty(net->wpa_eap.anonid)) {
				xml_node_new_element("anonid", wpa_eap, net->wpa_eap.anonid);
			}

			xml_node_t *tls = xml_node_new("tls", wpa_eap);

			if ((cert = net->wpa_eap.tls.ca_cert)) {
				if (!ni_string_empty(cert->name)) {
					xml_node_new_element("ca-cert", tls, cert->name);
					/* FIXME/ADDME file data and size exporting */
				}
			}

			if ((cert = net->wpa_eap.tls.client_cert)) {
				if (!ni_string_empty(cert->name)) {
					xml_node_new_element("client-cert", tls, cert->name);
					/* FIXME/ADDME file data and size exporting */
				}
			}

			if ((cert = net->wpa_eap.tls.client_key)) {
				if (!ni_string_empty(cert->name)) {
					xml_node_new_element("client-key", tls, cert->name);
					/* FIXME/ADDME file data and size exporting */
				}
			}

			if (!ni_string_empty(net->wpa_eap.tls.client_key_passwd)) {
				xml_node_new_element("client-key-passwd", tls,
						net->wpa_eap.tls.client_key_passwd);
				/* FIXME/ADDME file data and size exporting */
			}

			break;

		default:
			return FALSE;
			break;
		}
	}

	return TRUE;
}
Exemple #13
0
/*
 * Create a new TUN/TAP interface
 */
static ni_netdev_t *
__ni_objectmodel_tuntap_create(ni_netdev_t *cfg, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev = NULL;
	const char *iftype;
	const ni_tuntap_t *tuntap;
	const char *err;
	int rv;

	iftype = ni_linktype_type_to_name(cfg->link.type);
	if (cfg->link.type != NI_IFTYPE_TUN && cfg->link.type != NI_IFTYPE_TAP) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
			"BUG: Cannot handle %s type in tun/tap factory", iftype);
		return NULL;
	}

	ni_debug_dbus("%s.newDevice(name=%s)", iftype, cfg->name);
	tuntap = ni_netdev_get_tuntap(cfg);
	if ((err = ni_tuntap_validate(tuntap))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		return NULL;
	}

	if (ni_string_empty(cfg->name)) {
		if (ni_string_empty(cfg->name) &&
		    (cfg->name = (char *) ni_netdev_make_name(nc, iftype, 0))) {
			ni_string_dup(&cfg->name, cfg->name);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Unable to create %s interface: "
				"name argument missed", iftype);
			return NULL;
		}
		cfg->name = NULL;
	} else if(!ni_string_eq(cfg->name, cfg->name)) {
		ni_string_dup(&cfg->name, cfg->name);
	}

	if (cfg->link.type == NI_IFTYPE_TAP && cfg->link.hwaddr.len) {
		if (cfg->link.hwaddr.type == ARPHRD_VOID)
			cfg->link.hwaddr.type = ARPHRD_ETHER;

		if (cfg->link.hwaddr.type != ARPHRD_ETHER
		||  cfg->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
					"Cannot create %s interface: "
					"invalid ethernet address '%s'", iftype,
					ni_link_address_print(&cfg->link.hwaddr));
			return NULL;
		}
	}

	if ((rv = ni_system_tuntap_create(nc, cfg, &dev)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || dev == NULL
		|| (cfg->name && dev && !ni_string_eq(dev->name, cfg->name))) {
			ni_dbus_set_error_from_code(error, rv,
				"Unable to create %s interface %s",
				iftype, cfg->name);
			return NULL;
		}
		ni_debug_dbus("%s interface exists (and name matches)", iftype);
	}

	if (dev->link.type != cfg->link.type) {
		dbus_set_error(error,
			DBUS_ERROR_FAILED,
			"Unable to create %s: existing interface %s is of type %s",
			iftype, dev->name, ni_linktype_type_to_name(dev->link.type));
		return NULL;
	}

	return dev;
}