From a23c90adc1f402d599c1d3a3e2ba9a32563725d0 Mon Sep 17 00:00:00 2001 From: Andreas Fankhauser hiddenalpha.ch Date: Fri, 5 Apr 2024 17:02:39 +0200 Subject: A first version of the tool. --- .gitignore | 2 + Makefile | 56 ++++++++++++++++++++ src/main/c/getaddrinfocli.c | 122 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 src/main/c/getaddrinfocli.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2247d5f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/build +/dist diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e2e86e6 --- /dev/null +++ b/Makefile @@ -0,0 +1,56 @@ + +CC=gcc +LD=gcc +MKDIR_P=mkdir -p +RIMRAF=rm -rf +COPYTO=cp -t +DIRNAME=dirname +MD5SUM=md5sum -b +TAR=tar +INSTALL_ROOT=/usr/local + +CFLAGS=-Wall -Werror -pedantic -std=c89 -fPIC -fmax-errors=1 -DPROJECT_VERSION=$(PROJECT_VERSION) -D_POSIX_C_SOURCE=200112L + +LDFLAGS=-Wl,-s,--as-needed,--gc-sections,-pie + +LIBS=-dy -lc + +PROJECT_VERSION=$(shell (git describe --tags 2>/dev/null|sed 's,^v,,'|egrep .) || date -u +0.0.0-%Y%m%d.%H%M%S) + +ARCH=$(shell $(CC) -v 2>&1 | egrep '^Target: ' | sed -E 's,^Target: +(.*)$$,\1,') + +.SILENT: + +default: +default: dist/getaddrinfo-$(PROJECT_VERSION)+$(ARCH).tgz + +.PHONY: clean +clean: + echo " RM build dist" + $(RIMRAF) build dist + +build/bin/getaddrinfo: +build/bin/getaddrinfo: build/obj/main/c/getaddrinfocli.o + echo " LN $@" + $(MKDIR_P) "$(shell dirname "$@")" + $(LD) -o "$@" $(LDFLAGS) $^ $(LIBS) + +build/obj/main/c/getaddrinfocli.o: +build/obj/main/c/getaddrinfocli.o: src/main/c/getaddrinfocli.c + echo " CC $@" + $(MKDIR_P) "$(shell dirname "$@")" + $(CC) -c -o "$@" $(CFLAGS) $^ + +dist/getaddrinfo-$(PROJECT_VERSION)+$(ARCH).tgz: +dist/getaddrinfo-$(PROJECT_VERSION)+$(ARCH).tgz: build/bin/getaddrinfo + echo " PKG $@" + $(MKDIR_P) "$(shell dirname "$@")" build/tar build/tar/bin + $(COPYTO) build/tar/bin/. build/bin/getaddrinfo + echo "version=$(PROJECT_VERSION)" > build/tar/METADATA.INI + echo "builtAt=$(shell date -u +%Y-%m-%dT%H:%M:%SZ)" >> build/tar/METADATA.INI + $(TAR) --owner=0 --group=0 -czf "$@" -C build/tar METADATA.INI bin/getaddrinfo + +.PHONY: install +install: + $(TAR) -f dist/getaddrinfo-*+$(ARCH).tgz -C "$(INSTALL_ROOT)" -x bin + diff --git a/src/main/c/getaddrinfocli.c b/src/main/c/getaddrinfocli.c new file mode 100644 index 0000000..209a4a6 --- /dev/null +++ b/src/main/c/getaddrinfocli.c @@ -0,0 +1,122 @@ +#ifdef USERCONFIG +USERCONFIG +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define STR_QUOT_(S) #S +#define STR_QUOT(S) STR_QUOT_(S) + + +static void printHelp( void ){ + printf("%s%s%s", " \n" + " ", strrchr(__FILE__,'/')+1, " - " STR_QUOT(PROJECT_VERSION) "\n" + " \n" + " Print result of getaddrinfo [1] to stdout.\n" + " \n" + " Example: getaddrinfo example.com\n" + " \n" + " [1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html\n" + " \n" + ); +} + + +int main( int argc, char**argv ){ + int err; + const char *nodename; + struct addrinfo *res = NULL, *it; + if( argc != 2 ){ fprintf(stderr, "EINVAL: Try --help\n"); err = -1; goto endFn; } + if( !strcmp(argv[1], "--help") ){ printHelp(); err = 0; goto endFn; } + nodename = argv[1]; assert(nodename != NULL); + err = getaddrinfo(nodename, NULL, NULL, &res); + if( err != 0 ){ + const char *ex; + switch( err ){ + case EAI_AGAIN: ex = "EAI_AGAIN"; break; + case EAI_BADFLAGS: ex = "EAI_BADFLAGS"; break; + case EAI_FAIL: ex = "EAI_FAIL"; break; + case EAI_FAMILY: ex = "EAI_FAMILY"; break; + case EAI_MEMORY: ex = "EAI_MEMORY"; break; + case EAI_NONAME: ex = "EAI_NONAME"; break; + case EAI_SERVICE: ex = "EAI_SERVICE"; break; + case EAI_SOCKTYPE: ex = "EAI_SOCKTYPE"; break; + case EAI_SYSTEM: ex = "EAI_SYSTEM"; break; +#ifdef EAI_ADDRFAMILY + case EAI_ADDRFAMILY: ex = "EAI_ADDRFAMILY"; break; +#endif +#ifdef EAI_NODATA + case EAI_NODATA: ex = "EAI_NODATA"; break; +#endif + default: + assert(!fprintf(stderr,"ERROR: getaddrinfo(): %d %s:%d\n", err, __FILE__, __LINE__)); + ex = NULL; + } + printf("%s: getaddrinfo(\"%s\")\n", ex, nodename); + err = -1; goto endFn; + } + printf("C: %-6s %-6s %-5s %-4s %s\n", "AF", "SOCK", "PROTO", "FLGS", "ADDR"); + for( it = res ; it != NULL ; it = it->ai_next ){ + const char *afStr, *typStr, *protoStr; + switch( it->ai_family ){ + case AF_UNIX : afStr = "UNIX" ; break; + case AF_INET : afStr = "INET" ; break; + case AF_INET6 : afStr = "INET6" ; break; + case AF_UNSPEC: afStr = "UNSPEC"; break; + default: assert(!fprintf(stderr,"TODO: ai_family %d\n", it->ai_family)); afStr = NULL; + } + switch( it->ai_socktype ){ + case SOCK_STREAM: typStr = "STREAM"; break; + case SOCK_DGRAM : typStr = "DGRAM" ; break; + case SOCK_RAW : typStr = "RAW" ; break; + default: assert(!fprintf(stderr, "TODO: ai_socktype %d\n", it->ai_socktype)); typStr = NULL; + } + switch( it->ai_protocol ){ + case 0: protoStr = "0"; break; + case IPPROTO_TCP: protoStr = "TCP"; break; + case IPPROTO_UDP: protoStr = "UDP"; break; + default: assert(!fprintf(stderr, "TODO: ai_protocol %d\n", it->ai_protocol)); protoStr = NULL; + } + printf("R: %-6s %-6s %-5s 0x%02X", + afStr, + typStr, + protoStr, + it->ai_flags + ); + switch( it->ai_family ){ + case AF_UNIX: /*TODO anything useful to print here?*/ break; + case AF_INET: { + #define ADDR4 ((struct sockaddr_in*)it->ai_addr) + uint_least32_t ip; + assert(it->ai_addrlen == 16); + assert(ADDR4->sin_family == AF_INET); + ip = ntohl(ADDR4->sin_addr.s_addr); + printf(" %d.%d.%d.%d", ip >> 24 & 0xFF, ip >> 16 & 0xFF, ip >> 8 & 0xFF, ip & 0xFF); + break; } + #undef ADDR4 + case AF_INET6: { + #define ADDR6 ((struct sockaddr_in6*)it->ai_addr) + char buf[INET6_ADDRSTRLEN + 1]; + if( inet_ntop(it->ai_family, &ADDR6->sin6_addr, buf, sizeof buf) == NULL ){ + snprintf(buf, sizeof buf, "inet_ntop(): errno=%d", errno); + } + printf(" %s", buf); + break; } + #undef ADDR6 + default: assert(!fprintf(stderr,"TODO: ai_family %d\n", it->ai_family)); + } + if( it->ai_canonname != NULL ) printf(" cn=\"%s\"", it->ai_canonname); + puts(""); + } + err = 0; +endFn: + if( res != NULL ) freeaddrinfo(res); + return !!err; +} + -- cgit v1.1