php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
sockaddr_conv.c
Go to the documentation of this file.
1#include <php.h>
2#include <php_network.h>
3#include "php_sockets.h"
4
5#ifdef PHP_WIN32
6#include "windows_common.h"
7#else
8#include <netdb.h>
9#include <arpa/inet.h>
10#endif
11
12extern zend_result php_string_to_if_index(const char *val, unsigned *out);
13
14#ifdef HAVE_IPV6
15/* Sets addr by hostname, or by ip in string form (AF_INET6) */
16int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_sock) /* {{{ */
17{
18 struct in6_addr tmp;
19#ifdef HAVE_GETADDRINFO
20 struct addrinfo hints;
21 struct addrinfo *addrinfo = NULL;
22#endif
23 char *scope = strchr(string, '%');
24
25 if (inet_pton(AF_INET6, string, &tmp)) {
26 memcpy(&(sin6->sin6_addr.s6_addr), &(tmp.s6_addr), sizeof(struct in6_addr));
27 } else {
28#ifdef HAVE_GETADDRINFO
29
30 memset(&hints, 0, sizeof(struct addrinfo));
31 hints.ai_family = AF_INET6;
32#ifdef AI_V4MAPPED
33 hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
34#else
35 hints.ai_flags = AI_ADDRCONFIG;
36#endif
37 getaddrinfo(string, NULL, &hints, &addrinfo);
38 if (!addrinfo) {
39#ifdef PHP_WIN32
40 PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
41#else
42 PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));
43#endif
44 return 0;
45 }
46 if (addrinfo->ai_family != PF_INET6 || addrinfo->ai_addrlen != sizeof(struct sockaddr_in6)) {
47 php_error_docref(NULL, E_WARNING, "Host lookup failed: Non AF_INET6 domain returned on AF_INET6 socket");
48 freeaddrinfo(addrinfo);
49 return 0;
50 }
51
52 memcpy(&(sin6->sin6_addr.s6_addr), ((struct sockaddr_in6*)(addrinfo->ai_addr))->sin6_addr.s6_addr, sizeof(struct in6_addr));
53 freeaddrinfo(addrinfo);
54
55#else
56 /* No IPv6 specific hostname resolution is available on this system? */
57 php_error_docref(NULL, E_WARNING, "Host lookup failed: getaddrinfo() not available on this system");
58 return 0;
59#endif
60
61 }
62
63 if (scope) {
64 zend_long lval = 0;
65 double dval = 0;
66 unsigned scope_id = 0;
67
68 scope++;
69
70 if (IS_LONG == is_numeric_string(scope, strlen(scope), &lval, &dval, 0)) {
71 if (lval > 0 && (zend_ulong)lval <= UINT_MAX) {
72 scope_id = lval;
73 }
74 } else {
75 php_string_to_if_index(scope, &scope_id);
76 }
77
78 sin6->sin6_scope_id = scope_id;
79 }
80
81 return 1;
82}
83/* }}} */
84#endif
85
86/* Sets addr by hostname, or by ip in string form (AF_INET) */
87int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_sock) /* {{{ */
88{
89 struct in_addr tmp;
90 struct hostent *host_entry;
91
92 if (inet_pton(AF_INET, string, &tmp)) {
93 sin->sin_addr.s_addr = tmp.s_addr;
94 } else {
95 if (strlen(string) > MAXFQDNLEN || ! (host_entry = php_network_gethostbyname(string))) {
96 /* Note: < -10000 indicates a host lookup error */
97#ifdef PHP_WIN32
98 PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
99#else
100 PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));
101#endif
102 return 0;
103 }
104 if (host_entry->h_addrtype != AF_INET) {
105 php_error_docref(NULL, E_WARNING, "Host lookup failed: Non AF_INET domain returned on AF_INET socket");
106 return 0;
107 }
108 memcpy(&(sin->sin_addr.s_addr), host_entry->h_addr_list[0], host_entry->h_length);
109 }
110
111 return 1;
112}
113/* }}} */
114
115/* Sets addr by hostname or by ip in string form (AF_INET or AF_INET6,
116 * depending on the socket) */
117int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, char *string, php_socket *php_sock) /* {{{ */
118{
119 if (php_sock->type == AF_INET) {
120 struct sockaddr_in t = {0};
121 if (php_set_inet_addr(&t, string, php_sock)) {
122 memcpy(ss, &t, sizeof t);
123 ss->ss_family = AF_INET;
124 *ss_len = sizeof(t);
125 return 1;
126 }
127 }
128#ifdef HAVE_IPV6
129 else if (php_sock->type == AF_INET6) {
130 struct sockaddr_in6 t = {0};
131 if (php_set_inet6_addr(&t, string, php_sock)) {
132 memcpy(ss, &t, sizeof t);
133 ss->ss_family = AF_INET6;
134 *ss_len = sizeof(t);
135 return 1;
136 }
137 }
138#endif
139 else {
141 "IP address used in the context of an unexpected type of socket");
142 }
143 return 0;
144}
inet_pton(string $ip)
sin(float $num)
strchr(string $haystack, string $needle, bool $before_needle=false)
unsigned int socklen_t
Definition fastcgi.c:87
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
zval * val
Definition ffi.c:4262
#define NULL
Definition gdcache.h:45
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
PHPAPI struct hostent * php_network_gethostbyname(const char *name)
Definition network.c:1350
#define MAXFQDNLEN
int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, char *string, php_socket *php_sock)
int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_sock)
zend_result php_string_to_if_index(const char *val, unsigned *out)
Definition multicast.c:62
int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_sock)
const AI_V4MAPPED
const AF_INET
const AI_ADDRCONFIG
const AF_INET6
unsigned short ss_family
#define h_errno
strlen(string $string)
#define E_WARNING
Definition zend_errors.h:24
int32_t zend_long
Definition zend_long.h:42
uint32_t zend_ulong
Definition zend_long.h:43
#define dval(x)
#define IS_LONG
Definition zend_types.h:604
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
new_op_array scope
out($f, $s)