VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.h@ 82968

Last change on this file since 82968 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.4 KB
Line 
1/* $Id: VBoxNetFltRt-win.h 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * VBoxNetFltRt-win.h - Bridged Networking Driver, Windows Specific Code.
4 * NetFlt Runtime API
5 */
6/*
7 * Copyright (C) 2011-2020 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#ifndef VBOX_INCLUDED_SRC_VBoxNetFlt_win_drv_VBoxNetFltRt_win_h
28#define VBOX_INCLUDED_SRC_VBoxNetFlt_win_drv_VBoxNetFltRt_win_h
29#ifndef RT_WITHOUT_PRAGMA_ONCE
30# pragma once
31#endif
32DECLHIDDEN(VOID) vboxNetFltWinUnload(IN PDRIVER_OBJECT DriverObject);
33
34#ifndef VBOXNETADP
35# if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
36DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET pPacket2, const INT cbMatch);
37DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG pSG, const INT cbMatch);
38# endif
39#endif
40
41/*************************
42 * packet queue API *
43 *************************/
44
45
46#define LIST_ENTRY_2_PACKET_INFO(pListEntry) \
47 ( (PVBOXNETFLT_PACKET_INFO)((uint8_t *)(pListEntry) - RT_UOFFSETOF(VBOXNETFLT_PACKET_INFO, ListEntry)) )
48
49#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
50
51#define VBOX_SLE_2_PKTRSVD_PT(_pEntry) \
52 ( (PVBOXNETFLT_PKTRSVD_PT)((uint8_t *)(_pEntry) - RT_UOFFSETOF(VBOXNETFLT_PKTRSVD_PT, ListEntry)) )
53
54#define VBOX_SLE_2_SENDPACKET(_pEntry) \
55 ( (PNDIS_PACKET)((uint8_t *)(VBOX_SLE_2_PKTRSVD_PT(_pEntry)) - RT_UOFFSETOF(NDIS_PACKET, ProtocolReserved)) )
56
57#endif
58/**
59 * enqueus the packet info to the tail of the queue
60 */
61DECLINLINE(void) vboxNetFltWinQuEnqueueTail(PVBOXNETFLT_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo)
62{
63 InsertTailList(pQueue, &pPacketInfo->ListEntry);
64}
65
66DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PVBOXNETFLT_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo)
67{
68 Assert(pPacketInfo->pPool);
69 InsertHeadList(pQueue, &pPacketInfo->ListEntry);
70}
71
72/**
73 * enqueus the packet info to the tail of the queue
74 */
75DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo)
76{
77 Assert(pPacketInfo->pPool);
78 NdisAcquireSpinLock(&pQueue->Lock);
79 vboxNetFltWinQuEnqueueTail(&pQueue->Queue, pPacketInfo);
80 NdisReleaseSpinLock(&pQueue->Lock);
81}
82
83DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo)
84{
85 NdisAcquireSpinLock(&pQueue->Lock);
86 vboxNetFltWinQuEnqueueHead(&pQueue->Queue, pPacketInfo);
87 NdisReleaseSpinLock(&pQueue->Lock);
88}
89
90/**
91 * dequeus the packet info from the head of the queue
92 */
93DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuDequeueHead(PVBOXNETFLT_PACKET_QUEUE pQueue)
94{
95 PLIST_ENTRY pListEntry = RemoveHeadList(pQueue);
96 if (pListEntry != pQueue)
97 {
98 PVBOXNETFLT_PACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
99 Assert(pInfo->pPool);
100 return pInfo;
101 }
102 return NULL;
103}
104
105DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuDequeueTail(PVBOXNETFLT_PACKET_QUEUE pQueue)
106{
107 PLIST_ENTRY pListEntry = RemoveTailList(pQueue);
108 if (pListEntry != pQueue)
109 {
110 PVBOXNETFLT_PACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
111 Assert(pInfo->pPool);
112 return pInfo;
113 }
114 return NULL;
115}
116
117DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuInterlockedDequeueHead(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue)
118{
119 PVBOXNETFLT_PACKET_INFO pInfo;
120 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
121 pInfo = vboxNetFltWinQuDequeueHead(&pInterlockedQueue->Queue);
122 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
123 return pInfo;
124}
125
126DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuInterlockedDequeueTail(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue)
127{
128 PVBOXNETFLT_PACKET_INFO pInfo;
129 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
130 pInfo = vboxNetFltWinQuDequeueTail(&pInterlockedQueue->Queue);
131 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
132 return pInfo;
133}
134
135DECLINLINE(void) vboxNetFltWinQuDequeue(PVBOXNETFLT_PACKET_INFO pInfo)
136{
137 RemoveEntryList(&pInfo->ListEntry);
138}
139
140DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue, PVBOXNETFLT_PACKET_INFO pInfo)
141{
142 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
143 vboxNetFltWinQuDequeue(pInfo);
144 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
145}
146
147/**
148 * allocates the packet info from the pool
149 */
150DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PVBOXNETFLT_PACKET_INFO_POOL pPool)
151{
152 return vboxNetFltWinQuInterlockedDequeueHead(&pPool->Queue);
153}
154
155/**
156 * returns the packet info to the pool
157 */
158DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PVBOXNETFLT_PACKET_INFO pInfo)
159{
160 PVBOXNETFLT_PACKET_INFO_POOL pPool = pInfo->pPool;
161 vboxNetFltWinQuInterlockedEnqueueHead(&pPool->Queue, pInfo);
162}
163
164/** initializes the packet queue */
165#define INIT_PACKET_QUEUE(_pQueue) InitializeListHead((_pQueue))
166
167/** initializes the packet queue */
168#define INIT_INTERLOCKED_PACKET_QUEUE(_pQueue) \
169 { \
170 INIT_PACKET_QUEUE(&(_pQueue)->Queue); \
171 NdisAllocateSpinLock(&(_pQueue)->Lock); \
172 }
173
174/** delete the packet queue */
175#define FINI_INTERLOCKED_PACKET_QUEUE(_pQueue) NdisFreeSpinLock(&(_pQueue)->Lock)
176
177/** returns the packet the packet info contains */
178#define GET_PACKET_FROM_INFO(_pPacketInfo) (ASMAtomicUoReadPtr((void * volatile *)&(_pPacketInfo)->pPacket))
179
180/** assignes the packet to the packet info */
181#define SET_PACKET_TO_INFO(_pPacketInfo, _pPacket) (ASMAtomicUoWritePtr(&(_pPacketInfo)->pPacket, (_pPacket)))
182
183/** returns the flags the packet info contains */
184#define GET_FLAGS_FROM_INFO(_pPacketInfo) (ASMAtomicUoReadU32((volatile uint32_t *)&(_pPacketInfo)->fFlags))
185
186/** sets flags to the packet info */
187#define SET_FLAGS_TO_INFO(_pPacketInfo, _fFlags) (ASMAtomicUoWriteU32((volatile uint32_t *)&(_pPacketInfo)->fFlags, (_fFlags)))
188
189#ifdef VBOXNETFLT_NO_PACKET_QUEUE
190DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pInstance, PVOID pvPacket, const UINT fFlags);
191#else
192DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags);
193DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance);
194DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance);
195#endif /* #ifndef VBOXNETFLT_NO_PACKET_QUEUE */
196
197
198#ifndef VBOXNETADP
199/**
200 * searches the list entry in a single-linked list
201 */
202DECLINLINE(bool) vboxNetFltWinSearchListEntry(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
203{
204 PSINGLE_LIST_ENTRY pHead = &pList->Head;
205 PSINGLE_LIST_ENTRY pCur;
206 PSINGLE_LIST_ENTRY pPrev;
207 for (pCur = pHead->Next, pPrev = pHead; pCur; pPrev = pCur, pCur = pCur->Next)
208 {
209 if (pEntry2Search == pCur)
210 {
211 if (bRemove)
212 {
213 pPrev->Next = pCur->Next;
214 if (pCur == pList->pTail)
215 {
216 pList->pTail = pPrev;
217 }
218 }
219 return true;
220 }
221 }
222 return false;
223}
224
225#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
226
227DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacket(PVBOXNETFLT_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove)
228{
229 PSINGLE_LIST_ENTRY pHead = &pList->Head;
230 PSINGLE_LIST_ENTRY pCur;
231 PSINGLE_LIST_ENTRY pPrev;
232 PNDIS_PACKET pCurPacket;
233 for (pCur = pHead->Next, pPrev = pHead; pCur; pPrev = pCur, pCur = pCur->Next)
234 {
235 pCurPacket = VBOX_SLE_2_SENDPACKET(pCur);
236 if (pCurPacket == pPacket2Search || vboxNetFltWinMatchPackets(pPacket2Search, pCurPacket, cbMatch))
237 {
238 if (bRemove)
239 {
240 pPrev->Next = pCur->Next;
241 if (pCur == pList->pTail)
242 {
243 pList->pTail = pPrev;
244 }
245 }
246 return pCurPacket;
247 }
248 }
249 return NULL;
250}
251
252DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacketBySG(PVBOXNETFLT_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove)
253{
254 PSINGLE_LIST_ENTRY pHead = &pList->Head;
255 PSINGLE_LIST_ENTRY pCur;
256 PSINGLE_LIST_ENTRY pPrev;
257 PNDIS_PACKET pCurPacket;
258 for (pCur = pHead->Next, pPrev = pHead; pCur; pPrev = pCur, pCur = pCur->Next)
259 {
260 pCurPacket = VBOX_SLE_2_SENDPACKET(pCur);
261 if (vboxNetFltWinMatchPacketAndSG(pCurPacket, pSG, cbMatch))
262 {
263 if (bRemove)
264 {
265 pPrev->Next = pCur->Next;
266 if (pCur == pList->pTail)
267 {
268 pList->pTail = pPrev;
269 }
270 }
271 return pCurPacket;
272 }
273 }
274 return NULL;
275}
276
277#endif /* #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) */
278
279DECLINLINE(bool) vboxNetFltWinSListIsEmpty(PVBOXNETFLT_SINGLE_LIST pList)
280{
281 return !pList->Head.Next;
282}
283
284DECLINLINE(void) vboxNetFltWinPutTail(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
285{
286 pList->pTail->Next = pEntry;
287 pList->pTail = pEntry;
288 pEntry->Next = NULL;
289}
290
291DECLINLINE(void) vboxNetFltWinPutHead(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
292{
293 pEntry->Next = pList->Head.Next;
294 pList->Head.Next = pEntry;
295 if (!pEntry->Next)
296 pList->pTail = pEntry;
297}
298
299DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PVBOXNETFLT_SINGLE_LIST pList)
300{
301 PSINGLE_LIST_ENTRY pEntry = pList->Head.Next;
302 if (pEntry && pEntry == pList->pTail)
303 {
304 pList->Head.Next = NULL;
305 pList->pTail = &pList->Head;
306 }
307 return pEntry;
308}
309
310DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
311{
312 bool bFound;
313 NdisAcquireSpinLock(&pList->Lock);
314 bFound = vboxNetFltWinSearchListEntry(&pList->List, pEntry2Search, bRemove);
315 NdisReleaseSpinLock(&pList->Lock);
316 return bFound;
317}
318
319#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
320
321DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacket(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove)
322{
323 PNDIS_PACKET pFound;
324 NdisAcquireSpinLock(&pList->Lock);
325 pFound = vboxNetFltWinSearchPacket(&pList->List, pPacket2Search, cbMatch, bRemove);
326 NdisReleaseSpinLock(&pList->Lock);
327 return pFound;
328}
329
330DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacketBySG(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove)
331{
332 PNDIS_PACKET pFound;
333 NdisAcquireSpinLock(&pList->Lock);
334 pFound = vboxNetFltWinSearchPacketBySG(&pList->List, pSG, cbMatch, bRemove);
335 NdisReleaseSpinLock(&pList->Lock);
336 return pFound;
337}
338#endif /* #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) */
339
340DECLINLINE(void) vboxNetFltWinInterlockedPutTail(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
341{
342 NdisAcquireSpinLock(&pList->Lock);
343 vboxNetFltWinPutTail(&pList->List, pEntry);
344 NdisReleaseSpinLock(&pList->Lock);
345}
346
347DECLINLINE(void) vboxNetFltWinInterlockedPutHead(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
348{
349 NdisAcquireSpinLock(&pList->Lock);
350 vboxNetFltWinPutHead(&pList->List, pEntry);
351 NdisReleaseSpinLock(&pList->Lock);
352}
353
354DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList)
355{
356 PSINGLE_LIST_ENTRY pEntry;
357 NdisAcquireSpinLock(&pList->Lock);
358 pEntry = vboxNetFltWinGetHead(&pList->List);
359 NdisReleaseSpinLock(&pList->Lock);
360 return pEntry;
361}
362
363# if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
364DECLINLINE(void) vboxNetFltWinLbPutSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, bool bFromIntNet)
365{
366 PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
367 pSrv->bFromIntNet = bFromIntNet;
368 vboxNetFltWinInterlockedPutHead(&pNetFlt->u.s.WinIf.SendPacketQueue, &pSrv->ListEntry);
369}
370
371DECLINLINE(bool) vboxNetFltWinLbIsFromIntNet(PNDIS_PACKET pPacket)
372{
373 PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
374 return pSrv->bFromIntNet;
375}
376
377DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBack(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, bool bRemove)
378{
379 return vboxNetFltWinInterlockedSearchPacket(&pNetFlt->u.s.WinIf.SendPacketQueue, pPacket, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove);
380}
381
382DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBackBySG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, bool bRemove)
383{
384 return vboxNetFltWinInterlockedSearchPacketBySG(&pNetFlt->u.s.WinIf.SendPacketQueue, pSG, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove);
385}
386
387DECLINLINE(bool) vboxNetFltWinLbRemoveSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket)
388{
389 PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
390 bool bRet = vboxNetFltWinInterlockedSearchListEntry(&pNetFlt->u.s.WinIf.SendPacketQueue, &pSrv->ListEntry, true);
391#ifdef DEBUG_misha
392 Assert(bRet == (pNetFlt->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE));
393#endif
394 return bRet;
395}
396
397# endif
398
399#endif
400
401#ifdef DEBUG_misha
402DECLHIDDEN(bool) vboxNetFltWinCheckMACs(PNDIS_PACKET pPacket, PRTMAC pDst, PRTMAC pSrc);
403DECLHIDDEN(bool) vboxNetFltWinCheckMACsSG(PINTNETSG pSG, PRTMAC pDst, PRTMAC pSrc);
404extern RTMAC g_vboxNetFltWinVerifyMACBroadcast;
405extern RTMAC g_vboxNetFltWinVerifyMACGuest;
406
407# define VBOXNETFLT_LBVERIFY(_pnf, _p) \
408 do { \
409 Assert(!vboxNetFltWinCheckMACs(_p, NULL, &g_vboxNetFltWinVerifyMACGuest)); \
410 Assert(!vboxNetFltWinCheckMACs(_p, NULL, &(_pnf)->u.s.MacAddr)); \
411 } while (0)
412
413# define VBOXNETFLT_LBVERIFYSG(_pnf, _p) \
414 do { \
415 Assert(!vboxNetFltWinCheckMACsSG(_p, NULL, &g_vboxNetFltWinVerifyMACGuest)); \
416 Assert(!vboxNetFltWinCheckMACsSG(_p, NULL, &(_pnf)->u.s.MacAddr)); \
417 } while (0)
418
419#else
420# define VBOXNETFLT_LBVERIFY(_pnf, _p) do { } while (0)
421# define VBOXNETFLT_LBVERIFYSG(_pnf, _p) do { } while (0)
422#endif
423
424/** initializes the list */
425#define INIT_SINGLE_LIST(_pList) \
426 { \
427 (_pList)->Head.Next = NULL; \
428 (_pList)->pTail = &(_pList)->Head; \
429 }
430
431/** initializes the list */
432#define INIT_INTERLOCKED_SINGLE_LIST(_pList) \
433 do { \
434 INIT_SINGLE_LIST(&(_pList)->List); \
435 NdisAllocateSpinLock(&(_pList)->Lock); \
436 } while (0)
437
438/** delete the packet queue */
439#define FINI_INTERLOCKED_SINGLE_LIST(_pList) \
440 do { \
441 Assert(vboxNetFltWinSListIsEmpty(&(_pList)->List)); \
442 NdisFreeSpinLock(&(_pList)->Lock) \
443 } while (0)
444
445
446/**************************************************************************
447 * PVBOXNETFLTINS , WinIf reference/dereference (i.e. retain/release) API *
448 **************************************************************************/
449
450
451DECLHIDDEN(void) vboxNetFltWinWaitDereference(PVBOXNETFLT_WINIF_DEVICE pState);
452
453DECLINLINE(void) vboxNetFltWinReferenceModeNetFlt(PVBOXNETFLTINS pIns)
454{
455 ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
456}
457
458DECLINLINE(void) vboxNetFltWinReferenceModePassThru(PVBOXNETFLTINS pIns)
459{
460 ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
461}
462
463DECLINLINE(void) vboxNetFltWinIncReferenceModeNetFlt(PVBOXNETFLTINS pIns, uint32_t v)
464{
465 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, v);
466}
467
468DECLINLINE(void) vboxNetFltWinIncReferenceModePassThru(PVBOXNETFLTINS pIns, uint32_t v)
469{
470 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, v);
471}
472
473DECLINLINE(void) vboxNetFltWinDereferenceModeNetFlt(PVBOXNETFLTINS pIns)
474{
475 ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
476}
477
478DECLINLINE(void) vboxNetFltWinDereferenceModePassThru(PVBOXNETFLTINS pIns)
479{
480 ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
481}
482
483DECLINLINE(void) vboxNetFltWinDecReferenceModeNetFlt(PVBOXNETFLTINS pIns, uint32_t v)
484{
485 Assert(v);
486 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, (uint32_t)(-((int32_t)v)));
487}
488
489DECLINLINE(void) vboxNetFltWinDecReferenceModePassThru(PVBOXNETFLTINS pIns, uint32_t v)
490{
491 Assert(v);
492 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, (uint32_t)(-((int32_t)v)));
493}
494
495DECLINLINE(void) vboxNetFltWinSetPowerState(PVBOXNETFLT_WINIF_DEVICE pState, NDIS_DEVICE_POWER_STATE State)
496{
497 ASMAtomicUoWriteU32((volatile uint32_t *)&pState->PowerState, State);
498}
499
500DECLINLINE(NDIS_DEVICE_POWER_STATE) vboxNetFltWinGetPowerState(PVBOXNETFLT_WINIF_DEVICE pState)
501{
502 return (NDIS_DEVICE_POWER_STATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->PowerState);
503}
504
505DECLINLINE(void) vboxNetFltWinSetOpState(PVBOXNETFLT_WINIF_DEVICE pState, VBOXNETDEVOPSTATE State)
506{
507 ASMAtomicUoWriteU32((volatile uint32_t *)&pState->OpState, State);
508}
509
510DECLINLINE(VBOXNETDEVOPSTATE) vboxNetFltWinGetOpState(PVBOXNETFLT_WINIF_DEVICE pState)
511{
512 return (VBOXNETDEVOPSTATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->OpState);
513}
514
515DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState)
516{
517 if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
518 {
519 /** @todo r=bird: Since this is a volatile member, why don't you declare it as
520 * such and save yourself all the casting? */
521 ASMAtomicIncU32((uint32_t volatile *)&pState->cReferences);
522 return true;
523 }
524 return false;
525}
526
527#ifndef VBOXNETADP
528DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2)
529{
530 if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
531 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
532 && vboxNetFltWinGetPowerState(pState2) == NdisDeviceStateD0
533 && vboxNetFltWinGetOpState(pState2) == kVBoxNetDevOpState_Initialized)
534 {
535 ASMAtomicIncU32((uint32_t volatile *)&pState1->cReferences);
536 ASMAtomicIncU32((uint32_t volatile *)&pState2->cReferences);
537 return true;
538 }
539 return false;
540}
541#endif
542
543DECLINLINE(void) vboxNetFltWinDereferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState)
544{
545 ASMAtomicDecU32((uint32_t volatile *)&pState->cReferences);
546 /** @todo r=bird: Add comment explaining why these cannot hit 0 or why
547 * reference are counted */
548}
549
550#ifndef VBOXNETADP
551DECLINLINE(void) vboxNetFltWinDereferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2)
552{
553 ASMAtomicDecU32((uint32_t volatile *)&pState1->cReferences);
554 ASMAtomicDecU32((uint32_t volatile *)&pState2->cReferences);
555}
556#endif
557
558DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState, uint32_t v)
559{
560 Assert(v);
561 ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, (uint32_t)(-((int32_t)v)));
562}
563
564#ifndef VBOXNETADP
565DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2, uint32_t v)
566{
567 ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, (uint32_t)(-((int32_t)v)));
568 ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, (uint32_t)(-((int32_t)v)));
569}
570#endif
571
572DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState, uint32_t v)
573{
574 Assert(v);
575 if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
576 {
577 ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, v);
578 return true;
579 }
580 return false;
581}
582
583#ifndef VBOXNETADP
584DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2, uint32_t v)
585{
586 if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
587 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
588 && vboxNetFltWinGetPowerState(pState2) == NdisDeviceStateD0
589 && vboxNetFltWinGetOpState(pState2) == kVBoxNetDevOpState_Initialized)
590 {
591 ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, v);
592 ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, v);
593 return true;
594 }
595 return false;
596}
597#endif
598
599
600DECLINLINE(bool) vboxNetFltWinReferenceWinIfNetFlt(PVBOXNETFLTINS pNetFlt, bool * pbNetFltActive)
601{
602 RTSpinlockAcquire((pNetFlt)->hSpinlock);
603#ifndef VBOXNETADP
604 if (!vboxNetFltWinDoReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState))
605#else
606 if (!vboxNetFltWinDoReferenceDevice(&pNetFlt->u.s.WinIf.MpState))
607#endif
608 {
609 RTSpinlockRelease((pNetFlt)->hSpinlock);
610 *pbNetFltActive = false;
611 return false;
612 }
613
614 if (pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
615 {
616 vboxNetFltWinReferenceModePassThru(pNetFlt);
617 RTSpinlockRelease((pNetFlt)->hSpinlock);
618 *pbNetFltActive = false;
619 return true;
620 }
621
622 vboxNetFltRetain((pNetFlt), true /* fBusy */);
623 vboxNetFltWinReferenceModeNetFlt(pNetFlt);
624 RTSpinlockRelease((pNetFlt)->hSpinlock);
625
626 *pbNetFltActive = true;
627 return true;
628}
629
630DECLINLINE(bool) vboxNetFltWinIncReferenceWinIfNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t v, bool *pbNetFltActive)
631{
632 uint32_t i;
633
634 Assert(v);
635 if (!v)
636 {
637 *pbNetFltActive = false;
638 return false;
639 }
640
641 RTSpinlockAcquire((pNetFlt)->hSpinlock);
642#ifndef VBOXNETADP
643 if (!vboxNetFltWinDoIncReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v))
644#else
645 if (!vboxNetFltWinDoIncReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v))
646#endif
647 {
648 RTSpinlockRelease(pNetFlt->hSpinlock);
649 *pbNetFltActive = false;
650 return false;
651 }
652
653 if (pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
654 {
655 vboxNetFltWinIncReferenceModePassThru(pNetFlt, v);
656
657 RTSpinlockRelease((pNetFlt)->hSpinlock);
658 *pbNetFltActive = false;
659 return true;
660 }
661
662 vboxNetFltRetain(pNetFlt, true /* fBusy */);
663
664 vboxNetFltWinIncReferenceModeNetFlt(pNetFlt, v);
665
666 RTSpinlockRelease(pNetFlt->hSpinlock);
667
668 /* we have marked it as busy, so can do the res references outside the lock */
669 for (i = 0; i < v-1; i++)
670 {
671 vboxNetFltRetain(pNetFlt, true /* fBusy */);
672 }
673
674 *pbNetFltActive = true;
675
676 return true;
677}
678
679DECLINLINE(void) vboxNetFltWinDecReferenceNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t n)
680{
681 uint32_t i;
682 for (i = 0; i < n; i++)
683 {
684 vboxNetFltRelease(pNetFlt, true);
685 }
686
687 vboxNetFltWinDecReferenceModeNetFlt(pNetFlt, n);
688}
689
690DECLINLINE(void) vboxNetFltWinDereferenceNetFlt(PVBOXNETFLTINS pNetFlt)
691{
692 vboxNetFltRelease(pNetFlt, true);
693
694 vboxNetFltWinDereferenceModeNetFlt(pNetFlt);
695}
696
697DECLINLINE(void) vboxNetFltWinDecReferenceWinIf(PVBOXNETFLTINS pNetFlt, uint32_t v)
698{
699#ifdef VBOXNETADP
700 vboxNetFltWinDecReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v);
701#else
702 vboxNetFltWinDecReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v);
703#endif
704}
705
706DECLINLINE(void) vboxNetFltWinDereferenceWinIf(PVBOXNETFLTINS pNetFlt)
707{
708#ifdef VBOXNETADP
709 vboxNetFltWinDereferenceDevice(&pNetFlt->u.s.WinIf.MpState);
710#else
711 vboxNetFltWinDereferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState);
712#endif
713}
714
715DECLINLINE(bool) vboxNetFltWinIncReferenceWinIf(PVBOXNETFLTINS pNetFlt, uint32_t v)
716{
717 Assert(v);
718 if (!v)
719 {
720 return false;
721 }
722
723 RTSpinlockAcquire(pNetFlt->hSpinlock);
724#ifdef VBOXNETADP
725 if (vboxNetFltWinDoIncReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v))
726#else
727 if (vboxNetFltWinDoIncReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v))
728#endif
729 {
730 RTSpinlockRelease(pNetFlt->hSpinlock);
731 return true;
732 }
733
734 RTSpinlockRelease(pNetFlt->hSpinlock);
735 return false;
736}
737
738DECLINLINE(bool) vboxNetFltWinReferenceWinIf(PVBOXNETFLTINS pNetFlt)
739{
740 RTSpinlockAcquire(pNetFlt->hSpinlock);
741#ifdef VBOXNETADP
742 if (vboxNetFltWinDoReferenceDevice(&pNetFlt->u.s.WinIf.MpState))
743#else
744 if (vboxNetFltWinDoReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState))
745#endif
746 {
747 RTSpinlockRelease(pNetFlt->hSpinlock);
748 return true;
749 }
750
751 RTSpinlockRelease(pNetFlt->hSpinlock);
752 return false;
753}
754
755/***********************************************
756 * methods for accessing the network card info *
757 ***********************************************/
758
759DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PVBOXNETFLTINS pNetFlt, PRTMAC pMac);
760DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PVBOXNETFLTINS pNetFlt);
761DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PVBOXNETFLTINS pNetFlt, bool bYes);
762DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PVBOXNETFLTINS pNetFlt, NDIS_PHYSICAL_MEDIUM * pMedium);
763
764/*********************
765 * mem alloc API *
766 *********************/
767
768DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength);
769
770DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pMemBuf);
771
772/* convenience method used which allocates and initializes the PINTNETSG containing one
773 * segment referring the buffer of size cbBufSize
774 * the allocated PINTNETSG should be freed with the vboxNetFltWinMemFree.
775 *
776 * This is used when our ProtocolReceive callback is called and we have to return the indicated NDIS_PACKET
777 * on a callback exit. This is why we allocate the PINTNETSG and put the packet info there and enqueue it
778 * for the packet queue */
779DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbBufSize, PINTNETSG *ppSG);
780
781/************************
782 * WinIf init/fini API *
783 ************************/
784#if defined(VBOXNETADP)
785DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext);
786DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf);
787#else
788DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
789DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf, PNDIS_STRING pOurDeviceName);
790#endif
791
792DECLHIDDEN(VOID) vboxNetFltWinPtFiniWinIf(PVBOXNETFLTWIN pWinIf);
793
794/************************************
795 * Execute Job at passive level API *
796 ************************************/
797
798typedef VOID (*PFNVBOXNETFLT_JOB_ROUTINE) (PVOID pContext);
799
800DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext);
801
802/*******************************
803 * Ndis Packets processing API *
804 *******************************/
805DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory);
806
807DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeMem);
808
809#ifdef DEBUG_NETFLT_PACKETS
810#define DBG_CHECK_PACKETS(_p1, _p2) \
811 { \
812 bool _b = vboxNetFltWinMatchPackets(_p1, _p2, -1); \
813 Assert(_b); \
814 }
815
816#define DBG_CHECK_PACKET_AND_SG(_p, _sg) \
817 { \
818 bool _b = vboxNetFltWinMatchPacketAndSG(_p, _sg, -1); \
819 Assert(_b); \
820 }
821
822#define DBG_CHECK_SGS(_sg1, _sg2) \
823 { \
824 bool _b = vboxNetFltWinMatchSGs(_sg1, _sg2, -1); \
825 Assert(_b); \
826 }
827
828#else
829#define DBG_CHECK_PACKETS(_p1, _p2)
830#define DBG_CHECK_PACKET_AND_SG(_p, _sg)
831#define DBG_CHECK_SGS(_sg1, _sg2)
832#endif
833
834/**
835 * Ndis loops back broadcast packets posted to the wire by IntNet
836 * This routine is used in the mechanism of preventing this looping
837 *
838 * @param pAdapt
839 * @param pPacket
840 * @param bOnRecv true is we are receiving the packet from the wire
841 * false otherwise (i.e. the packet is from the host)
842 *
843 * @return true if the packet is a looped back one, false otherwise
844 */
845#ifdef VBOX_LOOPBACK_USEFLAGS
846DECLINLINE(bool) vboxNetFltWinIsLoopedBackPacket(PNDIS_PACKET pPacket)
847{
848 return (NdisGetPacketFlags(pPacket) & g_fPacketIsLoopedBack) == g_fPacketIsLoopedBack;
849}
850#endif
851
852/**************************************************************
853 * utility methods for ndis packet creation/initialization *
854 **************************************************************/
855
856#define VBOXNETFLT_OOB_INIT(_p) \
857 { \
858 NdisZeroMemory(NDIS_OOB_DATA_FROM_PACKET(_p), sizeof(NDIS_PACKET_OOB_DATA)); \
859 NDIS_SET_PACKET_HEADER_SIZE(_p, VBOXNETFLT_PACKET_ETHEADER_SIZE); \
860 }
861
862#ifndef VBOXNETADP
863
864DECLINLINE(NDIS_STATUS) vboxNetFltWinCopyPacketInfoOnRecv(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket, bool bForceStatusResources)
865{
866 NDIS_STATUS Status = bForceStatusResources ? NDIS_STATUS_RESOURCES : NDIS_GET_PACKET_STATUS(pSrcPacket);
867 NDIS_SET_PACKET_STATUS(pDstPacket, Status);
868
869 NDIS_PACKET_FIRST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pSrcPacket);
870 NDIS_PACKET_LAST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pSrcPacket);
871
872 NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
873
874 NDIS_SET_ORIGINAL_PACKET(pDstPacket, NDIS_GET_ORIGINAL_PACKET(pSrcPacket));
875 NDIS_SET_PACKET_HEADER_SIZE(pDstPacket, NDIS_GET_PACKET_HEADER_SIZE(pSrcPacket));
876
877 return Status;
878}
879
880DECLINLINE(void) vboxNetFltWinCopyPacketInfoOnSend(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
881{
882 NDIS_PACKET_FIRST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pSrcPacket);
883 NDIS_PACKET_LAST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pSrcPacket);
884
885 NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
886
887 NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(pDstPacket),
888 NDIS_OOB_DATA_FROM_PACKET(pSrcPacket),
889 sizeof (NDIS_PACKET_OOB_DATA));
890
891 NdisIMCopySendPerPacketInfo(pDstPacket, pSrcPacket);
892
893 PVOID pMediaSpecificInfo = NULL;
894 UINT fMediaSpecificInfoSize = 0;
895
896 NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(pSrcPacket, &pMediaSpecificInfo, &fMediaSpecificInfoSize);
897
898 if (pMediaSpecificInfo || fMediaSpecificInfoSize)
899 {
900 NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(pDstPacket, pMediaSpecificInfo, fMediaSpecificInfoSize);
901 }
902}
903
904DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket);
905DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareRecvPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket, bool bDpr);
906#endif
907
908DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis);
909
910#define MACS_EQUAL(_m1, _m2) \
911 ((_m1).au16[0] == (_m2).au16[0] \
912 && (_m1).au16[1] == (_m2).au16[1] \
913 && (_m1).au16[2] == (_m2).au16[2])
914
915
916DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PVBOXNETFLTINS pNetFlt, bool bOnUnbind);
917DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING pSrc);
918
919
920/**
921 * Sets the enmState member atomically.
922 *
923 * Used for all updates.
924 *
925 * @param pThis The instance.
926 * @param enmNewState The new value.
927 */
928DECLINLINE(void) vboxNetFltWinSetWinIfState(PVBOXNETFLTINS pNetFlt, VBOXNETFLT_WINIFSTATE enmNewState)
929{
930 ASMAtomicWriteU32((uint32_t volatile *)&pNetFlt->u.s.WinIf.enmState, enmNewState);
931}
932
933/**
934 * Gets the enmState member atomically.
935 *
936 * Used for all reads.
937 *
938 * @returns The enmState value.
939 * @param pThis The instance.
940 */
941DECLINLINE(VBOXNETFLT_WINIFSTATE) vboxNetFltWinGetWinIfState(PVBOXNETFLTINS pNetFlt)
942{
943 return (VBOXNETFLT_WINIFSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pNetFlt->u.s.WinIf.enmState);
944}
945
946/* reference the driver module to prevent driver unload */
947DECLHIDDEN(void) vboxNetFltWinDrvReference();
948/* dereference the driver module to prevent driver unload */
949DECLHIDDEN(void) vboxNetFltWinDrvDereference();
950
951
952#ifndef VBOXNETADP
953# define VBOXNETFLT_PROMISCUOUS_SUPPORTED(_pNetFlt) (!(_pNetFlt)->fDisablePromiscuous)
954#else
955# define STATISTIC_INCREASE(_s) ASMAtomicIncU32((uint32_t volatile *)&(_s));
956
957DECLHIDDEN(void) vboxNetFltWinGenerateMACAddress(RTMAC *pMac);
958DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
959DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
960
961#endif
962#endif /* !VBOX_INCLUDED_SRC_VBoxNetFlt_win_drv_VBoxNetFltRt_win_h */
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