Changeset 55652 in vbox for trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
- Timestamp:
- May 5, 2015 3:28:45 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
r52618 r55652 52 52 #include <sys/errno.h> 53 53 #include <sys/ioccom.h> 54 #include <sys/filio.h> 54 55 #include <sys/malloc.h> 55 56 #include <sys/proc.h> … … 62 63 #include <net/kpi_interfacefilter.h> 63 64 RT_C_DECLS_END 65 66 #include <sys/kpi_socket.h> 64 67 #include <net/if.h> 68 #include <net/if_var.h> 69 #include <netinet/in.h> 70 #include <netinet/in_var.h> 71 #include <netinet6/in6_var.h> 65 72 66 73 #define VBOXNETFLT_OS_SPECFIC 1 … … 87 94 static kern_return_t VBoxNetFltDarwinStart(struct kmod_info *pKModInfo, void *pvData); 88 95 static kern_return_t VBoxNetFltDarwinStop(struct kmod_info *pKModInfo, void *pvData); 96 97 static void vboxNetFltDarwinSysSockUpcall(socket_t pSysSock, void *pvData, int fWait); 89 98 RT_C_DECLS_END 90 99 … … 1294 1303 if (pIfFilter) 1295 1304 iflt_detach(pIfFilter); 1305 1306 if (pThis->u.s.pSysSock != NULL) 1307 { 1308 sock_close(pThis->u.s.pSysSock); 1309 pThis->u.s.pSysSock = NULL; 1310 } 1296 1311 } 1297 1312 … … 1300 1315 { 1301 1316 NOREF(pvContext); 1302 return vboxNetFltDarwinAttachToInterface(pThis, false /* fRediscovery */); 1317 1318 int rc = vboxNetFltDarwinAttachToInterface(pThis, false /* fRediscovery */); 1319 if (RT_FAILURE(rc)) 1320 return rc; 1321 1322 if (pThis->pSwitchPort->pfnNotifyHostAddress == NULL) 1323 return rc; 1324 1325 /* 1326 * XXX: uwe 1327 * 1328 * Learn host's IP addresses and set up notifications for changes. 1329 * To avoid racing, set up notifications first. 1330 * 1331 * XXX: This should probably be global, since the only thing 1332 * specific to ifnet here is its IPv6 link-local address. 1333 */ 1334 errno_t error; 1335 1336 error = sock_socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT, 1337 vboxNetFltDarwinSysSockUpcall, pThis, 1338 &pThis->u.s.pSysSock); 1339 if (error != 0) 1340 { 1341 LogRel(("sock_socket(SYSPROTO_EVENT): error %d\n", error)); 1342 return rc; 1343 } 1344 1345 int nbio = 1; 1346 error = sock_ioctl(pThis->u.s.pSysSock, FIONBIO, &nbio); 1347 if (error != 0) 1348 { 1349 LogRel(("FIONBIO: error %d\n", error)); 1350 sock_close(pThis->u.s.pSysSock); 1351 return rc; 1352 } 1353 1354 if (!sock_isnonblocking(pThis->u.s.pSysSock)) 1355 { 1356 LogRel(("FIONBIO ok, but socket is blocking?!\n")); 1357 sock_close(pThis->u.s.pSysSock); 1358 return rc; 1359 } 1360 1361 struct kev_request req; 1362 req.vendor_code = KEV_VENDOR_APPLE; 1363 req.kev_class = KEV_NETWORK_CLASS; 1364 req.kev_subclass = KEV_ANY_SUBCLASS; /* need both INET and INET6, so have to request all */ 1365 1366 error = sock_ioctl(pThis->u.s.pSysSock, SIOCSKEVFILT, &req); 1367 if (error != 0) 1368 { 1369 LogRel(("SIOCSKEVFILT: error %d\n", error)); 1370 sock_close(pThis->u.s.pSysSock); 1371 return rc; 1372 } 1373 1374 ifnet_t pIfNet = pThis->u.s.pIfNet; /* already retained */ 1375 1376 ifaddr_t *pIfAddrList; 1377 error = ifnet_get_address_list(/* all interfaces*/ NULL, &pIfAddrList); 1378 if (error != 0) 1379 { 1380 LogRel(("ifnet_get_address_list: error %d\n", error)); 1381 return rc; 1382 } 1383 1384 for (ifaddr_t *pIfAddr = pIfAddrList; *pIfAddr != NULL; ++pIfAddr) 1385 { 1386 ifaddr_t ifa = *pIfAddr; 1387 sa_family_t family = ifaddr_address_family(ifa); 1388 struct sockaddr_storage ss; 1389 1390 error = ifaddr_address(ifa, (struct sockaddr *)&ss, sizeof(ss)); 1391 if (error != 0) 1392 { 1393 LogRel(("getting address family %d: error %d\n", family, error)); 1394 continue; 1395 } 1396 1397 if (family == AF_INET) 1398 { 1399 struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 1400 u_int32_t u32Addr = ntohl(sin->sin_addr.s_addr); 1401 1402 if ((u32Addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 1403 continue; 1404 1405 Log(("> inet %RTnaipv4\n", sin->sin_addr.s_addr)); 1406 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1407 /* :fAdded */ true, kIntNetAddrType_IPv4, &sin->sin_addr); 1408 } 1409 else if (family == AF_INET6) 1410 { 1411 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 1412 1413 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) 1414 continue; 1415 1416 /* link-local from other interfaces are out of scope */ 1417 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && ifaddr_ifnet(ifa) != pIfNet) 1418 continue; 1419 1420 Log(("> inet6 %RTnaipv6\n", &sin6->sin6_addr)); 1421 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1422 /* :fAdded */ true, kIntNetAddrType_IPv6, &sin6->sin6_addr); 1423 } 1424 } 1425 1426 ifnet_free_address_list(pIfAddrList); 1427 1428 /* 1429 * Now that we've got current addresses, check for events that 1430 * might have happened while we were working. 1431 */ 1432 vboxNetFltDarwinSysSockUpcall(pThis->u.s.pSysSock, pThis, MBUF_DONTWAIT); 1433 1434 return rc; 1435 } 1436 1437 1438 static void vboxNetFltDarwinSysSockUpcall(socket_t pSysSock, void *pvData, int fWait) 1439 { 1440 PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)pvData; 1441 errno_t error; 1442 1443 NOREF(fWait); 1444 1445 if (RT_UNLIKELY(pSysSock != pThis->u.s.pSysSock)) 1446 { 1447 Log(("vboxNetFltDarwinSysSockUpcall: %p != %p?\n", 1448 pSysSock, pThis->u.s.pSysSock)); 1449 return; 1450 } 1451 1452 for (;;) { 1453 mbuf_t m; 1454 size_t len = sizeof(struct kern_event_msg) - sizeof(u_int32_t) 1455 + sizeof(struct kev_in6_data); 1456 1457 error = sock_receivembuf(pSysSock, NULL, &m, 0, &len); 1458 if (error == EWOULDBLOCK) 1459 { 1460 Log(("vboxNetFltDarwinSysSockUpcall: EWOULDBLOCK - we are done\n")); 1461 error = 0; 1462 break; 1463 } 1464 else if (error != 0) 1465 { 1466 Log(("sock_receivembuf: error %d\n", error)); 1467 break; 1468 } 1469 1470 if (len < sizeof(struct kern_event_msg) - sizeof(u_int32_t)) 1471 { 1472 Log(("vboxNetFltDarwinSysSockUpcall: %u bytes is too short\n", 1473 (unsigned int)len)); 1474 mbuf_freem(m); 1475 return; 1476 } 1477 1478 struct kern_event_msg *msg = (struct kern_event_msg *)mbuf_data(m); 1479 if (msg->kev_subclass == KEV_INET_SUBCLASS) 1480 { 1481 if (len - (sizeof(struct kern_event_msg) - sizeof(u_int32_t)) < sizeof(struct kev_in_data)) 1482 { 1483 Log(("vboxNetFltDarwinSysSockUpcall: %u bytes is too short for KEV_INET_SUBCLASS\n", 1484 (unsigned int)len)); 1485 mbuf_freem(m); 1486 return; 1487 } 1488 1489 struct kev_in_data *iev = (struct kev_in_data *)msg->event_data; 1490 PCRTNETADDRU pAddr = (PCRTNETADDRU)&iev->ia_addr; 1491 switch (msg->event_code) 1492 { 1493 case KEV_INET_NEW_ADDR: 1494 Log(("KEV_INET_NEW_ADDR %RTnaipv4\n", pAddr->IPv4)); 1495 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1496 /* :fAdded */ true, kIntNetAddrType_IPv4, pAddr); 1497 break; 1498 1499 case KEV_INET_ADDR_DELETED: 1500 Log(("KEV_INET_ADDR_DELETED %RTnaipv4\n", pAddr->IPv4)); 1501 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1502 /* :fAdded */ false, kIntNetAddrType_IPv4, &iev->ia_addr); 1503 break; 1504 1505 default: 1506 Log(("KEV INET event %u addr %RTnaipv4\n", msg->event_code, pAddr->IPv4)); 1507 break; 1508 } 1509 } 1510 else if (msg->kev_subclass == KEV_INET6_SUBCLASS) 1511 { 1512 if (len - (sizeof(struct kern_event_msg) - sizeof(u_int32_t)) < sizeof(struct kev_in6_data)) 1513 { 1514 Log(("vboxNetFltDarwinSysSockUpcall: %u bytes is too short for KEV_INET6_SUBCLASS\n", 1515 (unsigned int)len)); 1516 mbuf_freem(m); 1517 return; 1518 } 1519 1520 struct kev_in6_data *iev6 = (struct kev_in6_data *)msg->event_data; 1521 PCRTNETADDRU pAddr = (PCRTNETADDRU)&iev6->ia_addr.sin6_addr; 1522 switch (msg->event_code) 1523 { 1524 case KEV_INET6_NEW_USER_ADDR: 1525 Log(("KEV_INET6_NEW_USER_ADDR: %RTnaipv6\n", pAddr)); 1526 goto kev_inet6_new; 1527 1528 case KEV_INET6_NEW_LL_ADDR: 1529 Log(("KEV_INET6_NEW_LL_ADDR: %RTnaipv6\n", pAddr)); 1530 /* XXX: uwe: TODO: only interface we are attached to */ 1531 goto kev_inet6_new; 1532 1533 case KEV_INET6_NEW_RTADV_ADDR: 1534 Log(("KEV_INET6_NEW_RTADV_ADDR: %RTnaipv6\n", pAddr)); 1535 goto kev_inet6_new; 1536 1537 kev_inet6_new: 1538 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1539 /* :fAdded */ true, kIntNetAddrType_IPv6, pAddr); 1540 break; 1541 1542 case KEV_INET6_ADDR_DELETED: 1543 Log(("KEV_INET6_ADDR_DELETED: %RTnaipv6\n", pAddr)); 1544 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1545 /* :fAdded */ false, kIntNetAddrType_IPv6, pAddr); 1546 break; 1547 1548 default: 1549 Log(("KEV INET6 event %u addr %RTnaipv6\n", msg->event_code, pAddr)); 1550 break; 1551 } 1552 } 1553 else 1554 { 1555 Log(("vboxNetFltDarwinSysSockUpcall: subclass %u ignored\n", 1556 (unsigned)msg->kev_subclass)); 1557 } 1558 1559 mbuf_freem(m); 1560 } 1303 1561 } 1304 1562 … … 1314 1572 pThis->u.s.fNeedSetPromiscuous = false; 1315 1573 //pThis->u.s.MacAddr = {0}; 1574 pThis->u.s.pSysSock = NULL; 1316 1575 1317 1576 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.