VirtualBox

source: vbox/trunk/src/VBox/Main/linux/NetIf-linux.cpp@ 28312

Last change on this file since 28312 was 26163, checked in by vboxsync, 15 years ago

PDM: s/pUsbReg/pReg/g (2nd try, backed out r57176)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
Line 
1/* $Id: NetIf-linux.cpp 26163 2010-02-02 18:58:33Z 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 <net/route.h>
35#include <netinet/in.h>
36#include <stdio.h>
37#include <unistd.h>
38#include <iprt/asm.h>
39
40#include "HostNetworkInterfaceImpl.h"
41#include "netif.h"
42#include "Logging.h"
43
44static int getDefaultIfaceName(char *pszName)
45{
46 FILE *fp = fopen("/proc/net/route", "r");
47 char szBuf[1024];
48 char szIfName[17];
49 char szAddr[129];
50 char szGateway[129];
51 char szMask[129];
52 int iTmp;
53 int iFlags;
54
55 if (fp)
56 {
57 while (fgets(szBuf, sizeof(szBuf)-1, fp))
58 {
59 int n = sscanf(szBuf, "%16s %128s %128s %X %d %d %d %128s %d %d %d\n",
60 szIfName, szAddr, szGateway, &iFlags, &iTmp, &iTmp, &iTmp,
61 szMask, &iTmp, &iTmp, &iTmp);
62 if (n < 10 || !(iFlags & RTF_UP))
63 continue;
64
65 if (strcmp(szAddr, "00000000") == 0 && strcmp(szMask, "00000000") == 0)
66 {
67 fclose(fp);
68 strncpy(pszName, szIfName, 16);
69 pszName[16] = 0;
70 return VINF_SUCCESS;
71 }
72 }
73 }
74 return VERR_INTERNAL_ERROR;
75}
76
77static int getInterfaceInfo(int iSocket, const char *pszName, PNETIFINFO pInfo)
78{
79 // Zeroing out pInfo is a bad idea as it should contain both short and long names at
80 // this point. So make sure the strucure is cleared by the caller if necessary!
81 // memset(pInfo, 0, sizeof(*pInfo));
82 struct ifreq Req;
83 memset(&Req, 0, sizeof(Req));
84 strncpy(Req.ifr_name, pszName, sizeof(Req.ifr_name) - 1);
85 if (ioctl(iSocket, SIOCGIFHWADDR, &Req) >= 0)
86 {
87 switch (Req.ifr_hwaddr.sa_family)
88 {
89 case ARPHRD_ETHER:
90 pInfo->enmMediumType = NETIF_T_ETHERNET;
91 break;
92 default:
93 pInfo->enmMediumType = NETIF_T_UNKNOWN;
94 break;
95 }
96 /* Generate UUID from name and MAC address. */
97 RTUUID uuid;
98 RTUuidClear(&uuid);
99 memcpy(&uuid, Req.ifr_name, RT_MIN(sizeof(Req.ifr_name), sizeof(uuid)));
100 uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80;
101 uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000;
102 memcpy(uuid.Gen.au8Node, &Req.ifr_hwaddr.sa_data, sizeof(uuid.Gen.au8Node));
103 pInfo->Uuid = uuid;
104
105 memcpy(&pInfo->MACAddress, Req.ifr_hwaddr.sa_data, sizeof(pInfo->MACAddress));
106
107 if (ioctl(iSocket, SIOCGIFADDR, &Req) >= 0)
108 memcpy(pInfo->IPAddress.au8,
109 &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr,
110 sizeof(pInfo->IPAddress.au8));
111
112 if (ioctl(iSocket, SIOCGIFNETMASK, &Req) >= 0)
113 memcpy(pInfo->IPNetMask.au8,
114 &((struct sockaddr_in *)&Req.ifr_addr)->sin_addr.s_addr,
115 sizeof(pInfo->IPNetMask.au8));
116
117 if (ioctl(iSocket, SIOCGIFFLAGS, &Req) >= 0)
118 pInfo->enmStatus = Req.ifr_flags & IFF_UP ? NETIF_S_UP : NETIF_S_DOWN;
119
120 FILE *fp = fopen("/proc/net/if_inet6", "r");
121 if (fp)
122 {
123 RTNETADDRIPV6 IPv6Address;
124 unsigned uIndex, uLength, uScope, uTmp;
125 char szName[30];
126 for (;;)
127 {
128 memset(szName, 0, sizeof(szName));
129 int n = fscanf(fp,
130 "%08x%08x%08x%08x"
131 " %02x %02x %02x %02x %20s\n",
132 &IPv6Address.au32[0], &IPv6Address.au32[1],
133 &IPv6Address.au32[2], &IPv6Address.au32[3],
134 &uIndex, &uLength, &uScope, &uTmp, szName);
135 if (n == EOF)
136 break;
137 if (n != 9 || uLength > 128)
138 {
139 Log(("getInterfaceInfo: Error while reading /proc/net/if_inet6, n=%d uLength=%u\n",
140 n, uLength));
141 break;
142 }
143 if (!strcmp(Req.ifr_name, szName))
144 {
145 pInfo->IPv6Address.au32[0] = htonl(IPv6Address.au32[0]);
146 pInfo->IPv6Address.au32[1] = htonl(IPv6Address.au32[1]);
147 pInfo->IPv6Address.au32[2] = htonl(IPv6Address.au32[2]);
148 pInfo->IPv6Address.au32[3] = htonl(IPv6Address.au32[3]);
149 ASMBitSetRange(&pInfo->IPv6NetMask, 0, uLength);
150 }
151 }
152 fclose(fp);
153 }
154 }
155 return VINF_SUCCESS;
156}
157
158int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list)
159{
160 char szDefaultIface[256];
161 int rc = getDefaultIfaceName(szDefaultIface);
162 if (RT_FAILURE(rc))
163 {
164 Log(("NetIfList: Failed to find default interface.\n"));
165 szDefaultIface[0] = 0;
166 }
167 int sock = socket(AF_INET, SOCK_DGRAM, 0);
168 if (sock >= 0)
169 {
170 FILE *fp = fopen("/proc/net/dev", "r");
171 if (fp)
172 {
173 char buf[256];
174 while (fgets(buf, sizeof(buf), fp))
175 {
176 char *pszEndOfName = strchr(buf, ':');
177 if (!pszEndOfName)
178 continue;
179 *pszEndOfName = 0;
180 int iFirstNonWS = strspn(buf, " ");
181 char *pszName = buf+iFirstNonWS;
182 NETIFINFO Info;
183 RT_ZERO(Info);
184 rc = getInterfaceInfo(sock, pszName, &Info);
185 if (RT_FAILURE(rc))
186 break;
187 if (Info.enmMediumType == NETIF_T_ETHERNET)
188 {
189 ComObjPtr<HostNetworkInterface> IfObj;
190 IfObj.createObject();
191
192 HostNetworkInterfaceType_T enmType;
193 if (strncmp("vboxnet", pszName, 7))
194 enmType = HostNetworkInterfaceType_Bridged;
195 else
196 enmType = HostNetworkInterfaceType_HostOnly;
197
198 if (SUCCEEDED(IfObj->init(Bstr(pszName), enmType, &Info)))
199 {
200 if (strcmp(pszName, szDefaultIface) == 0)
201 list.push_front(IfObj);
202 else
203 list.push_back(IfObj);
204 }
205 }
206
207 }
208 fclose(fp);
209 }
210 close(sock);
211 }
212 else
213 rc = VERR_INTERNAL_ERROR;
214
215 return rc;
216}
217
218int NetIfGetConfigByName(PNETIFINFO pInfo)
219{
220 int rc = VINF_SUCCESS;
221 int sock = socket(AF_INET, SOCK_DGRAM, 0);
222 if (sock < 0)
223 return VERR_NOT_IMPLEMENTED;
224 rc = getInterfaceInfo(sock, pInfo->szShortName, pInfo);
225 close(sock);
226 return rc;
227}
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