* Make sure the SIOCGIFCONF never returns an address with an address length
smaller than sizeof(sockaddr). This fixes a compatibility issue with other platforms - portable software often assumes that the amount of bytes to add to an ifreq structure is the larger amount between sizeof(ifreq), and basically what the _SIZEOF_ADDR_IFREQ() macro returns, instead of always relying on that macro. * Renamed UserBuffer::Copy() to Push, ConsumedAmount() to BytesConsumed(), added Pad() method. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37927 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
40061f8fd5
commit
715fed4479
@ -292,7 +292,8 @@ acquire_device_interface(net_device_interface* interface)
|
||||
|
||||
|
||||
void
|
||||
get_device_interface_address(net_device_interface* interface, sockaddr* _address)
|
||||
get_device_interface_address(net_device_interface* interface,
|
||||
sockaddr* _address)
|
||||
{
|
||||
sockaddr_dl &address = *(sockaddr_dl*)_address;
|
||||
|
||||
@ -306,8 +307,7 @@ get_device_interface_address(net_device_interface* interface, sockaddr* _address
|
||||
address.sdl_alen = interface->device->address.length;
|
||||
memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen);
|
||||
|
||||
address.sdl_len = sizeof(sockaddr_dl) - sizeof(address.sdl_data)
|
||||
+ address.sdl_nlen + address.sdl_alen;
|
||||
address.sdl_len = sizeof(sockaddr_dl);
|
||||
}
|
||||
|
||||
|
||||
@ -341,15 +341,16 @@ list_device_interfaces(void* _buffer, size_t* bufferSize)
|
||||
UserBuffer buffer(_buffer, *bufferSize);
|
||||
|
||||
while (net_device_interface* interface = iterator.Next()) {
|
||||
ifreq request;
|
||||
strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE);
|
||||
get_device_interface_address(interface, &request.ifr_addr);
|
||||
buffer.Push(interface->device->name, IF_NAMESIZE);
|
||||
|
||||
if (buffer.Copy(&request, IF_NAMESIZE + request.ifr_addr.sa_len) == NULL)
|
||||
sockaddr address;
|
||||
get_device_interface_address(interface, &address);
|
||||
|
||||
if (buffer.Push(&address, address.sa_len) == NULL)
|
||||
return buffer.Status();
|
||||
}
|
||||
|
||||
*bufferSize = buffer.ConsumedAmount();
|
||||
*bufferSize = buffer.BytesConsumed();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -1385,27 +1385,38 @@ list_interfaces(int family, void* _buffer, size_t* bufferSize)
|
||||
|
||||
InterfaceList::Iterator iterator = sInterfaces.GetIterator();
|
||||
while (Interface* interface = iterator.Next()) {
|
||||
ifreq request;
|
||||
strlcpy(request.ifr_name, interface->name, IF_NAMESIZE);
|
||||
// Copy name
|
||||
buffer.Push(interface->name, IF_NAMESIZE);
|
||||
|
||||
// Copy address
|
||||
InterfaceAddress* address = interface->FirstForFamily(family);
|
||||
sockaddr_storage storage;
|
||||
|
||||
if (address != NULL && address->local != NULL) {
|
||||
// copy actual address
|
||||
memcpy(&request.ifr_addr, address->local, address->local->sa_len);
|
||||
// Actual address
|
||||
memcpy(&storage, address->local, address->local->sa_len);
|
||||
} else {
|
||||
// empty address
|
||||
request.ifr_addr.sa_len = 2;
|
||||
request.ifr_addr.sa_family = AF_UNSPEC;
|
||||
// Empty address
|
||||
storage.ss_len = 2;
|
||||
storage.ss_family = AF_UNSPEC;
|
||||
}
|
||||
|
||||
if (storage.ss_len < sizeof(sockaddr)) {
|
||||
// Make sure at least sizeof(sockaddr) bytes are written for
|
||||
// compatibility with other platforms
|
||||
memset((uint8*)&storage + storage.ss_len, 0,
|
||||
sizeof(sockaddr) - storage.ss_len);
|
||||
storage.ss_len = sizeof(sockaddr);
|
||||
}
|
||||
|
||||
if (address != NULL)
|
||||
address->ReleaseReference();
|
||||
|
||||
if (buffer.Copy(&request, IF_NAMESIZE
|
||||
+ request.ifr_addr.sa_len) == NULL)
|
||||
if (buffer.Push(&storage, storage.ss_len) == NULL)
|
||||
return buffer.Status();
|
||||
}
|
||||
|
||||
*bufferSize = buffer.ConsumedAmount();
|
||||
*bufferSize = buffer.BytesConsumed();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -282,7 +282,7 @@ copy_address(UserBuffer& buffer, sockaddr* address)
|
||||
if (address == NULL)
|
||||
return NULL;
|
||||
|
||||
return (sockaddr*)buffer.Copy(address, address->sa_len);
|
||||
return (sockaddr*)buffer.Push(address, address->sa_len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,11 +123,11 @@ base_fifo_clear(FifoType* fifo)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// #pragma mark - UserBuffer
|
||||
|
||||
|
||||
void*
|
||||
UserBuffer::Copy(void* source, size_t length)
|
||||
UserBuffer::Push(void* source, size_t length)
|
||||
{
|
||||
if (fStatus != B_OK)
|
||||
return NULL;
|
||||
@ -139,7 +139,7 @@ UserBuffer::Copy(void* source, size_t length)
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
fStatus = user_memcpy(fBuffer, source, length);
|
||||
if (fStatus < B_OK)
|
||||
if (fStatus != B_OK)
|
||||
return NULL;
|
||||
#else
|
||||
memcpy(fBuffer, source, length);
|
||||
@ -154,6 +154,36 @@ UserBuffer::Copy(void* source, size_t length)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
UserBuffer::Pad(size_t length)
|
||||
{
|
||||
if (fStatus != B_OK)
|
||||
return fStatus;
|
||||
|
||||
if (fAvailable < length)
|
||||
return fStatus = ENOBUFS;
|
||||
|
||||
fStatus = user_memset(fBuffer, 0, length);
|
||||
if (fStatus != B_OK)
|
||||
return fStatus;
|
||||
|
||||
fAvailable -= length;
|
||||
fBuffer += length;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
UserBuffer::PadToNext(size_t length)
|
||||
{
|
||||
return Pad((BytesConsumed() + length - 1) / length - BytesConsumed());
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
uint16
|
||||
compute_checksum(uint8* _buffer, size_t length)
|
||||
{
|
||||
|
@ -16,13 +16,19 @@ class UserBuffer {
|
||||
public:
|
||||
UserBuffer(void* buffer, size_t size);
|
||||
|
||||
void* Copy(void* source, size_t size);
|
||||
status_t Status() const;
|
||||
size_t ConsumedAmount() const;
|
||||
void* Push(void* source, size_t size);
|
||||
status_t Pad(size_t length);
|
||||
status_t PadToNext(size_t length);
|
||||
|
||||
status_t Status() const
|
||||
{ return fStatus; }
|
||||
size_t BytesConsumed() const
|
||||
{ return fBufferSize - fAvailable; }
|
||||
|
||||
private:
|
||||
uint8* fBuffer;
|
||||
size_t fBufferSize, fAvailable;
|
||||
size_t fBufferSize;
|
||||
size_t fAvailable;
|
||||
status_t fStatus;
|
||||
};
|
||||
|
||||
@ -38,20 +44,6 @@ UserBuffer::UserBuffer(void* buffer, size_t size)
|
||||
}
|
||||
|
||||
|
||||
inline status_t
|
||||
UserBuffer::Status() const
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
|
||||
inline size_t
|
||||
UserBuffer::ConsumedAmount() const
|
||||
{
|
||||
return fBufferSize - fAvailable;
|
||||
}
|
||||
|
||||
|
||||
// checksums
|
||||
uint16 compute_checksum(uint8* _buffer, size_t length);
|
||||
uint16 checksum(uint8* buffer, size_t length);
|
||||
|
Loading…
Reference in New Issue
Block a user