@@ -607,6 +607,8 @@ static char *php_strerror(int error TSRMLS_DC) /* {{{ */
607
607
/* }}} */
608
608
609
609
#if HAVE_IPV6
610
+ static int php_get_if_index_from_string (const char * val , unsigned * out TSRMLS_DC );
611
+
610
612
/* Sets addr by hostname, or by ip in string form (AF_INET6) */
611
613
static int php_set_inet6_addr (struct sockaddr_in6 * sin6 , char * string , php_socket * php_sock TSRMLS_DC ) /* {{{ */
612
614
{
@@ -615,6 +617,7 @@ static int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socke
615
617
struct addrinfo hints ;
616
618
struct addrinfo * addrinfo = NULL ;
617
619
#endif
620
+ char * scope = strchr (string , '%' );
618
621
619
622
if (inet_pton (AF_INET6 , string , & tmp )) {
620
623
memcpy (& (sin6 -> sin6_addr .s6_addr ), & (tmp .s6_addr ), sizeof (struct in6_addr ));
@@ -649,6 +652,22 @@ static int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socke
649
652
650
653
}
651
654
655
+ if (scope ++ ) {
656
+ long lval = 0 ;
657
+ double dval = 0 ;
658
+ unsigned scope_id = 0 ;
659
+
660
+ if (IS_LONG == is_numeric_string (scope , strlen (scope ), & lval , & dval , 0 )) {
661
+ if (lval > 0 && lval <= UINT_MAX ) {
662
+ scope_id = lval ;
663
+ }
664
+ } else {
665
+ php_get_if_index_from_string (scope , & scope_id TSRMLS_CC );
666
+ }
667
+
668
+ sin6 -> sin6_scope_id = scope_id ;
669
+ }
670
+
652
671
return 1 ;
653
672
}
654
673
/* }}} */
@@ -714,6 +733,28 @@ static int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, char
714
733
return 0 ;
715
734
}
716
735
736
+ static int php_get_if_index_from_string (const char * val , unsigned * out TSRMLS_DC )
737
+ {
738
+ #if HAVE_IF_NAMETOINDEX
739
+ unsigned int ind ;
740
+
741
+ ind = if_nametoindex (val );
742
+ if (ind == 0 ) {
743
+ php_error_docref (NULL TSRMLS_CC , E_WARNING ,
744
+ "no interface with name \"%s\" could be found" , val );
745
+ return FAILURE ;
746
+ } else {
747
+ * out = ind ;
748
+ return SUCCESS ;
749
+ }
750
+ #else
751
+ php_error_docref (NULL TSRMLS_CC , E_WARNING ,
752
+ "this platform does not support looking up an interface by "
753
+ "name, an integer interface index must be supplied instead" );
754
+ return FAILURE ;
755
+ #endif
756
+ }
757
+
717
758
static int php_get_if_index_from_zval (zval * val , unsigned * out TSRMLS_DC )
718
759
{
719
760
int ret ;
@@ -729,26 +770,10 @@ static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC)
729
770
ret = SUCCESS ;
730
771
}
731
772
} else {
732
- #if HAVE_IF_NAMETOINDEX
733
- unsigned int ind ;
734
773
zval_add_ref (& val );
735
774
convert_to_string_ex (& val );
736
- ind = if_nametoindex (Z_STRVAL_P (val ));
737
- if (ind == 0 ) {
738
- php_error_docref (NULL TSRMLS_CC , E_WARNING ,
739
- "no interface with name \"%s\" could be found" , Z_STRVAL_P (val ));
740
- ret = FAILURE ;
741
- } else {
742
- * out = ind ;
743
- ret = SUCCESS ;
744
- }
775
+ ret = php_get_if_index_from_string (Z_STRVAL_P (val ), out TSRMLS_CC );
745
776
zval_ptr_dtor (& val );
746
- #else
747
- php_error_docref (NULL TSRMLS_CC , E_WARNING ,
748
- "this platform does not support looking up an interface by "
749
- "name, an integer interface index must be supplied instead" );
750
- ret = FAILURE ;
751
- #endif
752
777
}
753
778
754
779
return ret ;
0 commit comments