12
12
#include <netinet/in.h>
13
13
#include <sys/un.h>
14
14
15
+ #include <sys/ioctl.h>
16
+ #include <net/if.h>
17
+
15
18
#include <limits.h>
16
19
#include <stdarg.h>
17
20
#include <stddef.h>
@@ -53,6 +56,8 @@ typedef struct {
53
56
#define KEY_RECVMSG_RET "recvmsg_ret"
54
57
#define KEY_CMSG_LEN "cmsg_len"
55
58
59
+ const struct key_value empty_key_value_list [] = {{0 }};
60
+
56
61
/* PARAMETERS */
57
62
static int param_get_bool (void * ctx , const char * key , int def )
58
63
{
@@ -331,25 +336,6 @@ void from_zval_write_int(const zval *arr_value, char *field, ser_context *ctx)
331
336
ival = (int )lval ;
332
337
memcpy (field , & ival , sizeof (ival ));
333
338
}
334
- static void from_zval_write_unsigned (const zval * arr_value , char * field , ser_context * ctx )
335
- {
336
- long lval ;
337
- unsigned ival ;
338
-
339
- lval = from_zval_integer_common (arr_value , ctx );
340
- if (ctx -> err .has_error ) {
341
- return ;
342
- }
343
-
344
- if (sizeof (long ) > sizeof (ival ) && (lval < 0 || lval > UINT_MAX )) {
345
- do_from_zval_err (ctx , "%s" , "given PHP integer is out of bounds "
346
- "for a native unsigned int" );
347
- return ;
348
- }
349
-
350
- ival = (unsigned )lval ;
351
- memcpy (field , & ival , sizeof (ival ));
352
- }
353
339
static void from_zval_write_uint32 (const zval * arr_value , char * field , ser_context * ctx )
354
340
{
355
341
long lval ;
@@ -1192,32 +1178,50 @@ void to_zval_read_msghdr(const char *msghdr_c, zval *zv, res_context *ctx)
1192
1178
/* CONVERSIONS for if_index */
1193
1179
static void from_zval_write_ifindex (const zval * zv , char * uinteger , ser_context * ctx )
1194
1180
{
1195
- zval * va ; unsigned * out ;
1196
- unsigned ret ;
1197
- zval lzval = zval_used_for_init ;
1181
+ unsigned ret ;
1182
+ zval lzval = zval_used_for_init ;
1198
1183
1199
1184
if (Z_TYPE_P (zv ) == IS_LONG ) {
1200
- if (Z_LVAL_P (zv ) < 0 || Z_LVAL_P (zv ) > UINT_MAX ) {
1185
+ if (Z_LVAL_P (zv ) < 0 || Z_LVAL_P (zv ) > UINT_MAX ) { /* allow 0 (unspecified interface) */
1201
1186
do_from_zval_err (ctx , "the interface index cannot be negative or "
1202
1187
"larger than %u; given %ld" , UINT_MAX , Z_LVAL_P (zv ));
1203
1188
} else {
1204
1189
ret = (unsigned )Z_LVAL_P (zv );
1205
1190
}
1206
1191
} else {
1207
- #if HAVE_IF_NAMETOINDEX
1208
-
1209
1192
if (Z_TYPE_P (zv ) != IS_STRING ) {
1210
1193
ZVAL_COPY_VALUE (& lzval , zv );
1211
1194
zval_copy_ctor (& lzval );
1212
1195
convert_to_string (& lzval );
1213
1196
zv = & lzval ;
1214
1197
}
1215
1198
1199
+ #if HAVE_IF_NAMETOINDEX
1216
1200
ret = if_nametoindex (Z_STRVAL_P (zv ));
1217
1201
if (ret == 0 ) {
1218
1202
do_from_zval_err (ctx , "no interface with name \"%s\" could be "
1219
1203
"found" , Z_STRVAL_P (zv ));
1220
1204
}
1205
+ #elif defined(SIOCGIFINDEX )
1206
+ {
1207
+ struct ifreq ifr ;
1208
+ if (strlcpy (ifr .ifr_name , Z_STRVAL_P (zv ), sizeof (ifr .ifr_name ))
1209
+ >= sizeof (ifr .ifr_name )) {
1210
+ do_from_zval_err (ctx , "the interface name \"%s\" is too large " ,
1211
+ Z_STRVAL_P (zv ));
1212
+ } else if (ioctl (ctx -> sock -> bsd_socket , SIOCGIFINDEX , & ifr ) < 0 ) {
1213
+ if (errno == ENODEV ) {
1214
+ do_from_zval_err (ctx , "no interface with name \"%s\" could be "
1215
+ "found" , Z_STRVAL_P (zv ));
1216
+ } else {
1217
+ do_from_zval_err (ctx , "error fetching interface index for "
1218
+ "interface with name \"%s\" (errno %d)" ,
1219
+ Z_STRVAL_P (zv ), errno );
1220
+ }
1221
+ } else {
1222
+ ret = (unsigned )ifr .ifr_ifindex ;
1223
+ }
1224
+ }
1221
1225
#else
1222
1226
do_from_zval_err (ctx ,
1223
1227
"this platform does not support looking up an interface by "
@@ -1236,7 +1240,7 @@ static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context
1236
1240
#ifdef IPV6_PKTINFO
1237
1241
static const field_descriptor descriptors_in6_pktinfo [] = {
1238
1242
{"addr" , sizeof ("addr" ), 1 , offsetof(struct in6_pktinfo , ipi6_addr ), from_zval_write_sin6_addr , to_zval_read_sin6_addr },
1239
- {"ifindex" , sizeof ("ifindex" ), 1 , offsetof(struct in6_pktinfo , ipi6_ifindex ), from_zval_write_unsigned , to_zval_read_unsigned },
1243
+ {"ifindex" , sizeof ("ifindex" ), 1 , offsetof(struct in6_pktinfo , ipi6_ifindex ), from_zval_write_ifindex , to_zval_read_unsigned },
1240
1244
{0 }
1241
1245
};
1242
1246
void from_zval_write_in6_pktinfo (const zval * container , char * in6_pktinfo_c , ser_context * ctx )
@@ -1294,6 +1298,7 @@ size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx)
1294
1298
static void from_zval_write_fd_array_aux (zval * * elem , unsigned i , void * * args , ser_context * ctx )
1295
1299
{
1296
1300
int * iarr = args [0 ];
1301
+ TSRMLS_FETCH ();
1297
1302
1298
1303
if (Z_TYPE_PP (elem ) == IS_RESOURCE ) {
1299
1304
php_stream * stream ;
@@ -1375,8 +1380,8 @@ void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx)
1375
1380
return ;
1376
1381
}
1377
1382
if (S_ISSOCK (statbuf .st_mode )) {
1378
- php_socket * sock = socket_import_file_descriptor (fd );
1379
- zend_register_resource (elem , sock , php_sockets_le_socket ());
1383
+ php_socket * sock = socket_import_file_descriptor (fd TSRMLS_CC );
1384
+ zend_register_resource (elem , sock , php_sockets_le_socket () TSRMLS_CC );
1380
1385
} else {
1381
1386
php_stream * stream = php_stream_fopen_from_fd (fd , "rw" , NULL );
1382
1387
php_stream_to_zval (stream , elem );
0 commit comments