VirtualBox

source: vbox/trunk/src/VBox/Main/linux/NetIfList-linux.cpp@ 16111

Last change on this file since 16111 was 15936, checked in by vboxsync, 16 years ago

Changed the way linux network interfaces are enumerated so the interfaces without assigned IP addresses are shown as well. GUI and VBoxManage list hostifs are impacted.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 KB
Line 
1/* $Id: NetIfList-linux.cpp 15936 2009-01-14 12:37:54Z vboxsync $ */
2/** @file
3 * Main - NetIfList, Linux implementation.
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#define LOG_GROUP LOG_GROUP_MAIN
28
29#include <iprt/err.h>
30#include <list>
31#include <sys/ioctl.h>
32#include <net/if.h>
33#include <net/if_arp.h>
34#include <netinet/in.h>
35#include <stdio.h>
36#include <unistd.h>
37#include <iprt/asm.h>
38
39#include "HostNetworkInterfaceImpl.h"
40#include "netif.h"
41#include "Logging.h"
42
43static int getInterfaceInfo(int iSocket, const char *pszName, PNETIFINFO pInfo)
44{
45 memset(pInfo, 0, sizeof(*pInfo));
46 struct ifreq Req;
47 memset(&Req, 0, sizeof(Req));
48 strncpy(Req.ifr_name, pszName, sizeof(Req.ifr_name) - 1);
49 if (ioctl(iSocket, SIOCGIFHWADDR, &Req) >= 0)
50 {
51 switch (Req.ifr_hwaddr.sa_family)
52 {
53 case ARPHRD_ETHER:
54 pInfo->enmType = NETIF_T_ETHERNET;
55 break;
56 default:
57 pInfo->enmType = NETIF_T_UNKNOWN;
58 break;
59 }
60 /* Pick up some garbage from stack. */
61 RTUUID uuid;
62 Assert(sizeof(uuid) <= sizeof(Req));
63 memcpy(uuid.Gen.au8Node, &Req.ifr_hwaddr.sa_data, sizeof(uuid.Gen.au8Node));
64 pInfo->Uuid = uuid;
65 memcpy(&pInfo->MACAddress, Req.ifr_hwaddr.sa_data, sizeof(pInfo->MACAddress));
66
67 if (ioctl(iSocket, SIOCGIFADDR, &Req) >= 0)
68 memcpy(pInfo->IPAddress.au8,
69 &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr,
70 sizeof(pInfo->IPAddress.au8));
71
72 if (ioctl(iSocket, SIOCGIFNETMASK, &Req) >= 0)
73 memcpy(pInfo->IPNetMask.au8,
74 &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr,
75 sizeof(pInfo->IPNetMask.au8));
76
77 if (ioctl(iSocket, SIOCGIFFLAGS, &Req) >= 0)
78 pInfo->enmStatus = Req.ifr_flags & IFF_UP ? NETIF_S_UP : NETIF_S_DOWN;
79
80 FILE *fp = fopen("/proc/net/if_inet6", "r");
81 if (fp)
82 {
83 RTNETADDRIPV6 IPv6Address;
84 unsigned uIndex, uLength, uScope, uTmp;
85 char szName[30];
86 for (;;)
87 {
88 memset(szName, 0, sizeof(szName));
89 int n = fscanf(fp,
90 "%08x%08x%08x%08x"
91 " %02x %02x %02x %02x %20s\n",
92 &IPv6Address.au32[0], &IPv6Address.au32[1],
93 &IPv6Address.au32[2], &IPv6Address.au32[3],
94 &uIndex, &uLength, &uScope, &uTmp, szName);
95 if (n == EOF)
96 break;
97 if (n != 9 || uLength > 128)
98 {
99 Log(("getInterfaceInfo: Error while reading /proc/net/if_inet6, n=%d uLength=%u\n",
100 n, uLength));
101 break;
102 }
103 if (!strcmp(Req.ifr_name, szName))
104 {
105 pInfo->IPv6Address.au32[0] = htonl(IPv6Address.au32[0]);
106 pInfo->IPv6Address.au32[1] = htonl(IPv6Address.au32[1]);
107 pInfo->IPv6Address.au32[2] = htonl(IPv6Address.au32[2]);
108 pInfo->IPv6Address.au32[3] = htonl(IPv6Address.au32[3]);
109 ASMBitSetRange(&pInfo->IPv6NetMask, 0, uLength);
110 }
111 }
112 fclose(fp);
113 }
114 }
115 return VINF_SUCCESS;
116}
117
118int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
119{
120 int rc = VINF_SUCCESS;
121 int sock = socket(AF_INET, SOCK_DGRAM, 0);
122 if (sock >= 0)
123 {
124 FILE *fp = fopen("/proc/net/dev", "r");
125 if (fp)
126 {
127 char buf[256];
128 while (fgets(buf, sizeof(buf), fp))
129 {
130 char *pszEndOfName = strchr(buf, ':');
131 if (!pszEndOfName)
132 continue;
133 *pszEndOfName = 0;
134 int iFirstNonWS = strspn(buf, " ");
135 char *pszName = buf+iFirstNonWS;
136 NETIFINFO Info;
137 rc = getInterfaceInfo(sock, pszName, &Info);
138 if (RT_FAILURE(rc))
139 break;
140 if (Info.enmType == NETIF_T_ETHERNET)
141 {
142 ComObjPtr<HostNetworkInterface> IfObj;
143 IfObj.createObject();
144 if (SUCCEEDED(IfObj->init(Bstr(pszName), &Info)))
145 list.push_back(IfObj);
146 }
147
148 }
149 fclose(fp);
150 }
151 close(sock);
152 }
153
154 return rc;
155}
156
157
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette