pmlag

Poor man's link aggregation
git clone git://git.finwo.net/app/pmlag
Log | Files | Refs | LICENSE

commit 876db202f8684ec30f015e8f83a190004a744a39
parent 5154b545644b288fa67b5bab3a7c0fac8a75ec51
Author: finwo <finwo@pm.me>
Date:   Sat,  5 Sep 2026 21:32:07 +0200

Basic config parsing with includes

Diffstat:
M.gitignore | 1+
ACODE_OF_CONDUCT.md | 6++++++
MMakefile | 1-
Mexample.conf | 61+++++++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/main.c | 57++++++++++++++++++++++++++++++++++++++++++++++++---------
Asrc/util/config-root.c | 208+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/util/config-root.h | 15+++++++++++++++
Dsrc/util/config.c | 120-------------------------------------------------------------------------------
Dsrc/util/config.h | 21---------------------
Asrc/util/routing-table.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/util/routing-table.h | 31+++++++++++++++++++++++++++++++
Asrc/util/socket.c | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/util/socket.h | 9+++++++++
Mtarget/common/.dep | 6+++---
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