41
41
# include <netdb.h>
42
42
# include <netinet/in.h>
43
43
# include <netinet/tcp.h>
44
- # include <netinet/udp.h>
45
44
# include <sys/un.h>
46
45
# include <arpa/inet.h>
47
46
# include <sys/time.h>
55
54
# ifdef HAVE_IF_NAMETOINDEX
56
55
# include <net/if.h>
57
56
# endif
58
- # ifdef HAVE_NETINET_ETHER_H
59
- # include <netinet/ether.h>
60
- # include <netinet/ip.h>
61
- # include <linux/ipv6.h>
62
- # endif
63
57
# if defined(HAVE_LINUX_SOCK_DIAG_H )
64
58
# include <linux/sock_diag.h>
65
59
# else
@@ -126,9 +120,6 @@ static PHP_RSHUTDOWN_FUNCTION(sockets);
126
120
127
121
zend_class_entry * socket_ce ;
128
122
static zend_object_handlers socket_object_handlers ;
129
- #ifdef AF_PACKET
130
- zend_class_entry * socket_ethinfo_ce ;
131
- #endif
132
123
133
124
static zend_object * socket_create_object (zend_class_entry * class_type ) {
134
125
php_socket * intern = zend_object_alloc (sizeof (php_socket ), class_type );
@@ -491,9 +482,6 @@ static PHP_MINIT_FUNCTION(sockets)
491
482
socket_object_handlers .get_gc = socket_get_gc ;
492
483
socket_object_handlers .compare = zend_objects_not_comparable ;
493
484
494
- #if defined(AF_PACKET )
495
- socket_ethinfo_ce = register_class_SocketEthernetInfo ();
496
- #endif
497
485
address_info_ce = register_class_AddressInfo ();
498
486
address_info_ce -> create_object = address_info_create_object ;
499
487
address_info_ce -> default_object_handlers = & address_info_object_handlers ;
@@ -1400,7 +1388,7 @@ PHP_FUNCTION(socket_bind)
1400
1388
struct sockaddr_ll * sa = (struct sockaddr_ll * ) sock_type ;
1401
1389
socklen_t sa_len = sizeof (sa );
1402
1390
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 ) {
1404
1392
zend_value_error ("invalid AF_PACKET socket" );
1405
1393
RETURN_THROWS ();
1406
1394
}
@@ -1515,9 +1503,7 @@ PHP_FUNCTION(socket_recvfrom)
1515
1503
struct sockaddr_in6 sin6 ;
1516
1504
#endif
1517
1505
#ifdef AF_PACKET
1518
- struct sockaddr_ll sll ;
1519
- int protoid ;
1520
- socklen_t protoidlen = sizeof (protoid );
1506
+ //struct sockaddr_ll sll;
1521
1507
#endif
1522
1508
char addrbuf [INET6_ADDRSTRLEN ];
1523
1509
socklen_t slen ;
@@ -1546,15 +1532,6 @@ PHP_FUNCTION(socket_recvfrom)
1546
1532
RETURN_FALSE ;
1547
1533
}
1548
1534
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
-
1558
1535
recv_buf = zend_string_alloc (arg3 + 1 , 0 );
1559
1536
1560
1537
switch (php_sock -> type ) {
@@ -1633,19 +1610,14 @@ PHP_FUNCTION(socket_recvfrom)
1633
1610
break ;
1634
1611
#endif
1635
1612
#ifdef AF_PACKET
1613
+ /*
1636
1614
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
1644
1617
slen = sizeof(sll);
1645
1618
memset(&sll, 0, sizeof(sll));
1646
1619
sll.sll_family = AF_PACKET;
1647
1620
char ifrname[IFNAMSIZ];
1648
- zval zpayload ;
1649
1621
1650
1622
retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&sll, (socklen_t *)&slen);
1651
1623
@@ -1654,93 +1626,20 @@ PHP_FUNCTION(socket_recvfrom)
1654
1626
zend_string_efree(recv_buf);
1655
1627
RETURN_FALSE;
1656
1628
}
1629
+ ZSTR_LEN(recv_buf) = retval;
1630
+ ZSTR_VAL(recv_buf)[ZSTR_LEN(recv_buf)] = '\0';
1657
1631
1658
1632
if (UNEXPECTED(!if_indextoname(sll.sll_ifindex, ifrname))) {
1659
1633
PHP_SOCKET_ERROR(php_sock, "unable to get the interface name", errno);
1660
1634
zend_string_efree(recv_buf);
1661
1635
RETURN_FALSE;
1662
1636
}
1663
1637
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);
1738
1639
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);
1743
1641
break;
1642
+ */
1744
1643
#endif
1745
1644
default :
1746
1645
zend_argument_value_error (1 , "must be one of AF_UNIX, AF_INET, or AF_INET6" );
@@ -1762,10 +1661,7 @@ PHP_FUNCTION(socket_sendto)
1762
1661
struct sockaddr_in6 sin6 ;
1763
1662
#endif
1764
1663
#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;
1769
1665
#endif
1770
1666
int retval ;
1771
1667
size_t buf_len ;
@@ -1798,15 +1694,6 @@ PHP_FUNCTION(socket_sendto)
1798
1694
RETURN_THROWS ();
1799
1695
}
1800
1696
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
-
1810
1697
switch (php_sock -> type ) {
1811
1698
case AF_UNIX :
1812
1699
memset (& s_un , 0 , sizeof (s_un ));
@@ -1851,33 +1738,23 @@ PHP_FUNCTION(socket_sendto)
1851
1738
break ;
1852
1739
#endif
1853
1740
#ifdef AF_PACKET
1741
+ /*
1854
1742
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
- }
1862
1743
if (port_is_null) {
1863
1744
zend_argument_value_error(6, "cannot be null when the socket type is AF_PACKET");
1864
1745
RETURN_THROWS();
1865
1746
}
1866
1747
1867
- halen = ZSTR_LEN (addr ) > ETH_ALEN ? ETH_ALEN : (unsigned char )ZSTR_LEN (addr );
1868
-
1869
1748
memset(&sll, 0, sizeof(sll));
1870
- memcpy (sll .sll_addr , addr , halen );
1871
1749
sll.sll_family = AF_PACKET;
1872
1750
sll.sll_ifindex = port;
1873
- sll .sll_halen = halen ;
1874
1751
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));
1877
1753
break;
1754
+ */
1878
1755
#endif
1879
1756
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" );
1881
1758
RETURN_THROWS ();
1882
1759
}
1883
1760
@@ -3003,6 +2880,8 @@ PHP_FUNCTION(socket_addrinfo_connect)
3003
2880
3004
2881
ai = Z_ADDRESS_INFO_P (arg1 );
3005
2882
2883
+ PHP_ETH_PROTO_CHECK (ai -> addrinfo .ai_protocol , ai -> addrinfo .ai_family );
2884
+
3006
2885
object_init_ex (return_value , socket_ce );
3007
2886
php_sock = Z_SOCKET_P (return_value );
3008
2887
0 commit comments