VirtualBox

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

Last change on this file since 29826 was 29643, checked in by vboxsync, 14 years ago

netflt/win: always set no-loopback flag for intnet->wire packets to prevent ndis misbehave

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