diff --git a/package/libgluonutil/src/libgluonutil.c b/package/libgluonutil/src/libgluonutil.c index e7a88fd1..0950f0d8 100644 --- a/package/libgluonutil/src/libgluonutil.c +++ b/package/libgluonutil/src/libgluonutil.c @@ -28,13 +28,16 @@ #include #include + #include + +#include +#include +#include #include #include #include #include -#include -#include /** * Merges two JSON objects @@ -129,6 +132,74 @@ char * gluonutil_get_interface_address(const char *ifname) { return gluonutil_read_line(path); } +void gluonutil_get_interface_lower(char out[IF_NAMESIZE], const char *ifname) { + strncpy(out, ifname, IF_NAMESIZE-1); + out[IF_NAMESIZE-1] = 0; + + const char *format = "/sys/class/net/%s/lower_*"; + char pattern[strlen(format) + IF_NAMESIZE]; + + while (true) { + snprintf(pattern, sizeof(pattern), format, out); + size_t pattern_len = strlen(pattern); + + glob_t lower; + if (glob(pattern, GLOB_NOSORT, NULL, &lower) != 0) + break; + + strncpy(out, lower.gl_pathv[0] + pattern_len - 1, IF_NAMESIZE-1); + + globfree(&lower); + } +} + +enum gluonutil_interface_type lookup_interface_type(const char *devtype) { + if (strcmp(devtype, "wlan") == 0) + return GLUONUTIL_INTERFACE_TYPE_WIRELESS; + + if (strcmp(devtype, "l2tpeth") == 0 || strcmp(devtype, "wireguard") == 0) + return GLUONUTIL_INTERFACE_TYPE_TUNNEL; + + /* Regular wired interfaces do not set DEVTYPE, so if this point is + * reached, we have something different */ + return GLUONUTIL_INTERFACE_TYPE_UNKNOWN; +} + +enum gluonutil_interface_type gluonutil_get_interface_type(const char *ifname) { + const char *pattern = "/sys/class/net/%s/%s"; + + /* Default to wired type when no DEVTYPE is set */ + enum gluonutil_interface_type ret = GLUONUTIL_INTERFACE_TYPE_WIRED; + char *line = NULL, path[PATH_MAX]; + size_t buflen = 0; + ssize_t len; + FILE *f; + + snprintf(path, sizeof(path), pattern, ifname, "tun_flags"); + if (access(path, F_OK) == 0) + return GLUONUTIL_INTERFACE_TYPE_TUNNEL; + + snprintf(path, sizeof(path), pattern, ifname, "uevent"); + f = fopen(path, "r"); + if (!f) + return GLUONUTIL_INTERFACE_TYPE_UNKNOWN; + + while ((len = getline(&line, &buflen, f)) >= 0) { + if (len == 0) + continue; + + if (line[len-1] == '\n') + line[len-1] = '\0'; + + if (strncmp(line, "DEVTYPE=", 8) == 0) { + ret = lookup_interface_type(line+8); + break; + } + } + + fclose(f); + return ret; +} struct json_object * gluonutil_wrap_string(const char *str) { diff --git a/package/libgluonutil/src/libgluonutil.h b/package/libgluonutil/src/libgluonutil.h index 39b253ba..b33b93e7 100644 --- a/package/libgluonutil/src/libgluonutil.h +++ b/package/libgluonutil/src/libgluonutil.h @@ -27,6 +27,7 @@ #ifndef _LIBGLUON_LIBGLUON_H_ #define _LIBGLUON_LIBGLUON_H_ +#include #include #include @@ -34,7 +35,18 @@ char * gluonutil_read_line(const char *filename); char * gluonutil_get_sysconfig(const char *key); char * gluonutil_get_node_id(void); + +enum gluonutil_interface_type { + GLUONUTIL_INTERFACE_TYPE_UNKNOWN, + GLUONUTIL_INTERFACE_TYPE_WIRED, + GLUONUTIL_INTERFACE_TYPE_WIRELESS, + GLUONUTIL_INTERFACE_TYPE_TUNNEL, +}; + +void gluonutil_get_interface_lower(char out[IF_NAMESIZE], const char *ifname); char * gluonutil_get_interface_address(const char *ifname); +enum gluonutil_interface_type gluonutil_get_interface_type(const char *ifname); + bool gluonutil_get_node_prefix6(struct in6_addr *prefix); struct json_object * gluonutil_wrap_string(const char *str);