From 1f9c8c4576524824cf035824a9cac69ac8371aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 6 Aug 2010 12:58:02 +0000 Subject: [PATCH] * 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 --- headers/posix/net/if.h | 5 +++- .../network/stack/device_interfaces.cpp | 13 +++++++--- .../kernel/network/stack/interfaces.cpp | 26 +++++++++---------- src/apps/networkstatus/NetworkStatusView.cpp | 4 +-- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/headers/posix/net/if.h b/headers/posix/net/if.h index 04bdcaec4a..a7edb673e9 100644 --- a/headers/posix/net/if.h +++ b/headers/posix/net/if.h @@ -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) \ - (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 */ diff --git a/src/add-ons/kernel/network/stack/device_interfaces.cpp b/src/add-ons/kernel/network/stack/device_interfaces.cpp index 061328ba95..dc794c7b86 100644 --- a/src/add-ons/kernel/network/stack/device_interfaces.cpp +++ b/src/add-ons/kernel/network/stack/device_interfaces.cpp @@ -307,7 +307,8 @@ get_device_interface_address(net_device_interface* interface, address.sdl_alen = interface->device->address.length; 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()) { buffer.Push(interface->device->name, IF_NAMESIZE); - sockaddr address; - get_device_interface_address(interface, &address); + sockaddr_storage 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(); } diff --git a/src/add-ons/kernel/network/stack/interfaces.cpp b/src/add-ons/kernel/network/stack/interfaces.cpp index 6d4e1299fb..fad592eb33 100644 --- a/src/add-ons/kernel/network/stack/interfaces.cpp +++ b/src/add-ons/kernel/network/stack/interfaces.cpp @@ -1415,29 +1415,29 @@ list_interfaces(int family, void* _buffer, size_t* bufferSize) // Copy address InterfaceAddress* address = interface->FirstForFamily(family); - sockaddr_storage storage; + size_t length = 0; if (address != NULL && address->local != NULL) { // Actual address - memcpy(&storage, address->local, address->local->sa_len); + buffer.Push(address->local, length = address->local->sa_len); } else { // 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); + sockaddr empty; + empty.sa_len = 2; + empty.sa_family = AF_UNSPEC; + buffer.Push(&empty, length = empty.sa_len); } if (address != NULL) 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(); } diff --git a/src/apps/networkstatus/NetworkStatusView.cpp b/src/apps/networkstatus/NetworkStatusView.cpp index df28cc2162..7865aed3b1 100644 --- a/src/apps/networkstatus/NetworkStatusView.cpp +++ b/src/apps/networkstatus/NetworkStatusView.cpp @@ -530,8 +530,8 @@ NetworkStatusView::_Update(bool force) fStatus = status; } - interface = (ifreq *)((addr_t)interface + IF_NAMESIZE - + interface->ifr_addr.sa_len); + interface = (ifreq *)((addr_t)interface + + _SIZEOF_ADDR_IFREQ(interface[0])); } free(buffer);