%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% module #include "dk4conf.h" #include "dk4types.h" #include "dk4error.h" #include "dk4mem.h" #include "dk4sock.h" #include "dk4str8.h" #include "dk4strw.h" #include "dk4mai8dsz.h" #include "dk4maiwdsz.h" $!trace-include #if DK4_CHAR_SIZE > 1 #if DK4_ON_WINDOWS int dk4socket_wc_get_allowed_peer( dk4_allowed_peer_t *peerptr, const wchar_t *str, dk4_er_t *erp ) { wchar_t mycp[128]; IN_ADDR in4; IN_ADDR ma4; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 IN6_ADDR in6; IN6_ADDR ma6; #endif wchar_t *maptr; const wchar_t *endptr = NULL; size_t bitno = 0; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 size_t i = 0; #endif unsigned long nm4 = 0UL; int back = DK4_SOCKET_RESULT_FAILED; int af = AF_UNSPEC; int res = 0; if ((NULL != peerptr) && (NULL != str)) { if (0 != dk4strw_cpy_s(mycp, DK4_SIZEOF(mycp,wchar_t), str, erp)) { maptr = dk4strw_chr(mycp, L'/'); if (NULL != maptr) { *(maptr++) = L'\0'; } back = dk4socket_wc_inet_pton(&in4, sizeof(in4), AF_INET, mycp, erp); if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET; } #if DK4_HAVE_STRUCT_SOCKADDR_IN6 else { back = dk4socket_wc_inet_pton(&in6, sizeof(in6), AF_INET6, mycp, erp); if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET6; } } #endif if (DK4_SOCKET_RESULT_SUCCESS == back) { back = DK4_SOCKET_RESULT_FAILED; if (NULL != maptr) { res = dk4ma_input_wc_dec_size_t(&bitno, maptr, &endptr, 1, NULL); if (0 != res) { /* Bit number */ switch (af) { case AF_INET : { if (0 != dk4socket_mask_bits(&nm4, bitno, erp)) { ma4.s_addr = dk4socket_htonl(nm4); DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4)); DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4)); peerptr->af = af; back = DK4_SOCKET_RESULT_SUCCESS; } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { back = dk4socket_mask6_bits(&ma6, bitno, erp); if (DK4_SOCKET_RESULT_SUCCESS == back) { DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6)); DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6)); peerptr->af = af; } } break; #endif default : { } } } else { /* Mask as address */ switch (af) { case AF_INET : { back = dk4socket_wc_inet_pton( &ma4, sizeof(ma4), AF_INET, maptr, erp ); if (DK4_SOCKET_RESULT_SUCCESS == back) { DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4)); DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4)); peerptr->af = af; } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { back = dk4socket_wc_inet_pton( &ma6, sizeof(ma6), AF_INET6, maptr, erp ); if (DK4_SOCKET_RESULT_SUCCESS == back) { DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6)); DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6)); peerptr->af = af; } } break; #endif } } } else { /* Host */ switch (af) { case AF_INET : { ma4.s_addr = dk4socket_htonl(0xFFFFFFFFUL); DK4_MEMCPY(&((peerptr->data).ipv4.ad), &in4, sizeof(in4)); DK4_MEMCPY(&((peerptr->data).ipv4.ma), &ma4, sizeof(ma4)); peerptr->af = af; back = DK4_SOCKET_RESULT_SUCCESS; } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { for (i = 0; i < 16; i++) { ma6.s6_addr[i] = 0xFF; } DK4_MEMCPY(&((peerptr->data).ipv6.ad), &in6, sizeof(in6)); DK4_MEMCPY(&((peerptr->data).ipv6.ma), &ma6, sizeof(ma6)); peerptr->af = af; back = DK4_SOCKET_RESULT_SUCCESS; } break; #endif default : { /* Must not happen */ } break; } } } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } #else #error No networking functions using wchar_t host and service names available! #endif #endif int dk4socket_get_allowed_peer( dk4_allowed_peer_t *peerptr, const dkChar *str, dk4_er_t *erp ) { #if DK4_CHAR_SIZE > 1 return ( dk4socket_wc_get_allowed_peer(peerptr, str, erp) ); #else return ( dk4socket_c8_get_allowed_peer(peerptr, str, erp) ); #endif }