* Changed the _SIZEOF_ADDR_IFREQ() macro such that it can be used how we are

using it - hopefully, that is actually correct (it's adopted from FreeBSD).
* Fixed bug that cut off the sockaddr_dl reported by the system, so that DHCP
  wouldn't work anymore (and ifconfig wouldn't show the actual MAC address
  anymore).
* Changed the listing code to actually pad to ifreq size, and leave the length
  of the sockaddr untouched.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37941 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-08-06 12:58:02 +00:00
parent 8b6048a285
commit 1f9c8c4576
4 changed files with 28 additions and 20 deletions
+4 -1
View File
@@ -94,8 +94,11 @@ struct ifconf {
}; };
}; };
/* Macro that returns the size of a single address within a SIOCGIFCONF buffer;
it looks like this because of compatibility with other platforms. */
#define _SIZEOF_ADDR_IFREQ(request) \ #define _SIZEOF_ADDR_IFREQ(request) \
(sizeof((request).ifr_name) + (request).ifr_addr.sa_len) (IF_NAMESIZE + (request).ifr_addr.sa_len > (int)sizeof(ifreq) \
? IF_NAMESIZE + (request).ifr_addr.sa_len : sizeof(ifreq))
/* POSIX definitions follow */ /* POSIX definitions follow */
@@ -307,7 +307,8 @@ get_device_interface_address(net_device_interface* interface,
address.sdl_alen = interface->device->address.length; address.sdl_alen = interface->device->address.length;
memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen); memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen);
address.sdl_len = sizeof(sockaddr_dl); address.sdl_len = sizeof(sockaddr_dl) - sizeof(address.sdl_data)
+ address.sdl_nlen + address.sdl_alen;
} }
@@ -343,10 +344,14 @@ list_device_interfaces(void* _buffer, size_t* bufferSize)
while (net_device_interface* interface = iterator.Next()) { while (net_device_interface* interface = iterator.Next()) {
buffer.Push(interface->device->name, IF_NAMESIZE); buffer.Push(interface->device->name, IF_NAMESIZE);
sockaddr address; sockaddr_storage address;
get_device_interface_address(interface, &address); get_device_interface_address(interface, (sockaddr*)&address);
if (buffer.Push(&address, address.sa_len) == NULL) buffer.Push(&address, address.ss_len);
if (IF_NAMESIZE + address.ss_len < (int)sizeof(ifreq))
buffer.Pad(sizeof(ifreq) - IF_NAMESIZE - address.ss_len);
if (buffer.Status() != B_OK)
return buffer.Status(); return buffer.Status();
} }
+13 -13
View File
@@ -1415,29 +1415,29 @@ list_interfaces(int family, void* _buffer, size_t* bufferSize)
// Copy address // Copy address
InterfaceAddress* address = interface->FirstForFamily(family); InterfaceAddress* address = interface->FirstForFamily(family);
sockaddr_storage storage; size_t length = 0;
if (address != NULL && address->local != NULL) { if (address != NULL && address->local != NULL) {
// Actual address // Actual address
memcpy(&storage, address->local, address->local->sa_len); buffer.Push(address->local, length = address->local->sa_len);
} else { } else {
// Empty address // Empty address
storage.ss_len = 2; sockaddr empty;
storage.ss_family = AF_UNSPEC; empty.sa_len = 2;
} empty.sa_family = AF_UNSPEC;
buffer.Push(&empty, length = empty.sa_len);
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) if (address != NULL)
address->ReleaseReference(); address->ReleaseReference();
if (buffer.Push(&storage, storage.ss_len) == NULL) if (IF_NAMESIZE + length < sizeof(ifreq)) {
// Make sure at least sizeof(ifreq) bytes are written for each
// interface for compatibility with other platforms
buffer.Pad(sizeof(ifreq) - IF_NAMESIZE - length);
}
if (buffer.Status() != B_OK)
return buffer.Status(); return buffer.Status();
} }
+2 -2
View File
@@ -530,8 +530,8 @@ NetworkStatusView::_Update(bool force)
fStatus = status; fStatus = status;
} }
interface = (ifreq *)((addr_t)interface + IF_NAMESIZE interface = (ifreq *)((addr_t)interface
+ interface->ifr_addr.sa_len); + _SIZEOF_ADDR_IFREQ(interface[0]));
} }
free(buffer); free(buffer);