VirtualBox

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

Last change on this file since 33868 was 33540, checked in by vboxsync, 14 years ago

*: spelling fixes, thanks Timeless!

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