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:
M | httping.c | | | 26 | ++++++++++++++------------ |
M | ping.c | | | 57 | ++++----------------------------------------------------- |
M | ping.h | | | 6 | +++++- |
A | resolve.c | | | 63 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | resolve.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