aboutsummaryrefslogtreecommitdiff
path: root/miniwifi.c
blob: 4b1ba57844d54d30df56809f938ad40a096c6488 (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
#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";

    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

    return 0;
}