]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/wifi-util.c
sd-netlink: split message_new() into two parts and introduces message_new_full()
[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"
b492aea0
ZJS
4#include "wifi-util.h"
5
78404d22 6int 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
68nodata:
69 if (iftype)
70 *iftype = 0;
71 if (ssid)
72 *ssid = NULL;
73 return 0;
b492aea0
ZJS
74}
75
78404d22 76int 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
125nodata:
126 *bssid = (struct ether_addr) {};
127 return 0;
b492aea0 128}