cnping

Minimal Graphical Ping Tool
git clone https://git.sinitax.com/cnlohr/cnping
Log | Files | Refs | Submodules | README | LICENSE | sfeed.txt

commit 7b505848408df6a0d4400d3aaf86cf17b65df305
parent 35e2594ad52bcdd99ab8d178746e1fb834db8c5d
Author: mrbesen <y.g.2@gmx.de>
Date:   Sun, 11 Sep 2022 17:23:45 +0200

http-ping with ipv6 support

Diffstat:
Mhttping.c | 26++++++++++++++------------
Mping.c | 57++++-----------------------------------------------------
Mping.h | 6+++++-
Aresolve.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresolve.h | 17+++++++++++++++++
5 files changed, 103 insertions(+), 66 deletions(-)

diff --git a/httping.c b/httping.c @@ -1,8 +1,10 @@ #include "httping.h" +#include <errno.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "resolve.h" #ifndef TCC #include <unistd.h> @@ -49,8 +51,9 @@ void DoHTTPing( const char * addy, double minperiod, int * seqnoptr, volatile do exit( -2 ); } #endif - struct sockaddr_in serveraddr; - struct hostent *server; + struct sockaddr_in6 serveraddr; + socklen_t serveraddr_len; + int serverresolve; int httpsock; int addylen = strlen(addy); char hostname[addylen+1]; @@ -75,22 +78,21 @@ void DoHTTPing( const char * addy, double minperiod, int * seqnoptr, volatile do } /* gethostbyname: get the server's DNS entry */ + serveraddr_len = sizeof(serveraddr); *getting_host_by_name = 1; - server = gethostbyname(hostname); + serverresolve = resolveName((struct sockaddr*) &serveraddr, &serveraddr_len, hostname); *getting_host_by_name = 0; - if (server == NULL) { + + if (serverresolve != 1) { ERRMB("ERROR, no such host as \"%s\"\n", hostname); goto fail; } /* build the server's Internet address */ - memset((char *) &serveraddr, 0, sizeof(serveraddr)); - serveraddr.sin_family = AF_INET; - memcpy((char *)&serveraddr.sin_addr.s_addr, (char *)server->h_addr, server->h_length); - serveraddr.sin_port = htons(portno); - + serveraddr.sin6_port = htons(portno); + reconnect: - *socketptr = httpsock = socket(AF_INET, SOCK_STREAM, 0); + *socketptr = httpsock = socket(serveraddr.sin6_family, SOCK_STREAM, 0); if (httpsock < 0) { ERRMB( "Error opening socket\n" ); @@ -109,9 +111,9 @@ reconnect: #endif /* connect: create a connection with the server */ - if (connect(httpsock, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) + if (connect(httpsock, (struct sockaddr*)&serveraddr, serveraddr_len) < 0) { - ERRMB( "%s: ERROR connecting\n", hostname ); + ERRMB( "%s: ERROR connecting: %s (%d)\n", hostname, strerror(errno), errno ); goto fail; } diff --git a/ping.c b/ping.c @@ -11,6 +11,7 @@ #include <assert.h> #include "ping.h" #include "error_handling.h" +#include "resolve.h" #ifdef TCC #include "tccheader.h" @@ -182,7 +183,6 @@ void ping(struct sockaddr_in *addr ) #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <netinet/icmp6.h> - #include <arpa/inet.h> // inet_pton (parsing ipv4 and ipv6 notation) #endif #include "rawdraw/os_generic.h" @@ -295,54 +295,6 @@ int createSocket() return -1; } -// try to parse hostname -// * as dot notation (1.1.1.1) -// * as ipv6 notation (abcd:ef00::1) -// * as hostname (resolve DNS) -static int resolveName(struct sockaddr* addr, socklen_t* addr_len, const char* hostname) -{ - // try to parse ipv4 - int parseresult = inet_pton(AF_INET, hostname, &((struct sockaddr_in*) addr)->sin_addr); - if(parseresult == 1) - { - struct sockaddr_in* ipv4addr = ((struct sockaddr_in*) addr); - ipv4addr->sin_family = AF_INET; - *addr_len = sizeof(struct sockaddr_in); - return 1; - } - - // try to parse ipv6 - parseresult = inet_pton(AF_INET6, hostname, &((struct sockaddr_in6*) addr)->sin6_addr); - if(parseresult == 1) - { - struct sockaddr_in6* ipv6addr = ((struct sockaddr_in6*) addr); - ipv6addr->sin6_family = AF_INET6; - *addr_len = sizeof(struct sockaddr_in6); - return 1; - } - - // try to resolve DNS - struct addrinfo* res = NULL; - int errorcode = getaddrinfo(hostname, NULL, NULL, &res); - - if( errorcode != 0) - { - ERRM("Error: cannot resolve hostname %s: %s\n", hostname, gai_strerror(errorcode)); - exit( -1 ); - } - - if(res->ai_addrlen > *addr_len) - { - // error - exit( -1 ); - } - memcpy(addr, res->ai_addr, res->ai_addrlen); - *addr_len = res->ai_addrlen; - - freeaddrinfo(res); - return 1; -} - void listener() { #ifndef WIN32 @@ -445,7 +397,7 @@ void ping(struct sockaddr *addr, socklen_t addr_len ) if( sr <= 0 ) { ping_failed_to_send = 1; - ERRM("Ping send failed: %s familiy: %d\n", strerror(errno), addr->sa_family); + ERRM("Ping send failed: %s errno: %d\n", strerror(errno), errno); } else { @@ -500,8 +452,7 @@ void ping_setup(const char * strhost, const char * device) } #else // resolve host - memset(&psaddr, 0, sizeof(psaddr)); - psaddr_len = sizeof(struct sockaddr_in6); + psaddr_len = sizeof(psaddr); resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost); sd = createSocket(); @@ -534,6 +485,6 @@ void do_pinger( ) ping((struct sockaddr*) &psaddr, psaddr_len ); } - +// used by the ERRMB makro from error_handling.h char errbuffer[1024]; diff --git a/ping.h b/ping.h @@ -2,7 +2,11 @@ #define _PING_H #include <stdint.h> -#include <sys/socket.h> // for socklen_t +#ifdef WIN32 + typedef int socklen_t; +#else + #include <sys/socket.h> +#endif struct sockaddr_in; diff --git a/resolve.c b/resolve.c @@ -0,0 +1,63 @@ +#include "resolve.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "error_handling.h" + +#ifdef WIN32 + +#else // !WIN32 + #include <arpa/inet.h> // inet_pton (parsing ipv4 and ipv6 notation) + + #include <sys/types.h> + #include <sys/socket.h> + #include <netdb.h> +#endif + +int resolveName(struct sockaddr* addr, socklen_t* addr_len, const char* hostname) +{ + int result; + struct addrinfo* res = NULL; + + // zero addr + memset(addr, 0, *addr_len); + + // try to parse ipv4 + result = inet_pton(AF_INET, hostname, &((struct sockaddr_in*) addr)->sin_addr); + if(result == 1) + { + addr->sa_family = AF_INET; + *addr_len = sizeof(struct sockaddr_in); + return 1; + } + + // try to parse ipv6 + result = inet_pton(AF_INET6, hostname, &((struct sockaddr_in6*) addr)->sin6_addr); + if(result == 1) + { + addr->sa_family = AF_INET6; + *addr_len = sizeof(struct sockaddr_in6); + return 1; + } + + // try to resolve DNS + result = getaddrinfo(hostname, NULL, NULL, &res); + if( result != 0) + { + ERRM( "Error: cannot resolve hostname %s: %s\n", hostname, gai_strerror(result) ); + exit( -1 ); + } + + if(res->ai_addrlen > *addr_len) + { + // error - this should not happen + freeaddrinfo(res); + exit( -1 ); + } + memcpy(addr, res->ai_addr, res->ai_addrlen); + *addr_len = res->ai_addrlen; + + freeaddrinfo(res); + return 1; +} diff --git a/resolve.h b/resolve.h @@ -0,0 +1,17 @@ +#ifndef _RESOLVE_H +#define _RESOLVE_H + +#ifdef WIN32 + typedef int socklen_t; +#else + #include <sys/socket.h> +#endif + +// try to parse hostname +// * as dot notation (1.1.1.1) +// * as ipv6 notation (abcd:ef00::1) +// * as hostname (resolve DNS) +// returns 1 on success +int resolveName(struct sockaddr* addr, socklen_t* addr_len, const char* hostname); + +#endif