static int print_iface_handler(struct nl_msg *msg, void *arg)
{
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
	unsigned int *wiphy = arg;
	const char *indent = "";

	nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
		  genlmsg_attrlen(gnlh, 0), NULL);

	if (wiphy && tb_msg[NL80211_ATTR_WIPHY]) {
		unsigned int thiswiphy = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]);
		indent = "\t";
		if (*wiphy != thiswiphy)
			printf("phy#%d\n", thiswiphy);
		*wiphy = thiswiphy;
	}

	if (tb_msg[NL80211_ATTR_IFNAME])
		printf("%sInterface %s\n", indent, nla_get_string(tb_msg[NL80211_ATTR_IFNAME]));
	else
		printf("%sUnnamed/non-netdev interface\n", indent);
	if (tb_msg[NL80211_ATTR_IFINDEX])
		printf("%s\tifindex %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX]));
	if (tb_msg[NL80211_ATTR_WDEV])
		printf("%s\twdev 0x%llx\n", indent,
		       (unsigned long long)nla_get_u64(tb_msg[NL80211_ATTR_WDEV]));
	if (tb_msg[NL80211_ATTR_MAC]) {
		char mac_addr[20];
		mac_addr_n2a(mac_addr, nla_data(tb_msg[NL80211_ATTR_MAC]));
		printf("%s\taddr %s\n", indent, mac_addr);
	}
	if (tb_msg[NL80211_ATTR_SSID]) {
		printf("%s\tssid ", indent);
		print_ssid_escaped(nla_len(tb_msg[NL80211_ATTR_SSID]),
				   nla_data(tb_msg[NL80211_ATTR_SSID]));
		printf("\n");
	}
	if (tb_msg[NL80211_ATTR_IFTYPE])
		printf("%s\ttype %s\n", indent, iftype_name(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE])));
	if (!wiphy && tb_msg[NL80211_ATTR_WIPHY])
		printf("%s\twiphy %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]));
	if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
		uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);

		printf("%s\tchannel %d (%d MHz)", indent,
		       ieee80211_frequency_to_channel(freq), freq);

		if (tb_msg[NL80211_ATTR_CHANNEL_WIDTH]) {
			printf(", width: %s",
				channel_width_name(nla_get_u32(tb_msg[NL80211_ATTR_CHANNEL_WIDTH])));
			if (tb_msg[NL80211_ATTR_CENTER_FREQ1])
				printf(", center1: %d MHz",
					nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ1]));
			if (tb_msg[NL80211_ATTR_CENTER_FREQ2])
				printf(", center2: %d MHz",
					nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ2]));
		} else if (tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
			enum nl80211_channel_type channel_type;

			channel_type = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
			printf(" %s", channel_type_name(channel_type));
		}

		printf("\n");
	}

	return NL_SKIP;
}
Beispiel #2
0
static int print_wowlan_handler(struct nl_msg *msg, void *arg)
{
	struct nlattr *attrs[NL80211_ATTR_MAX + 1];
	struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG];
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	struct nlattr *pattern;
	int rem_pattern;

	nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
		  genlmsg_attrlen(gnlh, 0), NULL);

	if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
		printf("WoWLAN is disabled.\n");
		return NL_SKIP;
	}

	/* XXX: use policy */
	nla_parse(trig, MAX_NL80211_WOWLAN_TRIG,
		  nla_data(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
		  nla_len(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
		  NULL);

	printf("WoWLAN is enabled:\n");
	if (trig[NL80211_WOWLAN_TRIG_ANY])
		printf(" * wake up on special any trigger\n");
	if (trig[NL80211_WOWLAN_TRIG_DISCONNECT])
		printf(" * wake up on disconnect\n");
	if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT])
		printf(" * wake up on magic packet\n");
	if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
		printf(" * wake up on GTK rekeying failure\n");
	if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
		printf(" * wake up on EAP identity request\n");
	if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
		printf(" * wake up on 4-way handshake\n");
	if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
		printf(" * wake up on RF-kill release\n");
	if (trig[NL80211_WOWLAN_TRIG_NET_DETECT]) {
		struct nlattr *match, *freq,
			*nd[NUM_NL80211_ATTR], *tb[NUM_NL80211_ATTR];
		int rem_match;

		printf(" * wake up on network detection\n");
		nla_parse(nd, NUM_NL80211_ATTR,
			  nla_data(trig[NL80211_WOWLAN_TRIG_NET_DETECT]),
			  nla_len(trig[NL80211_WOWLAN_TRIG_NET_DETECT]), NULL);

		if (nd[NL80211_ATTR_SCHED_SCAN_INTERVAL])
			printf("\tscan interval: %u msecs\n",
			       nla_get_u32(nd[NL80211_ATTR_SCHED_SCAN_INTERVAL]));

		if (nd[NL80211_ATTR_SCHED_SCAN_DELAY])
			printf("\tinitial scan delay: %u secs\n",
			       nla_get_u32(nd[NL80211_ATTR_SCHED_SCAN_DELAY]));

		if (nd[NL80211_ATTR_SCHED_SCAN_MATCH]) {
			printf("\tmatches:\n");
			nla_for_each_nested(match,
					    nd[NL80211_ATTR_SCHED_SCAN_MATCH],
					    rem_match) {
				nla_parse(tb, NUM_NL80211_ATTR, nla_data(match),
					  nla_len(match),
					  NULL);
				printf("\t\tSSID: ");
				print_ssid_escaped(
					nla_len(tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]),
					nla_data(tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]));
				printf("\n");
			}
		}
		if (nd[NL80211_ATTR_SCAN_FREQUENCIES]) {
			printf("\tfrequencies:");
			nla_for_each_nested(freq,
					    nd[NL80211_ATTR_SCAN_FREQUENCIES],
					    rem_match) {
				printf(" %d", nla_get_u32(freq));
			}
			printf("\n");
		}