%% options %% module #include "dk4sock.h" #include "dk4mem.h" #include "dk4strw.h" #include "dk4strd.h" #include "dk4maowd.h" #include "dk4maowh.h" #include "dk4rec23.h" $!trace-include /** Constant texts used by the module, not localized. */ static const wchar_t * const dk4socket_wc_kw[] = { $!string-table prefix=L # # 0 Separator between port number and address # @ # # 1 Separator between IPv4 address components # . # # 2 Separator between IPv6 address components # : $!end }; int dk4socket_wc_inet_ntop( wchar_t *dptr, size_t dsz, int afam, const void *src, dk4_er_t *erp ) { #if DK4_ON_WINDOWS #if DK4_HAVE_INET_NTOP /* +++++ +Windows +inet_ntop */ #if DK4_HAVE_STRUCT_SOCKADDR_IN6 struct in6_addr in6; #endif struct in_addr in4; int back = DK4_SOCKET_RESULT_FAILED; if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; } if ((NULL != dptr) && (NULL != src) && (0 < dsz)) { dk4socket_error_reset(); switch (afam) { case AF_INET : { DK4_MEMCPY(&in4, src, sizeof(in4)); if (NULL != InetNtopW(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 != InetNtopW(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; /* ----- +Windows +inet_ntop */ #else /* +++++ +Windows -inet_ntop */ wchar_t 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 = L'\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_wc_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)u1, 0, erp ); if (0 != res) { if (0 != dk4strw_cpy_s(dptr, dsz, buf, erp)) { u1 = ((ul >> 16) & 0x000000FFUL); res = dk4ma_write_wc_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)u1, 0, erp ); if (0 != res) { if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[1], erp)) { if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) { u1 = ((ul >> 8) & 0x000000FFUL); res = dk4ma_write_wc_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)u1, 0, erp ); if (0 != res) { if (0 != dk4strw_cat_s(dptr,dsz,dk4socket_wc_kw[1],erp)) { if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) { u1 = (ul & 0x000000FFUL); res = dk4ma_write_wc_decimal_unsigned( buf, sizeof(buf), (dk4_um_t)u1, 0, erp ); if (0 != res) { if ( 0 != dk4strw_cat_s(dptr,dsz,dk4socket_wc_kw[1],erp) ) { if (0 != dk4strw_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_wc_hex_unsigned( buf, sizeof(buf), (dk4_um_t)us, 0, erp ); if (0 != res) { if (0 == i) { if (0 == dk4strw_cpy_s(dptr, dsz, buf, erp)) { back = DK4_SOCKET_RESULT_FAILED; i = 8; } } else { if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[2], erp)) { if (0 != dk4strw_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; /* ----- +Windows -inet_ntop */ #endif #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return DK4_SOCKET_RESULT_FAILED; #endif } int dk4socket_wc_addr_port_to_text( wchar_t *dptr, size_t dsz, int afam, const struct sockaddr *saptr, size_t sasz, dk4_er_t *erp ) { #if DK4_ON_WINDOWS #if DK4_HAVE_GETNAMEINFO /* +++++ +getnameinfo */ wchar_t hbuf[64]; wchar_t pbuf[64]; const DWORD szh = DK4_SIZEOF(hbuf,wchar_t); const DWORD szp = DK4_SIZEOF(pbuf,wchar_t); int back = DK4_SOCKET_RESULT_FAILED; int res; 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 = GetNameInfoW(saptr, (socklen_t)sasz, hbuf, szh, pbuf, szp, res); #else res = GetNameInfoW(saptr, sasz, hbuf, szh, pbuf, szp, res); #endif if (0 == res) { if (0 != dk4strw_cpy_s(dptr, dsz, pbuf, erp)) { if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[0], erp)) { if (0 != dk4strw_cat_s(dptr, dsz, hbuf, erp)) { back = DK4_SOCKET_RESULT_SUCCESS; } } } } else { dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; /* ----- +getnameinfo */ #else /* +++++ -getnameinfo */ wchar_t hbuf[64]; wchar_t pbuf[64]; struct sockaddr_in *psoin4; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 *psoin6; #endif int back = DK4_SOCKET_RESULT_FAILED; int hpah = 0; int res; unsigned short us; if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\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_wc_decimal_unsigned( pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp ); if (0 != res) { res = dk4socket_wc_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_wc_decimal_unsigned( pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp ); if (0 != res) { res = dk4socket_wc_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 != dk4strw_cpy_s(dptr, dsz, pbuf, erp)) { if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[0], erp)) { if (0 != dk4strw_cat_s(dptr, dsz, hbuf, erp)) { back = DK4_SOCKET_RESULT_SUCCESS; } } } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; /* ----- -getnameinfo */ #endif #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return DK4_SOCKET_RESULT_FAILED; #endif } int dk4socket_wc_sockaddr_to_text( wchar_t *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_wc_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_wc_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; }