VirtualBox

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

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

HostNetIf API: Fixed UUID generation for host network interfaces on Linux.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.6 KB
Line 
1/* $Id: NetIfList-linux.cpp 16251 2009-01-27 09:13:47Z 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 /* Generate UUID from name and MAC address. */
61 RTUUID uuid;
62 RTUuidClear(&uuid);
63 memcpy(&uuid, Req.ifr_name, RT_MIN(sizeof(Req.ifr_name), sizeof(uuid)));
64 uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80;
65 uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000;
66 memcpy(uuid.Gen.au8Node, &Req.ifr_hwaddr.sa_data, sizeof(uuid.Gen.au8Node));
67 pInfo->Uuid = uuid;
68
69 memcpy(&pInfo->MACAddress, Req.ifr_hwaddr.sa_data, sizeof(pInfo->MACAddress));
70
71 if (ioctl(iSocket, SIOCGIFADDR, &Req) >= 0)
72 memcpy(pInfo->IPAddress.au8,
73 &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr,
74 sizeof(pInfo->IPAddress.au8));
75
76 if (ioctl(iSocket, SIOCGIFNETMASK, &Req) >= 0)
77 memcpy(pInfo->IPNetMask.au8,
78 &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr,
79 sizeof(pInfo->IPNetMask.au8));
80
81 if (ioctl(iSocket, SIOCGIFFLAGS, &Req) >= 0)
82 pInfo->enmStatus = Req.ifr_flags & IFF_UP ? NETIF_S_UP : NETIF_S_DOWN;
83
84 FILE *fp = fopen("/proc/net/if_inet6", "r");
85 if (fp)
86 {
87 RTNETADDRIPV6 IPv6Address;
88 unsigned uIndex, uLength, uScope, uTmp;
89 char szName[30];
90 for (;;)
91 {
92 memset(szName, 0, sizeof(szName));
93 int n = fscanf(fp,
94 "%08x%08x%08x%08x"
95 " %02x %02x %02x %02x %20s\n",
96 &IPv6Address.au32[0], &IPv6Address.au32[1],
97 &IPv6Address.au32[2], &IPv6Address.au32[3],
98 &uIndex, &uLength, &uScope, &uTmp, szName);
99 if (n == EOF)
100 break;
101 if (n != 9 || uLength > 128)
102 {
103 Log(("getInterfaceInfo: Error while reading /proc/net/if_inet6, n=%d uLength=%u\n",
104 n, uLength));
105 break;
106 }
107 if (!strcmp(Req.ifr_name, szName))
108 {
109 pInfo->IPv6Address.au32[0] = htonl(IPv6Address.au32[0]);
110 pInfo->IPv6Address.au32[1] = htonl(IPv6Address.au32[1]);
111 pInfo->IPv6Address.au32[2] = htonl(IPv6Address.au32[2]);
112 pInfo->IPv6Address.au32[3] = htonl(IPv6Address.au32[3]);
113 ASMBitSetRange(&pInfo->IPv6NetMask, 0, uLength);
114 }
115 }
116 fclose(fp);
117 }
118 }
119 return VINF_SUCCESS;
120}
121
122int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
123{
124 int rc = VINF_SUCCESS;
125 int sock = socket(AF_INET, SOCK_DGRAM, 0);
126 if (sock >= 0)
127 {
128 FILE *fp = fopen("/proc/net/dev", "r");
129 if (fp)
130 {
131 char buf[256];
132 while (fgets(buf, sizeof(buf), fp))
133 {
134 char *pszEndOfName = strchr(buf, ':');
135 if (!pszEndOfName)
136 continue;
137 *pszEndOfName = 0;
138 int iFirstNonWS = strspn(buf, " ");
139 char *pszName = buf+iFirstNonWS;
140 NETIFINFO Info;
141 rc = getInterfaceInfo(sock, pszName, &Info);
142 if (RT_FAILURE(rc))
143 break;
144 if (Info.enmType == NETIF_T_ETHERNET)
145 {
146 ComObjPtr<HostNetworkInterface> IfObj;
147 IfObj.createObject();
148 if (SUCCEEDED(IfObj->init(Bstr(pszName), &Info)))
149 list.push_back(IfObj);
150 }
151
152 }
153 fclose(fp);
154 }
155 close(sock);
156 }
157
158 return rc;
159}
160
161
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