libgluonutil: introduce gluonutil_get_interface_lower() and gluonutil_get_interface_type()
gluonutil_get_interface_lower() recursively determines the lower of an interface until the base interface is found. gluonutil_get_interface_type() tries do distinguish wired, wireless and tunnel interfaces. For tunnel interfaces, TUN/TAP, L2TPETH and Wireguard are supported at the moment.
This commit is contained in:
		
							parent
							
								
									72c71d35ac
								
							
						
					
					
						commit
						41b3c91284
					
				| @ -28,13 +28,16 @@ | ||||
| 
 | ||||
| #include <json-c/json.h> | ||||
| #include <uci.h> | ||||
| 
 | ||||
| #include <arpa/inet.h> | ||||
| 
 | ||||
| #include <errno.h> | ||||
| #include <glob.h> | ||||
| #include <limits.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <limits.h> | ||||
| #include <errno.h> | ||||
| 
 | ||||
| /**
 | ||||
|  * 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) { | ||||
|  | ||||
| @ -27,6 +27,7 @@ | ||||
| #ifndef _LIBGLUON_LIBGLUON_H_ | ||||
| #define _LIBGLUON_LIBGLUON_H_ | ||||
| 
 | ||||
| #include <net/if.h> | ||||
| #include <netinet/in.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| @ -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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user