4141# include <netdb.h>
4242# include <netinet/in.h>
4343# include <netinet/tcp.h>
44- # include <netinet/udp.h>
4544# include <sys/un.h>
4645# include <arpa/inet.h>
4746# include <sys/time.h>
5554# ifdef HAVE_IF_NAMETOINDEX
5655# include <net/if.h>
5756# endif
58- # ifdef HAVE_NETINET_ETHER_H
59- # include <netinet/ether.h>
60- # include <netinet/ip.h>
61- # include <linux/ipv6.h>
62- # endif
6357# if defined(HAVE_LINUX_SOCK_DIAG_H )
6458# include <linux/sock_diag.h>
6559# else
@@ -126,9 +120,6 @@ static PHP_RSHUTDOWN_FUNCTION(sockets);
126120
127121zend_class_entry * socket_ce ;
128122static zend_object_handlers socket_object_handlers ;
129- #ifdef AF_PACKET
130- zend_class_entry * socket_ethinfo_ce ;
131- #endif
132123
133124static zend_object * socket_create_object (zend_class_entry * class_type ) {
134125 php_socket * intern = zend_object_alloc (sizeof (php_socket ), class_type );
@@ -491,9 +482,6 @@ static PHP_MINIT_FUNCTION(sockets)
491482 socket_object_handlers .get_gc = socket_get_gc ;
492483 socket_object_handlers .compare = zend_objects_not_comparable ;
493484
494- #if defined(AF_PACKET )
495- socket_ethinfo_ce = register_class_SocketEthernetInfo ();
496- #endif
497485 address_info_ce = register_class_AddressInfo ();
498486 address_info_ce -> create_object = address_info_create_object ;
499487 address_info_ce -> default_object_handlers = & address_info_object_handlers ;
@@ -1400,7 +1388,7 @@ PHP_FUNCTION(socket_bind)
14001388 struct sockaddr_ll * sa = (struct sockaddr_ll * ) sock_type ;
14011389 socklen_t sa_len = sizeof (sa );
14021390
1403- if (getsockname (php_sock -> bsd_socket , ( struct sockaddr * ) sa , & sa_len ) < 0 ) {
1391+ if (getsockname (php_sock -> bsd_socket , sock_type , & sa_len ) < 0 ) {
14041392 zend_value_error ("invalid AF_PACKET socket" );
14051393 RETURN_THROWS ();
14061394 }
@@ -1515,9 +1503,7 @@ PHP_FUNCTION(socket_recvfrom)
15151503 struct sockaddr_in6 sin6 ;
15161504#endif
15171505#ifdef AF_PACKET
1518- struct sockaddr_ll sll ;
1519- int protoid ;
1520- socklen_t protoidlen = sizeof (protoid );
1506+ //struct sockaddr_ll sll;
15211507#endif
15221508 char addrbuf [INET6_ADDRSTRLEN ];
15231509 socklen_t slen ;
@@ -1546,15 +1532,6 @@ PHP_FUNCTION(socket_recvfrom)
15461532 RETURN_FALSE ;
15471533 }
15481534
1549- #ifdef AF_PACKET
1550- // ethernet header + payload
1551- // possibly follow-up PR SOCK_DGRAM
1552- if (php_sock -> type == AF_PACKET && arg3 < 60 ) {
1553- zend_argument_value_error (3 , "must be at least 60 for AF_PACKET" );
1554- RETURN_THROWS ();
1555- }
1556- #endif
1557-
15581535 recv_buf = zend_string_alloc (arg3 + 1 , 0 );
15591536
15601537 switch (php_sock -> type ) {
@@ -1633,19 +1610,14 @@ PHP_FUNCTION(socket_recvfrom)
16331610 break ;
16341611#endif
16351612#ifdef AF_PACKET
1613+ /*
16361614 case AF_PACKET:
1637- getsockopt (php_sock -> bsd_socket , SOL_SOCKET , SO_TYPE , (char * ) & protoid , & protoidlen );
1638-
1639- // TODO: SOCK_DGRAM support
1640- if (protoid != SOCK_RAW ) {
1641- zend_argument_value_error (1 , "must be SOCK_RAW socket type" );
1642- RETURN_THROWS ();
1643- }
1615+ // TODO expose and use proper ethernet frame type instead i.e. src mac, dst mac and payload to userland
1616+ // ditto for socket_sendto
16441617 slen = sizeof(sll);
16451618 memset(&sll, 0, sizeof(sll));
16461619 sll.sll_family = AF_PACKET;
16471620 char ifrname[IFNAMSIZ];
1648- zval zpayload ;
16491621
16501622 retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&sll, (socklen_t *)&slen);
16511623
@@ -1654,93 +1626,20 @@ PHP_FUNCTION(socket_recvfrom)
16541626 zend_string_efree(recv_buf);
16551627 RETURN_FALSE;
16561628 }
1629+ ZSTR_LEN(recv_buf) = retval;
1630+ ZSTR_VAL(recv_buf)[ZSTR_LEN(recv_buf)] = '\0';
16571631
16581632 if (UNEXPECTED(!if_indextoname(sll.sll_ifindex, ifrname))) {
16591633 PHP_SOCKET_ERROR(php_sock, "unable to get the interface name", errno);
16601634 zend_string_efree(recv_buf);
16611635 RETURN_FALSE;
16621636 }
16631637
1664- struct ethhdr * e = (struct ethhdr * )ZSTR_VAL (recv_buf );
1665- unsigned short protocol = ntohs (e -> h_proto );
1666- unsigned char * payload ;
1667-
1668- zval obj ;
1669- object_init_ex (& obj , socket_ethinfo_ce );
1670- array_init (& zpayload );
1671-
1672- switch (protocol ) {
1673- case ETH_P_IP : {
1674- payload = ((unsigned char * )e + sizeof (struct ethhdr ));
1675- struct iphdr * ip = (struct iphdr * )payload ;
1676- unsigned char * ipdata = payload + (ip -> ihl * 4 );
1677- struct in_addr s , d ;
1678- s .s_addr = ip -> saddr ;
1679- d .s_addr = ip -> daddr ;
1680- add_assoc_string (& zpayload , "ipsrc" , inet_ntoa (s ));
1681- add_assoc_string (& zpayload , "ipdst" , inet_ntoa (d ));
1682-
1683- switch (ip -> protocol ) {
1684- case IPPROTO_TCP : {
1685- struct tcphdr * tcp = (struct tcphdr * )ipdata ;
1686- add_assoc_long (& zpayload , "portsrc" , ntohs (tcp -> th_sport ));
1687- add_assoc_long (& zpayload , "portdst" , ntohs (tcp -> th_dport ));
1688- break ;
1689- }
1690- case IPPROTO_UDP : {
1691- struct udphdr * udp = (struct udphdr * )ipdata ;
1692- add_assoc_long (& zpayload , "portsrc" , ntohs (udp -> uh_sport ));
1693- add_assoc_long (& zpayload , "portdst" , ntohs (udp -> uh_dport ));
1694- break ;
1695- }
1696- default :
1697- zend_string_efree (recv_buf );
1698- zval_ptr_dtor (& zpayload );
1699- zval_ptr_dtor (& obj );
1700- zend_value_error ("unsupported ip header protocol" );
1701- RETURN_THROWS ();
1702- }
1703- break ;
1704- }
1705- case ETH_P_IPV6 : {
1706- payload = ((unsigned char * )e + sizeof (struct ethhdr ));
1707- struct ipv6hdr * ip = (struct ipv6hdr * )payload ;
1708- char s [INET6_ADDRSTRLEN ], d [INET6_ADDRSTRLEN ];
1709- inet_ntop (AF_INET6 , & ip -> saddr , s , sizeof (s ));
1710- inet_ntop (AF_INET6 , & ip -> daddr , d , sizeof (d ));
1711- add_assoc_string (& zpayload , "ipsrc" , s );
1712- add_assoc_string (& zpayload , "ipdst" , d );
1713- break ;
1714- }
1715- case ETH_P_LOOP : {
1716- struct ethhdr * innere = (struct ethhdr * )((unsigned char * )e + ETH_HLEN );
1717- add_assoc_string (& zpayload , "macsrc" , ether_ntoa ((struct ether_addr * )innere -> h_source ));
1718- add_assoc_string (& zpayload , "macdst" , ether_ntoa ((struct ether_addr * )innere -> h_dest ));
1719- break ;
1720- }
1721- default :
1722- zend_string_efree (recv_buf );
1723- zval_ptr_dtor (& zpayload );
1724- zval_ptr_dtor (& obj );
1725- zend_value_error ("unsupported ethernet protocol" );
1726- RETURN_THROWS ();
1727- }
1728-
1729- Z_DELREF (zpayload );
1730- zend_string_efree (recv_buf );
1731- zend_update_property (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("socket" ), arg1 );
1732- zend_update_property_string (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("macsrc" ), ether_ntoa ((struct ether_addr * )e -> h_source ));
1733- zend_update_property_string (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("macdst" ), ether_ntoa ((struct ether_addr * )e -> h_dest ));
1734- zend_update_property_long (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("ethprotocol" ), protocol );
1735- zend_update_property (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("payload" ), & zpayload );
1736-
1737- ZEND_TRY_ASSIGN_REF_VALUE (arg2 , & obj );
1638+ ZEND_TRY_ASSIGN_REF_NEW_STR(arg2, recv_buf);
17381639 ZEND_TRY_ASSIGN_REF_STRING(arg5, ifrname);
1739-
1740- if (arg6 ) {
1741- ZEND_TRY_ASSIGN_REF_LONG (arg6 , sll .sll_ifindex );
1742- }
1640+ ZEND_TRY_ASSIGN_REF_LONG(arg6, sll.sll_ifindex);
17431641 break;
1642+ */
17441643#endif
17451644 default :
17461645 zend_argument_value_error (1 , "must be one of AF_UNIX, AF_INET, or AF_INET6" );
@@ -1762,10 +1661,7 @@ PHP_FUNCTION(socket_sendto)
17621661 struct sockaddr_in6 sin6 ;
17631662#endif
17641663#ifdef AF_PACKET
1765- struct sockaddr_ll sll ;
1766- unsigned char halen ;
1767- int protoid ;
1768- socklen_t protoidlen = sizeof (protoid );
1664+ //struct sockaddr_ll sll;
17691665#endif
17701666 int retval ;
17711667 size_t buf_len ;
@@ -1798,15 +1694,6 @@ PHP_FUNCTION(socket_sendto)
17981694 RETURN_THROWS ();
17991695 }
18001696
1801- #ifdef AF_PACKET
1802- // ether header + payload
1803- // TODO dealing with SOCK_DGRAM
1804- if (php_sock -> type == AF_PACKET && len < 60 ) {
1805- zend_argument_value_error (3 , "must be at least 64 for AF_PACKET" );
1806- RETURN_THROWS ();
1807- }
1808- #endif
1809-
18101697 switch (php_sock -> type ) {
18111698 case AF_UNIX :
18121699 memset (& s_un , 0 , sizeof (s_un ));
@@ -1851,33 +1738,23 @@ PHP_FUNCTION(socket_sendto)
18511738 break ;
18521739#endif
18531740#ifdef AF_PACKET
1741+ /*
18541742 case AF_PACKET:
1855- getsockopt (php_sock -> bsd_socket , SOL_SOCKET , SO_TYPE , (char * ) & protoid , & protoidlen );
1856-
1857- // TODO: SOCK_DGRAM support
1858- if (protoid != SOCK_RAW ) {
1859- zend_argument_value_error (1 , "must be SOCK_RAW socket type" );
1860- RETURN_THROWS ();
1861- }
18621743 if (port_is_null) {
18631744 zend_argument_value_error(6, "cannot be null when the socket type is AF_PACKET");
18641745 RETURN_THROWS();
18651746 }
18661747
1867- halen = ZSTR_LEN (addr ) > ETH_ALEN ? ETH_ALEN : (unsigned char )ZSTR_LEN (addr );
1868-
18691748 memset(&sll, 0, sizeof(sll));
1870- memcpy (sll .sll_addr , addr , halen );
18711749 sll.sll_family = AF_PACKET;
18721750 sll.sll_ifindex = port;
1873- sll .sll_halen = halen ;
18741751
1875- // TODO allows to use more user friendly type to replace raw buffer usage
1876- retval = sendto (php_sock -> bsd_socket , buf , ((size_t )len > buf_len ) ? buf_len : (size_t )len , flags , (struct sockaddr * ) & sll , sizeof (sll ));
1752+ retval = sendto(php_sock->bsd_socket, buf, ((size_t)len > buf_len) ? buf_len : (size_t)len, flags, (struct sockaddr *) &sin, sizeof(sin));
18771753 break;
1754+ */
18781755#endif
18791756 default :
1880- zend_argument_value_error (1 , "must be one of AF_UNIX, AF_INET, AF_PACKET or AF_INET6" );
1757+ zend_argument_value_error (1 , "must be one of AF_UNIX, AF_INET, or AF_INET6" );
18811758 RETURN_THROWS ();
18821759 }
18831760
@@ -3003,6 +2880,8 @@ PHP_FUNCTION(socket_addrinfo_connect)
30032880
30042881 ai = Z_ADDRESS_INFO_P (arg1 );
30052882
2883+ PHP_ETH_PROTO_CHECK (ai -> addrinfo .ai_protocol , ai -> addrinfo .ai_family );
2884+
30062885 object_init_ex (return_value , socket_ce );
30072886 php_sock = Z_SOCKET_P (return_value );
30082887
0 commit comments