Changeset 56846 in vbox for trunk/src/VBox/HostDrivers/VBoxNetFlt
- Timestamp:
- Jul 7, 2015 8:09:37 PM (9 years ago)
- Location:
- trunk/src/VBox/HostDrivers/VBoxNetFlt
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk
r56293 r56846 61 61 $(PATH_SDK_$(VBOX_WINDDK_WLH)_LIB)/hal.lib \ 62 62 $(PATH_SDK_$(VBOX_WINDDK_WLH)_LIB)/ndis.lib \ 63 $(PATH_SDK_$(VBOX_WINDDK_WLH)_LIB)/tdi.lib \ 63 64 $(PATH_STAGE_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB) 64 65 VBoxNetFlt_LIBS = \ -
trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h
r56293 r56846 56 56 #include <iprt/time.h> 57 57 #include <iprt/net.h> 58 #include <iprt/list.h> 58 59 59 60 RT_C_DECLS_BEGIN … … 375 376 /* Protocol info */ 376 377 VBOXNETFLTGLOBALS_PT Pt; 378 /** lock protecting the filter list */ 379 NDIS_SPIN_LOCK lockFilters; 380 /** the head of filter list */ 381 RTLISTANCHOR listFilters; 382 /** IP address change notifier handle */ 383 HANDLE hNotifier; 377 384 #endif 378 385 } VBOXNETFLTGLOBALS_WIN, *PVBOXNETFLTGLOBALS_WIN; … … 457 464 /** packet filter flags set by us */ 458 465 ULONG fOurSetFilter; 466 /** our own list of filters, needed by notifier */ 467 RTLISTNODE node; 459 468 #else 460 469 volatile ULONG cTxSuccess; -
trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.cpp
r56293 r56846 18 18 #include <VBox/intnetinline.h> 19 19 #include <iprt/thread.h> 20 21 RT_C_DECLS_BEGIN 22 #include <tdikrnl.h> 23 RT_C_DECLS_END 24 #include <mstcpip.h> 20 25 21 26 /** represents the job element of the job queue … … 1678 1683 vboxNetFltWinMpDeregister(&g_VBoxNetFltGlobalsWin.Mp); 1679 1684 1685 #ifndef VBOXNETADP 1686 NdisFreeSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 1687 #endif /* VBOXNETADP */ 1688 1680 1689 LogFlow((__FUNCTION__" <== DO (0x%x)\n", DriverObject)); 1681 1690 … … 1729 1738 g_VBoxNetFltGlobalsWin.fPacketIsLoopedBack = NDIS_FLAGS_IS_LOOPBACK_PACKET; 1730 1739 1740 #ifndef VBOXNETADP 1741 RTListInit(&g_VBoxNetFltGlobalsWin.listFilters); 1742 NdisAllocateSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 1743 #endif 1744 1731 1745 Status = vboxNetFltWinMpRegister(&g_VBoxNetFltGlobalsWin.Mp, DriverObject, RegistryPath); 1732 1746 Assert(Status == STATUS_SUCCESS); … … 1749 1763 } 1750 1764 vboxNetFltWinMpDeregister(&g_VBoxNetFltGlobalsWin.Mp); 1765 #ifndef VBOXNETADP 1766 NdisFreeSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 1767 #endif /* VBOXNETADP */ 1751 1768 } 1752 1769 vboxNetFltWinJobFiniQueue(&g_VBoxJobQueue); … … 3272 3289 } 3273 3290 3291 #ifndef VBOXNETADP 3292 3293 DECLINLINE(bool) vboxNetFltWinIsAddrLinkLocal4(PCRTNETADDRIPV4 pAddr) 3294 { 3295 return (pAddr->s.Lo == 0xfea9); /* 169.254 */ 3296 } 3297 3298 DECLINLINE(bool) vboxNetFltWinIsAddrLinkLocal6(PCRTNETADDRIPV6 pAddr) 3299 { 3300 return ((pAddr->au8[0] == 0xfe) && ((pAddr->au8[1] & 0xc0) == 0x80)); 3301 } 3302 3303 void vboxNetFltWinNotifyHostAddress(PTA_ADDRESS pAddress, bool fAdded) 3304 { 3305 #ifdef DEBUG 3306 char szBuf[128]; 3307 #endif /* DEBUG */ 3308 void *pvAddr = NULL; 3309 INTNETADDRTYPE enmAddrType = kIntNetAddrType_Invalid; 3310 3311 LogFlow(("==>vboxNetFltWinNotifyHostAddress: AddrType=%d %s\n", 3312 pAddress->AddressType, fAdded ? "added" : "deleted")); 3313 if (pAddress->AddressType == TDI_ADDRESS_TYPE_IP) 3314 { 3315 PTDI_ADDRESS_IP pTdiAddrIp = (PTDI_ADDRESS_IP)pAddress->Address; 3316 /* 3317 * Note that we do not get loopback addresses here. If we did we should 3318 * have checked and ignored them too. 3319 */ 3320 if (!vboxNetFltWinIsAddrLinkLocal4((PCRTNETADDRIPV4)(&pTdiAddrIp->in_addr))) 3321 { 3322 pvAddr = &pTdiAddrIp->in_addr; 3323 enmAddrType = kIntNetAddrType_IPv4; 3324 } 3325 } 3326 else if (pAddress->AddressType == TDI_ADDRESS_TYPE_IP6) 3327 { 3328 PTDI_ADDRESS_IP6 pTdiAddrIp6 = (PTDI_ADDRESS_IP6)pAddress->Address; 3329 if (!vboxNetFltWinIsAddrLinkLocal6((PCRTNETADDRIPV6)(pTdiAddrIp6->sin6_addr))) 3330 { 3331 pvAddr = pTdiAddrIp6->sin6_addr; 3332 enmAddrType = kIntNetAddrType_IPv6; 3333 } 3334 } 3335 else 3336 { 3337 Log2(("vboxNetFltWinNotifyHostAddress: ignoring irrelevant address type %d\n", 3338 pAddress->AddressType)); 3339 LogFlow(("<==vboxNetFltWinNotifyHostAddress\n")); 3340 return; 3341 } 3342 if (pvAddr) 3343 { 3344 NdisAcquireSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 3345 /* At this point the list must contain at least one element. */ 3346 PVBOXNETFLTWIN pFilter = NULL; 3347 PVBOXNETFLTINS pInstance = NULL; 3348 RTListForEach(&g_VBoxNetFltGlobalsWin.listFilters, pFilter, VBOXNETFLTWIN, node) 3349 { 3350 pInstance = RT_FROM_MEMBER(pFilter, VBOXNETFLTINS, u.s.WinIf); 3351 if (vboxNetFltWinReferenceWinIf(pInstance)) 3352 { 3353 if (pInstance->pSwitchPort && pInstance->pSwitchPort->pfnNotifyHostAddress) 3354 break; 3355 vboxNetFltWinDereferenceWinIf(pInstance); 3356 } 3357 else 3358 Log2(("vboxNetFltWinNotifyHostAddress: failed to retain filter instance %p\n", pInstance)); 3359 pInstance = NULL; 3360 } 3361 NdisReleaseSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 3362 if (pInstance) 3363 { 3364 if (enmAddrType == kIntNetAddrType_IPv4) 3365 Log2(("vboxNetFltWin%sAddressHandler: %RTnaipv4\n", 3366 fAdded ? "Add" : "Del", *(PCRTNETADDRIPV4)pvAddr)); 3367 else 3368 Log2(("vboxNetFltWin%sAddressHandler: %RTnaipv6\n", 3369 fAdded ? "Add" : "Del", pvAddr)); 3370 pInstance->pSwitchPort->pfnNotifyHostAddress(pInstance->pSwitchPort, fAdded, 3371 enmAddrType, pvAddr); 3372 vboxNetFltWinDereferenceWinIf(pInstance); 3373 } 3374 else 3375 Log2(("vboxNetFltWinNotifyHostAddress: no filters require notification\n")); 3376 } 3377 else 3378 Log2(("vboxNetFltWinNotifyHostAddress: ignoring link-local address (%s)\n", szBuf)); 3379 LogFlow(("<==vboxNetFltWinNotifyHostAddress\n")); 3380 } 3381 3382 void vboxNetFltWinAddAddressHandler(PTA_ADDRESS Address, 3383 PUNICODE_STRING DeviceName, 3384 PTDI_PNP_CONTEXT Context) 3385 { 3386 vboxNetFltWinNotifyHostAddress(Address, true); 3387 } 3388 3389 void vboxNetFltWinDelAddressHandler(PTA_ADDRESS Address, 3390 PUNICODE_STRING DeviceName, 3391 PTDI_PNP_CONTEXT Context) 3392 { 3393 vboxNetFltWinNotifyHostAddress(Address, false); 3394 } 3395 3396 void vboxNetFltWinRegisterIpAddrNotifier(PVBOXNETFLTINS pThis) 3397 { 3398 LogFlow(("==>vboxNetFltWinRegisterIpAddrNotifier: instance=%p pThis->pSwitchPort=%p pThis->pSwitchPort->pfnNotifyHostAddress=%p\n", 3399 pThis, pThis->pSwitchPort, pThis->pSwitchPort ? pThis->pSwitchPort->pfnNotifyHostAddress : NULL)); 3400 if (pThis->pSwitchPort && pThis->pSwitchPort->pfnNotifyHostAddress) 3401 { 3402 NdisAcquireSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 3403 bool fRegisterHandlers = RTListIsEmpty(&g_VBoxNetFltGlobalsWin.listFilters); 3404 RTListPrepend(&g_VBoxNetFltGlobalsWin.listFilters, &pThis->u.s.WinIf.node); 3405 NdisReleaseSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 3406 3407 if (fRegisterHandlers) 3408 { 3409 TDI_CLIENT_INTERFACE_INFO Info; 3410 UNICODE_STRING ClientName = RTL_CONSTANT_STRING(L"VBoxNetFlt"); 3411 memset(&Info, 0, sizeof(Info)); 3412 Info.MajorTdiVersion = 2; 3413 Info.MinorTdiVersion = 0; 3414 Info.ClientName = &ClientName; 3415 Info.AddAddressHandlerV2 = vboxNetFltWinAddAddressHandler; 3416 Info.DelAddressHandlerV2 = vboxNetFltWinDelAddressHandler; 3417 Assert(!g_VBoxNetFltGlobalsWin.hNotifier); 3418 NTSTATUS Status = TdiRegisterPnPHandlers(&Info, sizeof(Info), &g_VBoxNetFltGlobalsWin.hNotifier); 3419 Log2(("vboxNetFltWinRegisterIpAddrNotifier: TdiRegisterPnPHandlers returned %d\n", Status)); 3420 } 3421 else 3422 Log2(("vboxNetFltWinRegisterIpAddrNotifier: already registed\n")); 3423 } 3424 else 3425 Log2(("vboxNetFltWinRegisterIpAddrNotifier: this instance does not require notifications, ignoring...\n")); 3426 LogFlow(("<==vboxNetFltWinRegisterIpAddrNotifier: notifier=%p\n", g_VBoxNetFltGlobalsWin.hNotifier)); 3427 } 3428 3429 void vboxNetFltWinUnregisterIpAddrNotifier(PVBOXNETFLTINS pThis) 3430 { 3431 LogFlow(("==>vboxNetFltWinUnregisterIpAddrNotifier: notifier=%p\n", g_VBoxNetFltGlobalsWin.hNotifier)); 3432 if (pThis->pSwitchPort && pThis->pSwitchPort->pfnNotifyHostAddress) 3433 { 3434 NdisAcquireSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 3435 /* At this point the list must contain at least one element. */ 3436 Assert(!RTListIsEmpty(&g_VBoxNetFltGlobalsWin.listFilters)); 3437 RTListNodeRemove(&pThis->u.s.WinIf.node); 3438 HANDLE hNotifier = NULL; 3439 if (RTListIsEmpty(&g_VBoxNetFltGlobalsWin.listFilters)) 3440 { 3441 /* 3442 * The list has become empty, so we need to deregister handlers. We 3443 * grab hNotifier and reset it while still holding the lock. This 3444 * guaranties that we won't interfere with setting it in 3445 * vboxNetFltWinRegisterIpAddrNotifier(). It is inconceivable that 3446 * vboxNetFltWinUnregisterIpAddrNotifier() will be called for the 3447 * same filter instance while it is still being processed by 3448 * vboxNetFltWinRegisterIpAddrNotifier(). This would require trunk 3449 * destruction in the middle of its creation. It is possible that 3450 * vboxNetFltWinUnregisterIpAddrNotifier() is called for another 3451 * filter instance, but in such case we won't even get here as the 3452 * list won't be empty. 3453 */ 3454 hNotifier = g_VBoxNetFltGlobalsWin.hNotifier; 3455 g_VBoxNetFltGlobalsWin.hNotifier = NULL; 3456 } 3457 NdisReleaseSpinLock(&g_VBoxNetFltGlobalsWin.lockFilters); 3458 if (hNotifier) 3459 { 3460 NTSTATUS Status = TdiDeregisterPnPHandlers(hNotifier); 3461 Log2(("vboxNetFltWinUnregisterIpAddrNotifier: TdiDeregisterPnPHandlers(%p) returned %d\n", 3462 hNotifier, Status)); 3463 } 3464 else 3465 Log2(("vboxNetFltWinUnregisterIpAddrNotifier: filters remain, do not deregister handlers yet\n")); 3466 } 3467 else 3468 Log2(("vboxNetFltWinUnregisterIpAddrNotifier: this instance did not require notifications, ignoring...\n")); 3469 LogFlow(("<==vboxNetFltWinUnregisterIpAddrNotifier\n")); 3470 } 3471 #else /* VBOXNETADP */ 3472 #define vboxNetFltWinRegisterIpAddrNotifier(x) 3473 #define vboxNetFltWinUnregisterIpAddrNotifier(x) 3474 #endif /* VBOXNETADP */ 3475 3274 3476 int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis) 3275 3477 { 3276 3478 NDIS_STATUS Status = vboxNetFltWinDisconnectIt(pThis); 3479 Log2(("vboxNetFltOsDisconnectIt: pThis=%p pThis->pSwitchPort=%p pThis->pSwitchPort->pfnNotifyHostAddress=%p\n", 3480 pThis, pThis->pSwitchPort, pThis->pSwitchPort ? pThis->pSwitchPort->pfnNotifyHostAddress : NULL)); 3481 vboxNetFltWinUnregisterIpAddrNotifier(pThis); 3277 3482 return Status == NDIS_STATUS_SUCCESS ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 3278 3483 } … … 3340 3545 int vboxNetFltOsConnectIt(PVBOXNETFLTINS pThis) 3341 3546 { 3547 Log2(("vboxNetFltOsConnectIt: pThis=%p pThis->pSwitchPort=%p pThis->pSwitchPort->pfnNotifyHostAddress=%p\n", 3548 pThis, pThis->pSwitchPort, pThis->pSwitchPort ? pThis->pSwitchPort->pfnNotifyHostAddress : NULL)); 3549 vboxNetFltWinRegisterIpAddrNotifier(pThis); 3342 3550 return vboxNetFltWinConnectIt(pThis); 3343 3551 }
Note:
See TracChangeset
for help on using the changeset viewer.