1
0
mirror of https://github.com/php/php-src.git synced 2026-04-23 16:08:35 +02:00
Files
archived-php-src/ext/sockets/sockaddr_conv.c
T
Christoph M. Becker c8955c078a Revert GH-10220
Cf. <https://github.com/php/php-src/pull/10220#issuecomment-1383739816>.

This reverts commit ecc880f491.
This reverts commit 588a07f737.
This reverts commit f377e15751.
This reverts commit b4ba16fe18.
This reverts commit 694ec1deea.
This reverts commit 6b34de8eba.
This reverts commit aa1cd02a43.
This reverts commit 308fd311ea.
This reverts commit 16203b53e1.
This reverts commit 738fb5ca54.
This reverts commit 9fdbefacd3.
This reverts commit cd4a7c1d90.
This reverts commit 928685eba2.
This reverts commit 01e5ffc85c.
2023-01-16 12:27:33 +01:00

149 lines
3.8 KiB
C

#include <php.h>
#include <php_network.h>
#include "php_sockets.h"
#ifdef PHP_WIN32
#include "windows_common.h"
#else
#include <netdb.h>
#include <arpa/inet.h>
#endif
extern int php_string_to_if_index(const char *val, unsigned *out);
#if HAVE_IPV6
/* Sets addr by hostname, or by ip in string form (AF_INET6) */
int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_sock) /* {{{ */
{
struct in6_addr tmp;
#if HAVE_GETADDRINFO
struct addrinfo hints;
struct addrinfo *addrinfo = NULL;
#endif
char *scope = strchr(string, '%');
if (inet_pton(AF_INET6, string, &tmp)) {
memcpy(&(sin6->sin6_addr.s6_addr), &(tmp.s6_addr), sizeof(struct in6_addr));
} else {
#if HAVE_GETADDRINFO
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET6;
#if HAVE_AI_V4MAPPED
hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
#else
hints.ai_flags = AI_ADDRCONFIG;
#endif
getaddrinfo(string, NULL, &hints, &addrinfo);
if (!addrinfo) {
#ifdef PHP_WIN32
PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
#else
PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));
#endif
return 0;
}
if (addrinfo->ai_family != PF_INET6 || addrinfo->ai_addrlen != sizeof(struct sockaddr_in6)) {
php_error_docref(NULL, E_WARNING, "Host lookup failed: Non AF_INET6 domain returned on AF_INET6 socket");
freeaddrinfo(addrinfo);
return 0;
}
memcpy(&(sin6->sin6_addr.s6_addr), ((struct sockaddr_in6*)(addrinfo->ai_addr))->sin6_addr.s6_addr, sizeof(struct in6_addr));
freeaddrinfo(addrinfo);
#else
/* No IPv6 specific hostname resolution is available on this system? */
php_error_docref(NULL, E_WARNING, "Host lookup failed: getaddrinfo() not available on this system");
return 0;
#endif
}
if (scope) {
zend_long lval = 0;
double dval = 0;
unsigned scope_id = 0;
scope++;
if (IS_LONG == is_numeric_string(scope, strlen(scope), &lval, &dval, 0)) {
if (lval > 0 && (zend_ulong)lval <= UINT_MAX) {
scope_id = lval;
}
} else {
php_string_to_if_index(scope, &scope_id);
}
sin6->sin6_scope_id = scope_id;
}
return 1;
}
/* }}} */
#endif
/* Sets addr by hostname, or by ip in string form (AF_INET) */
int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_sock) /* {{{ */
{
struct in_addr tmp;
struct hostent *host_entry;
#ifdef HAVE_INET_PTON
if (inet_pton(AF_INET, string, &tmp)) {
#else
if (inet_aton(string, &tmp)) {
#endif
sin->sin_addr.s_addr = tmp.s_addr;
} else {
if (strlen(string) > MAXFQDNLEN || ! (host_entry = php_network_gethostbyname(string))) {
/* Note: < -10000 indicates a host lookup error */
#ifdef PHP_WIN32
PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
#else
PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));
#endif
return 0;
}
if (host_entry->h_addrtype != AF_INET) {
php_error_docref(NULL, E_WARNING, "Host lookup failed: Non AF_INET domain returned on AF_INET socket");
return 0;
}
memcpy(&(sin->sin_addr.s_addr), host_entry->h_addr_list[0], host_entry->h_length);
}
return 1;
}
/* }}} */
/* Sets addr by hostname or by ip in string form (AF_INET or AF_INET6,
* depending on the socket) */
int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, char *string, php_socket *php_sock) /* {{{ */
{
if (php_sock->type == AF_INET) {
struct sockaddr_in t = {0};
if (php_set_inet_addr(&t, string, php_sock)) {
memcpy(ss, &t, sizeof t);
ss->ss_family = AF_INET;
*ss_len = sizeof(t);
return 1;
}
}
#if HAVE_IPV6
else if (php_sock->type == AF_INET6) {
struct sockaddr_in6 t = {0};
if (php_set_inet6_addr(&t, string, php_sock)) {
memcpy(ss, &t, sizeof t);
ss->ss_family = AF_INET6;
*ss_len = sizeof(t);
return 1;
}
}
#endif
else {
php_error_docref(NULL, E_WARNING,
"IP address used in the context of an unexpected type of socket");
}
return 0;
}