]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/wifi-util.c
network: rename wifi_iftype -> wlan_iftype
[thirdparty/systemd.git] / src / shared / wifi-util.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
b492aea0 2
b492aea0 3#include "log.h"
abad436d 4#include "string-table.h"
56fdc16d 5#include "string-util.h"
b492aea0
ZJS
6#include "wifi-util.h"
7
ae2b86de 8int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *ret_iftype, char **ret_ssid) {
b492aea0 9 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL;
ae2b86de 10 _cleanup_free_ char *ssid = NULL;
56fdc16d 11 const char *family;
ae2b86de 12 uint32_t iftype;
f3e235ff 13 size_t len;
b492aea0
ZJS
14 int r;
15
cc17c4c9
YW
16 assert(genl);
17 assert(ifindex > 0);
18
56fdc16d 19 r = sd_genl_message_new(genl, NL80211_GENL_NAME, NL80211_CMD_GET_INTERFACE, &m);
b492aea0
ZJS
20 if (r < 0)
21 return log_debug_errno(r, "Failed to create generic netlink message: %m");
22
23 r = sd_netlink_message_append_u32(m, NL80211_ATTR_IFINDEX, ifindex);
24 if (r < 0)
25 return log_debug_errno(r, "Could not append NL80211_ATTR_IFINDEX attribute: %m");
26
27 r = sd_netlink_call(genl, m, 0, &reply);
cc17c4c9
YW
28 if (r == -ENODEV) {
29 /* For obsolete WEXT driver. */
30 log_debug_errno(r, "Failed to request information about wifi interface %d. "
31 "The device doesn't seem to have nl80211 interface. Ignoring.",
32 ifindex);
33 goto nodata;
34 }
b492aea0
ZJS
35 if (r < 0)
36 return log_debug_errno(r, "Failed to request information about wifi interface %d: %m", ifindex);
a66a402d 37 if (!reply) {
66205cb3 38 log_debug("No reply received to request for information about wifi interface %d, ignoring.", ifindex);
cc17c4c9 39 goto nodata;
a66a402d 40 }
b492aea0
ZJS
41
42 r = sd_netlink_message_get_errno(reply);
43 if (r < 0)
44 return log_debug_errno(r, "Failed to get information about wifi interface %d: %m", ifindex);
45
56fdc16d 46 r = sd_genl_message_get_family_name(genl, reply, &family);
b492aea0
ZJS
47 if (r < 0)
48 return log_debug_errno(r, "Failed to determine genl family: %m");
56fdc16d
YW
49 if (!streq(family, NL80211_GENL_NAME)) {
50 log_debug("Received message of unexpected genl family '%s', ignoring.", family);
cc17c4c9 51 goto nodata;
b492aea0
ZJS
52 }
53
ae2b86de
YW
54 r = sd_netlink_message_read_u32(reply, NL80211_ATTR_IFTYPE, &iftype);
55 if (r < 0)
56 return log_debug_errno(r, "Failed to get NL80211_ATTR_IFTYPE attribute: %m");
78404d22 57
f3e235ff 58 r = sd_netlink_message_read_data_suffix0(reply, NL80211_ATTR_SSID, &len, (void**) &ssid);
ae2b86de
YW
59 if (r < 0 && r != -ENODATA)
60 return log_debug_errno(r, "Failed to get NL80211_ATTR_SSID attribute: %m");
f3e235ff
YW
61 if (r >= 0) {
62 if (len == 0) {
63 log_debug("SSID has zero length, ignoring the received SSID.");
64 ssid = mfree(ssid);
65 } else if (strlen_ptr(ssid) != len) {
66 log_debug("SSID contains NUL character(s), ignoring the received SSID.");
67 ssid = mfree(ssid);
68 }
69 }
78404d22 70
ae2b86de
YW
71 if (ret_iftype)
72 *ret_iftype = iftype;
73
74 if (ret_ssid)
75 *ret_ssid = TAKE_PTR(ssid);
b492aea0 76
cc17c4c9
YW
77 return 1;
78
79nodata:
ae2b86de
YW
80 if (ret_iftype)
81 *ret_iftype = 0;
82 if (ret_ssid)
83 *ret_ssid = NULL;
cc17c4c9 84 return 0;
b492aea0
ZJS
85}
86
ae2b86de 87int wifi_get_station(sd_netlink *genl, int ifindex, struct ether_addr *ret_bssid) {
b492aea0 88 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL;
56fdc16d 89 const char *family;
b492aea0
ZJS
90 int r;
91
cc17c4c9
YW
92 assert(genl);
93 assert(ifindex > 0);
ae2b86de 94 assert(ret_bssid);
cc17c4c9 95
56fdc16d 96 r = sd_genl_message_new(genl, NL80211_GENL_NAME, NL80211_CMD_GET_STATION, &m);
b492aea0
ZJS
97 if (r < 0)
98 return log_debug_errno(r, "Failed to create generic netlink message: %m");
99
100 r = sd_netlink_message_set_flags(m, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
101 if (r < 0)
102 return log_debug_errno(r, "Failed to set dump flag: %m");
103
104 r = sd_netlink_message_append_u32(m, NL80211_ATTR_IFINDEX, ifindex);
105 if (r < 0)
106 return log_debug_errno(r, "Could not append NL80211_ATTR_IFINDEX attribute: %m");
107
108 r = sd_netlink_call(genl, m, 0, &reply);
109 if (r < 0)
110 return log_debug_errno(r, "Failed to request information about wifi station: %m");
a66a402d 111 if (!reply) {
66205cb3 112 log_debug("No reply received to request for information about wifi station, ignoring.");
cc17c4c9 113 goto nodata;
a66a402d 114 }
b492aea0
ZJS
115
116 r = sd_netlink_message_get_errno(reply);
117 if (r < 0)
118 return log_debug_errno(r, "Failed to get information about wifi station: %m");
119
56fdc16d 120 r = sd_genl_message_get_family_name(genl, reply, &family);
b492aea0
ZJS
121 if (r < 0)
122 return log_debug_errno(r, "Failed to determine genl family: %m");
56fdc16d
YW
123 if (!streq(family, NL80211_GENL_NAME)) {
124 log_debug("Received message of unexpected genl family '%s', ignoring.", family);
cc17c4c9 125 goto nodata;
b492aea0
ZJS
126 }
127
ae2b86de 128 r = sd_netlink_message_read_ether_addr(reply, NL80211_ATTR_MAC, ret_bssid);
cc17c4c9
YW
129 if (r == -ENODATA)
130 goto nodata;
131 if (r < 0)
b492aea0
ZJS
132 return log_debug_errno(r, "Failed to get NL80211_ATTR_MAC attribute: %m");
133
cc17c4c9
YW
134 return 1;
135
136nodata:
ae2b86de 137 *ret_bssid = ETHER_ADDR_NULL;
cc17c4c9 138 return 0;
b492aea0 139}
abad436d
YW
140
141static const char * const nl80211_iftype_table[NUM_NL80211_IFTYPES] = {
142 [NL80211_IFTYPE_ADHOC] = "ad-hoc",
143 [NL80211_IFTYPE_STATION] = "station",
144 [NL80211_IFTYPE_AP] = "ap",
145 [NL80211_IFTYPE_AP_VLAN] = "ap-vlan",
146 [NL80211_IFTYPE_WDS] = "wds",
147 [NL80211_IFTYPE_MONITOR] = "monitor",
148 [NL80211_IFTYPE_MESH_POINT] = "mesh-point",
149 [NL80211_IFTYPE_P2P_CLIENT] = "p2p-client",
150 [NL80211_IFTYPE_P2P_GO] = "p2p-go",
151 [NL80211_IFTYPE_P2P_DEVICE] = "p2p-device",
152 [NL80211_IFTYPE_OCB] = "ocb",
153 [NL80211_IFTYPE_NAN] = "nan",
154};
155
156DEFINE_STRING_TABLE_LOOKUP_TO_STRING(nl80211_iftype, enum nl80211_iftype);