@@ -1435,6 +1435,54 @@ PHP_FUNCTION(socket_bind)
1435
1435
}
1436
1436
/* }}} */
1437
1437
1438
+ #ifdef AF_PACKET
1439
+ #define ETH_SUB_CHECKLENGTH (a , lyr ) \
1440
+ do { \
1441
+ if ((char *)ipdata + sizeof(a) < ZSTR_VAL(recv_buf) + slen) { \
1442
+ zend_string_efree(recv_buf); \
1443
+ Z_DELREF_P(zpayload); \
1444
+ ZEND_TRY_ASSIGN_REF_VALUE(arg2, obj); \
1445
+ ZEND_TRY_ASSIGN_REF_STRING(arg5, ifrname); \
1446
+ if (arg6) { \
1447
+ ZEND_TRY_ASSIGN_REF_LONG(arg6, sll.sll_ifindex);\
1448
+ } \
1449
+ zend_value_error("invalid %s header", lyr); \
1450
+ return FAILURE; \
1451
+ } \
1452
+ } while (0)
1453
+ static zend_result php_socket_afpacket_add_tcp (unsigned char * ipdata , struct sockaddr_ll sll , char * ifrname , zend_string * recv_buf ,
1454
+ size_t slen , zval * szpayload , zval * zpayload , zval * obj , zval * arg2 , zval * arg5 , zval * arg6 ) {
1455
+ struct tcphdr a ;
1456
+ ETH_SUB_CHECKLENGTH (a , "TCP" );
1457
+ memcpy (& a , ipdata , sizeof (a ));
1458
+ struct tcphdr * tcp = & a ;
1459
+ object_init_ex (szpayload , tcppacket_ce );
1460
+ zend_update_property_long (Z_OBJCE_P (szpayload ), Z_OBJ_P (szpayload ), ZEND_STRL ("srcPort" ), ntohs (tcp -> th_sport ));
1461
+ zend_update_property_long (Z_OBJCE_P (szpayload ), Z_OBJ_P (szpayload ), ZEND_STRL ("dstPort" ), ntohs (tcp -> th_dport ));
1462
+ zend_update_property_long (Z_OBJCE_P (szpayload ), Z_OBJ_P (szpayload ), ZEND_STRL ("headerSize" ), sizeof (* tcp ));
1463
+ zend_update_property_string (Z_OBJCE_P (szpayload ), Z_OBJ_P (szpayload ), ZEND_STRL ("rawPacket" ), (char * )ipdata );
1464
+ zend_update_property (Z_OBJCE_P (zpayload ), Z_OBJ_P (zpayload ), ZEND_STRL ("payload" ), szpayload );
1465
+ Z_DELREF_P (szpayload );
1466
+ return SUCCESS ;
1467
+ }
1468
+
1469
+ static zend_result php_socket_afpacket_add_udp (unsigned char * ipdata , struct sockaddr_ll sll , char * ifrname , zend_string * recv_buf ,
1470
+ size_t slen , zval * szpayload , zval * zpayload , zval * obj , zval * arg2 , zval * arg5 , zval * arg6 ) {
1471
+ struct udphdr a ;
1472
+ ETH_SUB_CHECKLENGTH (a , "UDP" );
1473
+ memcpy (& a , ipdata , sizeof (a ));
1474
+ struct udphdr * udp = & a ;
1475
+ object_init_ex (szpayload , udppacket_ce );
1476
+ zend_update_property_long (Z_OBJCE_P (szpayload ), Z_OBJ_P (szpayload ), ZEND_STRL ("srcPort" ), ntohs (udp -> uh_sport ));
1477
+ zend_update_property_long (Z_OBJCE_P (szpayload ), Z_OBJ_P (szpayload ), ZEND_STRL ("dstPort" ), ntohs (udp -> uh_dport ));
1478
+ zend_update_property_long (Z_OBJCE_P (szpayload ), Z_OBJ_P (szpayload ), ZEND_STRL ("headerSize" ), sizeof (* udp ));
1479
+ zend_update_property_string (Z_OBJCE_P (szpayload ), Z_OBJ_P (szpayload ), ZEND_STRL ("rawPacket" ), (char * )ipdata );
1480
+ zend_update_property (Z_OBJCE_P (zpayload ), Z_OBJ_P (zpayload ), ZEND_STRL ("payload" ), szpayload );
1481
+ Z_DELREF_P (szpayload );
1482
+ return SUCCESS ;
1483
+ }
1484
+ #endif
1485
+
1438
1486
/* {{{ Receives data from a connected socket */
1439
1487
PHP_FUNCTION (socket_recv )
1440
1488
{
@@ -1665,6 +1713,12 @@ PHP_FUNCTION(socket_recvfrom)
1665
1713
RETURN_FALSE ;
1666
1714
}
1667
1715
1716
+ if (UNEXPECTED (slen < ETH_HLEN )) {
1717
+ zend_value_error ("invalid ethernet frame buffer length" );
1718
+ zend_string_efree (recv_buf );
1719
+ RETURN_THROWS ();
1720
+ }
1721
+
1668
1722
if (UNEXPECTED (!if_indextoname (sll .sll_ifindex , ifrname ))) {
1669
1723
PHP_SOCKET_ERROR (php_sock , "unable to get the interface name" , errno );
1670
1724
zend_string_efree (recv_buf );
@@ -1681,6 +1735,7 @@ PHP_FUNCTION(socket_recvfrom)
1681
1735
zend_update_property_long (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("headerSize" ), ETH_HLEN );
1682
1736
zend_update_property_long (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("ethProtocol" ), protocol );
1683
1737
1738
+
1684
1739
switch (protocol ) {
1685
1740
case ETH_P_IP : {
1686
1741
payload = ((unsigned char * )e + ETH_HLEN );
@@ -1717,29 +1772,15 @@ PHP_FUNCTION(socket_recvfrom)
1717
1772
1718
1773
switch (ip -> protocol ) {
1719
1774
case IPPROTO_TCP : {
1720
- struct tcphdr a ;
1721
- memcpy (& a , ipdata , sizeof (a ));
1722
- struct tcphdr * tcp = & a ;
1723
- object_init_ex (& szpayload , tcppacket_ce );
1724
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("srcPort" ), ntohs (tcp -> th_sport ));
1725
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("dstPort" ), ntohs (tcp -> th_dport ));
1726
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("headerSize" ), sizeof (* tcp ));
1727
- zend_update_property_string (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("rawPacket" ), (char * )ipdata );
1728
- zend_update_property (Z_OBJCE (zpayload ), Z_OBJ (zpayload ), ZEND_STRL ("payload" ), & szpayload );
1729
- Z_DELREF (szpayload );
1775
+ if (php_socket_afpacket_add_tcp (ipdata , sll , ifrname , recv_buf , slen , & szpayload , & zpayload , & obj , arg2 , arg5 , arg6 ) == FAILURE ) {
1776
+ RETURN_THROWS ();
1777
+ }
1730
1778
break ;
1731
1779
}
1732
1780
case IPPROTO_UDP : {
1733
- struct udphdr a ;
1734
- memcpy (& a , ipdata , sizeof (a ));
1735
- struct udphdr * udp = & a ;
1736
- object_init_ex (& szpayload , udppacket_ce );
1737
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("srcPort" ), ntohs (udp -> uh_sport ));
1738
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("dstPort" ), ntohs (udp -> uh_dport ));
1739
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("headerSize" ), sizeof (* udp ));
1740
- zend_update_property_string (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("rawPacket" ), (char * )ipdata );
1741
- zend_update_property (Z_OBJCE (zpayload ), Z_OBJ (zpayload ), ZEND_STRL ("payload" ), & szpayload );
1742
- Z_DELREF (szpayload );
1781
+ if (php_socket_afpacket_add_udp (ipdata , sll , ifrname , recv_buf , slen , & szpayload , & zpayload , & obj , arg2 , arg5 , arg6 ) == FAILURE ) {
1782
+ RETURN_THROWS ();
1783
+ }
1743
1784
break ;
1744
1785
}
1745
1786
default :
@@ -1764,6 +1805,20 @@ PHP_FUNCTION(socket_recvfrom)
1764
1805
memcpy (& a , payload , sizeof (a ));
1765
1806
struct ipv6hdr * ip = & a ;
1766
1807
size_t totalip = sizeof (* ip ) + ip -> payload_len ;
1808
+ if (totalip < slen ) {
1809
+ ZVAL_NULL (& zpayload );
1810
+ zend_update_property (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("payload" ), & zpayload );
1811
+ zend_update_property_string (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("rawPacket" ), ZSTR_VAL (recv_buf ));
1812
+ zend_string_efree (recv_buf );
1813
+ ZEND_TRY_ASSIGN_REF_VALUE (arg2 , & obj );
1814
+ ZEND_TRY_ASSIGN_REF_STRING (arg5 , ifrname );
1815
+
1816
+ if (arg6 ) {
1817
+ ZEND_TRY_ASSIGN_REF_LONG (arg6 , sll .sll_ifindex );
1818
+ }
1819
+ zend_value_error ("invalid transport header length" );
1820
+ RETURN_THROWS ();
1821
+ }
1767
1822
char s [INET6_ADDRSTRLEN ], d [INET6_ADDRSTRLEN ];
1768
1823
inet_ntop (AF_INET6 , & ip -> saddr , s , sizeof (s ));
1769
1824
inet_ntop (AF_INET6 , & ip -> daddr , d , sizeof (d ));
@@ -1778,29 +1833,15 @@ PHP_FUNCTION(socket_recvfrom)
1778
1833
1779
1834
switch (ipprotocol ) {
1780
1835
case IPPROTO_TCP : {
1781
- struct tcphdr a ;
1782
- memcpy (& a , ipdata , sizeof (a ));
1783
- struct tcphdr * tcp = & a ;
1784
- object_init_ex (& szpayload , tcppacket_ce );
1785
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("srcPort" ), ntohs (tcp -> th_sport ));
1786
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("dstPort" ), ntohs (tcp -> th_dport ));
1787
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("headerSize" ), sizeof (* tcp ));
1788
- zend_update_property_string (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("rawPacket" ), (char * )ipdata );
1789
- zend_update_property (Z_OBJCE (zpayload ), Z_OBJ (zpayload ), ZEND_STRL ("payload" ), & szpayload );
1790
- Z_DELREF (szpayload );
1836
+ if (php_socket_afpacket_add_tcp (ipdata , sll , ifrname , recv_buf , slen , & szpayload , & zpayload , & obj , arg2 , arg5 , arg6 ) == FAILURE ) {
1837
+ RETURN_THROWS ();
1838
+ }
1791
1839
break ;
1792
1840
}
1793
1841
case IPPROTO_UDP : {
1794
- struct udphdr a ;
1795
- memcpy (& a , ipdata , sizeof (a ));
1796
- struct udphdr * udp = & a ;
1797
- object_init_ex (& szpayload , udppacket_ce );
1798
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("srcPort" ), ntohs (udp -> uh_sport ));
1799
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("dstPort" ), ntohs (udp -> uh_dport ));
1800
- zend_update_property_long (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("headerSize" ), sizeof (* udp ));
1801
- zend_update_property_string (Z_OBJCE (szpayload ), Z_OBJ (szpayload ), ZEND_STRL ("rawPacket" ), (char * )ipdata );
1802
- zend_update_property (Z_OBJCE (zpayload ), Z_OBJ (zpayload ), ZEND_STRL ("payload" ), & szpayload );
1803
- Z_DELREF (szpayload );
1842
+ if (php_socket_afpacket_add_udp (ipdata , sll , ifrname , recv_buf , slen , & szpayload , & zpayload , & obj , arg2 , arg5 , arg6 ) == FAILURE ) {
1843
+ RETURN_THROWS ();
1844
+ }
1804
1845
break ;
1805
1846
}
1806
1847
// TODO IPPROTO_ICMPV6 support
@@ -1821,7 +1862,21 @@ PHP_FUNCTION(socket_recvfrom)
1821
1862
break ;
1822
1863
}
1823
1864
case ETH_P_LOOP : {
1824
- struct ethhdr * innere = (struct ethhdr * )((unsigned char * )e + ETH_HLEN );
1865
+ payload = ((unsigned char * )e + ETH_HLEN );
1866
+ struct ethhdr a ;
1867
+ if ((char * )payload + sizeof (a ) < ZSTR_VAL (recv_buf ) + slen ) {
1868
+ zend_string_efree (recv_buf );
1869
+ Z_DELREF (zpayload );
1870
+ ZEND_TRY_ASSIGN_REF_VALUE (arg2 , & obj );
1871
+ ZEND_TRY_ASSIGN_REF_STRING (arg5 , ifrname );
1872
+ if (arg6 ) {
1873
+ ZEND_TRY_ASSIGN_REF_LONG (arg6 , sll .sll_ifindex );
1874
+ }
1875
+ zend_value_error ("invalid LOOP header" );
1876
+ RETURN_THROWS ();
1877
+ }
1878
+ memcpy (& a , payload , sizeof (a ));
1879
+ struct ethhdr * innere = & a ;
1825
1880
zval innerp ;
1826
1881
ZVAL_NULL (& innerp );
1827
1882
object_init_ex (& zpayload , ethpacket_ce );
0 commit comments