1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include "wifi_scan.h"
#define COLOR_CONNECTED "#859900"
#define COLOR_DISCONNECTED "#dc322f"
#define ICON_CONNECTED "f05a9"
#define ICON_DISCONNECTED "f16bc"
int main() {
const char *ip_addr = NULL;
const char *ssid = NULL;
const char *color = NULL;
const char *icon = NULL;
const char *fmt = "<span color=\"%s\"><span font=\"Symbols Nerd Font\">&#x%s;</span> %s %s</span>\n";
#ifdef DEBUG
for (int i = 0; true; ++i) {
#else
for (;;) {
#endif
#ifdef DEBUG
printf("\nloop #%d:\n", ++i);
#endif
color = COLOR_DISCONNECTED;
icon = ICON_DISCONNECTED;
// check if wlan0 has an IP address
struct ifreq ifr;
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, "wlan0", IFNAMSIZ - 1);
int station_fd = socket(AF_INET, SOCK_DGRAM, 0);
int ioctl_res = ioctl(station_fd, SIOCGIFADDR, &ifr);
#ifdef DEBUG
if (ioctl_res < 0) {
perror("ioctl()");
}
#endif
close(station_fd);
ip_addr = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
#ifdef DEBUG
printf("ip_addr set to: %s\n", ip_addr);
#endif
if (ioctl_res != 0 || strcmp(ip_addr, "0.0.0.0") == 0) {
ssid = "-";
ip_addr = "-";
#ifdef DEBUG
printf("ioctl() failed or ip set to 0:0:0:0, ssid set to: %s, ip_addr set to: %s\n", ssid, ip_addr);
#endif
} else {
// get ssid in case we have an IP
struct station_info station;
wifi_scan_station(wifi_scan_init("wlan0"), &station);
ssid = station.ssid;
#ifdef DEBUG
printf("ssid set to: %s\n", ssid);
#endif
// lastly, check if we can ping google
struct sockaddr_in sock_in;
sock_in.sin_family = AF_INET;
sock_in.sin_port = htons(443);
inet_pton(AF_INET, "8.8.8.8", &sock_in.sin_addr);
int remote_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
int connect_res = connect(remote_fd, (struct sockaddr *)&sock_in, sizeof(sock_in));
#ifdef DEBUG
if (connect_res < 0) {
perror("connect()");
}
#endif
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(remote_fd, &fdset);
struct timeval tv = { .tv_sec = 1, .tv_usec = 0 };
int select_res = select(remote_fd + 1, NULL, &fdset, NULL, &tv);
#ifdef DEBUG
if (select_res < 0) {
perror("select()");
}
#endif
if (select_res == 1) {
#ifdef DEBUG
printf("select() returned 1\n");
#endif
int so_error;
socklen_t len = sizeof so_error;
getsockopt(remote_fd, SOL_SOCKET, SO_ERROR, &so_error, &len);
// we have a good connection
if (so_error == 0) {
#ifdef DEBUG
printf("so_error set to 0, we must have internet\n");
#endif
color = COLOR_CONNECTED;
icon = ICON_CONNECTED;
}
}
close(remote_fd);
}
// print results
#ifndef DEBUG
printf(fmt, color, icon, ssid, ip_addr);
#endif
fflush(stdout);
sleep(1);
}
return 0;
}
|