From 882c2f75a8d5bc66746d52a30f8f9456a0038da2 Mon Sep 17 00:00:00 2001 From: 0scar Date: Tue, 31 Dec 2024 02:26:20 +0100 Subject: Make internet link interfaces global state The idea is to specifically watch some interfaces, and put a fs inotify on them. Eventually... --- status.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 25 deletions(-) diff --git a/status.c b/status.c index 7a7f9fb..2d9922e 100644 --- a/status.c +++ b/status.c @@ -56,7 +56,7 @@ struct interface_status { char ip6[INET6_ADDRSTRLEN]; } address; char ssid[IW_ESSID_MAX_SIZE + 1]; - char* name; + char name[IFNAMSIZ]; }; /* Prototypes */ @@ -91,6 +91,8 @@ static struct element statusbar[] = { { date, {2, 500000}, {0}, {0}}, }; +struct interface_status interfaces[8]; // surely noone has more than 8 interfaces. + /* Functions */ void date(char* buf) { @@ -190,39 +192,80 @@ get_all_bat_status(char* buf) { void get_essid(char* if_name, char* dst) { /* Get the SSID */ + struct iwreq wreq; size_t l = strlen(if_name); int sock = socket(AF_INET, SOCK_DGRAM, 0); - struct iwreq wreq; + + if (sock == -1) { + return; + } + memset(&wreq, 0, sizeof(struct iwreq)); - setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, if_name, l); + if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, if_name, l) == -1) { + close(sock); + return; + } strncpy(wreq.ifr_name, if_name, l); wreq.u.essid.pointer = dst; wreq.u.essid.length = IW_ESSID_MAX_SIZE; - if (ioctl(sock, SIOCGIWESSID, &wreq) == -1) { + //printf("#%s#\n", dst); + + // Test if we have wireless on this interface + if (ioctl(sock, SIOCGIWNAME, &wreq) != -1) { + // protocol stored in wreq.u.name + close(sock); + return; + } + + if (ioctl(sock, SIOCGIWESSID, &wreq) < 0) { dst[0] = '\0'; } -} -struct interface_status status[8]; // surely noone has more than 8 interfaces. + close(sock); + +} void get_net_link_status(char* buf) { struct ifaddrs* if_addr; size_t n = 0; size_t c = 0; - struct interface_status status[8]; // surely noone has more than 8 interfaces. - memset(status, 0, sizeof(struct interface_status[8])); getifaddrs(&if_addr); + while (c < 8 && strlen(interfaces[c].name) > 0) { + c++; + } + for (struct ifaddrs* ifa = if_addr; ifa != NULL; ifa = ifa->ifa_next) { + int i = 0; + const char* name = ifa->ifa_name; + + while (i < c && strcmp(name, interfaces[i].name)) i++; + + //if (i != c) { + //printf("found %s in %d\n", name, i); + //} /* We're not interested in interfaces that are not "up" */ - if (!(ifa->ifa_flags & IFF_UP)) + if (!(ifa->ifa_flags & IFF_LOWER_UP)) { + /* Remove it from the list */ + if (i < c) { + /* Don't memmove if last element */ + if (c - i > 1) { + memmove(&interfaces[i], &interfaces[i + 1], sizeof(struct interface_status) * (c - i)); + } + + /* "wipe" last element */ + memset(&interfaces[c - 1], 0, sizeof(struct interface_status)); + + c--; + } continue; + } /* Ignore loopback interface flag */ if (ifa->ifa_flags & IFF_LOOPBACK) @@ -238,19 +281,10 @@ get_net_link_status(char* buf) { // continue; /* Find the interface in status, if it exists */ - struct interface_status* s = &status[c]; - const char* name = ifa->ifa_name; + struct interface_status s; // = &status[c]; + memset(&s, 0, sizeof(struct interface_status)); - int i = 0; - for (int i = 0; i < c; i++) { - if (!strcmp(name, status[i].name)) { - s = &status[i]; - } - } - if (i == c) - c++; - - s->name = ifa->ifa_name; + s = interfaces[i]; if (ifa->ifa_addr != NULL) { const int family = ifa->ifa_addr->sa_family; @@ -260,10 +294,10 @@ get_net_link_status(char* buf) { if (family == AF_INET) { strsize = INET_ADDRSTRLEN; - dst = s->address.ip4; + dst = s.address.ip4; } else if (family == AF_INET6) { strsize = INET6_ADDRSTRLEN; - dst = s->address.ip6; + dst = s.address.ip6; } else if (family == AF_PACKET) { continue; } else @@ -276,13 +310,28 @@ get_net_link_status(char* buf) { } // Get the ESSID - get_essid(s->name, s->ssid); + get_essid(s.name, s.ssid); + + /* if we got nothing out of it, don't increment */ + if (ifa->ifa_addr == NULL && strlen(s.ssid) == 0) + continue; + + /* If the interface didn't exist in interfaces before, we should add + * the name:) */ + if (i == c) { + strncpy(s.name, name, IFNAMSIZ); + c++; + } + + memcpy(&interfaces[i], &s, sizeof(struct interface_status)); + } freeifaddrs(if_addr); + memset(buf, 0, ELEMENT_STRBUF_SZ); for (int i = 0; i < c; i++) { // int i = 0; { - struct interface_status* s = &status[i]; + struct interface_status* s = &interfaces[i]; // Write the status string to the output buffer const size_t namelen = strlen(s->name); strncat(buf + n, s->name, namelen); @@ -327,6 +376,8 @@ main(void) { struct timeval now; const struct timeval one_minute = {60, 0}; + memset(interfaces, 0, sizeof(struct interface_status[8])); + while (true) { gettimeofday(&now, NULL); unsigned i; @@ -371,6 +422,8 @@ main(void) { memset(buf, 0, STATUS_STRBUF_SZ); for (i = 0; i < num_elems; i++) { + if (!strlen(statusbar[i].buf)) + continue; strcat(buf, statusbar[i].buf); if (i != num_elems - 1) strcat(buf, ELEMENT_SEPERATOR); -- cgit v1.3