From 9526d60b2cf092444af86924288c222d804a36a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Wed, 12 Jan 2022 22:14:32 +0100 Subject: =?UTF-8?q?pcap=20in=20host=C5=A1t+net->hostip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- host.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 host.c (limited to 'host.c') diff --git a/host.c b/host.c new file mode 100644 index 0000000..b6e68dd --- /dev/null +++ b/host.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include +#include +struct in_net { + struct in_addr addr; + struct in_addr mask; +}; +/* not needed begin */ +#define POPCNT(y) int popcnt##x (uint##y##_t x) { \ + int c = 0; \ + for (int i = 0; i < y; i++) \ + if (1 << i & x) \ + c++; \ + return c; \ +} +POPCNT(32) +unsigned int power2[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648 }; /* ah yes, libmath */ +/* not needed end */ +struct in_addr host (struct in_net n, int h /* consecutive number of the host in the network */) { + n.addr.s_addr = ntohl(n.addr.s_addr & n.mask.s_addr); + n.mask.s_addr = ntohl(n.mask.s_addr); + int c = 1; + int s = 0; + for (int i = 0; i < 32; i++) + if (1 << i & ~n.mask.s_addr) { + if (1 << s++ & h) + n.addr.s_addr |= 1 << i; + c = c * 2; + } + if (h >= c) + n.addr.s_addr = 0; + n.addr.s_addr = htonl(n.addr.s_addr); + return n.addr; +} +int resolve (const char * d, uint32_t * r) { + struct addrinfo hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_DGRAM, + .ai_flags = 0, + .ai_protocol = 0, + .ai_canonname = NULL, + .ai_addr = NULL, + .ai_next = NULL + }; + struct addrinfo * result; + int ret = getaddrinfo(d, NULL, &hints, &result); + *r = ((struct sockaddr_in *) result->ai_addr)->sin_addr.s_addr; /* ah yes, C */ + freeaddrinfo(result); + return ret; +} +struct in_net str2net (char * s) { /* blocking, resolving */ + struct in_net r = { + .mask = { + .s_addr = 0 + }, + .addr = { + .s_addr = 0 + } + }; + char * m = strchr(s, '/'); + char o = '\0'; + int e; + if (m) { + o = *m; + *m++ = '\0'; + } else + m = "32"; + fprintf(stderr, "str2net: resolving %s ... ", s); + if ((e = resolve(s, &r.addr.s_addr))) { + fprintf(stderr, "failed: %s\n", gai_strerror(e)); + goto r; + } + fprintf(stderr, " %s mask %s ...", inet_ntoa(r.addr), m); + char * p; + int x = strtoll(m, &p, 10); + r.mask.s_addr = 0; + for (int j = 0; j < x && j < 32; j++) + r.mask.s_addr = r.mask.s_addr >> 1 | 1 << 31; + r.mask.s_addr = htonl(r.mask.s_addr); + if (*p) + if ((e = resolve(m, &r.mask.s_addr))) { + fprintf(stderr, "no: %s\n", gai_strerror(e)); + goto r; + } + fprintf(stderr, " %s\n", inet_ntoa(r.mask)); +r: + if (o) + *--m = o; + return r; +} -- cgit v1.2.3