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