summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Fankhauser hiddenalpha.ch2024-04-05 17:02:39 +0200
committerAndreas Fankhauser hiddenalpha.ch2024-04-05 17:02:39 +0200
commita23c90adc1f402d599c1d3a3e2ba9a32563725d0 (patch)
treed706ee94bc1beefcdd4875fde599c6bcbbb86dca
parent22f5dea3f7a009c1b2ca41aa3eeecb4fbc2473f9 (diff)
downloadgetaddrinfo-cli-a23c90adc1f402d599c1d3a3e2ba9a32563725d0.zip
getaddrinfo-cli-a23c90adc1f402d599c1d3a3e2ba9a32563725d0.tar.gz
A first version of the tool.
-rw-r--r--.gitignore2
-rw-r--r--Makefile56
-rw-r--r--src/main/c/getaddrinfocli.c122
3 files changed, 180 insertions, 0 deletions
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 <arpa/inet.h>
+#include <assert.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#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;
+}
+