]>
Commit | Line | Data |
---|---|---|
9ceb6854 | 1 | #include <net/if.h> |
9ceb6854 HS |
2 | |
3 | #include <netlink/genl/genl.h> | |
4 | #include <netlink/genl/family.h> | |
5 | #include <netlink/genl/ctrl.h> | |
6 | #include <netlink/msg.h> | |
7 | #include <netlink/attr.h> | |
8 | ||
9 | #include "nl80211.h" | |
10 | #include "iw.h" | |
11 | ||
12 | SECTION(survey); | |
13 | ||
14 | static int print_survey_handler(struct nl_msg *msg, void *arg) | |
15 | { | |
16 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; | |
17 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); | |
18 | struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1]; | |
19 | char dev[20]; | |
20 | ||
21 | static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = { | |
22 | [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 }, | |
23 | [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 }, | |
24 | }; | |
25 | ||
26 | nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), | |
27 | genlmsg_attrlen(gnlh, 0), NULL); | |
28 | ||
29 | if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); | |
30 | printf("Survey data from %s\n", dev); | |
31 | ||
32 | if (!tb[NL80211_ATTR_SURVEY_INFO]) { | |
33 | fprintf(stderr, "survey data missing!\n"); | |
34 | return NL_SKIP; | |
35 | } | |
36 | ||
37 | if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX, | |
38 | tb[NL80211_ATTR_SURVEY_INFO], | |
39 | survey_policy)) { | |
40 | fprintf(stderr, "failed to parse nested attributes!\n"); | |
41 | return NL_SKIP; | |
42 | } | |
43 | ||
44 | if (sinfo[NL80211_SURVEY_INFO_FREQUENCY]) | |
8b5faae4 | 45 | printf("\tfrequency:\t\t\t%u MHz%s\n", |
5a7a66be FF |
46 | nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]), |
47 | sinfo[NL80211_SURVEY_INFO_IN_USE] ? " [in use]" : ""); | |
9ceb6854 | 48 | if (sinfo[NL80211_SURVEY_INFO_NOISE]) |
8b5faae4 | 49 | printf("\tnoise:\t\t\t\t%d dBm\n", |
9ceb6854 | 50 | (int8_t)nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE])); |
8b5faae4 FF |
51 | if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) |
52 | printf("\tchannel active time:\t\t%llu ms\n", | |
53 | (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME])); | |
54 | if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) | |
55 | printf("\tchannel busy time:\t\t%llu ms\n", | |
56 | (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY])); | |
57 | if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY]) | |
58 | printf("\textension channel busy time:\t%llu ms\n", | |
59 | (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY])); | |
60 | if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) | |
61 | printf("\tchannel receive time:\t\t%llu ms\n", | |
62 | (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX])); | |
63 | if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) | |
64 | printf("\tchannel transmit time:\t\t%llu ms\n", | |
65 | (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX])); | |
9ceb6854 HS |
66 | return NL_SKIP; |
67 | } | |
68 | ||
69 | static int handle_survey_dump(struct nl80211_state *state, | |
05514f95 JB |
70 | struct nl_msg *msg, |
71 | int argc, char **argv, | |
72 | enum id_input id) | |
9ceb6854 | 73 | { |
34b23014 | 74 | register_handler(print_survey_handler, NULL); |
9ceb6854 HS |
75 | return 0; |
76 | } | |
77 | COMMAND(survey, dump, NULL, | |
78 | NL80211_CMD_GET_SURVEY, NLM_F_DUMP, CIB_NETDEV, handle_survey_dump, | |
79 | "List all gathered channel survey data"); | |
80 |