SIOCGIFCONF will now also report the size of the written buffer in ifconf.ifc_len
to cover the case the list of interfaces changed since SIOCGIFCOUNT was called. Patch by Hugo Santos. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20491 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -280,7 +280,12 @@ datalink_control(net_domain *_domain, int32 option, void *value,
|
|||||||
if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK)
|
if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return list_domain_interfaces(config.ifc_buf, config.ifc_len);
|
status_t result = list_domain_interfaces(config.ifc_buf,
|
||||||
|
(size_t *)&config.ifc_len);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return user_memcpy(value, &config, sizeof(struct ifconf));
|
||||||
}
|
}
|
||||||
|
|
||||||
case SIOCGRTSIZE:
|
case SIOCGRTSIZE:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -99,12 +99,13 @@ count_domain_interfaces()
|
|||||||
returned.
|
returned.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
list_domain_interfaces(void *buffer, size_t size)
|
list_domain_interfaces(void *buffer, size_t *_bufferSize)
|
||||||
{
|
{
|
||||||
BenaphoreLocker locker(sDomainLock);
|
BenaphoreLocker locker(sDomainLock);
|
||||||
|
|
||||||
|
uint8 *current = (uint8 *)buffer;
|
||||||
|
const uint8 *bufferEnd = current + (*_bufferSize);
|
||||||
net_domain_private *domain = NULL;
|
net_domain_private *domain = NULL;
|
||||||
size_t spaceLeft = size;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
domain = (net_domain_private *)list_get_next_item(&sDomains, domain);
|
domain = (net_domain_private *)list_get_next_item(&sDomains, domain);
|
||||||
@@ -118,8 +119,8 @@ list_domain_interfaces(void *buffer, size_t size)
|
|||||||
if (interface == NULL)
|
if (interface == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
size = IF_NAMESIZE + (interface->address ? interface->address->sa_len : 2);
|
size_t size = IF_NAMESIZE + (interface->address ? interface->address->sa_len : 2);
|
||||||
if (spaceLeft < size)
|
if ((current + size) > bufferEnd)
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
|
|
||||||
ifreq request;
|
ifreq request;
|
||||||
@@ -132,14 +133,14 @@ list_domain_interfaces(void *buffer, size_t size)
|
|||||||
request.ifr_addr.sa_family = AF_UNSPEC;
|
request.ifr_addr.sa_family = AF_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user_memcpy(buffer, &request, size) < B_OK)
|
if (user_memcpy(current, &request, size) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
buffer = (void *)((addr_t)buffer + size);
|
current += size;
|
||||||
spaceLeft -= size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*_bufferSize = current - (uint8 *)buffer;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -30,7 +30,7 @@ status_t init_domains();
|
|||||||
status_t uninit_domains();
|
status_t uninit_domains();
|
||||||
|
|
||||||
uint32 count_domain_interfaces();
|
uint32 count_domain_interfaces();
|
||||||
status_t list_domain_interfaces(void *buffer, size_t size);
|
status_t list_domain_interfaces(void *buffer, size_t *_bufferSize);
|
||||||
status_t add_interface_to_domain(net_domain *domain, struct ifreq& request);
|
status_t add_interface_to_domain(net_domain *domain, struct ifreq& request);
|
||||||
status_t remove_interface_from_domain(net_interface *interface);
|
status_t remove_interface_from_domain(net_interface *interface);
|
||||||
|
|
||||||
|
|||||||
@@ -258,12 +258,13 @@ count_device_interfaces()
|
|||||||
returned.
|
returned.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
list_device_interfaces(void *buffer, size_t size)
|
list_device_interfaces(void *buffer, size_t *_bufferSize)
|
||||||
{
|
{
|
||||||
BenaphoreLocker locker(sInterfaceLock);
|
BenaphoreLocker locker(sInterfaceLock);
|
||||||
|
|
||||||
|
uint8 *current = (uint8 *)buffer;
|
||||||
|
const uint8 *bufferEnd = current + (*_bufferSize);
|
||||||
net_device_interface *interface = NULL;
|
net_device_interface *interface = NULL;
|
||||||
size_t spaceLeft = size;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
interface = (net_device_interface *)list_get_next_item(&sInterfaces,
|
interface = (net_device_interface *)list_get_next_item(&sInterfaces,
|
||||||
@@ -275,17 +276,17 @@ list_device_interfaces(void *buffer, size_t size)
|
|||||||
strlcpy(request.ifr_name, interface->name, IF_NAMESIZE);
|
strlcpy(request.ifr_name, interface->name, IF_NAMESIZE);
|
||||||
get_device_interface_address(interface, &request.ifr_addr);
|
get_device_interface_address(interface, &request.ifr_addr);
|
||||||
|
|
||||||
size = IF_NAMESIZE + request.ifr_addr.sa_len;
|
size_t size = IF_NAMESIZE + request.ifr_addr.sa_len;
|
||||||
if (spaceLeft < size)
|
if ((current + size) > bufferEnd)
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
|
|
||||||
if (user_memcpy(buffer, &request, size) < B_OK)
|
if (user_memcpy(current, &request, size) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
buffer = (void *)((addr_t)buffer + size);
|
current += size;
|
||||||
spaceLeft -= size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*_bufferSize = current - (uint8 *)buffer;;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ void delete_interface(net_interface_private *interface);
|
|||||||
void get_device_interface_address(net_device_interface *interface,
|
void get_device_interface_address(net_device_interface *interface,
|
||||||
sockaddr *address);
|
sockaddr *address);
|
||||||
uint32 count_device_interfaces();
|
uint32 count_device_interfaces();
|
||||||
status_t list_device_interfaces(void *buffer, size_t size);
|
status_t list_device_interfaces(void *buffer, size_t *_bufferSize);
|
||||||
void put_device_interface(struct net_device_interface *interface);
|
void put_device_interface(struct net_device_interface *interface);
|
||||||
struct net_device_interface *get_device_interface(uint32 index);
|
struct net_device_interface *get_device_interface(uint32 index);
|
||||||
struct net_device_interface *get_device_interface(const char *name);
|
struct net_device_interface *get_device_interface(const char *name);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -174,12 +174,17 @@ link_control(net_protocol *_protocol, int level, int option, void *value,
|
|||||||
|
|
||||||
case SIOCGIFCONF:
|
case SIOCGIFCONF:
|
||||||
{
|
{
|
||||||
// count number of interfaces
|
// retrieve available interfaces
|
||||||
struct ifconf config;
|
struct ifconf config;
|
||||||
if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK)
|
if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return list_device_interfaces(config.ifc_buf, config.ifc_len);
|
status_t result = list_device_interfaces(config.ifc_buf,
|
||||||
|
(size_t *)&config.ifc_len);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return user_memcpy(value, &config, sizeof(struct ifconf));
|
||||||
}
|
}
|
||||||
|
|
||||||
case SIOCGIFADDR:
|
case SIOCGIFADDR:
|
||||||
|
|||||||
Reference in New Issue
Block a user