pmlag

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

commit 77b9baf5f15e2e865abfb0b935091b5c5268af5b
parent dff2c19a0738b02f3024b07446d952045f75fbad
Author: Robin Bron <robin@finwo.nl>
Date:   Sat, 30 Apr 2022 02:33:23 +0200

Initialized manpage

Diffstat:
M.gitignore | 3++-
A.gitmodules | 6++++++
MMakefile | 43++++++++++++++++++++++++++++++++++++++-----
MREADME.md | 112++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Alib/argparse | 1+
Alib/inih | 1+
Amanpage.1.md | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apmlag.html | 311+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/main.c | 150++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
9 files changed, 665 insertions(+), 72 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1,3 @@ pmlag -*.o +*.[ao] +pmlag.[1,html] diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "lib/argparse"] + path = lib/argparse + url = git://git.finwo.net/argparse +[submodule "lib/inih"] + path = lib/inih + url = git://git.finwo.net/inih diff --git a/Makefile b/Makefile @@ -1,11 +1,44 @@ -SRC=$(wildcard src/*.c) -OBJ=$(SRC:.c=.o) +# Setup core +SRC:=$(wildcard src/*.c) +LIBS= +CFLAGS?= +BIN=pmlag -default: pmlag +# Include lib/argparse +SRC+=lib/argparse/argparse.c +CFLAGS+=-Ilib/argparse +LIBS+=lib/argparse -pmlag: $(OBJ) - $(CC) $(SRC) -o pmlag +# Include lib/ini +SRC+=lib/inih/ini.c +CFLAGS+=-Ilib/inih +LIBS+=lib/inih +# Translate and default rule +OBJ:=$(SRC:.c=.o) +default: $(BIN) $(BIN).1 README.md + +# How to fetch libraries +$(LIBS): + git submodule update --init $@ + +# How to generate object files +$(OBJ): $(LIBS) + $(CC) $(CFLAGS) $(@:.o=.c) -c -o $@ + +# Build main binary +$(BIN): $(OBJ) + $(CC) $(CFLAGS) $(OBJ) -o $(BIN) + +# Build manpage +$(BIN).1: manpage.1.md + env NAME=$(BIN) envsubst < manpage.1.md | pandoc --standalone --from markdown --to man -o $(BIN).1 + env NAME=$(BIN) envsubst < manpage.1.md | pandoc --standalone --from markdown --to html -o $(BIN).html + +README.md: manpage.1.md + env NAME=$(BIN) envsubst < manpage.1.md > README.md + +# Cleanup .PHONY: clean clean: rm -rf $(OBJ) diff --git a/README.md b/README.md @@ -1,4 +1,110 @@ -PMLAG ------ +% pmlag(1) | General Commands Manual -Poor man's link aggregation +NAME +==== + +pmlag - Poor man's link aggregator + +SYNOPSIS +======== + +`pmlag [options]` + +DESCRIPTION +=========== + +pmlag is a tool for bonding network interfaces together when the hardware on +the other side of the cable(s) doesn't necessarily support it. + +OPTIONS +======= + +#### `-h, --help` + +Show the help message and exit + +#### `-c, --config <PATH>` + +Load a custom configuration instead of the default (/etc/pmlag.conf) + +CONFIGURATION +============= + +The configuration is an ini-like format, where the sections are the name of the +device being configured. + +The configuration can be reloaded by sending the USR1 signal to the process. + +#### broadcast + +Select the broadcast method for the bonded interface + +- flood: send out broadcast packages out over all interfaces +- balanced: send out broadcast packages according to balancing strategy + +#### mode + +Select the balancing mode for non-broadcast packages + +- balance-rr: weighted round-robin balancing +- active-backup: define a primary and backup interface + +#### mac + +Define the mac address of the bonded interface + +#### master + +Define which bonded interface the current described interface belongs to + +#### weight + +Behaves differently depending on the mode the bonded interface is in: + +- balance-rr: Specifies the share of traffic the interface transmits +- active-backup: Specifies the priority of the interface (higher = more preferred) + +Try to keep this number as low as possible, as it's used directly to define +the number of packets to send before moving to the next interface in the +round-robin strategy. + +### Example: + +```ini +[bond0] +broadcast=flood +mode=balance-rr +mac=01:23:45:67:89:AB + +[eth0] +master=bond0 +weight=1 + +[eth1] +master=bond0 +weight=10 +``` + +LICENSE +======= + +The MIT License (MIT) + +Copyright © 2022 finwo + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/argparse b/lib/argparse @@ -0,0 +1 @@ +Subproject commit ffd9c23427d0cb105e27f27f0cf97b463b6a8bf8 diff --git a/lib/inih b/lib/inih @@ -0,0 +1 @@ +Subproject commit 4bd3261ea422a99aa764e63820e16d19cdad33dd diff --git a/manpage.1.md b/manpage.1.md @@ -0,0 +1,110 @@ +% ${NAME}(1) | General Commands Manual + +NAME +==== + +${NAME} - Poor man's link aggregator + +SYNOPSIS +======== + +`${NAME} [options]` + +DESCRIPTION +=========== + +${NAME} is a tool for bonding network interfaces together when the hardware on +the other side of the cable(s) doesn't necessarily support it. + +OPTIONS +======= + +#### `-h, --help` + +Show the help message and exit + +#### `-c, --config <PATH>` + +Load a custom configuration instead of the default (/etc/${NAME}.conf) + +CONFIGURATION +============= + +The configuration is an ini-like format, where the sections are the name of the +device being configured. + +The configuration can be reloaded by sending the USR1 signal to the process. + +#### broadcast + +Select the broadcast method for the bonded interface + +- flood: send out broadcast packages out over all interfaces +- balanced: send out broadcast packages according to balancing strategy + +#### mode + +Select the balancing mode for non-broadcast packages + +- balance-rr: weighted round-robin balancing +- active-backup: define a primary and backup interface + +#### mac + +Define the mac address of the bonded interface + +#### master + +Define which bonded interface the current described interface belongs to + +#### weight + +Behaves differently depending on the mode the bonded interface is in: + +- balance-rr: Specifies the share of traffic the interface transmits +- active-backup: Specifies the priority of the interface (higher = more preferred) + +Try to keep this number as low as possible, as it's used directly to define +the number of packets to send before moving to the next interface in the +round-robin strategy. + +### Example: + +```ini +[bond0] +broadcast=flood +mode=balance-rr +mac=01:23:45:67:89:AB + +[eth0] +master=bond0 +weight=1 + +[eth1] +master=bond0 +weight=10 +``` + +LICENSE +======= + +The MIT License (MIT) + +Copyright © 2022 finwo + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/pmlag.html b/pmlag.html @@ -0,0 +1,311 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> +<head> + <meta charset="utf-8" /> + <meta name="generator" content="pandoc" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> + <title>pmlag(1) | General Commands Manual</title> + <style> + html { + line-height: 1.5; + font-family: Georgia, serif; + font-size: 20px; + color: #1a1a1a; + background-color: #fdfdfd; + } + body { + margin: 0 auto; + max-width: 36em; + padding-left: 50px; + padding-right: 50px; + padding-top: 50px; + padding-bottom: 50px; + hyphens: auto; + overflow-wrap: break-word; + text-rendering: optimizeLegibility; + font-kerning: normal; + } + @media (max-width: 600px) { + body { + font-size: 0.9em; + padding: 1em; + } + h1 { + font-size: 1.8em; + } + } + @media print { + body { + background-color: transparent; + color: black; + font-size: 12pt; + } + p, h2, h3 { + orphans: 3; + widows: 3; + } + h2, h3, h4 { + page-break-after: avoid; + } + } + p { + margin: 1em 0; + } + a { + color: #1a1a1a; + } + a:visited { + color: #1a1a1a; + } + img { + max-width: 100%; + } + h1, h2, h3, h4, h5, h6 { + margin-top: 1.4em; + } + h5, h6 { + font-size: 1em; + font-style: italic; + } + h6 { + font-weight: normal; + } + ol, ul { + padding-left: 1.7em; + margin-top: 1em; + } + li > ol, li > ul { + margin-top: 0; + } + blockquote { + margin: 1em 0 1em 1.7em; + padding-left: 1em; + border-left: 2px solid #e6e6e6; + color: #606060; + } + code { + font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace; + font-size: 85%; + margin: 0; + } + pre { + margin: 1em 0; + overflow: auto; + } + pre code { + padding: 0; + overflow: visible; + overflow-wrap: normal; + } + .sourceCode { + background-color: transparent; + overflow: visible; + } + hr { + background-color: #1a1a1a; + border: none; + height: 1px; + margin: 1em 0; + } + table { + margin: 1em 0; + border-collapse: collapse; + width: 100%; + overflow-x: auto; + display: block; + font-variant-numeric: lining-nums tabular-nums; + } + table caption { + margin-bottom: 0.75em; + } + tbody { + margin-top: 0.5em; + border-top: 1px solid #1a1a1a; + border-bottom: 1px solid #1a1a1a; + } + th { + border-top: 1px solid #1a1a1a; + padding: 0.25em 0.5em 0.25em 0.5em; + } + td { + padding: 0.125em 0.5em 0.25em 0.5em; + } + header { + margin-bottom: 4em; + text-align: center; + } + #TOC li { + list-style: none; + } + #TOC ul { + padding-left: 1.3em; + } + #TOC > ul { + padding-left: 0; + } + #TOC a:not(:hover) { + text-decoration: none; + } + code{white-space: pre-wrap;} + span.smallcaps{font-variant: small-caps;} + span.underline{text-decoration: underline;} + div.column{display: inline-block; vertical-align: top; width: 50%;} + div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} + ul.task-list{list-style: none;} + pre > code.sourceCode { white-space: pre; position: relative; } + pre > code.sourceCode > span { display: inline-block; line-height: 1.25; } + pre > code.sourceCode > span:empty { height: 1.2em; } + .sourceCode { overflow: visible; } + code.sourceCode > span { color: inherit; text-decoration: inherit; } + div.sourceCode { margin: 1em 0; } + pre.sourceCode { margin: 0; } + @media screen { + div.sourceCode { overflow: auto; } + } + @media print { + pre > code.sourceCode { white-space: pre-wrap; } + pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; } + } + pre.numberSource code + { counter-reset: source-line 0; } + pre.numberSource code > span + { position: relative; left: -4em; counter-increment: source-line; } + pre.numberSource code > span > a:first-child::before + { content: counter(source-line); + position: relative; left: -1em; text-align: right; vertical-align: baseline; + border: none; display: inline-block; + -webkit-touch-callout: none; -webkit-user-select: none; + -khtml-user-select: none; -moz-user-select: none; + -ms-user-select: none; user-select: none; + padding: 0 4px; width: 4em; + color: #aaaaaa; + } + pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; } + div.sourceCode + { } + @media screen { + pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; } + } + code span.al { color: #ff0000; font-weight: bold; } /* Alert */ + code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */ + code span.at { color: #7d9029; } /* Attribute */ + code span.bn { color: #40a070; } /* BaseN */ + code span.bu { } /* BuiltIn */ + code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */ + code span.ch { color: #4070a0; } /* Char */ + code span.cn { color: #880000; } /* Constant */ + code span.co { color: #60a0b0; font-style: italic; } /* Comment */ + code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */ + code span.do { color: #ba2121; font-style: italic; } /* Documentation */ + code span.dt { color: #902000; } /* DataType */ + code span.dv { color: #40a070; } /* DecVal */ + code span.er { color: #ff0000; font-weight: bold; } /* Error */ + code span.ex { } /* Extension */ + code span.fl { color: #40a070; } /* Float */ + code span.fu { color: #06287e; } /* Function */ + code span.im { } /* Import */ + code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */ + code span.kw { color: #007020; font-weight: bold; } /* Keyword */ + code span.op { color: #666666; } /* Operator */ + code span.ot { color: #007020; } /* Other */ + code span.pp { color: #bc7a00; } /* Preprocessor */ + code span.sc { color: #4070a0; } /* SpecialChar */ + code span.ss { color: #bb6688; } /* SpecialString */ + code span.st { color: #4070a0; } /* String */ + code span.va { color: #19177c; } /* Variable */ + code span.vs { color: #4070a0; } /* VerbatimString */ + code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ + .display.math{display: block; text-align: center; margin: 0.5rem auto;} + </style> + <!--[if lt IE 9]> + <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script> + <![endif]--> +</head> +<body> +<header id="title-block-header"> +<h1 class="title">pmlag(1) | General Commands Manual</h1> +</header> +<h1 id="name">NAME</h1> +<p>pmlag - Poor man’s link aggregator</p> +<h1 id="synopsis">SYNOPSIS</h1> +<p><code>pmlag [options]</code></p> +<h1 id="description">DESCRIPTION</h1> +<p>pmlag is a tool for bonding network interfaces together when the +hardware on the other side of the cable(s) doesn’t necessarily support +it.</p> +<h1 id="options">OPTIONS</h1> +<h4 id="h---help"><code>-h, --help</code></h4> +<p>Show the help message and exit</p> +<h4 id="c---config-path"><code>-c, --config &lt;PATH&gt;</code></h4> +<p>Load a custom configuration instead of the default +(/etc/pmlag.conf)</p> +<h1 id="configuration">CONFIGURATION</h1> +<p>The configuration is an ini-like format, where the sections are the +name of the device being configured.</p> +<p>The configuration can be reloaded by sending the USR1 signal to the +process.</p> +<h4 id="broadcast">broadcast</h4> +<p>Select the broadcast method for the bonded interface</p> +<ul> +<li>flood: send out broadcast packages out over all interfaces</li> +<li>balanced: send out broadcast packages according to balancing +strategy</li> +</ul> +<h4 id="mode">mode</h4> +<p>Select the balancing mode for non-broadcast packages</p> +<ul> +<li>balance-rr: weighted round-robin balancing</li> +<li>active-backup: define a primary and backup interface</li> +</ul> +<h4 id="mac">mac</h4> +<p>Define the mac address of the bonded interface</p> +<h4 id="master">master</h4> +<p>Define which bonded interface the current described interface belongs +to</p> +<h4 id="weight">weight</h4> +<p>Behaves differently depending on the mode the bonded interface is +in:</p> +<ul> +<li>balance-rr: Specifies the share of traffic the interface +transmits</li> +<li>active-backup: Specifies the priority of the interface (higher = +more preferred)</li> +</ul> +<p>Try to keep this number as low as possible, as it’s used directly to +define the number of packets to send before moving to the next interface +in the round-robin strategy.</p> +<h3 id="example">Example:</h3> +<div class="sourceCode" id="cb1"><pre +class="sourceCode ini"><code class="sourceCode ini"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">[bond0]</span></span> +<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="dt">broadcast</span><span class="ot">=</span><span class="st">flood</span></span> +<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="dt">mode</span><span class="ot">=</span><span class="st">balance-rr</span></span> +<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="dt">mac</span><span class="ot">=</span><span class="st">01:23:45:67:89:AB</span></span> +<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span> +<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">[eth0]</span></span> +<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="dt">master</span><span class="ot">=</span><span class="st">bond0</span></span> +<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="dt">weight</span><span class="ot">=</span><span class="dv">1</span></span> +<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span> +<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">[eth1]</span></span> +<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="dt">master</span><span class="ot">=</span><span class="st">bond0</span></span> +<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="dt">weight</span><span class="ot">=</span><span class="dv">10</span></span></code></pre></div> +<h1 id="license">LICENSE</h1> +<p>The MIT License (MIT)</p> +<p>Copyright © 2022 finwo</p> +<p>Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +“Software”), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions:</p> +<p>The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software.</p> +<p>THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p> +</body> +</html> diff --git a/src/main.c b/src/main.c @@ -1,77 +1,101 @@ -#include <arpa/inet.h> -#include <net/ethernet.h> -#include <net/if.h> -#include <netinet/ip.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <linux/if_packet.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <linux/if_ether.h> +#include <sys/socket.h> +#include "argparse.h" +#include "ini.h" #include "socket.h" #ifdef __cplusplus extern "C" { #endif -#define INTERFACE "wlp2s0" -#define ERR_NAME "pmlag" - -int main(int argc, char **argv) { - int sockfd = sockraw_open(INTERFACE); - - // Prepare ingress buffer - int buflen; - unsigned char *buffer = (unsigned char *) malloc(65536); - memset(buffer, 0, 65536); - struct sockaddr saddr; - int saddr_len = sizeof(saddr); - - // Fetch a packet - buflen = recvfrom(sockfd, buffer, 65536, 0, &saddr, (socklen_t *)&saddr_len); - if (buflen < 0) { - perror(ERR_NAME ": recvfrom"); - exit(EXIT_FAILURE); - } - - printf("\n"); - printf("Got packet: %d bytes\n", buflen); - printf("\n"); - - struct ethhdr *eth = (struct ethhdr *)(buffer); - printf("Ethernet header\n"); - printf("\t|- DST %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",eth->h_dest[0],eth->h_dest[1],eth->h_dest[2],eth->h_dest[3],eth->h_dest[4],eth->h_dest[5]); - printf("\t|- SRC %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",eth->h_source[0],eth->h_source[1],eth->h_source[2],eth->h_source[3],eth->h_source[4],eth->h_source[5]); - printf("\t|- PROTO %d\n",eth->h_proto); - - printf("\n"); - - struct sockaddr_in source; - struct sockaddr_in dest; - if (eth->h_proto == 8) { - unsigned short iphdrlen; - struct iphdr *ip = (struct iphdr*)(buffer + sizeof(struct ethhdr)); - memset(&source, 0, sizeof(source)); - source.sin_addr.s_addr = ip->saddr; - memset(&dest, 0, sizeof(dest)); - dest.sin_addr.s_addr = ip->daddr; - - printf("IP header\n"); - printf("\t|- Version %d\n",(unsigned int)ip->version); - printf("\t|- Internet hlen %d DWORDS or %d Bytes\n",(unsigned int)ip->ihl,((unsigned int)(ip->ihl))*4); - printf("\t|- Type Of Service %d\n",(unsigned int)ip->tos); - printf("\t|- Total Length %d Bytes\n",ntohs(ip->tot_len)); - printf("\t|- Identification %d\n",ntohs(ip->id)); - printf("\t|- Time To Live %d\n",(unsigned int)ip->ttl); - printf("\t|- Protocol %d\n",(unsigned int)ip->protocol); - printf("\t|- Header Checksum %d\n",ntohs(ip->check)); - printf("\t|- Source IP %s\n", inet_ntoa(source.sin_addr)); - printf("\t|- Destination IP %s\n",inet_ntoa(dest.sin_addr)); - - printf("\n"); - } +#ifndef NAME +#define NAME "pmlag" +#endif + +static const char *const usage[] = { + NAME " [options]", + NULL +}; + +int main(int argc, const char **argv) { + const char *config_file = "/etc/" NAME ".conf"; + + struct argparse_option options[] = { + OPT_HELP(), + OPT_STRING('c', "config", &config_file, "Config file to use", NULL, 0, 0), + OPT_END(), + }; + + struct argparse argparse; + 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 doesn't necessarily support it." + "\n" + ); + argc = argparse_parse(&argparse, argc, argv); + + /* int sockfd = sockraw_open(INTERFACE); */ + + /* // Prepare ingress buffer */ + /* int buflen; */ + /* unsigned char *buffer = (unsigned char *) malloc(65536); */ + /* memset(buffer, 0, 65536); */ + /* struct sockaddr saddr; */ + /* int saddr_len = sizeof(saddr); */ + + /* // Fetch a packet */ + /* buflen = recvfrom(sockfd, buffer, 65536, 0, &saddr, (socklen_t *)&saddr_len); */ + /* if (buflen < 0) { */ + /* perror("recvfrom"); */ + /* exit(EXIT_FAILURE); */ + /* } */ + + /* printf("\n"); */ + /* printf("Got packet: %d bytes\n", buflen); */ + /* printf("\n"); */ + + /* struct ethhdr *eth = (struct ethhdr *)(buffer); */ + /* printf("Ethernet header\n"); */ + /* printf("\t|- DST %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",eth->h_dest[0],eth->h_dest[1],eth->h_dest[2],eth->h_dest[3],eth->h_dest[4],eth->h_dest[5]); */ + /* printf("\t|- SRC %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",eth->h_source[0],eth->h_source[1],eth->h_source[2],eth->h_source[3],eth->h_source[4],eth->h_source[5]); */ + /* printf("\t|- PROTO %d\n",eth->h_proto); */ + + /* printf("\n"); */ + + /* struct sockaddr_in source; */ + /* struct sockaddr_in dest; */ + /* if (eth->h_proto == 8) { */ + /* unsigned short iphdrlen; */ + /* struct iphdr *ip = (struct iphdr*)(buffer + sizeof(struct ethhdr)); */ + /* memset(&source, 0, sizeof(source)); */ + /* source.sin_addr.s_addr = ip->saddr; */ + /* memset(&dest, 0, sizeof(dest)); */ + /* dest.sin_addr.s_addr = ip->daddr; */ + + /* printf("IP header\n"); */ + /* printf("\t|- Version %d\n",(unsigned int)ip->version); */ + /* printf("\t|- Internet hlen %d DWORDS or %d Bytes\n",(unsigned int)ip->ihl,((unsigned int)(ip->ihl))*4); */ + /* printf("\t|- Type Of Service %d\n",(unsigned int)ip->tos); */ + /* printf("\t|- Total Length %d Bytes\n",ntohs(ip->tot_len)); */ + /* printf("\t|- Identification %d\n",ntohs(ip->id)); */ + /* printf("\t|- Time To Live %d\n",(unsigned int)ip->ttl); */ + /* printf("\t|- Protocol %d\n",(unsigned int)ip->protocol); */ + /* printf("\t|- Header Checksum %d\n",ntohs(ip->check)); */ + /* printf("\t|- Source IP %s\n", inet_ntoa(source.sin_addr)); */ + /* printf("\t|- Destination IP %s\n",inet_ntoa(dest.sin_addr)); */ + + /* printf("\n"); */ + /* } */ return 0; }