summaryrefslogtreecommitdiffstats
path: root/ffvisd
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-08-28 16:47:35 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-08-28 16:47:35 +0200
commit46184653cf903bf49b7b5b71488124315cc55135 (patch)
tree34c2e1a3f7296a0f1cfe5c60b11877aa9ce97acb /ffvisd
parent33ef1a62c5fac968d05f34e9e48bc8f4108a437f (diff)
downloadffd-46184653cf903bf49b7b5b71488124315cc55135.tar
ffd-46184653cf903bf49b7b5b71488124315cc55135.zip
Some cleanup
Diffstat (limited to 'ffvisd')
-rw-r--r--ffvisd/ffvisd.c102
1 files changed, 80 insertions, 22 deletions
diff --git a/ffvisd/ffvisd.c b/ffvisd/ffvisd.c
index 309fad2..a169e89 100644
--- a/ffvisd/ffvisd.c
+++ b/ffvisd/ffvisd.c
@@ -26,15 +26,21 @@
#define _GNU_SOURCE
+#include <libgen.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/types.h>
-#include <dirent.h>
+#include <unistd.h>
+
+#include <net/ethernet.h>
#include <net/if.h>
+#include <net/if_arp.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
#define ANNOUNCE_INTERVAL 20
@@ -43,12 +49,15 @@
#define SYSFS_PATH_MAX 256
#define SYSFS_CLASS_NET "/sys/class/net"
+#define FFD_MAGIC 0xffd
+#define FFVISD_VERSION 0
+
//static char *mesh = "bat0";
typedef struct _ffvisd_eth_address_t {
- uint8_t address[6];
+ uint8_t address[ETH_ALEN];
} ffvisd_eth_address_t;
typedef struct _ffvisd_ipv6_host_address_t {
@@ -63,20 +72,39 @@ typedef struct _ffvisd_server_announce_t {
} ffvisd_server_announce_t;
typedef struct _ffvisd_announce_t {
- uint32_t magic;
- uint32_t version;
+ uint16_t magic;
+ uint16_t version;
uint32_t n_servers;
uint32_t reserved;
ffvisd_server_announce_t servers[];
} ffvisd_announce_t;
+typedef enum _ffvisd_iftype_t {
+ IF_UNKNOWN = 0,
+ IF_WIRED,
+ IF_WIRELESS,
+ IF_VIRTUAL,
+ IF_BRIDGE,
+ IF_MESH,
+ IF_MAX
+} ffvisd_iftype_t;
+
typedef struct _ffvisd_iface_t {
unsigned ifindex;
- unsigned iftype;
+ ffvisd_iftype_t iftype;
char *ifname;
+ char *bridge_iface;
char *mesh_iface;
} ffvisd_iface_t;
+static const char *ffvisd_iftype_names[IF_MAX] = {
+ [IF_UNKNOWN] = "unknown",
+ [IF_WIRED] = "wired",
+ [IF_WIRELESS] = "wireless",
+ [IF_VIRTUAL] = "virtual",
+ [IF_BRIDGE] = "bridge",
+ [IF_MESH] = "mesh",
+};
typedef void (*iface_cb)(const ffvisd_iface_t *iface, void *arg);
@@ -109,58 +137,88 @@ bool iface_file_read(const char *ifname, const char *file, const char *format, .
return ret;
}
-ffvisd_iface_t* ffvisd_iface_new(const char *ifname) {
- ffvisd_iface_t *iface = calloc(1, sizeof(ffvisd_iface_t));
+bool iface_file_exists(const char *ifname, const char *file) {
+ char filename[SYSFS_PATH_MAX];
- iface->ifname = strdup(ifname);
+ snprintf(filename, SYSFS_PATH_MAX, SYSFS_CLASS_NET"/%s/%s", ifname, file);
- if (!iface_file_read(ifname, "ifindex", "%u", &iface->ifindex)) {
- ffvisd_iface_free(iface);
+ struct stat st;
+ return (stat(filename, &st) == 0);
+}
+
+char* get_bridge(const char *ifname) {
+ char filename[SYSFS_PATH_MAX], filename2[SYSFS_PATH_MAX] = {0};
+
+ snprintf(filename, SYSFS_PATH_MAX, SYSFS_CLASS_NET"/%s/brport/bridge", ifname);
+ if (readlink(filename, filename2, sizeof(filename2)) < 0)
return NULL;
- }
+
+ return strdup(basename(filename2));
+}
+
+ffvisd_iface_t* ffvisd_iface_new(const char *ifname, unsigned ifindex) {
+ ffvisd_iface_t *iface = calloc(1, sizeof(ffvisd_iface_t));
+
+ iface->ifname = strdup(ifname);
+ iface->ifindex = ifindex;
if (!iface_file_read(ifname, "batman_adv/mesh_iface", "%as", &iface->mesh_iface) || !strcmp(iface->mesh_iface, "none")) {
free(iface->mesh_iface);
iface->mesh_iface = NULL;
}
+ iface->bridge_iface = get_bridge(ifname);
+
+ int type;
+ if (iface_file_read(ifname, "type", "%i", &type) && type == ARPHRD_ETHER) {
+ if(iface_file_exists(ifname, "mesh"))
+ iface->iftype = IF_MESH;
+ else if(iface_file_exists(ifname, "bridge"))
+ iface->iftype = IF_BRIDGE;
+ else if(iface_file_exists(ifname, "tun_flags"))
+ iface->iftype = IF_VIRTUAL;
+ else if(iface_file_exists(ifname, "wireless"))
+ iface->iftype = IF_WIRELESS;
+ else
+ iface->iftype = IF_WIRED;
+ }
+
return iface;
}
void ffvisd_iface_free(ffvisd_iface_t *iface) {
if (iface) {
free(iface->ifname);
+ free(iface->bridge_iface);
free(iface->mesh_iface);
free(iface);
}
}
void ffvisd_iface_foreach(iface_cb cb, void *arg) {
- struct dirent **namelist;
-
- int i, count = scandir(SYSFS_CLASS_NET, &namelist, NULL, NULL);
+ struct if_nameindex *ifaces = if_nameindex();
- if (count < 0) {
- fprintf(stderr, "error: scandir: %m");
+ if (!ifaces) {
+ fprintf(stderr, "error: if_nameindex: %m");
return;
}
- for (i = 0; i < count; i++) {
- ffvisd_iface_t *iface = ffvisd_iface_new(namelist[i]->d_name);
+ int i;
+ for (i = 0; ifaces[i].if_name; i++) {
+ ffvisd_iface_t *iface = ffvisd_iface_new(ifaces[i].if_name, ifaces[i].if_index);
if (iface)
cb(iface, arg);
ffvisd_iface_free(iface);
- free(namelist[i]);
}
- free(namelist);
+ if_freenameindex(ifaces);
}
void pr_iface_info(const ffvisd_iface_t *iface, void *arg) {
- printf("Interface %s: ifindex=%i mesh_iface=%s iftype=%i\n", iface->ifname, iface->ifindex, iface->mesh_iface, iface->iftype);
+ printf("Interface %s: ifindex=%i bridge_iface=%s mesh_iface=%s iftype=%s\n", iface->ifname, iface->ifindex, iface->bridge_iface, iface->mesh_iface, ffvisd_iftype_names[iface->iftype]);
}