commit 876db202f8684ec30f015e8f83a190004a744a39
parent 5154b545644b288fa67b5bab3a7c0fac8a75ec51
Author: finwo <finwo@pm.me>
Date: Sat, 5 Sep 2026 21:32:07 +0200
Basic config parsing with includes
Diffstat:
14 files changed, 620 insertions(+), 168 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,3 +1,4 @@
/bak/
/build/
/lib/
+*.o
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
@@ -0,0 +1,6 @@
+<!-- 46b43825-f791-485e-9445-415ee7bbbf2d -->
+# Contributor Code of Conduct
+
+This project adheres to No Code of Conduct. We are all adults. We accept anyone's contributions. Nothing else matters.
+
+For more information please visit the [No Code of Conduct](https://github.com/domgetter/NCoC) homepage.
diff --git a/Makefile b/Makefile
@@ -9,7 +9,6 @@ build/${TARGET}/pmlag: build/${TARGET} $(wildcard src/*.c src/*.h src/*/*.c src/
build/${TARGET}: $(wildcard src/*.c src/*.h src/*/*.c src/*/*.h)
mkdir -p build/${TARGET}
- cp -rT .dep build/${TARGET}/.dep
cp -rT manpage.1.md build/${TARGET}/manpage.1.md
cp -rT src/ build/${TARGET}/src
cp -rT target/common/ build/${TARGET}
diff --git a/example.conf b/example.conf
@@ -1,14 +1,47 @@
-[bond-A]
-interface = eth0
-interface = eth1
-tick = 100 # Tick every 100ms, allows fast link drop
-# pizza calzone
-# pizza = yum
- # pizza = yum
-a # b = c
-d e = f
-
-[bond-B]
-interface = eth2
-interface = eth3
-tick = 0 # No tick = only "normal" auto discovery
+include config/*.cnf
+
+# Basic bond
+bond bon0
+ interface eth1
+ interface eth2
+
+# Set specific mac & ip
+bond bon1
+ interface eth1 eth2
+ address 192.0.0.1/32
+ address fe80::1/128
+ mac 9c:6b:00:60:05:98
+
+# Routed interface, L3 only
+# Auto-announce routes
+routed rnic0
+ address 192.0.0.1/32
+ route auto
+
+# Routed interface, L3 only
+# Fixed routes
+routed rnic1
+ address 192.0.0.1/32
+ address fe80::1/128
+ route 0.0.0.0/0
+ neighbour 9c:6b:00:60:05:98
+ ttl 3600
+ metric 600
+ route 10.0.0.0/8
+ neighbour 9c:6b:00:60:05:F0
+ ttl 1800
+ metric 100
+
+# Routed interface, L3 only
+# Mixed routes
+routed rnic1
+ address 192.0.0.1/32
+ address fe80::1/128
+ # Propagate routes with metric +50
+ route auto
+ ttl 300
+ metric 50
+ # Static routes
+ # Basic routes, ttl=300, metric=0
+ route 0.0.0.0/0 9c:6b:00:60:05:98
+ route 10.0.0.0/8 9c:6b:00:60:05:F0
diff --git a/src/main.c b/src/main.c
@@ -1,18 +1,27 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+
+#include <libgen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
#include "cofyc/argparse.h"
-#include "util/config.h"
+#include "util/config-root.h"
static const char *const usage[] = {
__NAME " [options]",
- NULL
+ __NAME " --help",
+ NULL,
};
int main(int argc, const char **argv) {
- char *config_file="/etc/pmlag/pmlag.conf";
+ char *config_file="/etc/network/pmlag";
+ FILE *config_fd;
// Seed random
uint32_t seed;
@@ -33,16 +42,46 @@ int main(int argc, const char **argv) {
argparse_init(&argparse, options, usage, 0);
argparse_describe(&argparse, NULL,
// TODO: format to terminal width
- "\n" __NAME " is a tool for bonding network interfaces together when the "
- "hardware\non the other side of the cable(s) doesn't support it."
"\n"
+ __NAME " is a tool for bonding network interfaces together when the hardware\n"
+ "on the other side of the cable(s) doesn't support it.\n"
);
argc = argparse_parse(&argparse, argc, argv);
- struct pmlag_configuration *config = calloc(1, sizeof(struct pmlag_configuration));
+ // Check the config exists
+ char *config_file_real = realpath(config_file, NULL);
+ if (!config_file_real) {
+ fprintf(stderr, "Could not resolve config file `%s`\n", config_file);
+ return 1;
+ }
+ config_fd = fopen(config_file_real, "r");
+ if (!config_fd) {
+ perror("Could not open config file");
+ return 1;
+ }
+
+ // Start the actual parse
+ char *config_dirname = calloc(strlen(config_file_real)+1, 1);
+ strcpy(config_dirname, config_file_real);
+ dirname(config_dirname);
+ if (cfg_parse(config_dirname, config_fd, NULL) < 0) {
+ fprintf(stderr, "Error during reading configuration from %s\n", config_file_real);
+ return 1;
+ }
- printf("Config file: %s\n", config_file);
- config_load(config_file, config);
+// struct pmlag_configuration *config = calloc(1, sizeof(struct pmlag_configuration));
- return 0;
+ // printf("Config file: %s\n", config_file);
+ // config_file = realpath(config_file, NULL);
+ // printf("Realpath : %s\n", config_file);
+ // printf("dirname : %s\n", dirname(config_file));
+ // // cfg_parse(
+// // config_load(config_file, config);
+
+// return 0;
+ return 42;
}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/util/config-root.c b/src/util/config-root.c
@@ -0,0 +1,208 @@
+#include <glob.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include "config-root.h"
+
+#define CFG_MAX_REG 256
+
+static int handler_count = 0;
+static const char *handler_name[CFG_MAX_REG];
+static cfg_directive_fn handler_fn[CFG_MAX_REG];
+
+void cfg_register_directive(const char *name, cfg_directive_fn fn) {
+ handler_name[handler_count] = name;
+ handler_fn [handler_count] = fn;
+ handler_count++;
+}
+
+int cfg_parse(const char *wd, FILE *fd, void *user) {
+ struct cnf_directive *dir = NULL;
+ glob_t globbuf;
+ int globflags;
+ int i;
+
+ char *strtmp = NULL;
+ FILE *nfd;
+
+ for(;;) {
+ if (dir) cnf_directive_free(dir);
+ dir = cnf_directive_read(fd);
+ if (!dir) break; // EOF = done
+
+cfg_parse_reparse:
+
+ // Core handlers
+ if (!strcasecmp("include", dir->name)) {
+ globflags = GLOB_ERR;
+ for ( i = 0 ; i < dir->argc ; i++ ) {
+ strtmp = malloc(snprintf(NULL, 0, "%s/%s", wd, dir->argv[i])+1);
+ sprintf(strtmp, "%s/%s", wd, dir->argv[i]);
+ glob(strtmp, globflags, NULL, &globbuf);
+ free(strtmp);
+ globflags = GLOB_ERR | GLOB_APPEND;
+ }
+ for( i = 0 ; i < globbuf.gl_pathc ; i++ ) {
+ strtmp = calloc(strlen(globbuf.gl_pathv[i])+1, 1);
+ strcpy(strtmp, globbuf.gl_pathv[i]);
+ dirname(strtmp);
+ nfd = fopen(globbuf.gl_pathv[i], "r");
+ if (!nfd) {
+ perror("Could not open config file for reading");
+ return CFG_RET_ERROR;
+ }
+ if (cfg_parse(strtmp, nfd, user) < 0) {
+ fprintf(stderr, "Error during reading configuration from %s\n", globbuf.gl_pathv[i]);
+ return CFG_RET_ERROR;
+ }
+ fclose(nfd);
+ free(strtmp);
+ }
+ globfree(&globbuf);
+ continue;
+ }
+
+ // Dynamic handlers
+ for(i = 0 ; i < handler_count ; i++) {
+ if (!strcasecmp(handler_name[i], dir->name)) {
+ dir = handler_fn[i](fd, dir, user);
+ if (dir) goto cfg_parse_reparse;
+ goto cfg_parse_cleanup;
+ }
+ }
+
+ // Here = not found
+ fprintf(stderr, "Unknown directive: %s\n", dir->name);
+ return CFG_RET_ERROR;
+ }
+
+ // Cleanup here
+cfg_parse_cleanup:
+ if (dir) cnf_directive_free(dir);
+
+ return CFG_RET_OK;
+}
+
+// #include <stdio.h>
+// #include <stdlib.h>
+// #include <string.h>
+
+// #include "config.h"
+
+// #include "benhoyt/inih.h"
+// #include "finwo/mindex.h"
+
+// int mindex_bond_cmp(const void *a, const void *b, void *udata) {
+// (void)udata;
+// const struct pmlag_configuration_bond *_a = a;
+// const struct pmlag_configuration_bond *_b = b;
+// return strcmp(_a->name, _b->name);
+// }
+
+// void mindex_bond_purge(void *item, void *udata) {
+// struct pmlag_configuration_bond *bond = item;
+// (void)udata;
+// if (!item) return;
+// if (bond->name) free(bond->name);
+// }
+
+// #ifndef MIN
+// #define MIN(a,b) ((a)<(b)?(a):(b))
+// #endif
+
+// static int config_load_handler(
+// void *user,
+// const char *section,
+// const char *name,
+// const char *value
+// ) {
+// // struct pmlag_bond *bond = NULL;
+// // struct pmlag_iface *iface = NULL;
+// // int bond_index = 0;
+// // int iface_index = 0;
+// struct pmlag_configuration* config = (struct pmlag_configuration *) user;
+
+// // Detect invalid entries
+// int i, l;
+// for( i = 0, l = strlen(name) ; i < l ; i++ ) {
+// if (name[i] == 0x5F ) continue; // '_'
+// if (name[i] >= 0x30 && name[i] <= 0x39) continue; // 0-9
+// if (name[i] >= 0x41 && name[i] <= 0x5A) continue; // A-Z
+// if (name[i] >= 0x61 && name[i] <= 0x7A) continue; // a-z
+// return 0; // Reject
+// }
+
+// // Strip # comments from values
+// char *found_comment = strstr(value, "#");
+// if (found_comment) {
+// for(; found_comment > (value + 1) ;) {
+// if ( *(found_comment) >= 0x21 && *(found_comment-1) <= 0x7E ) break;
+// found_comment--;
+// }
+// *found_comment = 0x00;
+// }
+
+// // Find or create bond
+// struct pmlag_configuration_bond *config_bond = mindex_get(config->bonds, (&(struct pmlag_configuration_bond){ .name = (char *)section }));
+// if (!config_bond) {
+// config_bond = calloc(1, sizeof(struct pmlag_configuration_bond));
+// config_bond->name = strdup(section);
+// mindex_set(config->bonds, config_bond);
+// }
+
+// // // Find the bond
+// // struct pmlag_configuration_bond *config_bond = NULL;
+// // for( i = 0 ; i < config->bond_len ; i++ ) {
+// // if (!strcmp(config->bonds[i].name, section)) {
+// // config_bond = &(config->bonds[i]);
+// // break;
+// // }
+// // }
+// // printf("%s:%d\n", __FILE__, __LINE__);
+// // // Build new bond if missing
+// // if (!config_bond) {
+// // // Expand array size if needed
+// // if ((config->bond_len+1) > config->bond_cap) {
+// // config->bond_cap = MIN(1, config->bond_cap*2);
+// // config->bonds = realloc(config->bonds, config->bond_cap * sizeof(struct pmlag_configuration_bond));
+// // }
+// // // Append new entry to list
+// // memset(&(config->bonds[config->bond_len]), 0, sizeof(struct pmlag_configuration_bond));
+// // config_bond = &(config->bonds[config->bond_len]);
+// // config->bond_len++;
+// // }
+
+// // Detect # comments and remove them
+
+// return 1;
+// }
+
+// struct pmlag_configuration * config_load(char * filepath, struct pmlag_configuration *config) {
+// // Load config, entry-by-entry
+// if (!config) {
+// config = calloc(1, sizeof(struct pmlag_configuration));
+// }
+// if (!config->bonds) {
+// config->bonds = mindex_init(mindex_bond_cmp, mindex_bond_purge, NULL);
+// }
+
+// if (ini_parse(filepath, config_load_handler, config) < 0) {
+// fprintf(stderr, "Can not load %s\n", filepath);
+// return NULL;
+// }
+
+// printf("bond_len: %ld\n", mindex_length(config->bonds));
+// printf("\n");
+// printf("bonds:\n");
+// int l = mindex_length(config->bonds);
+// for(int i = 0 ; i < l ; i++) {
+// struct pmlag_configuration_bond *bond = mindex_nth(config->bonds, i);
+// printf(" - %s\n", bond->name);
+// }
+// printf("\n");
+
+// return config;
+// }
diff --git a/src/util/config-root.h b/src/util/config-root.h
@@ -0,0 +1,15 @@
+#ifndef __PMLAG_UTIL_CONFIG_ROOT_H__
+#define __PMLAG_UTIL_CONFIG_ROOT_H__
+
+#include <stdio.h>
+
+#include "finwo/cnfparse.h"
+
+#define CFG_RET_ERROR -1
+#define CFG_RET_OK 0
+
+typedef struct cnf_directive * (*cfg_directive_fn)(FILE *fd, struct cnf_directive *dir, void *user);
+void cfg_register_directive(const char *name, cfg_directive_fn fn);
+int cfg_parse(const char *wd, FILE *fd, void *user);
+
+#endif // __PMLAG_UTIL_CONFIG_ROOT_H__
diff --git a/src/util/config.c b/src/util/config.c
@@ -1,120 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "config.h"
-
-#include "benhoyt/inih.h"
-#include "finwo/mindex.h"
-
-int mindex_bond_cmp(const void *a, const void *b, void *udata) {
- (void)udata;
- const struct pmlag_configuration_bond *_a = a;
- const struct pmlag_configuration_bond *_b = b;
- return strcmp(_a->name, _b->name);
-}
-
-void mindex_bond_purge(void *item, void *udata) {
- struct pmlag_configuration_bond *bond = item;
- (void)udata;
- if (!item) return;
- if (bond->name) free(bond->name);
-}
-
-#ifndef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#endif
-
-static int config_load_handler(
- void *user,
- const char *section,
- const char *name,
- const char *value
-) {
- // struct pmlag_bond *bond = NULL;
- // struct pmlag_iface *iface = NULL;
- // int bond_index = 0;
- // int iface_index = 0;
- struct pmlag_configuration* config = (struct pmlag_configuration *) user;
-
- // Detect invalid entries
- int i, l;
- for( i = 0, l = strlen(name) ; i < l ; i++ ) {
- if (name[i] == 0x5F ) continue; // '_'
- if (name[i] >= 0x30 && name[i] <= 0x39) continue; // 0-9
- if (name[i] >= 0x41 && name[i] <= 0x5A) continue; // A-Z
- if (name[i] >= 0x61 && name[i] <= 0x7A) continue; // a-z
- return 0; // Reject
- }
-
- // Strip # comments from values
- char *found_comment = strstr(value, "#");
- if (found_comment) {
- for(; found_comment > (value + 1) ;) {
- if ( *(found_comment) >= 0x21 && *(found_comment-1) <= 0x7E ) break;
- found_comment--;
- }
- *found_comment = 0x00;
- }
-
- // Find or create bond
- struct pmlag_configuration_bond *config_bond = mindex_get(config->bonds, (&(struct pmlag_configuration_bond){ .name = (char *)section }));
- if (!config_bond) {
- config_bond = calloc(1, sizeof(struct pmlag_configuration_bond));
- config_bond->name = strdup(section);
- mindex_set(config->bonds, config_bond);
- }
-
- // // Find the bond
- // struct pmlag_configuration_bond *config_bond = NULL;
- // for( i = 0 ; i < config->bond_len ; i++ ) {
- // if (!strcmp(config->bonds[i].name, section)) {
- // config_bond = &(config->bonds[i]);
- // break;
- // }
- // }
- // printf("%s:%d\n", __FILE__, __LINE__);
- // // Build new bond if missing
- // if (!config_bond) {
- // // Expand array size if needed
- // if ((config->bond_len+1) > config->bond_cap) {
- // config->bond_cap = MIN(1, config->bond_cap*2);
- // config->bonds = realloc(config->bonds, config->bond_cap * sizeof(struct pmlag_configuration_bond));
- // }
- // // Append new entry to list
- // memset(&(config->bonds[config->bond_len]), 0, sizeof(struct pmlag_configuration_bond));
- // config_bond = &(config->bonds[config->bond_len]);
- // config->bond_len++;
- // }
-
- // Detect # comments and remove them
-
- return 1;
-}
-
-struct pmlag_configuration * config_load(char * filepath, struct pmlag_configuration *config) {
- // Load config, entry-by-entry
- if (!config) {
- config = calloc(1, sizeof(struct pmlag_configuration));
- }
- if (!config->bonds) {
- config->bonds = mindex_init(mindex_bond_cmp, mindex_bond_purge, NULL);
- }
-
- if (ini_parse(filepath, config_load_handler, config) < 0) {
- fprintf(stderr, "Can not load %s\n", filepath);
- return NULL;
- }
-
- printf("bond_len: %ld\n", mindex_length(config->bonds));
- printf("\n");
- printf("bonds:\n");
- int l = mindex_length(config->bonds);
- for(int i = 0 ; i < l ; i++) {
- struct pmlag_configuration_bond *bond = mindex_nth(config->bonds, i);
- printf(" - %s\n", bond->name);
- }
- printf("\n");
-
- return config;
-}
diff --git a/src/util/config.h b/src/util/config.h
@@ -1,21 +0,0 @@
-#ifndef __PMLAG_UTIL_CONFIG_H__
-#define __PMLAG_UTIL_CONFIG_H__
-
-#include <stdint.h>
-
-#include "finwo/mindex.h"
-
-struct pmlag_configuration_bond {
- char *name;
- char **interface;
- uint16_t interface_count;
- uint16_t tick_rate;
-};
-
-struct pmlag_configuration {
- struct mindex_t *bonds;
-};
-
-struct pmlag_configuration * config_load(char * filepath, struct pmlag_configuration *config);
-
-#endif // __PMLAG_UTIL_CONFIG_H__
diff --git a/src/util/routing-table.c b/src/util/routing-table.c
@@ -0,0 +1,96 @@
+// #include <linux/if_ether.h>
+// /* #include <stdio.h> */
+// /* #include <stdlib.h> */
+// #include <string.h>
+
+// #include "finwo/mindex.h"
+
+// #include "config.h"
+// #include "routing-table.h"
+
+// static int rt_compare(const void *a, const void *b, void *udata) {
+// struct pmlag_rt_entry *ta = (struct pmlag_rt_entry *)a;
+// struct pmlag_rt_entry *tb = (struct pmlag_rt_entry *)b;
+// if (a == b) return 0;
+// return memcmp(ta->mac, tb->mac, ETH_ALEN);
+// }
+
+// static void rt_purge(void *item, void *udata) {
+// struct pmlag_rt_entry *rt_entry = (struct pmlag_rt_entry *)item;
+// if (!rt_entry) return;
+// if (rt_entry->iface) free(rt_entry->iface);
+// if (rt_entry->mac) free(rt_entry->mac);
+// free(rt_entry);
+// }
+
+// struct mindex_t * rt_init(void *udata) {
+// return mindex_init(rt_compare, rt_purge, udata);
+// }
+
+// int rt_upsert(
+// struct mindex_t *rt,
+// struct pmlag_iface *iface,
+// unsigned char *mac,
+// int16_t bcidx
+// ) {
+// struct pmlag_rt_entry *rt_entry;
+// int i, isnew = 0;
+// int iface_found = 0;
+
+// // Attempt to fetch the rt entry
+// rt_entry = mindex_get(rt, &((struct pmlag_rt_entry){ .mac = mac }));
+
+// // None given, build new one
+// if (!rt_entry) {
+// rt_entry = calloc(1, sizeof(struct pmlag_rt_entry));
+// rt_entry->mac = malloc(ETH_ALEN);
+// rt_entry->bcidx = bcidx;
+// rt_entry->iface = calloc(iface->bond->iface_count, sizeof(struct pmlag_iface *));
+// rt_entry->iface_count = 0;
+// memcpy(rt_entry->mac, mac, ETH_ALEN);
+// isnew = 1;
+// }
+
+// // Clear interface list if bcidx is different
+// if (rt_entry->bcidx != bcidx) {
+// rt_entry->iface_count = 0;
+// rt_entry->bcidx = bcidx;
+// }
+
+// // Register the interface on the rt_entry
+// for( i = 0 ; i < rt_entry->iface_count ; i++ ) {
+// if (rt_entry->iface[i] != iface) continue;
+// iface_found = 1;
+// break;
+// }
+// if (!iface_found) {
+// rt_entry->iface[rt_entry->iface_count] = iface;
+// rt_entry->iface_count++;
+// }
+
+// // The actual upsert part
+// if (isnew) {
+// mindex_set(rt, rt_entry);
+// // Keep rt size in check
+// if (rt->length > PMLAG_RT_MAX) {
+// mindex_delete(rt, mindex_rand(rt));
+// }
+// }
+
+// return 0;
+// }
+
+// struct pmlag_iface * rt_find(
+// struct mindex_t *rt,
+// unsigned char *mac
+// ) {
+// struct pmlag_rt_entry *rt_entry;
+
+// // Attempt to fetch the rt entry
+// rt_entry = mindex_get(rt, &((struct pmlag_rt_entry){ .mac = mac }));
+// if (!rt_entry) return NULL;
+
+// // Unlock the routing table again
+// struct pmlag_iface *iface = rt_entry->iface[rand() % rt_entry->iface_count];
+// return iface;
+// }
diff --git a/src/util/routing-table.h b/src/util/routing-table.h
@@ -0,0 +1,31 @@
+// #ifndef __PMLAG_UTIL_RT_H__
+// #define __PMLAG_UTIL_RT_H__
+
+// #define PMLAG_RT_MAX 4096
+
+// #include "config.h"
+
+// #include "finwo/mindex.h"
+
+// struct pmlag_rt_entry {
+// unsigned char *mac; // mac address of the remote entity
+// uint16_t bcidx; // broadcast index last seen from the mac
+// struct pmlag_iface **iface;
+// int iface_count;
+// };
+
+// struct mindex_t * rt_init(void *udata);
+
+// int rt_upsert(
+// struct mindex_t *rt,
+// struct pmlag_iface *iface,
+// unsigned char *mac,
+// int16_t bcidx
+// );
+
+// struct pmlag_iface * rt_find(
+// struct mindex_t *rt,
+// unsigned char *mac
+// );
+
+// #endif // __PMLAG_UTIL_RT_H__
diff --git a/src/util/socket.c b/src/util/socket.c
@@ -0,0 +1,156 @@
+// #include <fcntl.h>
+// #include <linux/if_arp.h>
+// #include <linux/if_packet.h>
+// #include <linux/if_tun.h>
+// #include <linux/if.h>
+// #include <netinet/in.h>
+// #include <string.h>
+// #include <strings.h>
+// #include <sys/ioctl.h>
+// #include <stdio.h>
+// #include <stdlib.h>
+// #include <sys/socket.h>
+// #include <unistd.h>
+
+// #include "socket.h"
+
+// unsigned char * iface_mac(char * ifname) {
+// unsigned char *mac = calloc(1, ETH_ALEN);
+// struct ifreq ifr;
+// int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+// ifr.ifr_addr.sa_family = AF_INET;
+// strncpy(ifr.ifr_name , ifname , IFNAMSIZ-1);
+// ioctl(sockfd, SIOCGIFHWADDR, &ifr);
+// close(sockfd);
+// memcpy(mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+// return mac;
+// }
+
+// int iface_idx(int sockfd, char * ifname) {
+// struct ifreq ifr;
+// bzero(&ifr, sizeof(ifr));
+
+// // Get interface index
+// strncpy((char *)ifr.ifr_name, ifname, IFNAMSIZ);
+// if ((ioctl(sockfd, SIOCGIFINDEX, &ifr)) == -1) {
+// fprintf(stderr, "Error getting interface index for %s\n", ifname);
+// perror("Error getting interface index");
+// close(sockfd);
+// return -1;
+// }
+
+// return ifr.ifr_ifindex;
+// }
+
+// int if_ioctl(int cmd, struct ifreq* req) {
+// int ret, sock;
+// sock = socket(AF_INET, SOCK_PACKET, 0);
+// if (sock < 0) {
+// return -1;
+// }
+// ret = ioctl(sock, cmd, req);
+// close(sock);
+// return ret;
+// }
+
+// int sockraw_open(char * ifname) {
+// struct ifreq ifr;
+
+// // Open socket (P_ALL, due to custom ethertype field)
+// int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+// if (sockfd < 0) {
+// perror("Error opening socket");
+// close(sockfd);
+// return -1;
+// }
+
+// // Old bind to socket
+// struct sockaddr_ll sll;
+// bzero(&sll, sizeof(sll));
+// sll.sll_family = AF_PACKET;
+// sll.sll_ifindex = iface_idx(sockfd, ifname);
+// sll.sll_protocol = htons(ETH_P_ALL);
+// if (sll.sll_ifindex < 0) {
+// // Error already printed, not reprinting
+// return -1;
+// }
+// if((bind(sockfd, (struct sockaddr *)&sll, sizeof(sll))) == -1) {
+// perror("Error binding raw socket to interface");
+// close(sockfd);
+// return -1;
+// }
+
+// // Get current iface configuration
+// memset(&ifr, 0, sizeof(ifr));
+// strcpy(ifr.ifr_name, ifname);
+// if (if_ioctl(SIOCGIFFLAGS, &ifr) < 0) {
+// perror("Get interface flags");
+// }
+
+// // Set iface to promiscuous mode
+// ifr.ifr_flags |= IFF_PROMISC;
+// if (if_ioctl(SIOCSIFFLAGS, &ifr) < 0) {
+// perror("Configure interface promiscuous mode");
+// }
+
+// // Return the prepared socket
+// return sockfd;
+// }
+
+// int tap_alloc(char * ifname, unsigned char * mac) {
+// struct ifreq ifr;
+// int fd, err;
+
+// if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
+// perror("Open tun");
+// return -1;
+// }
+
+// // Bring up the interface
+// memset(&ifr, 0, sizeof(ifr));
+// ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+// if( *ifname ) {
+// strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+// }
+// if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
+// perror("Open tun");
+// close(fd);
+// return err;
+// }
+// strcpy(ifname, ifr.ifr_name);
+
+// // Set the interface's mac address
+// if ( mac ) {
+// // TODO: random, copied or specific mac address pulled from ini
+// memset(&ifr, 0, sizeof(ifr));
+// strcpy(ifr.ifr_name, ifname);
+// ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
+// memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ALEN);
+// if ((err = if_ioctl(SIOCSIFHWADDR, &ifr)) < 0) {
+// perror("Set if hwaddr");
+// close(fd);
+// return err;
+// }
+// }
+
+// // Fetch the current flags
+// memset(&ifr, 0, sizeof(ifr));
+// strcpy(ifr.ifr_name, ifname);
+// if (if_ioctl(SIOCGIFFLAGS, &ifr) < 0) {
+// perror("failed to get the interface flags");
+// close(fd);
+// return err;
+// }
+
+// // Bring up the interface
+// if (!(ifr.ifr_flags & IFF_UP)) {
+// ifr.ifr_flags |= IFF_UP;
+// if (if_ioctl(SIOCSIFFLAGS, &ifr) < 0) {
+// perror("failed to get the interface flags");
+// close(fd);
+// return err;
+// }
+// }
+
+// return fd;
+// }
diff --git a/src/util/socket.h b/src/util/socket.h
@@ -0,0 +1,9 @@
+// #ifndef __PMLAG_UTIL_SOCKET_H__
+// #define __PMLAG_UTIL_SOCKET_H__
+
+// int iface_idx(int sockfd, char * ifname);
+// unsigned char * iface_mac(char * ifname);
+// int tap_alloc(char * ifname, unsigned char * mac);
+// int sockraw_open(char * ifname);
+
+// #endif // __PMLAG_UTIL_SOCKET_H__
diff --git a/target/common/.dep b/target/common/.dep
@@ -1,3 +1,3 @@
-cofyc/argparse https://git.finwo.net/misc/dep-repository/archives/heads/pkg/cofyc/argparse.tar.gz
-finwo/cnfparse https://git.finwo.net/lib/cnfparse.c/archives/heads/main.tar.gz
-finwo/mindex https://git.finwo.net/lib/mindex.c/archives/heads/main.tar.gz
+cofyc/argparse https://git.finwo.net/misc/dep-repository/archives/heads/pkg/cofyc/argparse.tar.gz
+finwo/cnfparse https://git.finwo.net/lib/cnfparse.c/archives/heads/main.tar.gz
+finwo/mindex https://git.finwo.net/lib/mindex.c/archives/heads/main.tar.gz