diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 8398e004d0b6c..16a52e1e0fd45 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -536,6 +536,11 @@ static PHP_MINIT_FUNCTION(sockets) #ifdef SO_ACCEPTFILTER REGISTER_LONG_CONSTANT("SO_ACCEPTFILTER", SO_ACCEPTFILTER, CONST_CS | CONST_PERSISTENT); #endif +#ifdef SOL_FILTER + REGISTER_LONG_CONSTANT("SOL_FILTER", SOL_FILTER, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FIL_ATTACH", FIL_ATTACH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FIL_DETACH", FIL_DETACH, CONST_CS | CONST_PERSISTENT); +#endif #ifdef SO_DONTTRUNC REGISTER_LONG_CONSTANT("SO_DONTTRUNC", SO_DONTTRUNC, CONST_CS | CONST_PERSISTENT); #endif @@ -1853,6 +1858,32 @@ PHP_FUNCTION(socket_get_option) } } +#ifdef SOL_FILTER + if (level == SOL_FILTER) { + switch (optname) { + + case FIL_LIST: { + size_t i; + struct fil_info fi[32] = {{0}}; + optlen = sizeof(fi); + + if (getsockopt(php_sock->bsd_socket, level, optname, (char*)fi, &optlen) != 0) { + PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); + RETURN_FALSE; + } + + array_init(return_value); + + for (i = 0; i < optlen / sizeof(struct fil_info); i++) { + add_index_string(return_value, i, fi[i].fi_name); + } + + return; + } + } + } +#endif + optlen = sizeof(other_val); if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) { @@ -2004,6 +2035,23 @@ PHP_FUNCTION(socket_set_option) } #endif +#ifdef FIL_ATTACH + case FIL_ATTACH: + case FIL_DETACH: { + if (level != SOL_FILTER) { + php_error_docref(NULL, E_WARNING, "Invalid level"); + RETURN_FALSE; + } + if (Z_TYPE_P(arg4) != IS_STRING) { + php_error_docref(NULL, E_WARNING, "Invalid filter argument type"); + RETURN_FALSE; + } + opt_ptr = Z_STRVAL_P(arg4); + optlen = Z_STRLEN_P(arg4); + break; + } +#endif + default: default_case: convert_to_long(arg4);