VirtualBox

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

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

netflt/win: fix packet loss caused by packet status not being reset

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