VirtualBox

source: vbox/trunk/include/VBox/intnet.h@ 28231

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

intnet,VBoxNetFlt-linux: Added INTNETTRUNKSWPORT::pfnPreRecv for doing filtering and switching in difficult contexts. It currently returns broadcast all the time, but that will be addressed before long.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.1 KB
Line 
1/** @file
2 * INTNET - Internal Networking. (DEV,++)
3 */
4
5/*
6 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 *
25 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___VBox_intnet_h
31#define ___VBox_intnet_h
32
33#include <VBox/types.h>
34#include <VBox/stam.h>
35#include <VBox/sup.h>
36#include <iprt/assert.h>
37#include <iprt/asm.h>
38
39RT_C_DECLS_BEGIN
40
41
42/** Pointer to an internal network ring-0 instance. */
43typedef struct INTNET *PINTNET;
44
45/**
46 * Generic two-sided ring buffer.
47 *
48 * The deal is that there is exactly one writer and one reader.
49 * When offRead equals offWrite the buffer is empty. In the other
50 * extreme the writer will not use the last free byte in the buffer.
51 */
52typedef struct INTNETRINGBUF
53{
54 /** The offset from this structure to the start of the buffer. */
55 uint32_t offStart;
56 /** The offset from this structure to the end of the buffer. (exclusive). */
57 uint32_t offEnd;
58 /** The current read offset. */
59 uint32_t volatile offReadX;
60 /** Alignment. */
61 uint32_t u32Align0;
62
63 /** The committed write offset. */
64 uint32_t volatile offWriteCom;
65 /** Writer internal current write offset.
66 * This is ahead of offWriteCom when buffer space is handed to a third party for
67 * data gathering. offWriteCom will be assigned this value by the writer then
68 * the frame is ready. */
69 uint32_t volatile offWriteInt;
70 /** The number of bytes written (not counting overflows). */
71 STAMCOUNTER cbStatWritten;
72 /** The number of frames written (not counting overflows). */
73 STAMCOUNTER cStatFrames;
74 /** The number of overflows. */
75 STAMCOUNTER cOverflows;
76} INTNETRINGBUF;
77AssertCompileSize(INTNETRINGBUF, 48);
78/** Pointer to a ring buffer. */
79typedef INTNETRINGBUF *PINTNETRINGBUF;
80
81/** The alignment of a ring buffer. */
82#define INTNETRINGBUF_ALIGNMENT sizeof(INTNETHDR)
83
84/**
85 * Asserts the sanity of the specified INTNETRINGBUF structure.
86 */
87#define INTNETRINGBUF_ASSERT_SANITY(pRingBuf) \
88 do \
89 { \
90 AssertPtr(pRingBuf); \
91 { \
92 uint32_t const offWriteCom = (pRingBuf)->offWriteCom; \
93 uint32_t const offRead = (pRingBuf)->offReadX; \
94 uint32_t const offWriteInt = (pRingBuf)->offWriteInt; \
95 \
96 AssertMsg(offWriteCom == RT_ALIGN_32(offWriteCom, INTNETHDR_ALIGNMENT), ("%#x\n", offWriteCom)); \
97 AssertMsg(offWriteCom >= (pRingBuf)->offStart, ("%#x %#x\n", offWriteCom, (pRingBuf)->offStart)); \
98 AssertMsg(offWriteCom < (pRingBuf)->offEnd, ("%#x %#x\n", offWriteCom, (pRingBuf)->offEnd)); \
99 \
100 AssertMsg(offRead == RT_ALIGN_32(offRead, INTNETHDR_ALIGNMENT), ("%#x\n", offRead)); \
101 AssertMsg(offRead >= (pRingBuf)->offStart, ("%#x %#x\n", offRead, (pRingBuf)->offStart)); \
102 AssertMsg(offRead < (pRingBuf)->offEnd, ("%#x %#x\n", offRead, (pRingBuf)->offEnd)); \
103 \
104 AssertMsg(offWriteInt == RT_ALIGN_32(offWriteInt, INTNETHDR_ALIGNMENT), ("%#x\n", offWriteInt)); \
105 AssertMsg(offWriteInt >= (pRingBuf)->offStart, ("%#x %#x\n", offWriteInt, (pRingBuf)->offStart)); \
106 AssertMsg(offWriteInt < (pRingBuf)->offEnd, ("%#x %#x\n", offWriteInt, (pRingBuf)->offEnd)); \
107 AssertMsg( offRead <= offWriteCom \
108 ? offWriteCom <= offWriteInt || offWriteInt < offRead \
109 : offWriteCom <= offWriteInt, \
110 ("W=%#x W'=%#x R=%#x\n", offWriteCom, offWriteInt, offRead)); \
111 } \
112 } while (0)
113
114
115
116/**
117 * A interface buffer.
118 */
119typedef struct INTNETBUF
120{
121 /** Magic number (INTNETBUF_MAGIC). */
122 uint32_t u32Magic;
123 /** The size of the entire buffer. */
124 uint32_t cbBuf;
125 /** The size of the send area. */
126 uint32_t cbSend;
127 /** The size of the receive area. */
128 uint32_t cbRecv;
129 /** The receive buffer. */
130 INTNETRINGBUF Recv;
131 /** The send buffer. */
132 INTNETRINGBUF Send;
133 /** Number of times yields help solve an overflow. */
134 STAMCOUNTER cStatYieldsOk;
135 /** Number of times yields didn't help solve an overflow. */
136 STAMCOUNTER cStatYieldsNok;
137 /** Number of lost packets due to overflows. */
138 STAMCOUNTER cStatLost;
139 /** Number of bad frames (both rings). */
140 STAMCOUNTER cStatBadFrames;
141 /** Reserved for future use. */
142 STAMCOUNTER aStatReserved[2];
143} INTNETBUF;
144AssertCompileSize(INTNETBUF, 160);
145AssertCompileMemberOffset(INTNETBUF, Recv, 16);
146AssertCompileMemberOffset(INTNETBUF, Send, 64);
147
148/** Pointer to an interface buffer. */
149typedef INTNETBUF *PINTNETBUF;
150/** Pointer to a const interface buffer. */
151typedef INTNETBUF const *PCINTNETBUF;
152
153/** Magic number for INTNETBUF::u32Magic (Sir William Gerald Golding). */
154#define INTNETBUF_MAGIC UINT32_C(0x19110919)
155
156/**
157 * Asserts the sanity of the specified INTNETBUF structure.
158 */
159#define INTNETBUF_ASSERT_SANITY(pBuf) \
160 do \
161 { \
162 AssertPtr(pBuf); \
163 Assert((pBuf)->u32Magic == INTNETBUF_MAGIC); \
164 { \
165 uint32_t const offRecvStart = (pBuf)->Recv.offStart + RT_OFFSETOF(INTNETBUF, Recv); \
166 uint32_t const offRecvEnd = (pBuf)->Recv.offStart + RT_OFFSETOF(INTNETBUF, Recv); \
167 uint32_t const offSendStart = (pBuf)->Send.offStart + RT_OFFSETOF(INTNETBUF, Send); \
168 uint32_t const offSendEnd = (pBuf)->Send.offStart + RT_OFFSETOF(INTNETBUF, Send); \
169 \
170 Assert(offRecvEnd > offRecvStart); \
171 Assert(offRecvEnd - offRecvStart == (pBuf)->cbRecv); \
172 Assert(offRecvStart == sizeof(INTNETBUF)); \
173 \
174 Assert(offSendEnd > offSendStart); \
175 Assert(offSendEnd - offSendStart == (pBuf)->cbSend); \
176 Assert(pffSendEnd <= (pBuf)->cbBuf); \
177 \
178 Assert(offSendStart == offRecvEnd); \
179 } \
180 } while (0)
181
182
183/** Internal networking interface handle. */
184typedef uint32_t INTNETIFHANDLE;
185/** Pointer to an internal networking interface handle. */
186typedef INTNETIFHANDLE *PINTNETIFHANDLE;
187
188/** Or mask to obscure the handle index. */
189#define INTNET_HANDLE_MAGIC 0x88880000
190/** Mask to extract the handle index. */
191#define INTNET_HANDLE_INDEX_MASK 0xffff
192/** The maximum number of handles (exclusive) */
193#define INTNET_HANDLE_MAX 0xffff
194/** Invalid handle. */
195#define INTNET_HANDLE_INVALID (0)
196
197
198/**
199 * The frame header.
200 *
201 * The header is intentionally 8 bytes long. It will always
202 * start at an 8 byte aligned address. Assuming that the buffer
203 * size is a multiple of 8 bytes, that means that we can guarantee
204 * that the entire header is contiguous in both virtual and physical
205 * memory.
206 */
207typedef struct INTNETHDR
208{
209 /** Header type. This is currently serving as a magic, it
210 * can be extended later to encode special command frames and stuff. */
211 uint16_t u16Type;
212 /** The size of the frame. */
213 uint16_t cbFrame;
214 /** The offset from the start of this header to where the actual frame starts.
215 * This is used to keep the frame it self continguous in virtual memory and
216 * thereby both simplify access as well as the descriptor. */
217 int32_t offFrame;
218} INTNETHDR;
219AssertCompileSize(INTNETHDR, 8);
220AssertCompileSizeAlignment(INTNETBUF, sizeof(INTNETHDR));
221/** Pointer to a frame header.*/
222typedef INTNETHDR *PINTNETHDR;
223/** Pointer to a const frame header.*/
224typedef INTNETHDR const *PCINTNETHDR;
225
226/** The alignment of a frame header. */
227#define INTNETHDR_ALIGNMENT sizeof(INTNETHDR)
228AssertCompile(sizeof(INTNETHDR) == INTNETHDR_ALIGNMENT);
229AssertCompile(INTNETHDR_ALIGNMENT <= INTNETRINGBUF_ALIGNMENT);
230
231/** @name Frame types (INTNETHDR::u16Type).
232 * @{ */
233/** Normal frames. */
234#define INTNETHDR_TYPE_FRAME 0x2442
235/** Padding frames. */
236#define INTNETHDR_TYPE_PADDING 0x3553
237/** Generic segment offload frames.
238 * The frame starts with a PDMNETWORKGSO structure which is followed by the
239 * header template and data. */
240#define INTNETHDR_TYPE_GSO 0x4664
241AssertCompileSize(PDMNETWORKGSO, 8);
242/** @} */
243
244/**
245 * Asserts the sanity of the specified INTNETHDR.
246 */
247#define INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf) \
248 do \
249 { \
250 AssertPtr(pHdr); \
251 Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); \
252 Assert( (pHdr)->u16Type == INTNETHDR_TYPE_FRAME \
253 || (pHdr)->u16Type == INTNETHDR_TYPE_GSO \
254 || (pHdr)->u16Type == INTNETHDR_TYPE_PADDING); \
255 { \
256 uintptr_t const offHdr = (uintptr_t)pHdr - (uintptr_t)pRingBuf; \
257 uintptr_t const offFrame = offHdr + (pHdr)->offFrame; \
258 \
259 Assert(offHdr >= (pRingBuf)->offStart); \
260 Assert(offHdr < (pRingBuf)->offEnd); \
261 \
262 /* could do more thorough work here... later, perhaps. */ \
263 Assert(offFrame >= (pRingBuf)->offStart); \
264 Assert(offFrame < (pRingBuf)->offEnd); \
265 } \
266 } while (0)
267
268
269/**
270 * Scatter / Gather segment (internal networking).
271 */
272typedef struct INTNETSEG
273{
274 /** The physical address. NIL_RTHCPHYS is not set. */
275 RTHCPHYS Phys;
276 /** Pointer to the segment data. */
277 void *pv;
278 /** The segment size. */
279 uint32_t cb;
280} INTNETSEG;
281/** Pointer to a internal networking frame segment. */
282typedef INTNETSEG *PINTNETSEG;
283/** Pointer to a internal networking frame segment. */
284typedef INTNETSEG const *PCINTNETSEG;
285
286
287/**
288 * Scatter / Gather list (internal networking).
289 *
290 * This is used when communicating with the trunk port.
291 */
292typedef struct INTNETSG
293{
294 /** Owner data, don't touch! */
295 void *pvOwnerData;
296 /** User data. */
297 void *pvUserData;
298 /** User data 2 in case anyone needs it. */
299 void *pvUserData2;
300 /** GSO context information, set the type to invalid if not relevant. */
301 PDMNETWORKGSO GsoCtx;
302 /** The total length of the scatter gather list. */
303 uint32_t cbTotal;
304 /** The number of users (references).
305 * This is used by the SGRelease code to decide when it can be freed. */
306 uint16_t volatile cUsers;
307 /** Flags, see INTNETSG_FLAGS_* */
308 uint16_t volatile fFlags;
309#if ARCH_BITS == 64
310 /** Alignment padding. */
311 uint16_t uPadding;
312#endif
313 /** The number of segments allocated. */
314 uint16_t cSegsAlloc;
315 /** The number of segments actually used. */
316 uint16_t cSegsUsed;
317 /** Variable sized list of segments. */
318 INTNETSEG aSegs[1];
319} INTNETSG;
320AssertCompileSizeAlignment(INTNETSG, 8);
321/** Pointer to a scatter / gather list. */
322typedef INTNETSG *PINTNETSG;
323/** Pointer to a const scatter / gather list. */
324typedef INTNETSG const *PCINTNETSG;
325
326/** @name INTNETSG::fFlags definitions.
327 * @{ */
328/** Set if the SG is free. */
329#define INTNETSG_FLAGS_FREE RT_BIT_32(1)
330/** Set if the SG is a temporary one that will become invalid upon return.
331 * Try to finish using it before returning, and if that's not possible copy
332 * to other buffers.
333 * When not set, the callee should always free the SG.
334 * Attempts to free it made by the callee will be quietly ignored. */
335#define INTNETSG_FLAGS_TEMP RT_BIT_32(2)
336/** ARP packet, IPv4 + MAC.
337 * @internal */
338#define INTNETSG_FLAGS_ARP_IPV4 RT_BIT_32(3)
339/** Copied to the temporary buffer.
340 * @internal */
341#define INTNETSG_FLAGS_PKT_CP_IN_TMP RT_BIT_32(4)
342/** @} */
343
344
345/** @name Direction (frame source or destination)
346 * @{ */
347/** To/From the wire. */
348#define INTNETTRUNKDIR_WIRE RT_BIT_32(0)
349/** To/From the host. */
350#define INTNETTRUNKDIR_HOST RT_BIT_32(1)
351/** Mask of valid bits. */
352#define INTNETTRUNKDIR_VALID_MASK UINT32_C(3)
353/** @} */
354
355/**
356 * Switch decisions returned by INTNETTRUNKSWPORT::pfnPreRecv.
357 */
358typedef enum INTNETSWDECISION
359{
360 /** The usual invalid zero value. */
361 INTNETSWDECISION_INVALID = 0,
362 /** Everywhere. */
363 INTNETSWDECISION_BROADCAST,
364 /** Only to the internal network. */
365 INTNETSWDECISION_INTNET,
366 /** Only for the trunk (host/wire). */
367 INTNETSWDECISION_TRUNK,
368 /** The usual 32-bit type expansion. */
369 INTNETSWDECISION_32BIT_HACK = 0x7fffffff
370} INTNETSWDECISION;
371
372
373/** Pointer to the switch side of a trunk port. */
374typedef struct INTNETTRUNKSWPORT *PINTNETTRUNKSWPORT;
375/**
376 * This is the port on the internal network 'switch', i.e.
377 * what the driver is connected to.
378 *
379 * This is only used for the in-kernel trunk connections.
380 */
381typedef struct INTNETTRUNKSWPORT
382{
383 /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
384 uint32_t u32Version;
385
386 /**
387 * Examine the packet and figure out where it is going.
388 *
389 * This method is for making packet switching decisions in contexts where
390 * pfnRecv cannot be called or is no longer applicable. This method can be
391 * called from any context.
392 *
393 * @returns INTNETSWDECISION_BROADCAST, INTNETSWDECISION_INTNET or
394 * INTNETSWDECISION_TRUNK. The source is excluded from broadcast &
395 * trunk, of course.
396 *
397 * @param pSwitchPort Pointer to this structure.
398 * @param pvHdrs Pointer to the packet headers.
399 * @param cbHdrs Size of the packet headers. This must be at least 6
400 * bytes (the destination MAC address), but should if
401 * possibly also include any VLAN tag and network layer
402 * header (wireless mac address sharing).
403 * @param fSrc Where this frame comes from. Only one bit should be
404 * set!
405 *
406 * @remarks Will only grab the switch table spinlock (interrupt safe).
407 */
408 DECLR0CALLBACKMEMBER(INTNETSWDECISION, pfnPreRecv,(PINTNETTRUNKSWPORT pSwitchPort,
409 void const *pvHdrs, size_t cbHdrs, uint32_t fSrc));
410
411 /**
412 * Incoming frame.
413 *
414 * The frame may be modified when the trunk port on the switch is set to share
415 * the mac address of the host when hitting the wire. Currently rames containing
416 * ARP packets are subject to this, later other protocols like NDP/ICMPv6 may
417 * need editing as well when operating in this mode.
418 *
419 * @returns true if we've handled it and it should be dropped.
420 * false if it should hit the wire/host.
421 *
422 * @param pSwitchPort Pointer to this structure.
423 * @param pSG The (scatter /) gather structure for the frame.
424 * This will only be use during the call, so a temporary one can
425 * be used. The Phys member will not be used.
426 * @param fSrc Where this frame comes from. Only one bit should be set!
427 *
428 * @remarks Will grab the network semaphore.
429 *
430 * @remarks NAT and TAP will use this interface.
431 *
432 * @todo Do any of the host require notification before frame modifications? If so,
433 * we'll add a callback to INTNETTRUNKIFPORT for this (pfnSGModifying) and
434 * a SG flag.
435 */
436 DECLR0CALLBACKMEMBER(bool, pfnRecv,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG, uint32_t fSrc));
437
438 /**
439 * Retain a SG.
440 *
441 * @param pSwitchPort Pointer to this structure.
442 * @param pSG Pointer to the (scatter /) gather structure.
443 *
444 * @remarks Will not grab any locks.
445 */
446 DECLR0CALLBACKMEMBER(void, pfnSGRetain,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
447
448 /**
449 * Release a SG.
450 *
451 * This is called by the pfnXmit code when done with a SG. This may safe
452 * be done in an asynchronous manner.
453 *
454 * @param pSwitchPort Pointer to this structure.
455 * @param pSG Pointer to the (scatter /) gather structure.
456 *
457 * @remarks Will grab the network semaphore.
458 */
459 DECLR0CALLBACKMEMBER(void, pfnSGRelease,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
460
461 /**
462 * Selects whether outgoing SGs should have their physical address set.
463 *
464 * By enabling physical addresses in the scatter / gather segments it should
465 * be possible to save some unnecessary address translation and memory locking
466 * in the network stack. (Internal networking knows the physical address for
467 * all the INTNETBUF data and that it's locked memory.) There is a negative
468 * side effects though, frames that crosses page boundraries will require
469 * multiple scather / gather segments.
470 *
471 * @returns The old setting.
472 *
473 * @param pSwitchPort Pointer to this structure.
474 * @param fEnable Whether to enable or disable it.
475 *
476 * @remarks Will grab the network semaphore.
477 */
478 DECLR0CALLBACKMEMBER(bool, pfnSetSGPhys,(PINTNETTRUNKSWPORT pSwitchPort, bool fEnable));
479
480 /**
481 * Reports the GSO capabilities of the host, wire or both.
482 *
483 * This is supposed to be used only when creating, connecting or reconnecting
484 * the trunk. It is assumed that the GSO capabilities are kind of static the
485 * rest of the time.
486 *
487 * @param pSwitchPort Pointer to this structure.
488 * @param fGsoCapabilities The GSO capability bit mask. The bits
489 * corresponds to the GSO type with the same value.
490 * @param fDst The destination mask (INTNETTRUNKDIR_XXX).
491 *
492 * @remarks Will to take any locks.
493 */
494 DECLR0CALLBACKMEMBER(void, pfnReportGsoCapabilities,(PINTNETTRUNKSWPORT pSwitchPort, uint32_t fGsoCapabilities, uint32_t fDst));
495
496 /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
497 uint32_t u32VersionEnd;
498} INTNETTRUNKSWPORT;
499
500/** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
501#define INTNETTRUNKSWPORT_VERSION UINT32_C(0xA2CDf001)
502
503
504/** Pointer to the interface side of a trunk port. */
505typedef struct INTNETTRUNKIFPORT *PINTNETTRUNKIFPORT;
506/**
507 * This is the port on the trunk interface, i.e. the driver
508 * side which the internal network is connected to.
509 *
510 * This is only used for the in-kernel trunk connections.
511 *
512 * @remarks The internal network side is responsible for serializing all calls
513 * to this interface. This is (assumed) to be implemented using a lock
514 * that is only ever taken before a call to this interface. The lock
515 * is referred to as the out-bound trunk port lock.
516 */
517typedef struct INTNETTRUNKIFPORT
518{
519 /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
520 uint32_t u32Version;
521
522 /**
523 * Retain the object.
524 *
525 * It will normally be called while owning the internal network semaphore.
526 *
527 * @param pIfPort Pointer to this structure.
528 *
529 * @remarks The caller may own any locks or none at all, we don't care.
530 */
531 DECLR0CALLBACKMEMBER(void, pfnRetain,(PINTNETTRUNKIFPORT pIfPort));
532
533 /**
534 * Releases the object.
535 *
536 * This must be called for every pfnRetain call.
537 *
538 *
539 * @param pIfPort Pointer to this structure.
540 *
541 * @remarks Only the out-bound trunk port lock, unless the caller is certain the
542 * call is not going to cause destruction (wont happen).
543 */
544 DECLR0CALLBACKMEMBER(void, pfnRelease,(PINTNETTRUNKIFPORT pIfPort));
545
546 /**
547 * Disconnect from the switch and release the object.
548 *
549 * The is the counter action of the
550 * INTNETTRUNKNETFLTFACTORY::pfnCreateAndConnect method.
551 *
552 * @param pIfPort Pointer to this structure.
553 *
554 * @remarks Called holding the out-bound trunk port lock.
555 */
556 DECLR0CALLBACKMEMBER(void, pfnDisconnectAndRelease,(PINTNETTRUNKIFPORT pIfPort));
557
558 /**
559 * Changes the active state of the interface.
560 *
561 * The interface is created in the suspended (non-active) state and then activated
562 * when the VM/network is started. It may be suspended and re-activated later
563 * for various reasons. It will finally be suspended again before disconnecting
564 * the interface from the internal network, however, this might be done immediately
565 * before disconnecting and may leave an incoming frame waiting on the internal network
566 * semaphore. So, after the final suspend a pfnWaitForIdle is always called to make sure
567 * the interface is idle before pfnDisconnectAndRelease is called.
568 *
569 * A typical operation to performed by this method is to enable/disable promiscuous
570 * mode on the host network interface. (This is the reason we cannot call this when
571 * owning any semaphores.)
572 *
573 * @returns The previous state.
574 *
575 * @param pIfPort Pointer to this structure.
576 * @param fActive True if the new state is 'active', false if the new state is 'suspended'.
577 *
578 * @remarks Called holding the out-bound trunk port lock.
579 */
580 DECLR0CALLBACKMEMBER(bool, pfnSetActive,(PINTNETTRUNKIFPORT pIfPort, bool fActive));
581
582 /**
583 * Waits for the interface to become idle.
584 *
585 * This method must be called before disconnecting and releasing the
586 * object in order to prevent racing incoming/outgoing frames and device
587 * enabling/disabling.
588 *
589 * @returns IPRT status code (see RTSemEventWait).
590 * @param pIfPort Pointer to this structure.
591 * @param cMillies The number of milliseconds to wait. 0 means
592 * no waiting at all. Use RT_INDEFINITE_WAIT for
593 * an indefinite wait.
594 *
595 * @remarks Called holding the out-bound trunk port lock.
596 */
597 DECLR0CALLBACKMEMBER(int, pfnWaitForIdle,(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies));
598
599 /**
600 * Gets the MAC address of the host network interface that we're attached to.
601 *
602 * @param pIfPort Pointer to this structure.
603 * @param pMac Where to store the host MAC address.
604 *
605 * @remarks Called while owning the network and the out-bound trunk port semaphores.
606 */
607 DECLR0CALLBACKMEMBER(void, pfnGetMacAddress,(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac));
608
609 /**
610 * Tests if the mac address belongs to any of the host NICs
611 * and should take the host route.
612 *
613 * @returns true / false.
614 *
615 * @param pIfPort Pointer to this structure.
616 * @param pMac Pointer to the mac address.
617 *
618 * @remarks Called while owning the network and the out-bound trunk port semaphores.
619 *
620 * @remarks TAP and NAT will compare with their own MAC address and let all their
621 * traffic take the host direction.
622 *
623 * @remarks This didn't quiet work out the way it should... perhaps obsolete this
624 * with pfnGetHostMac?
625 */
626 DECLR0CALLBACKMEMBER(bool, pfnIsHostMac,(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac));
627
628 /**
629 * Tests whether the host is operating the interface is promiscuous mode.
630 *
631 * The default behavior of the internal networking 'switch' is to 'autodetect'
632 * promiscuous mode on the trunk port, which is when this method is used.
633 * For security reasons this default may of course be overridden so that the
634 * host cannot sniff at what's going on.
635 *
636 * Note that this differs from operating the trunk port on the switch in
637 * 'promiscuous' mode, because that relates to the bits going to the wire.
638 *
639 * @returns true / false.
640 *
641 * @param pIfPort Pointer to this structure.
642 *
643 * @remarks Usuaully called while owning the network and the out-bound trunk
644 * port semaphores.
645 */
646 DECLR0CALLBACKMEMBER(bool, pfnIsPromiscuous,(PINTNETTRUNKIFPORT pIfPort));
647
648 /**
649 * Transmit a frame.
650 *
651 * @return VBox status code. Error generally means we'll drop the frame.
652 * @param pIfPort Pointer to this structure.
653 * @param pSG Pointer to the (scatter /) gather structure for the frame.
654 * This may or may not be a temporary buffer. If it's temporary
655 * the transmit operation(s) then it's required to make a copy
656 * of the frame unless it can be transmitted synchronously.
657 * @param fDst The destination mask. At least one bit will be set.
658 *
659 * @remarks Called holding the out-bound trunk port lock.
660 *
661 * @remarks TAP and NAT will use this interface for all their traffic, see pfnIsHostMac.
662 *
663 * @todo
664 */
665 DECLR0CALLBACKMEMBER(int, pfnXmit,(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst));
666
667 /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
668 uint32_t u32VersionEnd;
669} INTNETTRUNKIFPORT;
670
671/** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
672#define INTNETTRUNKIFPORT_VERSION UINT32_C(0xA2CDe001)
673
674
675/**
676 * The component factory interface for create a network
677 * interface filter (like VBoxNetFlt).
678 */
679typedef struct INTNETTRUNKFACTORY
680{
681 /**
682 * Release this factory.
683 *
684 * SUPR0ComponentQueryFactory (SUPDRVFACTORY::pfnQueryFactoryInterface to be precise)
685 * will retain a reference to the factory and the caller has to call this method to
686 * release it once the pfnCreateAndConnect call(s) has been done.
687 *
688 * @param pIfFactory Pointer to this structure.
689 */
690 DECLR0CALLBACKMEMBER(void, pfnRelease,(struct INTNETTRUNKFACTORY *pIfFactory));
691
692 /**
693 * Create an instance for the specfied host interface and connects it
694 * to the internal network trunk port.
695 *
696 * The initial interface active state is false (suspended).
697 *
698 *
699 * @returns VBox status code.
700 * @retval VINF_SUCCESS and *ppIfPort set on success.
701 * @retval VERR_INTNET_FLT_IF_NOT_FOUND if the interface was not found.
702 * @retval VERR_INTNET_FLT_IF_BUSY if the interface is already connected.
703 * @retval VERR_INTNET_FLT_IF_FAILED if it failed for some other reason.
704 *
705 * @param pIfFactory Pointer to this structure.
706 * @param pszName The interface name (OS specific).
707 * @param pSwitchPort Pointer to the port interface on the switch that
708 * this interface is being connected to.
709 * @param fFlags Creation flags, see below.
710 * @param ppIfPort Where to store the pointer to the interface port
711 * on success.
712 *
713 * @remarks Called while owning the network and the out-bound trunk semaphores.
714 */
715 DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(struct INTNETTRUNKFACTORY *pIfFactory, const char *pszName,
716 PINTNETTRUNKSWPORT pSwitchPort, uint32_t fFlags,
717 PINTNETTRUNKIFPORT *ppIfPort));
718} INTNETTRUNKFACTORY;
719/** Pointer to the trunk factory. */
720typedef INTNETTRUNKFACTORY *PINTNETTRUNKFACTORY;
721
722/** The UUID for the (current) trunk factory. (case sensitive) */
723#define INTNETTRUNKFACTORY_UUID_STR "b010afb2-cb4c-44b7-9da9-1e113cfcd47c"
724
725/** @name INTNETTRUNKFACTORY::pfnCreateAndConnect flags.
726 * @{ */
727/** Don't put the filtered interface in promiscuous mode.
728 * This is used for wireless interface since these can misbehave if
729 * we try to put them in promiscuous mode. (Wireless interfaces are
730 * normally bridged on level 3 instead of level 2.) */
731#define INTNETTRUNKFACTORY_FLAG_NO_PROMISC RT_BIT_32(0)
732/** @} */
733
734
735/**
736 * The trunk connection type.
737 *
738 * Used by INTNETR0Open and assoicated interfaces.
739 */
740typedef enum INTNETTRUNKTYPE
741{
742 /** Invalid trunk type. */
743 kIntNetTrunkType_Invalid = 0,
744 /** No trunk connection. */
745 kIntNetTrunkType_None,
746 /** We don't care which kind of trunk connection if the network exists,
747 * if it doesn't exist create it without a connection. */
748 kIntNetTrunkType_WhateverNone,
749 /** VirtualBox host network interface filter driver.
750 * The trunk name is the name of the host network interface. */
751 kIntNetTrunkType_NetFlt,
752 /** VirtualBox adapter host driver. */
753 kIntNetTrunkType_NetAdp,
754 /** Nat service (ring-0). */
755 kIntNetTrunkType_SrvNat,
756 /** The end of valid types. */
757 kIntNetTrunkType_End,
758 /** The usual 32-bit hack. */
759 kIntNetTrunkType_32bitHack = 0x7fffffff
760} INTNETTRUNKTYPE;
761
762/** @name INTNETR0Open flags.
763 * @{ */
764/** Share the MAC address with the host when sending something to the wire via the trunk.
765 * This is typically used when the trunk is a NetFlt for a wireless interface. */
766#define INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE RT_BIT_32(0)
767/** Whether new participants should be subjected to access check or not. */
768#define INTNET_OPEN_FLAGS_PUBLIC RT_BIT_32(1)
769/** Ignore any requests for promiscuous mode. */
770#define INTNET_OPEN_FLAGS_IGNORE_PROMISC RT_BIT_32(2)
771/** Ignore any requests for promiscuous mode, quietly applied/ignored on open. */
772#define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC RT_BIT_32(3)
773/** Ignore any requests for promiscuous mode on the trunk wire connection. */
774#define INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_WIRE RT_BIT_32(4)
775/** Ignore any requests for promiscuous mode on the trunk wire connection, quietly applied/ignored on open. */
776#define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_WIRE RT_BIT_32(5)
777/** Ignore any requests for promiscuous mode on the trunk host connection. */
778#define INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_HOST RT_BIT_32(6)
779/** Ignore any requests for promiscuous mode on the trunk host connection, quietly applied/ignored on open. */
780#define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_HOST RT_BIT_32(7)
781/** The mask of flags which causes flag incompatibilities. */
782#define INTNET_OPEN_FLAGS_COMPATIBILITY_XOR_MASK (RT_BIT_32(0) | RT_BIT_32(1) | RT_BIT_32(2) | RT_BIT_32(4) | RT_BIT_32(6))
783/** The mask of flags is always ORed in, even on open. (the quiet stuff) */
784#define INTNET_OPEN_FLAGS_SECURITY_OR_MASK (RT_BIT_32(3) | RT_BIT_32(5) | RT_BIT_32(7))
785/** The mask of valid flags. */
786#define INTNET_OPEN_FLAGS_MASK UINT32_C(0x000000ff)
787/** @} */
788
789/** The maximum length of a network name. */
790#define INTNET_MAX_NETWORK_NAME 128
791
792/** The maximum length of a trunk name. */
793#define INTNET_MAX_TRUNK_NAME 64
794
795
796/**
797 * Request buffer for INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN.
798 * @see INTNETR0Open.
799 */
800typedef struct INTNETOPENREQ
801{
802 /** The request header. */
803 SUPVMMR0REQHDR Hdr;
804 /** Alternative to passing the taking the session from the VM handle.
805 * Either use this member or use the VM handle, don't do both. */
806 PSUPDRVSESSION pSession;
807 /** The network name. (input) */
808 char szNetwork[INTNET_MAX_NETWORK_NAME];
809 /** What to connect to the trunk port. (input)
810 * This is specific to the trunk type below. */
811 char szTrunk[INTNET_MAX_TRUNK_NAME];
812 /** The type of trunk link (NAT, Filter, TAP, etc). (input) */
813 INTNETTRUNKTYPE enmTrunkType;
814 /** Flags, see INTNET_OPEN_FLAGS_*. (input) */
815 uint32_t fFlags;
816 /** The size of the send buffer. (input) */
817 uint32_t cbSend;
818 /** The size of the receive buffer. (input) */
819 uint32_t cbRecv;
820 /** The handle to the network interface. (output) */
821 INTNETIFHANDLE hIf;
822} INTNETOPENREQ;
823/** Pointer to an INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN request buffer. */
824typedef INTNETOPENREQ *PINTNETOPENREQ;
825
826INTNETR0DECL(int) INTNETR0OpenReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETOPENREQ pReq);
827
828
829/**
830 * Request buffer for INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE.
831 * @see INTNETR0IfClose.
832 */
833typedef struct INTNETIFCLOSEREQ
834{
835 /** The request header. */
836 SUPVMMR0REQHDR Hdr;
837 /** Alternative to passing the taking the session from the VM handle.
838 * Either use this member or use the VM handle, don't do both. */
839 PSUPDRVSESSION pSession;
840 /** The handle to the network interface. */
841 INTNETIFHANDLE hIf;
842} INTNETIFCLOSEREQ;
843/** Pointer to an INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE request buffer. */
844typedef INTNETIFCLOSEREQ *PINTNETIFCLOSEREQ;
845
846INTNETR0DECL(int) INTNETR0IfCloseReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFCLOSEREQ pReq);
847
848
849/**
850 * Request buffer for INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER.
851 * @see INTNETR0IfGetRing3Buffer.
852 */
853typedef struct INTNETIFGETRING3BUFFERREQ
854{
855 /** The request header. */
856 SUPVMMR0REQHDR Hdr;
857 /** Alternative to passing the taking the session from the VM handle.
858 * Either use this member or use the VM handle, don't do both. */
859 PSUPDRVSESSION pSession;
860 /** Handle to the interface. */
861 INTNETIFHANDLE hIf;
862 /** The pointer to the ring3 buffer. (output) */
863 R3PTRTYPE(PINTNETBUF) pRing3Buf;
864} INTNETIFGETRING3BUFFERREQ;
865/** Pointer to an INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER request buffer. */
866typedef INTNETIFGETRING3BUFFERREQ *PINTNETIFGETRING3BUFFERREQ;
867
868INTNETR0DECL(int) INTNETR0IfGetRing3BufferReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFGETRING3BUFFERREQ pReq);
869
870
871/**
872 * Request buffer for INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE.
873 * @see INTNETR0IfSetPromiscuousMode.
874 */
875typedef struct INTNETIFSETPROMISCUOUSMODEREQ
876{
877 /** The request header. */
878 SUPVMMR0REQHDR Hdr;
879 /** Alternative to passing the taking the session from the VM handle.
880 * Either use this member or use the VM handle, don't do both. */
881 PSUPDRVSESSION pSession;
882 /** Handle to the interface. */
883 INTNETIFHANDLE hIf;
884 /** The new promiscuous mode. */
885 bool fPromiscuous;
886} INTNETIFSETPROMISCUOUSMODEREQ;
887/** Pointer to an INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE request buffer. */
888typedef INTNETIFSETPROMISCUOUSMODEREQ *PINTNETIFSETPROMISCUOUSMODEREQ;
889
890INTNETR0DECL(int) INTNETR0IfSetPromiscuousModeReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETPROMISCUOUSMODEREQ pReq);
891
892
893/**
894 * Request buffer for INTNETR0IfSetMacAddressReq / VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS.
895 * @see INTNETR0IfSetMacAddress.
896 */
897typedef struct INTNETIFSETMACADDRESSREQ
898{
899 /** The request header. */
900 SUPVMMR0REQHDR Hdr;
901 /** Alternative to passing the taking the session from the VM handle.
902 * Either use this member or use the VM handle, don't do both. */
903 PSUPDRVSESSION pSession;
904 /** Handle to the interface. */
905 INTNETIFHANDLE hIf;
906 /** The new MAC address. */
907 RTMAC Mac;
908} INTNETIFSETMACADDRESSREQ;
909/** Pointer to an INTNETR0IfSetMacAddressReq / VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS request buffer. */
910typedef INTNETIFSETMACADDRESSREQ *PINTNETIFSETMACADDRESSREQ;
911
912INTNETR0DECL(int) INTNETR0IfSetMacAddressReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq);
913
914
915/**
916 * Request buffer for INTNETR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE.
917 * @see INTNETR0IfSetActive.
918 */
919typedef struct INTNETIFSETACTIVEREQ
920{
921 /** The request header. */
922 SUPVMMR0REQHDR Hdr;
923 /** Alternative to passing the taking the session from the VM handle.
924 * Either use this member or use the VM handle, don't do both. */
925 PSUPDRVSESSION pSession;
926 /** Handle to the interface. */
927 INTNETIFHANDLE hIf;
928 /** The new state. */
929 bool fActive;
930} INTNETIFSETACTIVEREQ;
931/** Pointer to an INTNETR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE request buffer. */
932typedef INTNETIFSETACTIVEREQ *PINTNETIFSETACTIVEREQ;
933
934INTNETR0DECL(int) INTNETR0IfSetActiveReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq);
935
936
937/**
938 * Request buffer for INTNETR0IfSendReq / VMMR0_DO_INTNET_IF_SEND.
939 * @see INTNETR0IfSend.
940 */
941typedef struct INTNETIFSENDREQ
942{
943 /** The request header. */
944 SUPVMMR0REQHDR Hdr;
945 /** Alternative to passing the taking the session from the VM handle.
946 * Either use this member or use the VM handle, don't do both. */
947 PSUPDRVSESSION pSession;
948 /** Handle to the interface. */
949 INTNETIFHANDLE hIf;
950} INTNETIFSENDREQ;
951/** Pointer to an INTNETR0IfSend() argument package. */
952typedef INTNETIFSENDREQ *PINTNETIFSENDREQ;
953
954INTNETR0DECL(int) INTNETR0IfSendReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSENDREQ pReq);
955
956
957/**
958 * Request buffer for INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT.
959 * @see INTNETR0IfWait.
960 */
961typedef struct INTNETIFWAITREQ
962{
963 /** The request header. */
964 SUPVMMR0REQHDR Hdr;
965 /** Alternative to passing the taking the session from the VM handle.
966 * Either use this member or use the VM handle, don't do both. */
967 PSUPDRVSESSION pSession;
968 /** Handle to the interface. */
969 INTNETIFHANDLE hIf;
970 /** The number of milliseconds to wait. */
971 uint32_t cMillies;
972} INTNETIFWAITREQ;
973/** Pointer to an INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT request buffer. */
974typedef INTNETIFWAITREQ *PINTNETIFWAITREQ;
975
976INTNETR0DECL(int) INTNETR0IfWaitReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFWAITREQ pReq);
977
978
979#if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
980/** @name
981 * @{
982 */
983
984/**
985 * Create an instance of the Ring-0 internal networking service.
986 *
987 * @returns VBox status code.
988 * @param ppIntNet Where to store the instance pointer.
989 */
990INTNETR0DECL(int) INTNETR0Create(PINTNET *ppIntNet);
991
992/**
993 * Destroys an instance of the Ring-0 internal networking service.
994 *
995 * @param pIntNet Pointer to the instance data.
996 */
997INTNETR0DECL(void) INTNETR0Destroy(PINTNET pIntNet);
998
999/**
1000 * Opens a network interface and connects it to the specified network.
1001 *
1002 * @returns VBox status code.
1003 * @param pIntNet The internal network instance.
1004 * @param pSession The session handle.
1005 * @param pszNetwork The network name.
1006 * @param enmTrunkType The trunk type.
1007 * @param pszTrunk The trunk name. Its meaning is specfic to the type.
1008 * @param fFlags Flags, see INTNET_OPEN_FLAGS_*.
1009 * @param fRestrictAccess Whether new participants should be subjected to access check or not.
1010 * @param cbSend The send buffer size.
1011 * @param cbRecv The receive buffer size.
1012 * @param phIf Where to store the handle to the network interface.
1013 */
1014INTNETR0DECL(int) INTNETR0Open(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork,
1015 INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
1016 unsigned cbSend, unsigned cbRecv, PINTNETIFHANDLE phIf);
1017
1018/**
1019 * Close an interface.
1020 *
1021 * @returns VBox status code.
1022 * @param pIntNet The instance handle.
1023 * @param hIf The interface handle.
1024 * @param pSession The caller's session.
1025 */
1026INTNETR0DECL(int) INTNETR0IfClose(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
1027
1028/**
1029 * Gets the ring-0 address of the current buffer.
1030 *
1031 * @returns VBox status code.
1032 * @param pIntNet The instance data.
1033 * @param hIf The interface handle.
1034 * @param pSession The caller's session.
1035 * @param ppRing0Buf Where to store the address of the ring-3 mapping.
1036 */
1037INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF *ppRing0Buf);
1038
1039/**
1040 * Maps the default buffer into ring 3.
1041 *
1042 * @returns VBox status code.
1043 * @param pIntNet The instance data.
1044 * @param hIf The interface handle.
1045 * @param pSession The caller's session.
1046 * @param ppRing3Buf Where to store the address of the ring-3 mapping.
1047 */
1048INTNETR0DECL(int) INTNETR0IfGetRing3Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, R3PTRTYPE(PINTNETBUF) *ppRing3Buf);
1049
1050/**
1051 * Sets the promiscuous mode property of an interface.
1052 *
1053 * @returns VBox status code.
1054 * @param pIntNet The instance handle.
1055 * @param hIf The interface handle.
1056 * @param pSession The caller's session.
1057 * @param fPromiscuous Set if the interface should be in promiscuous mode, clear if not.
1058 */
1059INTNETR0DECL(int) INTNETR0IfSetPromiscuousMode( PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fPromiscuous);
1060INTNETR0DECL(int) INTNETR0IfSetMacAddress( PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PCRTMAC pMac);
1061INTNETR0DECL(int) INTNETR0IfSetActive( PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fActive);
1062
1063/**
1064 * Sends one or more frames.
1065 *
1066 * The function will first the frame which is passed as the optional
1067 * arguments pvFrame and cbFrame. These are optional since it also
1068 * possible to chain together one or more frames in the send buffer
1069 * which the function will process after considering it's arguments.
1070 *
1071 * @returns VBox status code.
1072 * @param pIntNet The instance data.
1073 * @param hIf The interface handle.
1074 * @param pSession The caller's session.
1075 */
1076INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
1077
1078/**
1079 * Wait for the interface to get signaled.
1080 * The interface will be signaled when is put into the receive buffer.
1081 *
1082 * @returns VBox status code.
1083 * @param pIntNet The instance handle.
1084 * @param hIf The interface handle.
1085 * @param pSession The caller's session.
1086 * @param cMillies Number of milliseconds to wait. RT_INDEFINITE_WAIT should be
1087 * used if indefinite wait is desired.
1088 */
1089INTNETR0DECL(int) INTNETR0IfWait(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, uint32_t cMillies);
1090
1091/** @} */
1092#endif /* IN_RING0 */
1093
1094RT_C_DECLS_END
1095
1096#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