Changeset 15442 in vbox for trunk/src/VBox/Main/solaris
- Timestamp:
- Dec 13, 2008 1:40:42 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/solaris/NetIfList-solaris.cpp
r15372 r15442 40 40 #include "netif.h" 41 41 42 43 PNETIFINFO NetIfList() 44 { 45 return NULL; 46 } 47 42 #include <list> 43 #include <map> 44 45 #ifdef VBOX_WITH_HOSTNETIF_API 46 47 #include <fcntl.h> 48 #include <unistd.h> 49 #include <stropts.h> 50 #include <errno.h> 51 #include <limits.h> 52 #include <stdio.h> 53 #ifdef VBOX_SOLARIS_NSL_RESOLVED 54 # include <libdevinfo.h> 55 #endif 56 #include <net/if.h> 57 #include <sys/socket.h> 58 #include <sys/sockio.h> 59 #include <net/if_arp.h> 60 #include <net/if.h> 61 #include <sys/types.h> 62 63 static void vboxSolarisAddHostIface(char *pszIface, int Instance, PCRTMAC pMac, void *pvHostNetworkInterfaceList) 64 { 65 std::list<ComObjPtr <HostNetworkInterface> > *pList = (std::list<ComObjPtr <HostNetworkInterface> > *)pvHostNetworkInterfaceList; 66 Assert(pList); 67 68 typedef std::map <std::string, std::string> NICMap; 69 typedef std::pair <std::string, std::string> NICPair; 70 static NICMap SolarisNICMap; 71 if (SolarisNICMap.empty()) 72 { 73 SolarisNICMap.insert(NICPair("afe", "ADMtek Centaur/Comet Fast Ethernet")); 74 SolarisNICMap.insert(NICPair("aggr", "Link Aggregation Interface")); 75 SolarisNICMap.insert(NICPair("bge", "Broadcom BCM57xx Gigabit Ethernet")); 76 SolarisNICMap.insert(NICPair("ce", "Cassini Gigabit Ethernet")); 77 SolarisNICMap.insert(NICPair("chxge", "Chelsio Ethernet")); 78 SolarisNICMap.insert(NICPair("dmfe", "Davicom Fast Ethernet")); 79 SolarisNICMap.insert(NICPair("dnet", "DEC 21040/41 21140 Ethernet")); 80 SolarisNICMap.insert(NICPair("e1000", "Intel PRO/1000 Gigabit Ethernet")); 81 SolarisNICMap.insert(NICPair("e1000g", "Intel PRO/1000 Gigabit Ethernet")); 82 SolarisNICMap.insert(NICPair("elx", "3COM EtherLink III Ethernet")); 83 SolarisNICMap.insert(NICPair("elxl", "3COM Ethernet")); 84 SolarisNICMap.insert(NICPair("eri", "eri Fast Ethernet")); 85 SolarisNICMap.insert(NICPair("ge", "GEM Gigabit Ethernet")); 86 SolarisNICMap.insert(NICPair("hme", "SUNW,hme Fast-Ethernet")); 87 SolarisNICMap.insert(NICPair("ipge", "PCI-E Gigabit Ethernet")); 88 SolarisNICMap.insert(NICPair("iprb", "Intel 82557/58/59 Ethernet")); 89 SolarisNICMap.insert(NICPair("mxfe", "Macronix 98715 Fast Ethernet")); 90 SolarisNICMap.insert(NICPair("nge", "Nvidia Gigabit Ethernet")); 91 SolarisNICMap.insert(NICPair("pcelx", "3COM EtherLink III PCMCIA Ethernet")); 92 SolarisNICMap.insert(NICPair("pcn", "AMD PCnet Ethernet")); 93 SolarisNICMap.insert(NICPair("qfe", "SUNW,qfe Quad Fast-Ethernet")); 94 SolarisNICMap.insert(NICPair("rge", "Realtek Gigabit Ethernet")); 95 SolarisNICMap.insert(NICPair("rtls", "Realtek 8139 Fast Ethernet")); 96 SolarisNICMap.insert(NICPair("skge", "SksKonnect Gigabit Ethernet")); 97 SolarisNICMap.insert(NICPair("spwr", "SMC EtherPower II 10/100 (9432) Ethernet")); 98 SolarisNICMap.insert(NICPair("vnic", "Virtual Network Interface Ethernet")); 99 SolarisNICMap.insert(NICPair("xge", "Neterior Xframe Gigabit Ethernet")); 100 SolarisNICMap.insert(NICPair("xge", "Neterior Xframe 10Gigabit Ethernet")); 101 } 102 103 /* 104 * Try picking up description from our NIC map. 105 */ 106 char szNICInstance[128]; 107 RTStrPrintf(szNICInstance, sizeof(szNICInstance), "%s%d", pszIface, Instance); 108 char szNICDesc[256]; 109 std::string Description = SolarisNICMap[pszIface]; 110 if (Description != "") 111 RTStrPrintf(szNICDesc, sizeof(szNICDesc), "%s - %s", szNICInstance, Description.c_str()); 112 else 113 RTStrPrintf(szNICDesc, sizeof(szNICDesc), "%s - Ethernet", szNICInstance); 114 115 /* 116 * Construct UUID with interface name and the MAC address if available. 117 */ 118 RTUUID Uuid; 119 RTUuidClear(&Uuid); 120 memcpy(&Uuid, szNICInstance, RT_MIN(strlen(szNICInstance), sizeof(Uuid))); 121 Uuid.Gen.u8ClockSeqHiAndReserved = (Uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; 122 Uuid.Gen.u16TimeHiAndVersion = (Uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; 123 if (pMac) 124 { 125 Uuid.Gen.au8Node[0] = pMac->au8[0]; 126 Uuid.Gen.au8Node[1] = pMac->au8[1]; 127 Uuid.Gen.au8Node[2] = pMac->au8[2]; 128 Uuid.Gen.au8Node[3] = pMac->au8[3]; 129 Uuid.Gen.au8Node[4] = pMac->au8[4]; 130 Uuid.Gen.au8Node[5] = pMac->au8[5]; 131 } 132 133 ComObjPtr<HostNetworkInterface> IfObj; 134 IfObj.createObject(); 135 if (SUCCEEDED(IfObj->init(Bstr(szNICDesc), Guid(Uuid)))) 136 pList->push_back(IfObj); 137 } 138 139 static boolean_t vboxSolarisAddLinkHostIface(const char *pszIface, void *pvHostNetworkInterfaceList) 140 { 141 /* 142 * Clip off the zone instance number from the interface name (if any). 143 */ 144 char szIfaceName[128]; 145 strcpy(szIfaceName, pszIface); 146 char *pszColon = (char *)memchr(szIfaceName, ':', sizeof(szIfaceName)); 147 if (pszColon) 148 *pszColon = '\0'; 149 150 /* 151 * Get the instance number from the interface name, then clip it off. 152 */ 153 int cbInstance = 0; 154 int cbIface = strlen(szIfaceName); 155 const char *pszEnd = pszIface + cbIface - 1; 156 for (int i = 0; i < cbIface - 1; i++) 157 { 158 if (!RT_C_IS_DIGIT(*pszEnd)) 159 break; 160 cbInstance++; 161 pszEnd--; 162 } 163 164 int Instance = atoi(pszEnd + 1); 165 strncpy(szIfaceName, pszIface, cbIface - cbInstance); 166 szIfaceName[cbIface - cbInstance] = '\0'; 167 168 /* 169 * Add the interface. 170 */ 171 vboxSolarisAddHostIface(szIfaceName, Instance, NULL, pvHostNetworkInterfaceList); 172 173 /* 174 * Continue walking... 175 */ 176 return _B_FALSE; 177 } 178 179 static bool vboxSolarisSortNICList(const ComObjPtr <HostNetworkInterface> Iface1, const ComObjPtr <HostNetworkInterface> Iface2) 180 { 181 Bstr Iface1Str; 182 (*Iface1).COMGETTER(Name) (Iface1Str.asOutParam()); 183 184 Bstr Iface2Str; 185 (*Iface2).COMGETTER(Name) (Iface2Str.asOutParam()); 186 187 return Iface1Str < Iface2Str; 188 } 189 190 static bool vboxSolarisSameNIC(const ComObjPtr <HostNetworkInterface> Iface1, const ComObjPtr <HostNetworkInterface> Iface2) 191 { 192 Bstr Iface1Str; 193 (*Iface1).COMGETTER(Name) (Iface1Str.asOutParam()); 194 195 Bstr Iface2Str; 196 (*Iface2).COMGETTER(Name) (Iface2Str.asOutParam()); 197 198 return (Iface1Str == Iface2Str); 199 } 200 201 # ifdef VBOX_SOLARIS_NSL_RESOLVED 202 static int vboxSolarisAddPhysHostIface(di_node_t Node, di_minor_t Minor, void *pvHostNetworkInterfaceList) 203 { 204 /* 205 * Skip aggregations. 206 */ 207 if (!strcmp(di_driver_name(Node), "aggr")) 208 return DI_WALK_CONTINUE; 209 210 /* 211 * Skip softmacs. 212 */ 213 if (!strcmp(di_driver_name(Node), "softmac")) 214 return DI_WALK_CONTINUE; 215 216 vboxSolarisAddHostIface(di_driver_name(Node), di_instance(Node), NULL, pvHostNetworkInterfaceList); 217 return DI_WALK_CONTINUE; 218 } 219 # endif /* VBOX_SOLARIS_NSL_RESOLVED */ 220 221 int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list) 222 { 223 224 # ifdef VBOX_SOLARIS_NSL_RESOLVED 225 226 /* 227 * Use libdevinfo for determining all physical interfaces. 228 */ 229 di_node_t Root; 230 Root = di_init("/", DINFOCACHE); 231 if (Root != DI_NODE_NIL) 232 { 233 di_walk_minor(Root, DDI_NT_NET, 0, &list, vboxSolarisAddPhysHostIface); 234 di_fini(Root); 235 } 236 237 /* 238 * Use libdlpi for determining all DLPI interfaces. 239 */ 240 if (VBoxSolarisLibDlpiFound()) 241 g_pfnLibDlpiWalk(vboxSolarisAddLinkHostIface, &list, 0); 242 243 # endif /* VBOX_SOLARIS_NSL_RESOLVED */ 244 245 /* 246 * This gets only the list of all plumbed logical interfaces. 247 * This is needed for zones which cannot access the device tree 248 * and in this case we just let them use the list of plumbed interfaces 249 * on the zone. 250 */ 251 int Sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 252 if (Sock > 0) 253 { 254 struct lifnum IfNum; 255 memset(&IfNum, 0, sizeof(IfNum)); 256 IfNum.lifn_family = AF_INET; 257 int rc = ioctl(Sock, SIOCGLIFNUM, &IfNum); 258 if (!rc) 259 { 260 struct lifreq Ifaces[24]; 261 struct lifconf IfConfig; 262 memset(&IfConfig, 0, sizeof(IfConfig)); 263 IfConfig.lifc_family = AF_INET; 264 IfConfig.lifc_len = sizeof(Ifaces); 265 IfConfig.lifc_buf = (caddr_t)&(Ifaces[0]); 266 rc = ioctl(Sock, SIOCGLIFCONF, &IfConfig); 267 if (!rc) 268 { 269 for (int i = 0; i < IfNum.lifn_count; i++) 270 { 271 /* 272 * Skip loopback interfaces. 273 */ 274 if (!strncmp(Ifaces[i].lifr_name, "lo", 2)) 275 continue; 276 277 NETIFINFO Info; 278 memset(&Info, 0, sizeof(Info)); 279 rc = ioctl(Sock, SIOCGLIFADDR, &(Ifaces[i])); 280 if (rc >= 0) 281 { 282 memcpy(Info.IPAddress.au8, &Ifaces[i].lifr_addr.sa_data, Info.IPAddress.au8); 283 // SIOCGLIFNETMASK 284 struct arpreq ArpReq; 285 memcpy(&ArpReq.arp_pa, &Ifaces[i].lifr_addr, sizeof(struct sockaddr_in)); 286 287 /* 288 * We might fail if the interface has not been assigned an IP address. 289 * That doesn't matter; as long as it's plumbed we can pick it up. 290 * But, if it has not acquired an IP address we cannot obtain it's MAC 291 * address this way, so we just use all zeros there. 292 */ 293 rc = ioctl(Sock, SIOCGARP, &ArpReq); 294 if (rc >= 0) 295 memcpy(&Info.MACAddress, ArpReq.arp_ha.sa_data, sizeof(Info.MACAddress)); 296 297 #if 0 298 char szNICDesc[LIFNAMSIZ + 256]; 299 char *pszIface = Ifaces[i].lifr_name; 300 strcpy(szNICDesc, pszIface); 301 302 vboxSolarisAddLinkHostIface(pszIface, &list); 303 #endif 304 } 305 306 rc = ioctl(Sock, SIOCGLIFNETMASK, &(Ifaces[i])); 307 if (rc >= 0) 308 { 309 memcpy(Info.IPNetMask.au8, &Ifaces[i].lifr_addr.sa_data, Info.IPNetMask.au8); 310 } 311 rc = ioctl(Sock, SIOCGLIFFLAGS, &(Ifaces[i])); 312 if (rc >= 0) 313 { 314 Info.enmStatus = Ifaces[i].lifr_flags & IFF_UP ? NETIF_S_UP : NETIF_S_DOWN; 315 } 316 char *pszIface = Ifaces[i].lifr_name; 317 vboxSolarisAddLinkHostIface(pszIface, &list); 318 } 319 } 320 } 321 close(Sock); 322 } 323 324 /* 325 * Weed out duplicates caused by dlpi_walk inconsistencies across Nevadas. 326 */ 327 list.sort(vboxSolarisSortNICList); 328 list.unique(vboxSolarisSameNIC); 329 330 return VINF_SUCCESS; 331 } 332 #else 333 int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list) 334 { 335 return VERR_NOT_IMPLEMENTED; 336 } 337 #endif
Note:
See TracChangeset
for help on using the changeset viewer.