]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
b492aea0 | 2 | |
b492aea0 | 3 | #include "log.h" |
b492aea0 ZJS |
4 | #include "wifi-util.h" |
5 | ||
78404d22 | 6 | int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftype, char **ssid) { |
b492aea0 | 7 | _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL; |
2324fd3a | 8 | sd_genl_family_t family; |
b492aea0 ZJS |
9 | int r; |
10 | ||
cc17c4c9 YW |
11 | assert(genl); |
12 | assert(ifindex > 0); | |
13 | ||
b492aea0 ZJS |
14 | r = sd_genl_message_new(genl, SD_GENL_NL80211, NL80211_CMD_GET_INTERFACE, &m); |
15 | if (r < 0) | |
16 | return log_debug_errno(r, "Failed to create generic netlink message: %m"); | |
17 | ||
18 | r = sd_netlink_message_append_u32(m, NL80211_ATTR_IFINDEX, ifindex); | |
19 | if (r < 0) | |
20 | return log_debug_errno(r, "Could not append NL80211_ATTR_IFINDEX attribute: %m"); | |
21 | ||
22 | r = sd_netlink_call(genl, m, 0, &reply); | |
cc17c4c9 YW |
23 | if (r == -ENODEV) { |
24 | /* For obsolete WEXT driver. */ | |
25 | log_debug_errno(r, "Failed to request information about wifi interface %d. " | |
26 | "The device doesn't seem to have nl80211 interface. Ignoring.", | |
27 | ifindex); | |
28 | goto nodata; | |
29 | } | |
b492aea0 ZJS |
30 | if (r < 0) |
31 | return log_debug_errno(r, "Failed to request information about wifi interface %d: %m", ifindex); | |
a66a402d | 32 | if (!reply) { |
66205cb3 | 33 | log_debug("No reply received to request for information about wifi interface %d, ignoring.", ifindex); |
cc17c4c9 | 34 | goto nodata; |
a66a402d | 35 | } |
b492aea0 ZJS |
36 | |
37 | r = sd_netlink_message_get_errno(reply); | |
38 | if (r < 0) | |
39 | return log_debug_errno(r, "Failed to get information about wifi interface %d: %m", ifindex); | |
40 | ||
41 | r = sd_genl_message_get_family(genl, reply, &family); | |
42 | if (r < 0) | |
43 | return log_debug_errno(r, "Failed to determine genl family: %m"); | |
44 | if (family != SD_GENL_NL80211) { | |
386059e1 | 45 | log_debug("Received message of unexpected genl family %" PRIi64 ", ignoring.", family); |
cc17c4c9 | 46 | goto nodata; |
b492aea0 ZJS |
47 | } |
48 | ||
78404d22 YW |
49 | if (iftype) { |
50 | uint32_t t; | |
51 | ||
52 | r = sd_netlink_message_read_u32(reply, NL80211_ATTR_IFTYPE, &t); | |
53 | if (r < 0) | |
54 | return log_debug_errno(r, "Failed to get NL80211_ATTR_IFTYPE attribute: %m"); | |
55 | *iftype = t; | |
56 | } | |
57 | ||
58 | if (ssid) { | |
59 | r = sd_netlink_message_read_string_strdup(reply, NL80211_ATTR_SSID, ssid); | |
cc17c4c9 | 60 | if (r == -ENODATA) |
a66a402d YW |
61 | *ssid = NULL; |
62 | else if (r < 0) | |
78404d22 YW |
63 | return log_debug_errno(r, "Failed to get NL80211_ATTR_SSID attribute: %m"); |
64 | } | |
b492aea0 | 65 | |
cc17c4c9 YW |
66 | return 1; |
67 | ||
68 | nodata: | |
69 | if (iftype) | |
70 | *iftype = 0; | |
71 | if (ssid) | |
72 | *ssid = NULL; | |
73 | return 0; | |
b492aea0 ZJS |
74 | } |
75 | ||
78404d22 | 76 | int wifi_get_station(sd_netlink *genl, int ifindex, struct ether_addr *bssid) { |
b492aea0 | 77 | _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL; |
2324fd3a | 78 | sd_genl_family_t family; |
b492aea0 ZJS |
79 | int r; |
80 | ||
cc17c4c9 YW |
81 | assert(genl); |
82 | assert(ifindex > 0); | |
83 | assert(bssid); | |
84 | ||
b492aea0 ZJS |
85 | r = sd_genl_message_new(genl, SD_GENL_NL80211, NL80211_CMD_GET_STATION, &m); |
86 | if (r < 0) | |
87 | return log_debug_errno(r, "Failed to create generic netlink message: %m"); | |
88 | ||
89 | r = sd_netlink_message_set_flags(m, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP); | |
90 | if (r < 0) | |
91 | return log_debug_errno(r, "Failed to set dump flag: %m"); | |
92 | ||
93 | r = sd_netlink_message_append_u32(m, NL80211_ATTR_IFINDEX, ifindex); | |
94 | if (r < 0) | |
95 | return log_debug_errno(r, "Could not append NL80211_ATTR_IFINDEX attribute: %m"); | |
96 | ||
97 | r = sd_netlink_call(genl, m, 0, &reply); | |
98 | if (r < 0) | |
99 | return log_debug_errno(r, "Failed to request information about wifi station: %m"); | |
a66a402d | 100 | if (!reply) { |
66205cb3 | 101 | log_debug("No reply received to request for information about wifi station, ignoring."); |
cc17c4c9 | 102 | goto nodata; |
a66a402d | 103 | } |
b492aea0 ZJS |
104 | |
105 | r = sd_netlink_message_get_errno(reply); | |
106 | if (r < 0) | |
107 | return log_debug_errno(r, "Failed to get information about wifi station: %m"); | |
108 | ||
109 | r = sd_genl_message_get_family(genl, reply, &family); | |
110 | if (r < 0) | |
111 | return log_debug_errno(r, "Failed to determine genl family: %m"); | |
112 | if (family != SD_GENL_NL80211) { | |
386059e1 | 113 | log_debug("Received message of unexpected genl family %" PRIi64 ", ignoring.", family); |
cc17c4c9 | 114 | goto nodata; |
b492aea0 ZJS |
115 | } |
116 | ||
117 | r = sd_netlink_message_read_ether_addr(reply, NL80211_ATTR_MAC, bssid); | |
cc17c4c9 YW |
118 | if (r == -ENODATA) |
119 | goto nodata; | |
120 | if (r < 0) | |
b492aea0 ZJS |
121 | return log_debug_errno(r, "Failed to get NL80211_ATTR_MAC attribute: %m"); |
122 | ||
cc17c4c9 YW |
123 | return 1; |
124 | ||
125 | nodata: | |
126 | *bssid = (struct ether_addr) {}; | |
127 | return 0; | |
b492aea0 | 128 | } |