6464# else
6565# undef SO_BPF_EXTENSIONS
6666# endif
67+ # if defined(HAVE_LINUX_IF_PACKET_H )
68+ # include <linux/if_packet.h>
69+ # endif
70+ # if defined(HAVE_LINUX_IF_ETHER_H )
71+ # include <linux/if_ether.h>
72+ # endif
6773#endif
6874
6975#include <stddef.h>
@@ -960,13 +966,16 @@ PHP_FUNCTION(socket_read)
960966/* {{{ Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type. */
961967PHP_FUNCTION (socket_getsockname )
962968{
963- zval * arg1 , * addr , * port = NULL ;
969+ zval * arg1 , * addr , * objint = NULL ;
964970 php_sockaddr_storage sa_storage = {0 };
965971 php_socket * php_sock ;
966972 struct sockaddr * sa ;
967973 struct sockaddr_in * sin ;
968974#ifdef HAVE_IPV6
969975 struct sockaddr_in6 * sin6 ;
976+ #endif
977+ #ifdef AF_PACKET
978+ struct sockaddr_ll * sll ;
970979#endif
971980 char addrbuf [INET6_ADDRSTRLEN ];
972981 struct sockaddr_un * s_un ;
@@ -977,7 +986,7 @@ PHP_FUNCTION(socket_getsockname)
977986 Z_PARAM_OBJECT_OF_CLASS (arg1 , socket_ce )
978987 Z_PARAM_ZVAL (addr )
979988 Z_PARAM_OPTIONAL
980- Z_PARAM_ZVAL (port )
989+ Z_PARAM_ZVAL (objint )
981990 ZEND_PARSE_PARAMETERS_END ();
982991
983992 php_sock = Z_SOCKET_P (arg1 );
@@ -997,8 +1006,8 @@ PHP_FUNCTION(socket_getsockname)
9971006 inet_ntop (AF_INET6 , & sin6 -> sin6_addr , addrbuf , sizeof (addrbuf ));
9981007 ZEND_TRY_ASSIGN_REF_STRING (addr , addrbuf );
9991008
1000- if (port != NULL ) {
1001- ZEND_TRY_ASSIGN_REF_LONG (port , htons (sin6 -> sin6_port ));
1009+ if (objint != NULL ) {
1010+ ZEND_TRY_ASSIGN_REF_LONG (objint , htons (sin6 -> sin6_port ));
10021011 }
10031012 RETURN_TRUE ;
10041013 break ;
@@ -1008,8 +1017,8 @@ PHP_FUNCTION(socket_getsockname)
10081017 addr_string = inet_ntop (AF_INET , & sin -> sin_addr , addrbuf , sizeof (addrbuf ));
10091018 ZEND_TRY_ASSIGN_REF_STRING (addr , addr_string );
10101019
1011- if (port != NULL ) {
1012- ZEND_TRY_ASSIGN_REF_LONG (port , htons (sin -> sin_port ));
1020+ if (objint != NULL ) {
1021+ ZEND_TRY_ASSIGN_REF_LONG (objint , htons (sin -> sin_port ));
10131022 }
10141023 RETURN_TRUE ;
10151024 break ;
@@ -1020,9 +1029,19 @@ PHP_FUNCTION(socket_getsockname)
10201029 ZEND_TRY_ASSIGN_REF_STRING (addr , s_un -> sun_path );
10211030 RETURN_TRUE ;
10221031 break ;
1032+ #ifdef AF_PACKET
1033+ case AF_PACKET :
1034+ sll = (struct sockaddr_ll * ) sa ;
1035+
1036+ if (objint != NULL ) {
1037+ ZEND_TRY_ASSIGN_REF_LONG (objint , sll -> sll_ifindex );
1038+ }
1039+ RETURN_TRUE ;
1040+ break ;
1041+ #endif
10231042
10241043 default :
1025- zend_argument_value_error (1 , "must be one of AF_UNIX, AF_INET, or AF_INET6" );
1044+ zend_argument_value_error (1 , "must be one of AF_UNIX, AF_PACKET, AF_INET, or AF_INET6" );
10261045 RETURN_THROWS ();
10271046 }
10281047}
@@ -1038,6 +1057,9 @@ PHP_FUNCTION(socket_getpeername)
10381057 struct sockaddr_in * sin ;
10391058#ifdef HAVE_IPV6
10401059 struct sockaddr_in6 * sin6 ;
1060+ #endif
1061+ #ifdef AF_PACKET
1062+ struct sockaddr_ll * sll ;
10411063#endif
10421064 char addrbuf [INET6_ADDRSTRLEN ];
10431065 struct sockaddr_un * s_un ;
@@ -1094,6 +1116,17 @@ PHP_FUNCTION(socket_getpeername)
10941116 ZEND_TRY_ASSIGN_REF_STRING (arg2 , s_un -> sun_path );
10951117 RETURN_TRUE ;
10961118 break ;
1119+ #ifdef AF_PACKET
1120+ case AF_PACKET :
1121+ sll = (struct sockaddr_ll * ) sa ;
1122+
1123+ if (arg3 != NULL ) {
1124+ ZEND_TRY_ASSIGN_REF_LONG (arg3 , sll -> sll_ifindex );
1125+ }
1126+ RETURN_TRUE ;
1127+ break ;
1128+ #endif
1129+
10971130
10981131 default :
10991132 zend_argument_value_error (1 , "must be one of AF_UNIX, AF_INET, or AF_INET6" );
@@ -1117,9 +1150,12 @@ PHP_FUNCTION(socket_create)
11171150 if (domain != AF_UNIX
11181151#ifdef HAVE_IPV6
11191152 && domain != AF_INET6
1153+ #endif
1154+ #ifdef AF_PACKET
1155+ & & domain != AF_PACKET
11201156#endif
11211157 && domain != AF_INET ) {
1122- zend_argument_value_error (1 , "must be one of AF_UNIX, AF_INET6, or AF_INET" );
1158+ zend_argument_value_error (1 , "must be one of AF_UNIX, AF_PACKET, AF_INET6, or AF_INET" );
11231159 RETURN_THROWS ();
11241160 }
11251161
@@ -1138,6 +1174,17 @@ PHP_FUNCTION(socket_create)
11381174 RETURN_THROWS ();
11391175 }
11401176
1177+ #ifdef ETH_P_ALL
1178+ if (protocol == ETH_P_IP || protocol == ETH_P_ARP || protocol == ETH_P_ALL ) {
1179+ if (domain != AF_PACKET ) {
1180+ zend_argument_value_error (1 , "must be AF_PACKET when one of the ETH_P_* constants is used" );
1181+ RETURN_THROWS ();
1182+ }
1183+ // Those constants are defined in host byte order
1184+ protocol = htons (protocol );
1185+ }
1186+ #endif
1187+
11411188 object_init_ex (return_value , socket_ce );
11421189 php_sock = Z_SOCKET_P (return_value );
11431190
@@ -2702,6 +2749,18 @@ PHP_FUNCTION(socket_addrinfo_bind)
27022749
27032750 ai = Z_ADDRESS_INFO_P (arg1 );
27042751
2752+ #ifdef ETH_P_ALL
2753+ if (ai -> addrinfo .ai_protocol == ETH_P_IP || ai -> addrinfo .ai_protocol == ETH_P_ARP ||
2754+ ai -> addrinfo .ai_protocol == ETH_P_ALL ) {
2755+ if (ai -> addrinfo .ai_family != AF_PACKET ) {
2756+ zend_value_error ("\"ai_family\" array option must be AF_PACKET when one of the ETH_P_* constants is used" );
2757+ RETURN_THROWS ();
2758+ }
2759+ // Those constants are defined in host byte order
2760+ ai -> addrinfo .ai_protocol = htons (ai -> addrinfo .ai_protocol );
2761+ }
2762+ #endif
2763+
27052764 object_init_ex (return_value , socket_ce );
27062765 php_sock = Z_SOCKET_P (return_value );
27072766
0 commit comments