From a38f91aff987f01cc885771554b4cd142599df3f Mon Sep 17 00:00:00 2001 From: batleram Date: Sat, 24 Oct 2026 15:13:04 -0400 Subject: initial baseline ~2500ms --- .gitignore | 2 ++ Makefile | 13 ++++++++ calc.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ calc.h | 15 +++++++++ 4 files changed, 134 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 calc.c create mode 100644 calc.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d629681 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.json +calc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..75b6c76 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ + +.PHONY: build + +build: calc.c + clang -o calc -O3 -ggdb ./calc.c + +bench: build + ./calc 10.0.0.0/8 2 + +bench2: build + ./calc 10.0.0.0/6 2 + + diff --git a/calc.c b/calc.c new file mode 100644 index 0000000..2f533b1 --- /dev/null +++ b/calc.c @@ -0,0 +1,104 @@ +#include "calc.h" +#include +#include +#include +#include + +int print_usage() { + printf("Invalid arguments:\n\tcalc \n"); + + return 1; +} + +uint32_t calc_netmask(unsigned int cidr) { + return UINT32_MAX << (32 - cidr); +} + +uint32_t segments_to_ip(unsigned int segments[4]) { + return (segments[0] << 3*8) | (segments[1] << 2*8) | (segments[2] << 1*8) | (segments[3]); +} + +uint32_t subnetmask_for_netspace(unsigned int desired_netspace) { + uint32_t start = UINT32_MAX; + // +1 because 2s complement + while (~start +1 < desired_netspace + 2) { + start = start << 1; + } + return start; +} + + +int main(int argc, char** argv) { + struct timespec start; + clock_gettime(CLOCK_MONOTONIC, &start); + + unsigned int segments[4] = {0}; + unsigned int cidr = 0; + unsigned int min_ips_per_subnet = 0; + // parse args + if (argc < 3) { + return print_usage(); + } + if (sscanf(argv[1], "%u.%u.%u.%u/%u", &segments[0], &segments[1], &segments[2], &segments[3], &cidr) != 5) return print_usage(); + if (sscanf(argv[2], "%u", &min_ips_per_subnet) != 1) return print_usage(); + + CalcRequest req = { + .network = segments_to_ip(segments), // fixed later + .netmask = calc_netmask(cidr), + .subnet_mask = subnetmask_for_netspace(min_ips_per_subnet), + .count = 0, // later + }; + // User can provide any ip address, this converts it to the network address + req.network = req.network & req.netmask; + // +1 because 2s complement + const unsigned int ips_per_subnet = ~req.subnet_mask + 1; + req.count = (~req.netmask+1) / (ips_per_subnet); + + FILE *out = fopen("file.json", "w"); + if (out == NULL) { + perror("Failed to open output file:"); + return errno; + } + + + fprintf(out, "[\n"); // file start + uint32_t offset = 0; + int i = 0; + while (i + +#define UINT_TO_SEGMENTS(i) (i>>24 & 0xff),(i>>16 & 0xff),(i>>8 & 0xff),(i & 0xff) + +int print_usage(); +uint32_t calc_netmask(unsigned int cidr); +uint32_t segments_to_ip(unsigned int segments[4]); +uint32_t cidr_for_netspace(unsigned int desired_netspace); + +typedef struct { + uint32_t network; + uint32_t netmask; + uint32_t subnet_mask; + uint32_t count; +} CalcRequest; -- cgit v1.2.3