[haiku-commits] r38025 - haiku/trunk/src/bin/network/ifconfig

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 11 Aug 2010 15:25:36 +0200 (CEST)

Author: axeld
Date: 2010-08-11 15:25:36 +0200 (Wed, 11 Aug 2010)
New Revision: 38025
Changeset: http://dev.haiku-os.org/changeset/38025

Modified:
   haiku/trunk/src/bin/network/ifconfig/Jamfile
   haiku/trunk/src/bin/network/ifconfig/ifconfig.cpp
Log:
* Reimplemented listing interfaces completely via the new C++ API. Only when
  configuring or deleting interfaces, the ioctl()s are used directly for now;
  but this should be changed as well.
* Applied patch by Atis partially that fixes mask creation by prefix length,
  and changes a few other minor things.


Modified: haiku/trunk/src/bin/network/ifconfig/Jamfile
===================================================================
--- haiku/trunk/src/bin/network/ifconfig/Jamfile        2010-08-11 13:18:36 UTC 
(rev 38024)
+++ haiku/trunk/src/bin/network/ifconfig/Jamfile        2010-08-11 13:25:36 UTC 
(rev 38025)
@@ -1,30 +1,8 @@
 SubDir HAIKU_TOP src bin network ifconfig ;
 
-if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
-       UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
-               # We need the public network headers also when not compiling 
for Haiku.
-               # Unfortunately we get more than we want, namely all POSIX 
headers.
-}
-
 UseHeaders [ FDirName $(HAIKU_TOP) src servers net ] : true ;
 
 BinCommand ifconfig :
        ifconfig.cpp
-       : be network
+       : be network bnetapi
 ;
-
-# Installation -- in the test directory for the time being
-HaikuInstall install-networking
-       : [ FDirName $(HAIKU_TEST_DIR) kits net ]
-       : ifconfig ;
-
-HaikuInstall install-userland-networking
-       : [ FDirName $(HAIKU_TEST_DIR) kits net userland ]
-       : ifconfig
-       : installed-userland-networking
-;
-
-Package haiku-networkingkit-cvs :
-       ifconfig :
-#      boot home config bin ;
-       boot home Desktop haiku-networkingkit ;

Modified: haiku/trunk/src/bin/network/ifconfig/ifconfig.cpp
===================================================================
--- haiku/trunk/src/bin/network/ifconfig/ifconfig.cpp   2010-08-11 13:18:36 UTC 
(rev 38024)
+++ haiku/trunk/src/bin/network/ifconfig/ifconfig.cpp   2010-08-11 13:25:36 UTC 
(rev 38025)
@@ -9,9 +9,6 @@
  */
 
 
-#include <Message.h>
-#include <Messenger.h>
-
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -27,6 +24,11 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <Message.h>
+#include <Messenger.h>
+#include <NetworkInterface.h>
+#include <NetworkRoster.h>
+
 #include <NetServer.h>
 
 
@@ -109,7 +111,6 @@
 }
 
 
-
 static bool
 inet_parse_address(const char* string, sockaddr* _address)
 {
@@ -160,7 +161,7 @@
        uint8 result = 0;
        uint32 hostMask = ntohl(mask.sin_addr.s_addr);
        for (uint8 i = 32; i > 0; i--) {
-               if (hostMask & (1 << (i - 1)) == 0)
+               if ((hostMask & (1 << (i - 1))) == 0)
                        break;
                result++;
        }
@@ -215,7 +216,7 @@
 
        for (uint8 i = 0; i < sizeof(in6_addr); i++, prefixLength -= 8) {
                if (prefixLength < 8) {
-                       const uint8 masks[] = {
+                       static const uint8 masks[] = {
                                0x00, 0x80, 0xc0, 0xe0,
                                0xf0, 0xf8, 0xfc, 0xfe
                        };
@@ -418,6 +419,19 @@
 }
 
 
+const address_family*
+get_address_family(int32 family)
+{
+       for (int32 i = 0; kFamilies[i].family >= 0; i++) {
+               if (kFamilies[i].family == family)
+                       return &kFamilies[i];
+       }
+
+       // defaults to AF_INET
+       return &kFamilies[0];
+}
+
+
 bool
 parse_address(int32 familyIndex, const char* argument, struct sockaddr& 
address)
 {
@@ -482,49 +496,43 @@
 
 
 void
-list_interface_address(int socket, const address_family* family,
-       uint32 flags, ifreq* request)
+list_interface_addresses(BNetworkInterface& interface, uint32 flags)
 {
-       if (ioctl(socket, SIOCGIFADDR, request, sizeof(struct ifreq)) < 0)
-               return;
+       int32 count = interface.CountAddresses();
+       for (int32 i = 0; i < count; i++) {
+               BNetworkInterfaceAddress address;
+               if (interface.GetAddressAt(i, address) != B_OK)
+                       break;
 
-       printf("\t%s addr: ", family->name);
-       family->print_address(&request->ifr_addr);
+               const address_family* family
+                       = get_address_family(address.Address().Family());
 
-       if ((flags & IFF_BROADCAST) != 0
-               && ioctl(socket, SIOCGIFBRDADDR, request, sizeof(struct ifreq)) 
== 0
-               && request->ifr_broadaddr.sa_family == family->family) {
-               printf(", Bcast: ");
-               family->print_address(&request->ifr_broadaddr);
-       }
-       if (ioctl(socket, SIOCGIFNETMASK, request, sizeof(struct ifreq)) == 0
-               && request->ifr_mask.sa_family == family->family) {
+               printf("\t%s addr: ", family->name);
+               family->print_address(address.Address());
+
+               if ((flags & IFF_BROADCAST) != 0) {
+                       printf(", Bcast: ");
+                       family->print_address(address.Broadcast());
+               }
                switch (family->preferred_format) {
                        case PREFER_OUTPUT_MASK:
                                printf(", Mask: ");
-                               family->print_address(&request->ifr_mask);
+                               family->print_address(address.Mask());
                                break;
                        case PREFER_OUTPUT_PREFIX_LENGTH:
                                printf(", Prefix Length: %u",
-                                       
family->mask_to_prefix_length(&request->ifr_mask));
+                                       
family->mask_to_prefix_length(address.Mask()));
                                break;
                }
+
+               putchar('\n');
        }
-       putchar('\n');
 }
 
 
 bool
-list_interface(const char* name, int addressFamily)
+list_interface(const char* name)
 {
-       ifreq request;
-       if (!prepare_request(request, name))
-               return true;
-
-       int socket = find_socket(request, addressFamily);
-       if (socket == -1)
-               return false;
-
        printf("%s", name);
        size_t length = strlen(name);
        if (length < 8)
@@ -534,60 +542,57 @@
 
        // get link level interface for this interface
 
-       int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0);
-       if (linkSocket < 0) {
-               printf("No link level: %s\n", strerror(errno));
-       } else {
+       BNetworkInterface interface(name);
+       BNetworkAddress linkAddress;
+       status_t status = interface.GetHardwareAddress(linkAddress);
+       if (status == B_OK) {
                const char *type = "unknown";
                char address[256];
                strcpy(address, "none");
 
-               if (ioctl(linkSocket, SIOCGIFADDR, &request, sizeof(struct 
ifreq))
-                               == 0) {
-                       sockaddr_dl &link = *(sockaddr_dl*)&request.ifr_addr;
+               switch (linkAddress.LinkLevelType()) {
+                       case IFT_ETHER:
+                       {
+                               type = "Ethernet";
 
-                       switch (link.sdl_type) {
-                               case IFT_ETHER:
-                               {
-                                       type = "Ethernet";
-
-                                       if (link.sdl_alen > 0) {
-                                               uint8 *mac = 
(uint8*)LLADDR(&link);
-                                               sprintf(address, 
"%02x:%02x:%02x:%02x:%02x:%02x",
-                                                       mac[0], mac[1], mac[2], 
mac[3], mac[4], mac[5]);
-                                       } else
-                                               strcpy(address, "not 
available");
-                                       break;
-                               }
-                               case IFT_LOOP:
-                                       type = "Local Loopback";
-                                       break;
-                               case IFT_MODEM:
-                                       type = "Modem";
-                                       break;
+                               if (linkAddress.LinkLevelAddressLength() > 0) {
+                                       uint8 *mac = 
linkAddress.LinkLevelAddress();
+                                       sprintf(address, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+                                               mac[0], mac[1], mac[2], mac[3], 
mac[4], mac[5]);
+                               } else
+                                       strcpy(address, "not available");
+                               break;
                        }
+                       case IFT_LOOP:
+                               type = "Local Loopback";
+                               break;
+                       case IFT_MODEM:
+                               type = "Modem";
+                               break;
                }
 
                printf("Hardware Type: %s, Address: %s\n", type, address);
-               close(linkSocket);
-       }
+       } else
+               printf("No link level: %s\n", strerror(status));
 
-       if (ioctl(socket, SIOCGIFMEDIA, &request, sizeof(struct ifreq)) == 0
-               && (request.ifr_media & IFM_ACTIVE) != 0) {
+       int media = interface.Media();
+       if ((media & IFM_ACTIVE) != 0) {
                // dump media state in case we're linked
                const char* type = "unknown";
                bool show = false;
 
                for (int32 i = 0; kMediaTypes[i].type >= 0; i++) {
                        // loopback don't really have a media anyway
-                       if (IFM_TYPE(request.ifr_media) == 0/*IFT_LOOP*/)
+                       if (IFM_TYPE(media) == 0/*IFT_LOOP*/)
                                break;
+
                        // only check for generic or correct subtypes
-                       if (kMediaTypes[i].type &&
-                               kMediaTypes[i].type != 
IFM_TYPE(request.ifr_media))
+                       if (kMediaTypes[i].type
+                               && kMediaTypes[i].type != IFM_TYPE(media))
                                continue;
+
                        for (int32 j = 0; kMediaTypes[i].subtypes[j].subtype >= 
0; j++) {
-                               if (kMediaTypes[i].subtypes[j].subtype == 
IFM_SUBTYPE(request.ifr_media)) {
+                               if (kMediaTypes[i].subtypes[j].subtype == 
IFM_SUBTYPE(media)) {
                                        // found a match
                                        type = 
kMediaTypes[i].subtypes[j].pretty;
                                        show = true;
@@ -600,32 +605,15 @@
                        printf("\tMedia Type: %s\n", type);
        }
 
-       uint32 flags = 0;
-       if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
-               flags = request.ifr_flags;
+       uint32 flags = interface.Flags();
 
-       for (int32 i = 0; kFamilies[i].family >= 0; i++) {
-               int familySocket = sAddressFamilySockets[i];
-               if (familySocket != -1) {
-                       list_interface_address(familySocket, &kFamilies[i],
-                               flags, &request);
-               }
-       }
+       list_interface_addresses(interface, flags);
 
        // Print MTU, metric, flags
 
-       printf("\tMTU: ");
-       if (ioctl(socket, SIOCGIFMTU, &request, sizeof(struct ifreq)) == 0)
-               printf("%d", request.ifr_mtu);
-       else
-               printf("-");
+       printf("\tMTU: %" B_PRId32 ", Metric: %" B_PRId32, interface.MTU(),
+               interface.Metric());
 
-       printf(", Metric: ");
-       if (ioctl(socket, SIOCGIFMETRIC, &request, sizeof(struct ifreq)) == 0)
-               printf("%d", request.ifr_metric);
-       else
-               printf("-");
-
        if (flags != 0) {
                const struct {
                        int                     value;
@@ -660,16 +648,16 @@
 
        // Print statistics
 
-       if (ioctl(socket, SIOCGIFSTATS, &request, sizeof(struct ifreq)) == 0) {
-               printf("\tReceive: %d packets, %d errors, %Ld bytes, %d mcasts, 
%d dropped\n",
-                       request.ifr_stats.receive.packets, 
request.ifr_stats.receive.errors,
-                       request.ifr_stats.receive.bytes, 
request.ifr_stats.receive.multicast_packets,
-                       request.ifr_stats.receive.dropped);
-               printf("\tTransmit: %d packets, %d errors, %Ld bytes, %d 
mcasts, %d dropped\n",
-                       request.ifr_stats.send.packets, 
request.ifr_stats.send.errors,
-                       request.ifr_stats.send.bytes, 
request.ifr_stats.send.multicast_packets,
-                       request.ifr_stats.send.dropped);
-               printf("\tCollisions: %d\n", request.ifr_stats.collisions);
+       ifreq_stats stats;
+       if (interface.GetStats(stats) == B_OK) {
+               printf("\tReceive: %d packets, %d errors, %Ld bytes, %d mcasts, 
%d "
+                       "dropped\n", stats.receive.packets, 
stats.receive.errors,
+                       stats.receive.bytes, stats.receive.multicast_packets,
+                       stats.receive.dropped);
+               printf("\tTransmit: %d packets, %d errors, %Ld bytes, %d 
mcasts, %d "
+                       "dropped\n", stats.send.packets, stats.send.errors,
+                       stats.send.bytes, stats.send.multicast_packets, 
stats.send.dropped);
+               printf("\tCollisions: %d\n", stats.collisions);
        }
 
        putchar('\n');
@@ -681,46 +669,20 @@
 list_interfaces(const char* name)
 {
        if (name != NULL) {
-               list_interface(name, -1);
+               list_interface(name);
                return;
        }
 
        // get a list of all interfaces
 
-       int socket = sAddressFamilySockets[0];
+       BNetworkRoster& roster = BNetworkRoster::Default();
 
-       ifconf config;
-       config.ifc_len = sizeof(config.ifc_value);
-       if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
-               return;
+       BNetworkInterface interface;
+       uint32 cookie = 0;
 
-       uint32 count = (uint32)config.ifc_value;
-       if (count == 0) {
-               fprintf(stderr, "%s: There are no interfaces yet!\n", 
kProgramName);
-               return;
+       while (roster.GetNextInterface(&cookie, interface) == B_OK) {
+               list_interface(interface.Name());
        }
-
-       void *buffer = malloc(count * sizeof(struct ifreq));
-       if (buffer == NULL) {
-               fprintf(stderr, "%s: Out of memory.\n", kProgramName);
-               return;
-       }
-
-       config.ifc_len = count * sizeof(struct ifreq);
-       config.ifc_buf = buffer;
-       if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
-               return;
-
-       ifreq* interface = (ifreq*)buffer;
-
-       for (uint32 i = 0; i < count; i++) {
-               list_interface(interface->ifr_name, 
interface->ifr_addr.sa_family);
-
-               interface = (ifreq*)((uint8*)interface
-                       + _SIZEOF_ADDR_IFREQ(interface[0]));
-       }
-
-       free(buffer);
 }
 
 
@@ -1052,8 +1014,7 @@
                BMessage message(kMsgConfigureInterface);
                message.AddString("device", name);
                BMessage address;
-               // TODO: this is not working for ipv6 yet
-               address.AddString("family", "inet");
+               address.AddString("family", kFamilies[familyIndex].name);
                address.AddBool("auto_config", true);
                message.AddMessage("address", &address);
 


Other related posts:

  • » [haiku-commits] r38025 - haiku/trunk/src/bin/network/ifconfig - axeld