VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h@ 29108

Last change on this file since 29108 was 29108, checked in by vboxsync, 15 years ago

net[flt|adp]/win: disable delayed packet processing when intnet is on

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.4 KB
Line 
1/* $Id: VBoxNetFlt-win.h 29108 2010-05-05 20:17:42Z vboxsync $ */
2/** @file
3 * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
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 * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
19 * Copyright (c) 1993-1999, Microsoft Corporation
20 */
21
22#ifndef ___VBoxNetFlt_win_h___
23#define ___VBoxNetFlt_win_h___
24
25/*
26 * globals
27 */
28
29/** global lock */
30extern NDIS_SPIN_LOCK g_GlobalLock;
31
32#ifdef VBOX_LOOPBACK_USEFLAGS
33extern UINT g_fPacketDontLoopBack;
34extern UINT g_fPacketIsLoopedBack;
35#endif
36
37/*
38 * Debug Print API
39 */
40#ifdef DEBUG
41
42#define DBGPRINT(Fmt) DbgPrint Fmt
43
44#else /* if DBG */
45
46#define DBGPRINT(Fmt)
47
48#endif /* if DBG */
49
50
51DECLHIDDEN(NTSTATUS) vboxNetFltWinPtDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
52DECLHIDDEN(VOID) vboxNetFltWinUnload(IN PDRIVER_OBJECT DriverObject);
53
54#ifndef VBOXNETADP
55# if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
56DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET pPacket2, const INT cbMatch);
57DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG pSG, const INT cbMatch);
58# endif
59#endif
60
61/*************************
62 * packet queue API *
63 *************************/
64
65
66#define LIST_ENTRY_2_PACKET_INFO(pListEntry) \
67 ( (PPACKET_INFO)((uint8_t *)(pListEntry) - RT_OFFSETOF(PACKET_INFO, ListEntry)) )
68
69#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
70
71#define VBOX_SLE_2_SEND_RSVD(_pEntry) \
72 ( (PSEND_RSVD)((uint8_t *)(_pEntry) - RT_OFFSETOF(SEND_RSVD, ListEntry)) )
73
74#define VBOX_SLE_2_SENDPACKET(_pEntry) \
75 ( (PNDIS_PACKET)((uint8_t *)(VBOX_SLE_2_SEND_RSVD(_pEntry)) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved)) )
76
77#endif
78/**
79 * enqueus the packet info to the tail of the queue
80 */
81DECLINLINE(void) vboxNetFltWinQuEnqueueTail(PPACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
82{
83 InsertTailList(pQueue, &pPacketInfo->ListEntry);
84}
85
86DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PPACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
87{
88 Assert(pPacketInfo->pPool);
89 InsertHeadList(pQueue, &pPacketInfo->ListEntry);
90}
91
92/**
93 * enqueus the packet info to the tail of the queue
94 */
95DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PINTERLOCKED_PACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
96{
97 Assert(pPacketInfo->pPool);
98 NdisAcquireSpinLock(&pQueue->Lock);
99 vboxNetFltWinQuEnqueueTail(&pQueue->Queue, pPacketInfo);
100 NdisReleaseSpinLock(&pQueue->Lock);
101}
102
103DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PINTERLOCKED_PACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
104{
105 NdisAcquireSpinLock(&pQueue->Lock);
106 vboxNetFltWinQuEnqueueHead(&pQueue->Queue, pPacketInfo);
107 NdisReleaseSpinLock(&pQueue->Lock);
108}
109
110/**
111 * dequeus the packet info from the head of the queue
112 */
113DECLINLINE(PPACKET_INFO) vboxNetFltWinQuDequeueHead(PPACKET_QUEUE pQueue)
114{
115 PLIST_ENTRY pListEntry = RemoveHeadList(pQueue);
116 if(pListEntry != pQueue)
117 {
118 PPACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
119 Assert(pInfo->pPool);
120 return pInfo;
121 }
122 return NULL;
123}
124
125DECLINLINE(PPACKET_INFO) vboxNetFltWinQuDequeueTail(PPACKET_QUEUE pQueue)
126{
127 PLIST_ENTRY pListEntry = RemoveTailList(pQueue);
128 if(pListEntry != pQueue)
129 {
130 PPACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
131 Assert(pInfo->pPool);
132 return pInfo;
133 }
134 return NULL;
135}
136
137DECLINLINE(PPACKET_INFO) vboxNetFltWinQuInterlockedDequeueHead(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue)
138{
139 PPACKET_INFO pInfo;
140 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
141 pInfo = vboxNetFltWinQuDequeueHead(&pInterlockedQueue->Queue);
142 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
143 return pInfo;
144}
145
146DECLINLINE(PPACKET_INFO) vboxNetFltWinQuInterlockedDequeueTail(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue)
147{
148 PPACKET_INFO pInfo;
149 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
150 pInfo = vboxNetFltWinQuDequeueTail(&pInterlockedQueue->Queue);
151 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
152 return pInfo;
153}
154
155DECLINLINE(void) vboxNetFltWinQuDequeue(PPACKET_INFO pInfo)
156{
157 RemoveEntryList(&pInfo->ListEntry);
158}
159
160DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue, PPACKET_INFO pInfo)
161{
162 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
163 vboxNetFltWinQuDequeue(pInfo);
164 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
165}
166
167/**
168 * allocates the packet info from the pool
169 */
170DECLINLINE(PPACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PPACKET_INFO_POOL pPool)
171{
172 return vboxNetFltWinQuInterlockedDequeueHead(&pPool->Queue);
173}
174
175/**
176 * returns the packet info to the pool
177 */
178DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PPACKET_INFO pInfo)
179{
180 PPACKET_INFO_POOL pPool = pInfo->pPool;
181 vboxNetFltWinQuInterlockedEnqueueHead(&pPool->Queue, pInfo);
182}
183
184/** initializes the packet queue */
185#define INIT_PACKET_QUEUE(_pQueue) InitializeListHead((_pQueue))
186
187/** initializes the packet queue */
188#define INIT_INTERLOCKED_PACKET_QUEUE(_pQueue) \
189 { \
190 INIT_PACKET_QUEUE(&(_pQueue)->Queue); \
191 NdisAllocateSpinLock(&(_pQueue)->Lock); \
192 }
193
194/** delete the packet queue */
195#define FINI_INTERLOCKED_PACKET_QUEUE(_pQueue) NdisFreeSpinLock(&(_pQueue)->Lock)
196
197/** returns the packet the packet info contains */
198#define GET_PACKET_FROM_INFO(_pPacketInfo) (ASMAtomicUoReadPtr((void * volatile *)&(_pPacketInfo)->pPacket))
199
200/** assignes the packet to the packet info */
201#define SET_PACKET_TO_INFO(_pPacketInfo, _pPacket) (ASMAtomicUoWritePtr((void * volatile *)&(_pPacketInfo)->pPacket, (_pPacket)))
202
203/** returns the flags the packet info contains */
204#define GET_FLAGS_FROM_INFO(_pPacketInfo) (ASMAtomicUoReadU32((volatile uint32_t *)&(_pPacketInfo)->fFlags))
205
206/** sets flags to the packet info */
207#define SET_FLAGS_TO_INFO(_pPacketInfo, _fFlags) (ASMAtomicUoWriteU32((volatile uint32_t *)&(_pPacketInfo)->fFlags, (_fFlags)))
208
209#ifdef VBOXNETFLT_NO_PACKET_QUEUE
210DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pInstance, PVOID pvPacket, const UINT fFlags);
211#else
212DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags);
213
214#ifndef VBOX_NETFLT_ONDEMAND_BIND
215DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance);
216
217DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance);
218#endif
219
220#endif /* #ifndef VBOXNETFLT_NO_PACKET_QUEUE */
221
222
223#ifndef VBOXNETADP
224/**
225 * searches the list entry in a single-linked list
226 */
227DECLINLINE(bool) vboxNetFltWinSearchListEntry(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
228{
229 PSINGLE_LIST_ENTRY pHead = &pList->Head;
230 PSINGLE_LIST_ENTRY pCur;
231 PSINGLE_LIST_ENTRY pPrev;
232 for(pCur = pHead->Next, pPrev = pHead; pCur; pPrev = pCur, pCur = pCur->Next)
233 {
234 if(pEntry2Search == pCur)
235 {
236 if(bRemove)
237 {
238 pPrev->Next = pCur->Next;
239 if(pCur == pList->pTail)
240 {
241 pList->pTail = pPrev;
242 }
243 }
244 return true;
245 }
246 }
247 return false;
248}
249
250#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
251
252DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacket(PSINGLE_LIST pList, PNDIS_PACKET pPacket2Search, 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(pCurPacket == pPacket2Search || vboxNetFltWinMatchPackets(pPacket2Search, pCurPacket, 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
277DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacketBySG(PSINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove)
278{
279 PSINGLE_LIST_ENTRY pHead = &pList->Head;
280 PSINGLE_LIST_ENTRY pCur;
281 PSINGLE_LIST_ENTRY pPrev;
282 PNDIS_PACKET pCurPacket;
283 for(pCur = pHead->Next, pPrev = pHead; pCur; pPrev = pCur, pCur = pCur->Next)
284 {
285 pCurPacket = VBOX_SLE_2_SENDPACKET(pCur);
286 if(vboxNetFltWinMatchPacketAndSG(pCurPacket, pSG, cbMatch))
287 {
288 if(bRemove)
289 {
290 pPrev->Next = pCur->Next;
291 if(pCur == pList->pTail)
292 {
293 pList->pTail = pPrev;
294 }
295 }
296 return pCurPacket;
297 }
298 }
299 return NULL;
300}
301
302#endif /* #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) */
303
304DECLINLINE(bool) vboxNetFltWinSListIsEmpty(PSINGLE_LIST pList)
305{
306 return !pList->Head.Next;
307}
308
309DECLINLINE(void) vboxNetFltWinPutTail(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
310{
311 pList->pTail->Next = pEntry;
312 pList->pTail = pEntry;
313 pEntry->Next = NULL;
314}
315
316DECLINLINE(void) vboxNetFltWinPutHead(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
317{
318 pEntry->Next = pList->Head.Next;
319 pList->Head.Next = pEntry;
320 if(!pEntry->Next)
321 pList->pTail = pEntry;
322}
323
324DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PSINGLE_LIST pList)
325{
326 PSINGLE_LIST_ENTRY pEntry = pList->Head.Next;
327 if(pEntry && pEntry == pList->pTail)
328 {
329 pList->Head.Next = NULL;
330 pList->pTail = &pList->Head;
331 }
332 return pEntry;
333}
334
335DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
336{
337 bool bFound;
338 NdisAcquireSpinLock(&pList->Lock);
339 bFound = vboxNetFltWinSearchListEntry(&pList->List, pEntry2Search, bRemove);
340 NdisReleaseSpinLock(&pList->Lock);
341 return bFound;
342}
343
344#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
345
346DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacket(PINTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove)
347{
348 PNDIS_PACKET pFound;
349 NdisAcquireSpinLock(&pList->Lock);
350 pFound = vboxNetFltWinSearchPacket(&pList->List, pPacket2Search, cbMatch, bRemove);
351 NdisReleaseSpinLock(&pList->Lock);
352 return pFound;
353}
354
355DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacketBySG(PINTERLOCKED_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove)
356{
357 PNDIS_PACKET pFound;
358 NdisAcquireSpinLock(&pList->Lock);
359 pFound = vboxNetFltWinSearchPacketBySG(&pList->List, pSG, cbMatch, bRemove);
360 NdisReleaseSpinLock(&pList->Lock);
361 return pFound;
362}
363#endif /* #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) */
364
365DECLINLINE(void) vboxNetFltWinInterlockedPutTail(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
366{
367 NdisAcquireSpinLock(&pList->Lock);
368 vboxNetFltWinPutTail(&pList->List, pEntry);
369 NdisReleaseSpinLock(&pList->Lock);
370}
371
372DECLINLINE(void) vboxNetFltWinInterlockedPutHead(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
373{
374 NdisAcquireSpinLock(&pList->Lock);
375 vboxNetFltWinPutHead(&pList->List, pEntry);
376 NdisReleaseSpinLock(&pList->Lock);
377}
378
379DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PINTERLOCKED_SINGLE_LIST pList)
380{
381 PSINGLE_LIST_ENTRY pEntry;
382 NdisAcquireSpinLock(&pList->Lock);
383 pEntry = vboxNetFltWinGetHead(&pList->List);
384 NdisReleaseSpinLock(&pList->Lock);
385 return pEntry;
386}
387
388# if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
389DECLINLINE(void) vboxNetFltWinLbPutSendPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, bool bFromIntNet)
390{
391 PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved;
392 pSrv->bFromIntNet = bFromIntNet;
393 vboxNetFltWinInterlockedPutHead(&pAdapt->SendPacketQueue, &pSrv->ListEntry);
394}
395
396DECLINLINE(bool) vboxNetFltWinLbIsFromIntNet(PNDIS_PACKET pPacket)
397{
398 PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved;
399 return pSrv->bFromIntNet;
400}
401
402DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBack(PADAPT pAdapt, PNDIS_PACKET pPacket, bool bRemove)
403{
404 return vboxNetFltWinInterlockedSearchPacket(&pAdapt->SendPacketQueue, pPacket, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove);
405}
406
407DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBackBySG(PADAPT pAdapt, PINTNETSG pSG, bool bRemove)
408{
409 return vboxNetFltWinInterlockedSearchPacketBySG(&pAdapt->SendPacketQueue, pSG, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove);
410}
411
412DECLINLINE(bool) vboxNetFltWinLbRemoveSendPacket(PADAPT pAdapt, PNDIS_PACKET pPacket)
413{
414 PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved;
415 return vboxNetFltWinInterlockedSearchListEntry(&pAdapt->SendPacketQueue, &pSrv->ListEntry, true);
416}
417
418# endif
419
420#endif
421
422#ifdef DEBUG_misha
423DECLHIDDEN(bool) vboxNetFltWinCheckMACs(PNDIS_PACKET pPacket, PRTMAC pDst, PRTMAC pSrc);
424DECLHIDDEN(bool) vboxNetFltWinCheckMACsSG(PINTNETSG pSG, PRTMAC pDst, PRTMAC pSrc);
425extern RTMAC g_vboxNetFltWinVerifyMACBroadcast;
426extern RTMAC g_vboxNetFltWinVerifyMACGuest;
427
428# define VBOXNETFLT_LBVERIFY(_pnf, _p) \
429 do { \
430 Assert(!vboxNetFltWinCheckMACs(_p, NULL, &g_vboxNetFltWinVerifyMACGuest)); \
431 Assert(!vboxNetFltWinCheckMACs(_p, NULL, &(_pnf)->u.s.MacAddr)); \
432 } while(0)
433
434# define VBOXNETFLT_LBVERIFYSG(_pnf, _p) \
435 do { \
436 Assert(!vboxNetFltWinCheckMACsSG(_p, NULL, &g_vboxNetFltWinVerifyMACGuest)); \
437 Assert(!vboxNetFltWinCheckMACsSG(_p, NULL, &(_pnf)->u.s.MacAddr)); \
438 } while(0)
439
440#else
441# define VBOXNETFLT_LBVERIFY(_pnf, _p) do{}while(0)
442# define VBOXNETFLT_LBVERIFYSG(_pnf, _p) do{}while(0)
443#endif
444
445/** initializes the list */
446#define INIT_SINGLE_LIST(_pList) \
447 { \
448 (_pList)->Head.Next = NULL; \
449 (_pList)->pTail = &(_pList)->Head; \
450 }
451
452/** initializes the list */
453#define INIT_INTERLOCKED_SINGLE_LIST(_pList) \
454 do { \
455 INIT_SINGLE_LIST(&(_pList)->List); \
456 NdisAllocateSpinLock(&(_pList)->Lock); \
457 } while(0)
458
459/** delete the packet queue */
460#define FINI_INTERLOCKED_SINGLE_LIST(_pList) \
461 do { \
462 Assert(vboxNetFltWinSListIsEmpty(&(_pList)->List)); \
463 NdisFreeSpinLock(&(_pList)->Lock) \
464 } while(0)
465
466
467/** obtains the PTRANSFERDATA_RSVD given a single list entry it contains */
468//#define PT_SLE_2_TRANSFERDATA_RSVD(_pl) \
469// ( (PTRANSFERDATA_RSVD)((uint8_t *)(_pl) - RT_OFFSETOF(TRANSFERDATA_RSVD, ListEntry)))
470
471///** obtains the ndis packet given a single list entry assuming it is stored in ProtocolReserved field of the packet */
472//#define PT_SLE_2_NDIS_PACKET(_pl) \
473// ( (PNDIS_PACKET)((uint8_t *)PT_SLE_2_TRANSFERDATA_RSVD(_pl) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved)))
474
475/**************************************************************************
476 * PADAPT, PVBOXNETFLTINS reference/dereference (i.e. retain/release) API *
477 **************************************************************************/
478
479/** get the PVBOXNETFLTINS from PADAPT */
480#define PADAPT_2_PVBOXNETFLTINS(_pAdapt) ( (PVBOXNETFLTINS)((uint8_t *)(_pAdapt) - RT_OFFSETOF(VBOXNETFLTINS, u.s.IfAdaptor)) )
481/** get the PADAPT from PVBOXNETFLTINS */
482#define PVBOXNETFLTINS_2_PADAPT(_pNetFlt) ( &(_pNetFlt)->u.s.IfAdaptor )
483
484DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState);
485
486DECLINLINE(void) vboxNetFltWinReferenceModeNetFlt(PVBOXNETFLTINS pIns)
487{
488 ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
489}
490
491DECLINLINE(void) vboxNetFltWinReferenceModePassThru(PVBOXNETFLTINS pIns)
492{
493 ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
494}
495
496DECLINLINE(void) vboxNetFltWinIncReferenceModeNetFlt(PVBOXNETFLTINS pIns, uint32_t v)
497{
498 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, v);
499}
500
501DECLINLINE(void) vboxNetFltWinIncReferenceModePassThru(PVBOXNETFLTINS pIns, uint32_t v)
502{
503 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, v);
504}
505
506DECLINLINE(void) vboxNetFltWinDereferenceModeNetFlt(PVBOXNETFLTINS pIns)
507{
508 ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
509}
510
511DECLINLINE(void) vboxNetFltWinDereferenceModePassThru(PVBOXNETFLTINS pIns)
512{
513 ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
514}
515
516DECLINLINE(void) vboxNetFltWinDecReferenceModeNetFlt(PVBOXNETFLTINS pIns, uint32_t v)
517{
518 Assert(v);
519 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, (uint32_t)(-((int32_t)v)));
520}
521
522DECLINLINE(void) vboxNetFltWinDecReferenceModePassThru(PVBOXNETFLTINS pIns, uint32_t v)
523{
524 Assert(v);
525 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, (uint32_t)(-((int32_t)v)));
526}
527
528DECLINLINE(void) vboxNetFltWinSetPowerState(PADAPT_DEVICE pState, NDIS_DEVICE_POWER_STATE State)
529{
530 ASMAtomicUoWriteU32((volatile uint32_t *)&pState->PowerState, State);
531}
532
533DECLINLINE(NDIS_DEVICE_POWER_STATE) vboxNetFltWinGetPowerState(PADAPT_DEVICE pState)
534{
535 return (NDIS_DEVICE_POWER_STATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->PowerState);
536}
537
538DECLINLINE(void) vboxNetFltWinSetOpState(PADAPT_DEVICE pState, VBOXNETDEVOPSTATE State)
539{
540 ASMAtomicUoWriteU32((volatile uint32_t *)&pState->OpState, State);
541}
542
543DECLINLINE(VBOXNETDEVOPSTATE) vboxNetFltWinGetOpState(PADAPT_DEVICE pState)
544{
545 return (VBOXNETDEVOPSTATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->OpState);
546}
547
548DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState)
549{
550 if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
551 {
552 /** @todo r=bird: Since this is a volatile member, why don't you declare it as
553 * such and save yourself all the casting? */
554 ASMAtomicIncU32((uint32_t volatile *)&pState->cReferences);
555 return true;
556 }
557 return false;
558}
559
560#ifndef VBOXNETADP
561DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2)
562{
563 if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
564 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
565 && vboxNetFltWinGetPowerState(pState2) == NdisDeviceStateD0
566 && vboxNetFltWinGetOpState(pState2) == kVBoxNetDevOpState_Initialized)
567 {
568 ASMAtomicIncU32((uint32_t volatile *)&pState1->cReferences);
569 ASMAtomicIncU32((uint32_t volatile *)&pState2->cReferences);
570 return true;
571 }
572 return false;
573}
574#endif
575
576DECLINLINE(void) vboxNetFltWinDereferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState)
577{
578/* NdisAcquireSpinLock(&pAdapt->Lock); */
579 ASMAtomicDecU32((uint32_t volatile *)&pState->cReferences);
580 /** @todo r=bird: Add comment explaining why these cannot hit 0 or why
581 * reference are counted */
582/* NdisReleaseSpinLock(&pAdapt->Lock); */
583}
584
585#ifndef VBOXNETADP
586DECLINLINE(void) vboxNetFltWinDereferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2)
587{
588/* NdisAcquireSpinLock(&pAdapt->Lock); */
589 ASMAtomicDecU32((uint32_t volatile *)&pState1->cReferences);
590 ASMAtomicDecU32((uint32_t volatile *)&pState2->cReferences);
591/* NdisReleaseSpinLock(&pAdapt->Lock); */
592}
593#endif
594
595DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
596{
597 Assert(v);
598 ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, (uint32_t)(-((int32_t)v)));
599}
600
601#ifndef VBOXNETADP
602DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v)
603{
604 ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, (uint32_t)(-((int32_t)v)));
605 ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, (uint32_t)(-((int32_t)v)));
606}
607#endif
608
609DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
610{
611 Assert(v);
612 if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
613 {
614 ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, v);
615 return true;
616 }
617 return false;
618}
619
620#ifndef VBOXNETADP
621DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v)
622{
623 if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
624 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
625 && vboxNetFltWinGetPowerState(pState2) == NdisDeviceStateD0
626 && vboxNetFltWinGetOpState(pState2) == kVBoxNetDevOpState_Initialized)
627 {
628 ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, v);
629 ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, v);
630 return true;
631 }
632 return false;
633}
634#endif
635
636#ifdef VBOX_NETFLT_ONDEMAND_BIND
637DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinReferenceAdaptNetFltFromAdapt(PADAPT pAdapt)
638{
639 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
640 PVBOXNETFLTINS pNetFlt;
641
642 pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
643
644 RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
645 if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
646 {
647 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
648 return NULL;
649 }
650
651 if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
652 {
653 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
654 return NULL;
655 }
656
657 vboxNetFltRetain((pNetFlt), true /* fBusy */);
658
659 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
660
661 return pNetFlt;
662}
663#else
664DECLINLINE(bool) vboxNetFltWinReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAPT pAdapt, bool * pbNetFltActive)
665{
666 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
667
668 RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
669#ifndef VBOXNETADP
670 if(!vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
671#else
672 if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
673#endif
674 {
675 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
676 *pbNetFltActive = false;
677 return false;
678 }
679
680 if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
681 {
682 vboxNetFltWinReferenceModePassThru(pNetFlt);
683 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
684 *pbNetFltActive = false;
685 return true;
686 }
687
688 vboxNetFltRetain((pNetFlt), true /* fBusy */);
689 vboxNetFltWinReferenceModeNetFlt(pNetFlt);
690 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
691
692 *pbNetFltActive = true;
693 return true;
694}
695#endif
696
697#ifdef VBOX_NETFLT_ONDEMAND_BIND
698DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinIncReferenceAdaptNetFltFromAdapt(PADAPT pAdapt, uint32_t v)
699{
700 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
701 PVBOXNETFLTINS pNetFlt;
702 uint32_t i;
703
704 Assert(v);
705 if(!v)
706 {
707 return NULL;
708 }
709
710 pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
711
712 RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
713 if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
714 {
715 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
716 return NULL;
717 }
718
719 if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState, v))
720 {
721 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
722 return NULL;
723 }
724
725 vboxNetFltRetain((pNetFlt), true /* fBusy */);
726
727 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
728
729 /* we have marked it as busy, so can do the res references outside the lock */
730 for(i = 0; i < v-1; i++)
731 {
732 vboxNetFltRetain((pNetFlt), true /* fBusy */);
733 }
734
735 return pNetFlt;
736}
737#else
738DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAPT pAdapt, uint32_t v, bool *pbNetFltActive)
739{
740 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
741 uint32_t i;
742
743 Assert(v);
744 if(!v)
745 {
746 *pbNetFltActive = false;
747 return false;
748 }
749
750 RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
751#ifndef VBOXNETADP
752 if(!vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
753#else
754 if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
755#endif
756 {
757 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
758 *pbNetFltActive = false;
759 return false;
760 }
761
762 if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
763 {
764 vboxNetFltWinIncReferenceModePassThru(pNetFlt, v);
765
766 RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
767 *pbNetFltActive = false;
768 return true;
769 }
770
771 vboxNetFltRetain(pNetFlt, true /* fBusy */);
772
773 vboxNetFltWinIncReferenceModeNetFlt(pNetFlt, v);
774
775 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
776
777 /* we have marked it as busy, so can do the res references outside the lock */
778 for(i = 0; i < v-1; i++)
779 {
780 vboxNetFltRetain(pNetFlt, true /* fBusy */);
781 }
782
783 *pbNetFltActive = true;
784
785 return true;
786}
787
788#endif
789
790DECLINLINE(void) vboxNetFltWinDecReferenceNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t n)
791{
792 uint32_t i;
793 for(i = 0; i < n; i++)
794 {
795 vboxNetFltRelease(pNetFlt, true);
796 }
797
798 vboxNetFltWinDecReferenceModeNetFlt(pNetFlt, n);
799}
800
801DECLINLINE(void) vboxNetFltWinDereferenceNetFlt(PVBOXNETFLTINS pNetFlt)
802{
803 vboxNetFltRelease(pNetFlt, true);
804
805 vboxNetFltWinDereferenceModeNetFlt(pNetFlt);
806}
807
808DECLINLINE(void) vboxNetFltWinDecReferenceAdapt(PADAPT pAdapt, uint32_t v)
809{
810#ifdef VBOX_NETFLT_ONDEMAND_BIND
811 vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->PTState, v);
812#elif defined(VBOXNETADP)
813 vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->MPState, v);
814#else
815 vboxNetFltWinDecReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v);
816#endif
817}
818
819DECLINLINE(void) vboxNetFltWinDereferenceAdapt(PADAPT pAdapt)
820{
821#ifdef VBOX_NETFLT_ONDEMAND_BIND
822 vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->PTState);
823#elif defined(VBOXNETADP)
824 vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->MPState);
825#else
826 vboxNetFltWinDereferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState);
827#endif
828}
829
830DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v)
831{
832 PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
833 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
834
835 Assert(v);
836 if(!v)
837 {
838 return false;
839 }
840
841 RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
842#ifdef VBOX_NETFLT_ONDEMAND_BIND
843 if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState))
844#elif defined(VBOXNETADP)
845 if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
846#else
847 if(vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
848#endif
849 {
850 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
851 return true;
852 }
853
854 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
855 return false;
856}
857
858DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt)
859{
860 PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
861 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
862 RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
863#ifdef VBOX_NETFLT_ONDEMAND_BIND
864 if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
865#elif defined(VBOXNETADP)
866 if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
867#else
868 if(vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
869#endif
870 {
871 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
872 return true;
873 }
874
875 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
876 return false;
877}
878
879/***********************************************
880 * methods for accessing the network card info *
881 ***********************************************/
882
883DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac);
884DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt);
885DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes);
886DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHYSICAL_MEDIUM * pMedium);
887
888/*********************
889 * mem alloc API *
890 *********************/
891
892DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength);
893
894DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pMemBuf);
895
896/* convenience method used which allocates and initializes the PINTNETSG containing one
897 * segment refering the buffer of size cbBufSize
898 * the allocated PINTNETSG should be freed with the vboxNetFltWinMemFree.
899 *
900 * This is used when our ProtocolReceive callback is called and we have to return the indicated NDIS_PACKET
901 * on a callback exit. This is why we allocate the PINTNETSG and put the packet info there and enqueue it
902 * for the packet queue */
903DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbBufSize, PINTNETSG *ppSG);
904
905/************************
906 * PADAPT init/fini API *
907 ************************/
908
909#if defined(VBOX_NETFLT_ONDEMAND_BIND)
910DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT pAdapt);
911#elif defined(VBOXNETADP)
912DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext);
913#else
914DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
915#endif
916
917#ifdef VBOX_NETFLT_ONDEMAND_BIND
918DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT pAdapt);
919#else
920DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
921#endif
922
923DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt);
924#ifndef VBOXNETADP
925DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName);
926#else
927DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt);
928#endif
929
930/************************************
931 * Execute Job at passive level API *
932 ************************************/
933
934typedef VOID (*JOB_ROUTINE) (PVOID pContext);
935
936DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(JOB_ROUTINE pRoutine, PVOID pContext);
937
938/*******************************
939 * Ndis Packets processing API *
940 *******************************/
941
942#ifndef NDIS_PACKET_FIRST_NDIS_BUFFER
943#define NDIS_PACKET_FIRST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Head)
944#endif
945
946#ifndef NDIS_PACKET_LAST_NDIS_BUFFER
947#define NDIS_PACKET_LAST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Tail)
948#endif
949
950#ifndef NDIS_PACKET_VALID_COUNTS
951#define NDIS_PACKET_VALID_COUNTS(_Packet) ((_Packet)->Private.ValidCounts)
952#endif
953
954
955DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory);
956
957DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeMem);
958
959#ifdef DEBUG_NETFLT_PACKETS
960#define DBG_CHECK_PACKETS(_p1, _p2) \
961 { \
962 bool _b = vboxNetFltWinMatchPackets(_p1, _p2, -1); \
963 Assert(_b); \
964 }
965
966#define DBG_CHECK_PACKET_AND_SG(_p, _sg) \
967 { \
968 bool _b = vboxNetFltWinMatchPacketAndSG(_p, _sg, -1); \
969 Assert(_b); \
970 }
971
972#define DBG_CHECK_SGS(_sg1, _sg2) \
973 { \
974 bool _b = vboxNetFltWinMatchSGs(_sg1, _sg2, -1); \
975 Assert(_b); \
976 }
977
978#else
979#define DBG_CHECK_PACKETS(_p1, _p2)
980#define DBG_CHECK_PACKET_AND_SG(_p, _sg)
981#define DBG_CHECK_SGS(_sg1, _sg2)
982#endif
983
984/**
985 * Ndis loops back broadcast packets posted to the wire by IntNet
986 * This routine is used in the mechanism of preventing this looping
987 *
988 * @param pAdapt
989 * @param pPacket
990 * @param bOnRecv true is we are receiving the packet from the wire
991 * false otherwise (i.e. the packet is from the host)
992 *
993 * @return true if the packet is a looped back one, false otherwise
994 */
995#ifdef VBOX_LOOPBACK_USEFLAGS
996DECLINLINE(bool) vboxNetFltWinIsLoopedBackPacket(PNDIS_PACKET pPacket)
997{
998 return (NdisGetPacketFlags(pPacket) & g_fPacketIsLoopedBack) == g_fPacketIsLoopedBack;
999}
1000#endif
1001
1002/**************************************************************
1003 * utility methofs for ndis packet creation/initialization *
1004 **************************************************************/
1005
1006#define VBOXNETFLT_OOB_INIT(_p) \
1007 { \
1008 NdisZeroMemory(NDIS_OOB_DATA_FROM_PACKET(_p), sizeof(NDIS_PACKET_OOB_DATA)); \
1009 NDIS_SET_PACKET_HEADER_SIZE(_p, ETH_HEADER_SIZE); \
1010 }
1011
1012#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
1013
1014DECLINLINE(NDIS_STATUS) vboxNetFltWinCopyPacketInfoOnRecv(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
1015{
1016 NDIS_STATUS fStatus;
1017
1018 /*
1019 * Get the original packet (it could be the same packet as the one
1020 * received or a different one based on the number of layered miniports
1021 * below) and set it on the indicated packet so the OOB data is visible
1022 * correctly to protocols above us.
1023 */
1024 NDIS_SET_ORIGINAL_PACKET(pDstPacket, NDIS_GET_ORIGINAL_PACKET(pSrcPacket));
1025
1026 /*
1027 * Set Packet Flags
1028 */
1029 NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
1030
1031 fStatus = NDIS_GET_PACKET_STATUS(pSrcPacket);
1032
1033 NDIS_SET_PACKET_STATUS(pDstPacket, fStatus);
1034 NDIS_SET_PACKET_HEADER_SIZE(pDstPacket, NDIS_GET_PACKET_HEADER_SIZE(pSrcPacket));
1035
1036 return fStatus;
1037}
1038
1039DECLINLINE(void) vboxNetFltWinCopyPacketInfoOnSend(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
1040{
1041 PVOID pMediaSpecificInfo = NULL;
1042 UINT fMediaSpecificInfoSize = 0;
1043
1044 NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
1045
1046#ifdef WIN9X
1047 /*
1048 * Work around the fact that NDIS does not initialize this
1049 * to FALSE on Win9x.
1050 */
1051 NDIS_PACKET_VALID_COUNTS(pDstPacket) = FALSE;
1052#endif /* WIN9X */
1053
1054 /*
1055 * Copy the OOB data from the original packet to the new
1056 * packet.
1057 */
1058 NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(pDstPacket),
1059 NDIS_OOB_DATA_FROM_PACKET(pSrcPacket),
1060 sizeof(NDIS_PACKET_OOB_DATA));
1061 /*
1062 * Copy relevant parts of the per packet info into the new packet
1063 */
1064#ifndef WIN9X
1065 NdisIMCopySendPerPacketInfo(pDstPacket, pSrcPacket);
1066#endif
1067
1068 /*
1069 * Copy the Media specific information
1070 */
1071 NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(pSrcPacket,
1072 &pMediaSpecificInfo,
1073 &fMediaSpecificInfoSize);
1074
1075 if (pMediaSpecificInfo || fMediaSpecificInfoSize)
1076 {
1077 NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(pDstPacket,
1078 pMediaSpecificInfo,
1079 fMediaSpecificInfoSize);
1080 }
1081}
1082
1083DECLHIDDEN(NDIS_STATUS)
1084vboxNetFltWinPrepareSendPacket(
1085 IN PADAPT pAdapt,
1086 IN PNDIS_PACKET pPacket,
1087 OUT PNDIS_PACKET *ppMyPacket
1088 /*, IN bool bNetFltActive*/
1089 );
1090
1091
1092DECLHIDDEN(NDIS_STATUS)
1093vboxNetFltWinPrepareRecvPacket(
1094 IN PADAPT pAdapt,
1095 IN PNDIS_PACKET pPacket,
1096 OUT PNDIS_PACKET *ppMyPacket,
1097 IN bool bDpr
1098 );
1099#endif
1100
1101DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis);
1102
1103#define MACS_EQUAL(_m1, _m2) \
1104 ((_m1).au16[0] == (_m2).au16[0] \
1105 && (_m1).au16[1] == (_m2).au16[1] \
1106 && (_m1).au16[2] == (_m2).au16[2])
1107
1108
1109DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOnUnbind);
1110DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING pSrc);
1111
1112
1113/**
1114 * Sets the enmState member atomically.
1115 *
1116 * Used for all updates.
1117 *
1118 * @param pThis The instance.
1119 * @param enmNewState The new value.
1120 */
1121DECLINLINE(void) vboxNetFltWinSetAdaptState(PADAPT pAdapt, VBOXADAPTSTATE enmNewState)
1122{
1123 ASMAtomicWriteU32((uint32_t volatile *)&pAdapt->enmState, enmNewState);
1124}
1125
1126/**
1127 * Gets the enmState member atomically.
1128 *
1129 * Used for all reads.
1130 *
1131 * @returns The enmState value.
1132 * @param pThis The instance.
1133 */
1134DECLINLINE(VBOXADAPTSTATE) vboxNetFltWinGetAdaptState(PADAPT pAdapt)
1135{
1136 return (VBOXADAPTSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pAdapt->enmState);
1137}
1138
1139
1140#ifndef VBOXNETADP
1141# define VBOXNETFLT_PROMISCUOUS_SUPPORTED(_pAdapt) \
1142 (!PADAPT_2_PVBOXNETFLTINS(_pAdapt)->fDisablePromiscuous)
1143// (!((_pAdapt)->PhMedium == NdisPhysicalMediumWirelessWan \
1144// || (_pAdapt)->PhMedium == NdisPhysicalMediumWirelessLan \
1145// || (_pAdapt)->PhMedium == NdisPhysicalMediumNative802_11 \
1146// || (_pAdapt)->PhMedium == NdisPhysicalMediumBluetooth \
1147// /*|| (_pAdapt)->PhMedium == NdisPhysicalMediumWiMax */ \
1148// ))
1149#else
1150# define STATISTIC_INCREASE(_s) ASMAtomicIncU32((uint32_t volatile *)&(_s));
1151
1152DECLHIDDEN(void) vboxNetFltWinGenerateMACAddress(RTMAC *pMac);
1153DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
1154DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
1155
1156#endif
1157#endif
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