diff options
| author | batleram <batleram@gmail.com> | 2026-10-24 15:13:04 -0400 |
|---|---|---|
| committer | batleram <batleram@gmail.com> | 2026-10-24 15:25:09 -0400 |
| commit | a38f91aff987f01cc885771554b4cd142599df3f (patch) | |
| tree | c1d8caf1e5c9a1364c1c8bdf08345c58dfe203c3 | |
initial baseline ~2500ms
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | Makefile | 13 | ||||
| -rw-r--r-- | calc.c | 104 | ||||
| -rw-r--r-- | calc.h | 15 |
4 files changed, 134 insertions, 0 deletions
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 + + @@ -0,0 +1,104 @@ +#include "calc.h" +#include <time.h> +#include <errno.h> +#include <stdint.h> +#include <stdio.h> + +int print_usage() { + printf("Invalid arguments:\n\tcalc <network/cidr> <ips per subnet>\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<req.count) { + const uint32_t network = req.network + offset; + const uint32_t first = network + 1; + const uint32_t broadcast = first + ips_per_subnet - 2; + const uint32_t last = broadcast - 1; + offset += ips_per_subnet; + if (i+1 == req.count) { + fprintf(out, + "\t{\n\t\t\"Reseau\": \"%hu.%hu.%hu.%hu\",\n\t\t\"Premiere\": \"%hu.%hu.%hu.%hu\",\n\t\t\"Derniere\": \"%hu.%hu.%hu.%hu\",\n\t\t\"Broadcast\": \"%hu.%hu.%hu.%hu\",\n\t\t\"Nbr\": \"%hu\"\n\t}\n", + UINT_TO_SEGMENTS(network), + UINT_TO_SEGMENTS(first), + UINT_TO_SEGMENTS(last), + UINT_TO_SEGMENTS(broadcast), + ips_per_subnet - 2 + ); + break; + } + fprintf(out, + "\t{\n\t\t\"Reseau\": \"%hu.%hu.%hu.%hu\",\n\t\t\"Premiere\": \"%hu.%hu.%hu.%hu\",\n\t\t\"Derniere\": \"%hu.%hu.%hu.%hu\",\n\t\t\"Broadcast\": \"%hu.%hu.%hu.%hu\",\n\t\t\"Nbr\": \"%hu\"\n\t},\n", + UINT_TO_SEGMENTS(network), + UINT_TO_SEGMENTS(first), + UINT_TO_SEGMENTS(last), + UINT_TO_SEGMENTS(broadcast), + ips_per_subnet - 2 + ); + i++; + } + fprintf(out, "]"); // file end + fflush(out); + fclose(out); + + struct timespec end; + clock_gettime(CLOCK_MONOTONIC, &end); + + printf("Time elapsed: %llu ms\n", (unsigned long long)((end.tv_sec - start.tv_sec) * 1e3 + (end.tv_nsec - start.tv_nsec) / 1e6)); + + return 0; +} @@ -0,0 +1,15 @@ +#include <stdint.h> + +#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; |
