Xinqi Bao's Git
1 /* See LICENSE file for copyright and license details. */
6 #include <sys/socket.h>
11 #define RSSI_TO_PERC(rssi) \
16 #if defined(__linux__)
18 #include <linux/wireless.h>
21 wifi_perc(const char *interface
)
30 if (esnprintf(path
, sizeof(path
), "/sys/class/net/%s/operstate",
34 if (!(fp
= fopen(path
, "r"))) {
35 warn("fopen '%s':", path
);
38 p
= fgets(status
, 5, fp
);
40 if (!p
|| strcmp(status
, "up\n") != 0) {
44 if (!(fp
= fopen("/proc/net/wireless", "r"))) {
45 warn("fopen '/proc/net/wireless':");
49 for (i
= 0; i
< 3; i
++) {
50 if (!(p
= fgets(buf
, sizeof(buf
) - 1, fp
)))
58 if (!(datastart
= strstr(buf
, interface
))) {
62 datastart
= (datastart
+(strlen(interface
)+1));
63 sscanf(datastart
+ 1, " %*d %d %*d %*d\t\t %*d\t "
64 "%*d\t\t%*d\t\t %*d\t %*d\t\t %*d", &cur
);
66 /* 70 is the max of /proc/net/wireless */
67 return bprintf("%d", (int)((float)cur
/ 70 * 100));
71 wifi_essid(const char *interface
)
73 static char id
[IW_ESSID_MAX_SIZE
+1];
77 memset(&wreq
, 0, sizeof(struct iwreq
));
78 wreq
.u
.essid
.length
= IW_ESSID_MAX_SIZE
+1;
79 if (esnprintf(wreq
.ifr_name
, sizeof(wreq
.ifr_name
), "%s",
84 if ((sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
85 warn("socket 'AF_INET':");
88 wreq
.u
.essid
.pointer
= id
;
89 if (ioctl(sockfd
,SIOCGIWESSID
, &wreq
) < 0) {
90 warn("ioctl 'SIOCGIWESSID':");
97 if (!strcmp(id
, "")) {
103 #elif defined(__OpenBSD__)
105 #include <net/if_media.h>
106 #include <net80211/ieee80211.h>
107 #include <sys/select.h> /* before <sys/ieee80211_ioctl.h> for NBBY */
108 #include <net80211/ieee80211_ioctl.h>
110 #include <sys/types.h>
113 load_ieee80211_nodereq(const char *interface
, struct ieee80211_nodereq
*nr
)
115 struct ieee80211_bssid bssid
;
117 uint8_t zero_bssid
[IEEE80211_ADDR_LEN
];
119 memset(&bssid
, 0, sizeof(bssid
));
120 memset(nr
, 0, sizeof(struct ieee80211_nodereq
));
121 if ((sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
122 warn("socket 'AF_INET':");
125 strlcpy(bssid
.i_name
, interface
, sizeof(bssid
.i_name
));
126 if ((ioctl(sockfd
, SIOCG80211BSSID
, &bssid
)) < 0) {
127 warn("ioctl 'SIOCG80211BSSID':");
131 memset(&zero_bssid
, 0, sizeof(zero_bssid
));
132 if (memcmp(bssid
.i_bssid
, zero_bssid
,
133 IEEE80211_ADDR_LEN
) == 0) {
137 strlcpy(nr
->nr_ifname
, interface
, sizeof(nr
->nr_ifname
));
138 memcpy(&nr
->nr_macaddr
, bssid
.i_bssid
, sizeof(nr
->nr_macaddr
));
139 if ((ioctl(sockfd
, SIOCG80211NODE
, nr
)) < 0 && nr
->nr_rssi
) {
140 warn("ioctl 'SIOCG80211NODE':");
145 return close(sockfd
), 1;
149 wifi_perc(const char *interface
)
151 struct ieee80211_nodereq nr
;
154 if (load_ieee80211_nodereq(interface
, &nr
)) {
155 if (nr
.nr_max_rssi
) {
156 q
= IEEE80211_NODEREQ_RSSI(&nr
);
158 q
= RSSI_TO_PERC(nr
.nr_rssi
);
160 return bprintf("%d", q
);
167 wifi_essid(const char *interface
)
169 struct ieee80211_nodereq nr
;
171 if (load_ieee80211_nodereq(interface
, &nr
)) {
172 return bprintf("%s", nr
.nr_nwid
);
177 #elif defined(__FreeBSD__)
179 #include <net80211/ieee80211_ioctl.h>
182 load_ieee80211req(int sock
, const char *interface
, void *data
, int type
, size_t *len
)
185 struct ieee80211req ireq
;
186 memset(&ireq
, 0, sizeof(ireq
));
188 ireq
.i_data
= (caddr_t
) data
;
191 strlcpy(ireq
.i_name
, interface
, sizeof(ireq
.i_name
));
192 if (ioctl(sock
, SIOCG80211
, &ireq
) < 0) {
193 snprintf(warn_buf
, sizeof(warn_buf
),
194 "ioctl: 'SIOCG80211': %d", type
);
204 wifi_perc(const char *interface
)
207 struct ieee80211req_sta_req sta
;
208 uint8_t buf
[24 * 1024];
210 uint8_t bssid
[IEEE80211_ADDR_LEN
];
216 if ((sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
217 warn("socket 'AF_INET':");
221 /* Retreive MAC address of interface */
222 len
= IEEE80211_ADDR_LEN
;
224 if (load_ieee80211req(sockfd
, interface
, &bssid
, IEEE80211_IOC_BSSID
, &len
))
226 /* Retrieve info on station with above BSSID */
227 memset(&info
, 0, sizeof(info
));
228 memcpy(info
.sta
.is_u
.macaddr
, bssid
, sizeof(bssid
));
231 if (load_ieee80211req(sockfd
, interface
, &info
, IEEE80211_IOC_STA_INFO
, &len
)) {
232 rssi_dbm
= info
.sta
.info
[0].isi_noise
+
233 info
.sta
.info
[0].isi_rssi
/ 2;
235 fmt
= bprintf("%d", RSSI_TO_PERC(rssi_dbm
));
244 wifi_essid(const char *interface
)
246 char ssid
[IEEE80211_NWID_LEN
+ 1];
251 if ((sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
252 warn("socket 'AF_INET':");
258 memset(&ssid
, 0, len
);
259 if (load_ieee80211req(sockfd
, interface
, &ssid
, IEEE80211_IOC_SSID
, &len
)) {
260 if (len
< sizeof(ssid
))
265 ssid
[len
- 1] = '\0';
266 fmt
= bprintf("%s", ssid
);