diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4sock33.ctr |
Initial commit
Diffstat (limited to 'support/dktools/dk4sock33.ctr')
-rw-r--r-- | support/dktools/dk4sock33.ctr | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/support/dktools/dk4sock33.ctr b/support/dktools/dk4sock33.ctr new file mode 100644 index 0000000000..d6ff6b842e --- /dev/null +++ b/support/dktools/dk4sock33.ctr @@ -0,0 +1,241 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2016-xxxx +license = bsd + + + +%% module + +#include "dk4conf.h" +#include "dk4types.h" +#include "dk4mem.h" +#include "dk4sock.h" +#include "dk4mai8dus.h" +#include "dk4mao8d.h" + + + +$!trace-include + + + +/** Attempt to convert an IPv4 or IPv6 address from text to address. + @param dptr Destination variable. + @param str Source text. + @return 1 on success, 0 on error. +*/ +static +int +dk4socket_c8_find_address(dk4_sockaddr_storage_t *dptr, const char *str) +{ +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + struct sockaddr_in6 *in6; +#endif + struct sockaddr_in *in4; +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + IN6_ADDR addr6; +#endif + IN_ADDR addr4; + int back = 0; + int res; + $? "+ dk4socket_c8_find_address" + res = dk4socket_c8_inet_pton(&addr4, sizeof(addr4), AF_INET, str, NULL); + if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". IPv4" + in4 = (struct sockaddr_in *)dptr; + in4->sin_family = AF_INET; + DK4_MEMCPY(&(in4->sin_addr), &addr4, sizeof(addr4)); + back = 1; + } else { +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + res = dk4socket_c8_inet_pton(&addr6, sizeof(addr6), AF_INET6, str, NULL); + if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". IPv6" + in6 = (struct sockaddr_in6 *)dptr; + in6->sin6_family = AF_INET6; + DK4_MEMCPY(&(in6->sin6_addr), &addr6, sizeof(addr6)); + back = 1; + } +#endif + } + $? "- dk4socket_c8_find_address %d", back + return back; +} + + + +/** Find address for one host name. + @param dptr Address of destination data structure. + @param remhost Remote host name. + @param remport Remote port number in host representation. + @param ip4 Flag: Prefer IPv4 over IPv6 addresses. + @return 1 on success, 0 on error. +*/ +static +int +dk4socket_c8_find_host( + dk4_sockaddr_storage_t *dptr, + const char *remhost, + unsigned short remport, + int ip4 +) +{ +#if DK4_HAVE_GETADDRINFO + char buf[16*sizeof(unsigned short)]; + struct addrinfo hints; + struct addrinfo *results = NULL; + struct addrinfo *rptr = NULL; + int back = 0; + int res = 0; + $? "+ dk4socket_c8_find_host (getaddrinfo) \"%s\"", TR_8STR(remhost) + res = dk4ma_write_c8_decimal_unsigned( + buf, sizeof(buf), (dk4_um_t)remport, 0, NULL + ); + if (0 != res) { + DK4_MEMRES(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = 0; + hints.ai_flags = AI_NUMERICSERV; + res = getaddrinfo(remhost, buf, &hints, &results); + if ((0 == res) && (NULL != results)) { $? ". getaddrinfo" + if (0 != ip4) { $? ". IPv4 preferred" + rptr = results; + while ((NULL != rptr) && (0 == back)) { $? ". entry" + if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) { + if (AF_INET == rptr->ai_addr->sa_family) { + if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) { + DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen); + back = 1; $? ". found" + } else { $? "! address too large" + } + } else { $? "! not IPv4" + } + } else { $? "! no address data" + } + rptr = rptr->ai_next; + } + if (0 == back) { + rptr = results; + while ((NULL != rptr) && (0 == back)) { $? ". entry" + if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) { + if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) { + DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen); + back = 1; $? ". found" + } else { $? "! address too large" + } + } else { $? "! no address data" + } + rptr = rptr->ai_next; + } + } + } else { $? ". any address family" + rptr = results; + while ((NULL != rptr) && (0 == back)) { $? ". entry" + if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) { + if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) { + DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen); + back = 1; $? ". found" + } else { $? "! address too large" + } + } else { $? "! no address data" + } + rptr = rptr->ai_next; + } + } + } else { $? "! getaddrinfo" + } + if (NULL != results) { freeaddrinfo(results); } + } else { $? "! failed to convert port no to text" + } + $? "- dk4socket_c8_find_host %d", back + return back; +#else +#if DK4_HAVE_GETHOSTBYNAME +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + struct sockaddr_in6 *sa6; +#endif + struct sockaddr_in *sa4; + struct hostent *hep = NULL; + int back = 0; + $? "+ dk4socket_c8_find_host (gethostbyname) \"%s\"", TR_8STR(remhost) + hep = gethostbyname(remhost); + if (NULL != hep) { $? ". entry" + if (NULL != hep->h_addr_list) { $? ". list" + if (NULL != *(hep->h_addr_list)) { $? ". element" + switch (hep->h_addrtype) { + case AF_INET : { $? ". IPv4" + sa4 = (struct sockaddr_in *)dptr; + DK4_MEMRES(sa4, sizeof(struct sockaddr_in)); + sa4->sin_family = AF_INET; + sa4->sin_port = dk4socket_htons(remport); + DK4_MEMCPY(&(sa4->sin_addr),*(hep->h_addr_list),sizeof(IN_ADDR)); + back = 1; $? ". found" + } break; +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + case AF_INET6 : { $? ". IPv6" + sa6 = (struct sockaddr_in6 *)dptr; + DK4_MEMRES(sa6, sizeof(struct sockaddr_in6)); + sa6->sin6_family = AF_INET6; + sa6->sin_port = dk4socket_htons(remport); + DK4_MEMCPY(&(sa6->sin6_addr),*(hep->h_addr_list),sizeof(IN6_ADDR)); + back = 1; $? ". found" + } break; +#endif + } + } else { $? "! NULL pointer" + } + } else { $? "! NULL list" + } + } else { $? "! not found" + } + $? "- dk4socket_c8_find_host %d", back + return back; +#else + int back = 0; + $? "+ dk4socket_c8_find_host (none) \"%s\"", TR_8STR(remhost) + $? "- dk4socket_c8_find_host %d", back + return back; +#endif +#endif +} + + + +int +dk4socket_c8_udp_addresses_numeric( + dk4_sockaddr_storage_t *array, + const char *remhost, + unsigned short remport, + unsigned short locport, + int ip4, + dk4_er_t *erp +) +{ + int back = DK4_SOCKET_RESULT_FAILED; + $? "+ dk4socket_c8_udp_addresses_numeric \"%s\"", TR_8STR(remhost) + if ((NULL != array) && (NULL != remhost) && (0 < remport) && (0 < locport)) { + DK4_MEMRES(array, (2*sizeof(dk4_sockaddr_storage_t))); + if (0 != dk4socket_c8_find_address(array, remhost)) { + $? ". address found" + back = dk4socket_complete_addresses(array, remport, locport); + $? ". back = %d", back + } + if (DK4_SOCKET_RESULT_FAILED == back) { $? ". no addr" + if (0 != dk4socket_c8_find_host(array, remhost, remport, ip4)) { + back = dk4socket_complete_addresses(array, remport, locport); + if (DK4_SOCKET_RESULT_FAILED == back) { $? "! not completed" + dk4error_set_simple_error_code(erp, DK4_E_BUG); + } + } else { $? "! host not found" + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } + } + } else { $? "! arguments" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + $? "- dk4socket_c8_udp_addresses_numeric %d", back + return back; +} + + |