%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% module #include "dk4sock.h" #include "dk4mem.h" #include "dk4str8.h" #include "dk4strd.h" #include "dk4mao8d.h" #include "dk4mao8h.h" #include "dk4rec23.h" $!trace-include /** Constant texts used by the module, not localized. */ static const char * const dk4socket_c8_kw[] = { $!string-table # # 0 Separator between port number and address # @ # # 1 Separator between IPv4 address components # . # # 2 Separator between IPv6 address components # : $!end }; int dk4socket_c8_inet_ntop( char *dptr, size_t dsz, int afam, const void *src, dk4_er_t *erp ) { #if DK4_HAVE_INET_NTOP #if DK4_ON_WINDOWS /* +++++ +inet_ntop +Windows */ #if DK4_HAVE_STRUCT_SOCKADDR_IN6 struct in6_addr in6; /* IPv6 host address */ #endif struct in_addr in4; /* IPv4 host address */ int back = DK4_SOCKET_RESULT_FAILED; if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; } if ((NULL != dptr) && (NULL != src) && (0 < dsz)) { dk4socket_error_reset(); switch (afam) { case AF_INET : { DK4_MEMCPY(&in4, src, sizeof(in4)); if (NULL != inet_ntop(afam, (void *)(&in4), dptr, dsz)) { back = DK4_SOCKET_RESULT_SUCCESS; } else { dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP); } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { DK4_MEMCPY(&in6, src, sizeof(in6)); if (NULL != inet_ntop(afam, (void *)(&in6), dptr, dsz)) { back = DK4_SOCKET_RESULT_SUCCESS; } else { dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP); } } break; #endif default : { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } break; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; /* ----- +inet_ntop +Windows */ #else /* +++++ +inet_ntop -Windows */ int back = DK4_SOCKET_RESULT_FAILED; if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; } if ((NULL != dptr) && (NULL != src) && (0 < dsz)) { if (NULL != inet_ntop(afam, src, dptr, dsz)) { back = DK4_SOCKET_RESULT_SUCCESS; } else { dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; /* ----- +inet_ntop -Windows */ #endif #else /* +++++ -inet_ntop */ char buf[16*sizeof(dk4_um_t)]; const struct in_addr *inp4; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 const struct in6_addr *inp6; #endif unsigned long ul; unsigned long u1; int back = DK4_SOCKET_RESULT_FAILED; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 int i; #endif int res; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 unsigned short us; #endif if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; } if ((NULL != dptr) && (NULL != src) && (0 < dsz)) { switch (afam) { case AF_INET : { inp4 = (const struct in_addr *)src; ul = inp4->s_addr; ul = dk4socket_htonl(ul); u1 = ((ul >> 24) & 0x000000FFUL); res = dk4ma_write_c8_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)u1, 0, erp ); if (0 != res) { if (0 != dk4str8_cpy_s(dptr, dsz, buf, erp)) { u1 = ((ul >> 16) & 0x000000FFUL); res = dk4ma_write_c8_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)u1, 0, erp ); if (0 != res) { if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[1], erp)) { if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) { u1 = ((ul >> 8) & 0x000000FFUL); res = dk4ma_write_c8_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)u1, 0, erp ); if (0 != res) { if (0 != dk4str8_cat_s(dptr,dsz,dk4socket_c8_kw[1],erp)) { if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) { u1 = (ul & 0x000000FFUL); res = dk4ma_write_c8_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)u1, 0, erp ); if (0 != res) { if ( 0 != dk4str8_cat_s(dptr,dsz,dk4socket_c8_kw[1],erp) ) { if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) { back = DK4_SOCKET_RESULT_SUCCESS; } } } } } } } } } } } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { inp6 = (const struct in6_addr *)src; back = DK4_SOCKET_RESULT_SUCCESS; for (i = 0; i < 8; i++) { #if DK4_ON_WINDOWS us = inp6->u.Word[i]; #else us = inp6->s6_addr16[i]; #endif us = dk4socket_htons(us); res = dk4ma_write_c8_hex_unsigned( buf, sizeof(buf), (dk4_um_t)us, 0, erp ); if (0 != res) { if (0 == i) { if (0 == dk4str8_cpy_s(dptr, dsz, buf, erp)) { back = DK4_SOCKET_RESULT_FAILED; i = 8; } } else { if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[2], erp)) { if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) { back = DK4_SOCKET_RESULT_FAILED; i = 8; } } else { back = DK4_SOCKET_RESULT_FAILED; i = 8; } } } else { back = DK4_SOCKET_RESULT_FAILED; i = 8; } } } break; #endif default : { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } break; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; /* ----- -inet_ntop */ #endif } int dk4socket_c8_addr_port_to_text( char *dptr, size_t dsz, int afam, const struct sockaddr *saptr, size_t sasz, dk4_er_t *erp ) { #if DK4_HAVE_GETNAMEINFO /* +++++ +getnameinfo */ char hbuf[64]; /* Buffer for host address */ char pbuf[64]; /* Buffer for port number */ int res; /* Operation result */ int back = DK4_SOCKET_RESULT_FAILED; $? "+ dk4socket_c8_addr_port_to_text (+getnameinfo)" if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; } if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) { res = NI_NUMERICHOST | NI_NUMERICSERV; dk4socket_error_reset(); #if DK4_HAVE_SOCKLEN_T res = getnameinfo( saptr, (socklen_t)sasz, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), res ); #else res = getnameinfo(saptr, sasz, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), res); #endif if (0 == res) { if (0 != dk4str8_cpy_s(dptr, dsz, pbuf, erp)) { if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[0], erp)) { if (0 != dk4str8_cat_s(dptr, dsz, hbuf, erp)) { back = DK4_SOCKET_RESULT_SUCCESS; } else { $? "! buffer length" } } else { $? "! buffer length" } } else { $? "! buffer length" } } else { $? "! getnameinfo" dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res); } } else { $? "! args" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4socket_c8_addr_port_to_text %d", back return back; /* ----- +getnameinfo */ #else /* +++++ -getnameinfo */ char hbuf[64]; /* Host address buffer */ char pbuf[64]; /* Port name buffer */ struct sockaddr_in *psoin4; /* IPv4 address */ #if DK4_HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 *psoin6; /* IPv6 address */ #endif int back = DK4_SOCKET_RESULT_FAILED; int hpah = 0; int res; unsigned short us; $? "+ dk4socket_c8_addr_port_to_text (-getnameinfo)" if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; } if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) { switch (afam) { case AF_INET : { psoin4 = (struct sockaddr_in *)saptr; us = psoin4->sin_port; us = dk4socket_ntohs(us); res = dk4ma_write_c8_decimal_unsigned( pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp ); if (0 != res) { res = dk4socket_c8_inet_ntop( hbuf, sizeof(hbuf), AF_INET, &(psoin4->sin_addr), erp ); if (DK4_SOCKET_RESULT_SUCCESS == res) { hpah = 1; } } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { psoin6 = (struct sockaddr_in6 *)saptr; us = psoin6->sin6_port; us = dk4socket_ntohs(us); res = dk4ma_write_c8_decimal_unsigned( pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp ); if (0 != res) { res = dk4socket_c8_inet_ntop( hbuf, sizeof(hbuf), AF_INET6, &(psoin6->sin6_addr), erp ); if (DK4_SOCKET_RESULT_SUCCESS == res) { hpah = 1; } } } break; #endif default : { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } break; } if (0 != hpah) { if (0 != dk4str8_cpy_s(dptr, dsz, pbuf, erp)) { if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[0], erp)) { if (0 != dk4str8_cat_s(dptr, dsz, hbuf, erp)) { back = DK4_SOCKET_RESULT_SUCCESS; } } } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4socket_c8_addr_port_to_text %d", back return back; /* ----- -getnameinfo */ #endif } int dk4socket_c8_sockaddr_to_text( char *dptr, size_t dsz, const dk4_sockaddr_storage_t *saptr, dk4_er_t *erp ) { const struct sockaddr *soa; int back = DK4_SOCKET_RESULT_FAILED; if ((NULL != dptr) && (NULL != saptr) && (0 < dsz)) { soa = (const struct sockaddr *)saptr; switch (soa->sa_family) { case AF_INET : { back = dk4socket_c8_addr_port_to_text( dptr, dsz, AF_INET, soa, sizeof(struct sockaddr_in), erp ); } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { back = dk4socket_c8_addr_port_to_text( dptr, dsz, AF_INET6, soa, sizeof(struct sockaddr_in6), erp ); } break; #endif default : { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } break; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; }