summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author0scar <qgt268@alumni.ku.dk>2024-12-30 20:10:53 +0000
committer0scar <qgt268@alumni.ku.dk>2024-12-30 20:11:22 +0000
commit6d1eefed8cc4c0eb39027a5c59622114e233322b (patch)
treeeb151451d80707be6aae43bb28a4a0b443f60cbc
parentb5b274ddb433150ca810d194ad051dea64bd5498 (diff)
Refactor internet interface status
-rw-r--r--status.c163
1 files changed, 118 insertions, 45 deletions
diff --git a/status.c b/status.c
index c134d1f..6b6c4a2 100644
--- a/status.c
+++ b/status.c
@@ -6,8 +6,8 @@
#include <linux/wireless.h>
#include <netinet/in.h>
#include <stdbool.h>
-#include <stdio.h>
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
@@ -47,6 +47,18 @@ struct battery_status {
float charge;
};
+#define ADDRSTRLEN \
+ (INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN
+struct interface_status {
+ enum { loopback, ethernet, wifi, wan } type;
+ struct {
+ char ip4[INET_ADDRSTRLEN];
+ char ip6[INET6_ADDRSTRLEN];
+ } address;
+ char ssid[IW_ESSID_MAX_SIZE + 1];
+ char* name;
+};
+
/* Prototypes */
void date(char* buf);
struct battery_status get_battery_status(const char* buf);
@@ -72,11 +84,11 @@ static char* battery_level_icon[] = {
static struct element statusbar[] = {
/* Add status elements here */
+ /*{element_function, {seconds, microseconds}, {0}, {0}},*/
{get_net_link_status, {5, 0}, {0}, {0}},
{ get_all_bat_status, {60, 0}, {0}, {0}},
{ date, {2, 500000}, {0}, {0}},
-
};
/* Functions */
@@ -176,73 +188,134 @@ get_all_bat_status(char* buf) {
}
void
+get_essid(char* if_name, char* dst) {
+ /* Get the SSID */
+ size_t l = strlen(if_name);
+ int sock = socket(AF_INET, SOCK_DGRAM, 0);
+ struct iwreq wreq;
+ memset(&wreq, 0, sizeof(struct iwreq));
+
+ setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, if_name, l);
+
+ 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) {
+ dst[0] = '\0';
+ }
+}
+
+struct interface_status status[8]; // surely noone has more than 8 interfaces.
+
+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);
for (struct ifaddrs* ifa = if_addr; ifa != NULL; ifa = ifa->ifa_next) {
+
+ /* We're not interested in interfaces that are not "up" */
+ if (!(ifa->ifa_flags & IFF_UP))
+ continue;
+
/* Ignore loopback interface flag */
if (ifa->ifa_flags & IFF_LOOPBACK)
continue;
- /* Ignore interfaces without an address */
- if (ifa->ifa_addr == NULL)
- continue;
+ ///* Ignore interfaces without an address */
+ // if (ifa->ifa_addr == NULL)
+ // continue;
- /* Ignore everythings not an IPv4 link */
- /* (AF_PACKET might be usefull if you want to display tx) */
- if (ifa->ifa_addr->sa_family != AF_INET)
- continue;
+ ///* Ignore everythings not an IPv4 link */
+ ///* (AF_PACKET might be usefull if you want to display tx) */
+ // if (ifa->ifa_addr->sa_family != AF_INET)
+ // continue;
+
+ /* Find the interface in status, if it exists */
+ struct interface_status* s = &status[c];
+ const char* name = ifa->ifa_name;
+
+ 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;
+
+ if (ifa->ifa_addr != NULL) {
+ const int family = ifa->ifa_addr->sa_family;
- if (ifa->ifa_flags & IFF_UP) {
+ size_t strsize = 0;
+ char* dst = NULL;
- size_t l = strlen(ifa->ifa_name);
- struct iwreq wreq;
- int sock;
- const size_t ipv6_charlen = 8 * 4 + 7;
- char address[ipv6_charlen + 1]; // in case of ipv6, plus null-byte
- char id[IW_ESSID_MAX_SIZE + 1];
+ if (family == AF_INET) {
+ strsize = INET_ADDRSTRLEN;
+ dst = s->address.ip4;
+ } else if (family == AF_INET6) {
+ strsize = INET6_ADDRSTRLEN;
+ dst = s->address.ip6;
+ } else if (family == AF_PACKET) {
+ continue;
+ } else
+ /* In this case, there's probably something horribly wrong */
+ continue;
/* Get the IP address */
- memset(address, 0, ipv6_charlen + 1);
- /* Use sa_family instead of hardcoding AF_INET, just in case
- * we get ip6'ed */
- /* Does inet_ntop add a null-byte? */
- inet_ntop(ifa->ifa_addr->sa_family,
- (void*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr, address,
- ipv6_charlen);
+ inet_ntop(family, (void*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr,
+ dst, strsize);
+ }
- /* Get the SSID */
- memset(id, 0, IW_ESSID_MAX_SIZE + 1);
- memset(&wreq, 0, sizeof(struct iwreq));
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifa->ifa_name, l);
+ // Get the ESSID
+ get_essid(s->name, s->ssid);
+ }
+ freeifaddrs(if_addr);
- strncpy(wreq.ifr_name, ifa->ifa_name, l);
+ for (int i = 0; i < c; i++) {
+ // int i = 0; {
+ struct interface_status* s = &status[i];
+ // Write the status string to the output buffer
+ const size_t namelen = strlen(s->name);
+ strncat(buf + n, s->name, namelen);
+ n += namelen;
- wreq.u.essid.pointer = id;
- wreq.u.essid.length = IW_ESSID_MAX_SIZE;
- ioctl(sock, SIOCGIWESSID, &wreq);
+ size_t ssid_len = strlen(s->ssid);
+ if (ssid_len > 0) {
+ buf[n++] = ' ';
+ buf[n++] = '(';
+ strncpy(buf + n, s->ssid, ssid_len);
+ n += ssid_len;
- strncpy(buf + n, ifa->ifa_name, l);
+ buf[n++] = ')';
+ }
- size_t ssid_len = strlen(id);
- if (ssid_len > 0) {
- buf[n + l] = ' ';
- buf[n + l + 1] = '(';
- strncpy(buf + n + l + 2, id, ssid_len);
- l += ssid_len;
- buf[n + l + 2] = ')';
+ { // Add the addresses
+ const size_t addr4_len = strlen(s->address.ip4);
+ if (addr4_len > 0) {
+ buf[n++] = ' ';
+ strncat(buf + n, s->address.ip4, addr4_len);
+ n += addr4_len;
}
- n += l;
-
- strcat(buf + n, address);
- n += strlen(address);
- strcat(buf + n, " ");
+ const size_t addr6_len = strlen(s->address.ip6);
+ if (addr6_len > 0) {
+ buf[n++] = ' ';
+ strncat(buf + n, s->address.ip6, addr6_len);
+ n += addr6_len;
+ }
+ }
+ if (i != c - 1) {
+ strncat(buf + n, " ", 3);
n += 2;
}
}