]> granicus.if.org Git - php/commitdiff
Build fixes; accept names for if_index
authorGustavo Lopes <glopes@nebm.ist.utl.pt>
Tue, 1 Jan 2013 22:38:19 +0000 (23:38 +0100)
committerGustavo Lopes <glopes@nebm.ist.utl.pt>
Sat, 2 Feb 2013 15:38:08 +0000 (16:38 +0100)
ext/sockets/conversions.c
ext/sockets/multicast.c
ext/sockets/multicast.h
ext/sockets/sendrecvmsg.c
ext/sockets/sendrecvmsg.h
ext/sockets/sockets.c

index 7ca9972ac0d3858d8ab36fd719dca0ce067c1bb6..54631604ab4b8b7554670e8d43697000af5c3038 100644 (file)
@@ -12,6 +12,9 @@
 #include <netinet/in.h>
 #include <sys/un.h>
 
+#include <sys/ioctl.h>
+#include <net/if.h>
+
 #include <limits.h>
 #include <stdarg.h>
 #include <stddef.h>
@@ -53,6 +56,8 @@ typedef struct {
 #define KEY_RECVMSG_RET "recvmsg_ret"
 #define KEY_CMSG_LEN   "cmsg_len"
 
+const struct key_value empty_key_value_list[] = {{0}};
+
 /* PARAMETERS */
 static int param_get_bool(void *ctx, const char *key, int def)
 {
@@ -331,25 +336,6 @@ void from_zval_write_int(const zval *arr_value, char *field, ser_context *ctx)
        ival = (int)lval;
        memcpy(field, &ival, sizeof(ival));
 }
-static void from_zval_write_unsigned(const zval *arr_value, char *field, ser_context *ctx)
-{
-       long lval;
-       unsigned ival;
-
-       lval = from_zval_integer_common(arr_value, ctx);
-       if (ctx->err.has_error) {
-               return;
-       }
-
-       if (sizeof(long) > sizeof(ival) && (lval < 0 || lval > UINT_MAX)) {
-               do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
-                               "for a native unsigned int");
-               return;
-       }
-
-       ival = (unsigned)lval;
-       memcpy(field, &ival, sizeof(ival));
-}
 static void from_zval_write_uint32(const zval *arr_value, char *field, ser_context *ctx)
 {
        long lval;
@@ -1192,20 +1178,17 @@ void to_zval_read_msghdr(const char *msghdr_c, zval *zv, res_context *ctx)
 /* CONVERSIONS for if_index */
 static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context *ctx)
 {
-       zval *va; unsigned *out;
-       unsigned ret;
-       zval                            lzval = zval_used_for_init;
+       unsigned        ret;
+       zval            lzval = zval_used_for_init;
 
        if (Z_TYPE_P(zv) == IS_LONG) {
-               if (Z_LVAL_P(zv) < 0 || Z_LVAL_P(zv) > UINT_MAX) {
+               if (Z_LVAL_P(zv) < 0 || Z_LVAL_P(zv) > UINT_MAX) { /* allow 0 (unspecified interface) */
                        do_from_zval_err(ctx, "the interface index cannot be negative or "
                                        "larger than %u; given %ld", UINT_MAX, Z_LVAL_P(zv));
                } else {
                        ret = (unsigned)Z_LVAL_P(zv);
                }
        } else {
-#if HAVE_IF_NAMETOINDEX
-
                if (Z_TYPE_P(zv) != IS_STRING) {
                        ZVAL_COPY_VALUE(&lzval, zv);
                        zval_copy_ctor(&lzval);
@@ -1213,11 +1196,32 @@ static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context
                        zv = &lzval;
                }
 
+#if HAVE_IF_NAMETOINDEX
                ret = if_nametoindex(Z_STRVAL_P(zv));
                if (ret == 0) {
                        do_from_zval_err(ctx, "no interface with name \"%s\" could be "
                                        "found", Z_STRVAL_P(zv));
                }
+#elif defined(SIOCGIFINDEX)
+               {
+                       struct ifreq ifr;
+                       if (strlcpy(ifr.ifr_name, Z_STRVAL_P(zv), sizeof(ifr.ifr_name))
+                                       >= sizeof(ifr.ifr_name)) {
+                               do_from_zval_err(ctx, "the interface name \"%s\" is too large ",
+                                               Z_STRVAL_P(zv));
+                       } else if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) {
+                               if (errno == ENODEV) {
+                                       do_from_zval_err(ctx, "no interface with name \"%s\" could be "
+                                                       "found", Z_STRVAL_P(zv));
+                               } else {
+                                       do_from_zval_err(ctx, "error fetching interface index for "
+                                                       "interface with name \"%s\" (errno %d)",
+                                                       Z_STRVAL_P(zv), errno);
+                               }
+                       } else {
+                               ret = (unsigned)ifr.ifr_ifindex;
+                       }
+               }
 #else
                do_from_zval_err(ctx,
                                "this platform does not support looking up an interface by "
@@ -1236,7 +1240,7 @@ static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context
 #ifdef IPV6_PKTINFO
 static const field_descriptor descriptors_in6_pktinfo[] = {
                {"addr", sizeof("addr"), 1, offsetof(struct in6_pktinfo, ipi6_addr), from_zval_write_sin6_addr, to_zval_read_sin6_addr},
-               {"ifindex", sizeof("ifindex"), 1, offsetof(struct in6_pktinfo, ipi6_ifindex), from_zval_write_unsigned, to_zval_read_unsigned},
+               {"ifindex", sizeof("ifindex"), 1, offsetof(struct in6_pktinfo, ipi6_ifindex), from_zval_write_ifindex, to_zval_read_unsigned},
                {0}
 };
 void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser_context *ctx)
@@ -1294,6 +1298,7 @@ size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx)
 static void from_zval_write_fd_array_aux(zval **elem, unsigned i, void **args, ser_context *ctx)
 {
        int *iarr = args[0];
+       TSRMLS_FETCH();
 
        if (Z_TYPE_PP(elem) == IS_RESOURCE) {
                php_stream *stream;
@@ -1375,8 +1380,8 @@ void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx)
                        return;
                }
                if (S_ISSOCK(statbuf.st_mode)) {
-                       php_socket *sock = socket_import_file_descriptor(fd);
-                       zend_register_resource(elem, sock, php_sockets_le_socket());
+                       php_socket *sock = socket_import_file_descriptor(fd TSRMLS_CC);
+                       zend_register_resource(elem, sock, php_sockets_le_socket() TSRMLS_CC);
                } else {
                        php_stream *stream = php_stream_fopen_from_fd(fd, "rw", NULL);
                        php_stream_to_zval(stream, elem);
index dc242693acc3cc8f3f11f469e981ee9ca078436a..5d29c9c5e265efb053fbb383c068fea1a310dc01 100644 (file)
@@ -250,7 +250,7 @@ mcast_req_fun:
 int php_do_setsockopt_ip_mcast(php_socket *php_sock,
                                                           int level,
                                                           int optname,
-                                                          zval **arg4)
+                                                          zval **arg4 TSRMLS_DC)
 {
        unsigned int    if_index;
        struct in_addr  if_addr;
@@ -319,7 +319,7 @@ dosockopt:
 int php_do_setsockopt_ipv6_mcast(php_socket *php_sock,
                                                                 int level,
                                                                 int optname,
-                                                                zval **arg4)
+                                                                zval **arg4 TSRMLS_DC)
 {
        unsigned int    if_index;
        void                    *opt_ptr;
index c363b5847272046b87bd5ced0fe036991a60eb39..1ad4673feb7196a41dafa808417691737df56706 100644 (file)
 int php_do_setsockopt_ip_mcast(php_socket *php_sock,
                                                           int level,
                                                           int optname,
-                                                          zval **arg4);
+                                                          zval **arg4 TSRMLS_DC);
 
 int php_do_setsockopt_ipv6_mcast(php_socket *php_sock,
                                                                 int level,
                                                                 int optname,
-                                                                zval **arg4);
+                                                                zval **arg4 TSRMLS_DC);
 
 int php_if_index_to_addr4(
         unsigned if_index,
index 6479bf90a850d1266961ec360df06c6030dd9469..b83b3ae48237824acb6ac3db995eac2c2234a784 100644 (file)
@@ -272,7 +272,7 @@ PHP_FUNCTION(socket_cmsg_space)
        RETURN_LONG((long)CMSG_SPACE(entry->size + n * entry->var_el_size));
 }
 
-int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval **arg4)
+int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC)
 {
        struct err_s    err = {0};
        zend_llist              *allocations = NULL;
@@ -311,7 +311,7 @@ dosockopt:
        return retval != 0 ? FAILURE : SUCCESS;
 }
 
-int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *result)
+int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *result TSRMLS_DC)
 {
        struct err_s            err = {0};
        void                            *buffer;
@@ -340,7 +340,7 @@ int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname,
                zval *zv = to_zval_run_conversions(buffer, reader, "in6_pktinfo",
                                empty_key_value_list, &err);
                if (err.has_error) {
-                       err_msg_dispose(&err);
+                       err_msg_dispose(&err TSRMLS_CC);
                        res = -1;
                } else {
                        ZVAL_COPY_VALUE(result, zv);
@@ -354,9 +354,7 @@ int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname,
 
 void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS)
 {
-       /* IPv6 ancillary data
-        * Note that support for sticky options via setsockopt() is not implemented
-        * yet (where special support is needed, i.e., the optval is not an int). */
+       /* IPv6 ancillary data */
 #ifdef IPV6_RECVPKTINFO
        REGISTER_LONG_CONSTANT("IPV6_RECVPKTINFO",              IPV6_RECVPKTINFO,       CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("IPV6_PKTINFO",          IPV6_PKTINFO,       CONST_CS | CONST_PERSISTENT);
index 55dca3c1fbc7b1bfff280c5288bcf40a0a48b037..5a3798274fd7e058e4c2ff35f9d801c301ac5bee 100644 (file)
@@ -12,8 +12,8 @@ PHP_FUNCTION(socket_cmsg_space);
 void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS);
 void php_socket_sendrecvmsg_shutdown(SHUTDOWN_FUNC_ARGS);
 
-int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval **arg4);
-int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *result);
+int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC);
+int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *result TSRMLS_DC);
 
 /* for conversions.c */
 typedef struct {
index 9c57e2d98d22ca22d5fa0024fe065fb2192d6076..2aeb4b0fd3327de0b2dbd659588a07379153fb2b 100644 (file)
@@ -1878,7 +1878,7 @@ PHP_FUNCTION(socket_get_option)
                }
                }
        } else if (level == IPPROTO_IPV6) {
-               int ret = php_do_getsockopt_ipv6_rfc3542(php_sock, level, optname, return_value);
+               int ret = php_do_getsockopt_ipv6_rfc3542(php_sock, level, optname, return_value TSRMLS_CC);
                if (ret == SUCCESS) {
                        return;
                } else if (ret == FAILURE) {
@@ -1981,15 +1981,15 @@ PHP_FUNCTION(socket_set_option)
 
 
        if (level == IPPROTO_IP) {
-               int res = php_do_setsockopt_ip_mcast(php_sock, level, optname, arg4);
+               int res = php_do_setsockopt_ip_mcast(php_sock, level, optname, arg4 TSRMLS_CC);
                HANDLE_SUBCALL(res);
        }
 
 #if HAVE_IPV6
        else if (level == IPPROTO_IPV6) {
-               int res = php_do_setsockopt_ipv6_mcast(php_sock, level, optname, arg4);
+               int res = php_do_setsockopt_ipv6_mcast(php_sock, level, optname, arg4 TSRMLS_CC);
                if (res == 1) {
-                       res = php_do_setsockopt_ipv6_rfc3542(php_sock, level, optname, arg4);
+                       res = php_do_setsockopt_ipv6_rfc3542(php_sock, level, optname, arg4 TSRMLS_CC);
                }
                HANDLE_SUBCALL(res);
        }
@@ -2273,7 +2273,7 @@ PHP_FUNCTION(socket_import_stream)
                RETURN_FALSE;
        }
 
-       retsock = socket_import_file_descriptor(socket);
+       retsock = socket_import_file_descriptor(socket TSRMLS_CC);
        if (retsock == NULL) {
                RETURN_FALSE;
        }