aboutsummaryrefslogtreecommitdiff
path: root/miniwifi.c
blob: b85c38aad35585d256cf90d73c2f934364f6832c (plain)
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;
}