VirtualBox

root/trunk/include/VBox/intnet.h

Revision 11157, 36.1 kB (checked in by vboxsync, 4 months ago)

Replaced PDMMAC by RTMAC.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /** @file
2  * INETNET - Internal Networking.
3  */
4
5 /*
6  * Copyright (C) 2006-2007 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
39 __BEGIN_DECLS
40
41
42 /** Pointer to an internal network ring-0 instance. */
43 typedef 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  */
52 typedef struct INTNETRINGBUF
53 {
54     /** The start of the buffer offset relative to the. (inclusive) */
55     uint32_t            offStart;
56     /** The offset to the end of the buffer. (exclusive) */
57     uint32_t            offEnd;
58     /** The current read offset. */
59     uint32_t volatile   offRead;
60     /** The current write offset. */
61     uint32_t volatile   offWrite;
62 } INTNETRINGBUF;
63 /** Pointer to a ring buffer. */
64 typedef INTNETRINGBUF *PINTNETRINGBUF;
65
66 /**
67  * Get the amount of space available for writing.
68  *
69  * @returns Number of available bytes.
70  * @param   pRingBuf        The ring buffer.
71  */
72 DECLINLINE(uint32_t) INTNETRingGetWritable(PINTNETRINGBUF pRingBuf)
73 {
74     return pRingBuf->offRead <= pRingBuf->offWrite
75         ?  pRingBuf->offEnd  - pRingBuf->offWrite + pRingBuf->offRead - pRingBuf->offStart - 1
76         :  pRingBuf->offRead - pRingBuf->offWrite - 1;
77 }
78
79
80 /**
81  * Get the amount of data ready for reading.
82  *
83  * @returns Number of ready bytes.
84  * @param   pRingBuf        The ring buffer.
85  */
86 DECLINLINE(uint32_t) INTNETRingGetReadable(PINTNETRINGBUF pRingBuf)
87 {
88     return pRingBuf->offRead <= pRingBuf->offWrite
89         ?  pRingBuf->offWrite - pRingBuf->offRead
90         :  pRingBuf->offEnd - pRingBuf->offRead + pRingBuf->offWrite - pRingBuf->offStart;
91 }
92
93
94 /**
95  * A interface buffer.
96  */
97 typedef struct INTNETBUF
98 {
99     /** The size of the entire buffer. */
100     uint32_t        cbBuf;
101     /** The size of the send area. */
102     uint32_t        cbSend;
103     /** The size of the receive area. */
104     uint32_t        cbRecv;
105     /** The receive buffer. */
106     INTNETRINGBUF   Recv;
107     /** The send buffer. */
108     INTNETRINGBUF   Send;
109     /** Number of times yields help solve an overflow. */
110     STAMCOUNTER     cStatYieldsOk;
111     /** Number of times yields didn't help solve an overflow. */
112     STAMCOUNTER     cStatYieldsNok;
113     /** Number of lost packets due to overflows. */
114     STAMCOUNTER     cStatLost;
115     /** Number of packets received (not counting lost ones). */
116     STAMCOUNTER     cStatRecvs;
117     /** Number of frame bytes received (not couting lost frames). */
118     STAMCOUNTER     cbStatRecv;
119     /** Number of packets received. */
120     STAMCOUNTER     cStatSends;
121     /** Number of frame bytes sent. */
122     STAMCOUNTER     cbStatSend;
123 } INTNETBUF;
124 /** Pointer to an interface buffer. */
125 typedef INTNETBUF *PINTNETBUF;
126 /** Pointer to a const interface buffer. */
127 typedef INTNETBUF const *PCINTNETBUF;
128
129 /** Internal networking interface handle. */
130 typedef uint32_t    INTNETIFHANDLE;
131 /** Pointer to an internal networking interface handle. */
132 typedef INTNETIFHANDLE *PINTNETIFHANDLE;
133
134 /** Or mask to obscure the handle index. */
135 #define INTNET_HANDLE_MAGIC         0x88880000
136 /** Mask to extract the handle index. */
137 #define INTNET_HANDLE_INDEX_MASK    0xffff
138 /** The maximum number of handles (exclusive) */
139 #define INTNET_HANDLE_MAX           0xffff
140 /** Invalid handle. */
141 #define INTNET_HANDLE_INVALID       (0)
142
143
144 /**
145  * The packet header.
146  *
147  * The header is intentionally 8 bytes long. It will always
148  * start at an 8 byte aligned address. Assuming that the buffer
149  * size is a multiple of 8 bytes, that means that we can guarantee
150  * that the entire header is contiguous in both virtual and physical
151  * memory.
152  */
153 #pragma pack(1)
154 typedef struct INTNETHDR
155 {
156     /** Header type. This is currently serving as a magic, it
157      * can be extended later to encode special command packets and stuff. */
158     uint16_t        u16Type;
159     /** The size of the frame. */
160     uint16_t        cbFrame;
161     /** The offset from the start of this header to where the actual frame starts.
162      * This is used to keep the frame it self continguous in virtual memory and
163      * thereby both simplify reading and   */
164     int32_t         offFrame;
165 } INTNETHDR;
166 #pragma pack()
167 /** Pointer to a packet header.*/
168 typedef INTNETHDR *PINTNETHDR;
169 /** Pointer to a const packet header.*/
170 typedef INTNETHDR const *PCINTNETHDR;
171
172 /** INTNETHDR::u16Type value for normal frames. */
173 #define INTNETHDR_TYPE_FRAME    0x2442
174
175
176 /**
177  * Calculates the pointer to the frame.
178  *
179  * @returns Pointer to the start of the frame.
180  * @param   pHdr        Pointer to the packet header
181  * @param   pBuf        The buffer the header is within. Only used in strict builds.
182  */
183 DECLINLINE(void *) INTNETHdrGetFramePtr(PCINTNETHDR pHdr, PCINTNETBUF pBuf)
184 {
185     uint8_t *pu8 = (uint8_t *)pHdr + pHdr->offFrame;
186 #ifdef VBOX_STRICT
187     const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf;
188     Assert(pHdr->u16Type == INTNETHDR_TYPE_FRAME);
189     Assert(off < pBuf->cbBuf);
190     Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
191 #endif
192     NOREF(pBuf);
193     return pu8;
194 }
195
196
197 /**
198  * Skips to the next (read) frame in the buffer.
199  *
200  * @param   pBuf        The buffer.
201  * @param   pRingBuf    The ring buffer in question.
202  */
203 DECLINLINE(void) INTNETRingSkipFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf)
204 {
205     uint32_t    offRead   = pRingBuf->offRead;
206     PINTNETHDR  pHdr      = (PINTNETHDR)((uint8_t *)pBuf + offRead);
207     Assert(pRingBuf->offRead < pBuf->cbBuf);
208     Assert(pRingBuf->offRead >= pRingBuf->offStart);
209     Assert(pRingBuf->offRead < pRingBuf->offEnd);
210
211     /* skip the frame */
212     offRead += pHdr->offFrame + pHdr->cbFrame;
213     offRead = RT_ALIGN_32(offRead, sizeof(INTNETHDR));
214     Assert(offRead <= pRingBuf->offEnd && offRead >= pRingBuf->offStart);
215     if (offRead >= pRingBuf->offEnd)
216         offRead = pRingBuf->offStart;
217     ASMAtomicXchgU32(&pRingBuf->offRead, offRead);
218 }
219
220
221 /**
222  * Scatter / Gather segment (internal networking).
223  */
224 typedef struct INTNETSEG
225 {
226     /** The physical address. NIL_RTHCPHYS is not set. */
227     RTHCPHYS        Phys;
228     /** Pointer to the segment data. */
229     void           *pv;
230     /** The segment size. */
231     uint32_t        cb;
232 } INTNETSEG;
233 /** Pointer to a internal networking packet segment. */
234 typedef INTNETSEG *PINTNETSEG;
235 /** Pointer to a internal networking packet segment. */
236 typedef INTNETSEG const *PCINTNETSEG;
237
238
239 /**
240  * Scatter / Gather list (internal networking).
241  *
242  * This is used when communicating with the trunk port.
243  */
244 typedef struct INTNETSG
245 {
246     /** Owner data, don't touch! */
247     void           *pvOwnerData;
248     /** User data. */
249     void           *pvUserData;
250     /** User data 2 in case anyone needs it. */
251     void           *pvUserData2;
252     /** The total length of the scatter gather list. */
253     uint32_t        cbTotal;
254     /** The number of users (references).
255      * This is used by the SGRelease code to decide when it can be freed. */
256     uint16_t volatile cUsers;
257     /** Flags, see INTNETSG_FLAGS_* */
258     uint16_t volatile fFlags;
259     /** The number of segments allocated. */
260     uint16_t        cSegsAlloc;
261     /** The number of segments actually used. */
262     uint16_t        cSegsUsed;
263     /** Variable sized list of segments. */
264     INTNETSEG       aSegs[1];
265 } INTNETSG;
266 /** Pointer to a scatter / gather list. */
267 typedef INTNETSG *PINTNETSG;
268 /** Pointer to a const scatter / gather list. */
269 typedef INTNETSG const *PCINTNETSG;
270
271 /** @name INTNETSG::fFlags definitions.
272  * @{ */
273 /** Set if the SG is free. */
274 #define INTNETSG_FLAGS_FREE             RT_BIT_32(1)
275 /** Set if the SG is a temporary one that will become invalid upon return.
276  * Try to finish using it before returning, and if that's not possible copy
277  * to other buffers.
278  * When not set, the callee should always free the SG.
279  * Attempts to free it made by the callee will be quietly ignored. */
280 #define INTNETSG_FLAGS_TEMP             RT_BIT_32(2)
281 /** ARP packet, IPv4 + MAC.
282  * @internal */
283 #define INTNETSG_FLAGS_ARP_IPV4         RT_BIT_32(3)
284 /** Copied to the temporary buffer.
285  * @internal */
286 #define INTNETSG_FLAGS_PKT_CP_IN_TMP    RT_BIT_32(4)
287 /** @} */
288
289
290 /** @name Direction (packet source or destination)
291  * @{ */
292 /** To/From the wire. */
293 #define INTNETTRUNKDIR_WIRE             RT_BIT_32(0)
294 /** To/From the host. */
295 #define INTNETTRUNKDIR_HOST             RT_BIT_32(1)
296 /** Mask of valid bits. */
297 #define INTNETTRUNKDIR_VALID_MASK       UINT32_C(3)
298 /** @} */
299
300
301 /** Pointer to the switch side of a trunk port. */
302 typedef struct INTNETTRUNKSWPORT *PINTNETTRUNKSWPORT;
303 /**
304  * This is the port on the internal network 'switch', i.e.
305  * what the driver is connected to.
306  *
307  * This is only used for the in-kernel trunk connections.
308  */
309 typedef struct INTNETTRUNKSWPORT
310 {
311     /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
312     uint32_t u32Version;
313
314     /**
315      * Selects whether outgoing SGs should have their physical address set.
316      *
317      * By enabling physical addresses in the scatter / gather segments it should
318      * be possible to save some unnecessary address translation and memory locking
319      * in the network stack. (Internal networking knows the physical address for
320      * all the INTNETBUF data and that it's locked memory.) There is a negative
321      * side effects though, frames that crosses page boundraries will require
322      * multiple scather / gather segments.
323      *
324      * @returns The old setting.
325      *
326      * @param   pSwitchPort Pointer to this structure.
327      * @param   fEnable     Whether to enable or disable it.
328      *
329      * @remarks Will grab the network semaphore.
330      */
331     DECLR0CALLBACKMEMBER(bool, pfnSetSGPhys,(PINTNETTRUNKSWPORT pSwitchPort, bool fEnable));
332
333     /**
334      * Incoming frame.
335      *
336      * The frame may be modified when the trunk port on the switch is set to share
337      * the mac address of the host when hitting the wire. Currently rames containing
338      * ARP packets are subject to this, later other protocols like NDP/ICMPv6 may
339      * need editing as well when operating in this mode.
340      *
341      * @returns true if we've handled it and it should be dropped.
342      *          false if it should hit the wire.
343      *
344      * @param   pSwitchPort Pointer to this structure.
345      * @param   pSG         The (scatter /) gather structure for the frame.
346      *                      This will only be use during the call, so a temporary one can
347      *                      be used. The Phys member will not be used.
348      * @param   fSrc        Where this frame comes from. Only one bit should be set!
349      *
350      * @remarks Will grab the network semaphore.
351      *
352      * @remarks NAT and TAP will use this interface.
353      *
354      * @todo    Do any of the host require notification before frame modifications? If so,
355      *          we'll add a callback to INTNETTRUNKIFPORT for this (pfnSGModifying) and
356      *          a SG flag.
357      */
358     DECLR0CALLBACKMEMBER(bool, pfnRecv,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG, uint32_t fSrc));
359
360     /**
361      * Retain a SG.
362      *
363      * @param   pSwitchPort Pointer to this structure.
364      * @param   pSG         Pointer to the (scatter /) gather structure.
365      *
366      * @remarks Will not grab any locks.
367      */
368     DECLR0CALLBACKMEMBER(void, pfnSGRetain,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
369
370     /**
371      * Release a SG.
372      *
373      * This is called by the pfnXmit code when done with a SG. This may safe
374      * be done in an asynchronous manner.
375      *
376      * @param   pSwitchPort Pointer to this structure.
377      * @param   pSG         Pointer to the (scatter /) gather structure.
378      *
379      * @remarks Will grab the network semaphore.
380      */
381     DECLR0CALLBACKMEMBER(void, pfnSGRelease,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
382
383     /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
384     uint32_t u32VersionEnd;
385 } INTNETTRUNKSWPORT;
386
387 /** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
388 #define INTNETTRUNKSWPORT_VERSION   UINT32_C(0xA2CDf001)
389
390
391 /** Pointer to the interface side of a trunk port. */
392 typedef struct INTNETTRUNKIFPORT *PINTNETTRUNKIFPORT;
393 /**
394  * This is the port on the trunk interface, i.e. the driver
395  * side which the internal network is connected to.
396  *
397  * This is only used for the in-kernel trunk connections.
398  *
399  * @remarks The internal network side is responsible for serializing all calls
400  *          to this interface. This is (assumed) to be implemented using a lock
401  *          that is only ever taken before a call to this interface. The lock
402  *          is referred to as the out-bound trunk port lock.
403  */
404 typedef struct INTNETTRUNKIFPORT
405 {
406     /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
407     uint32_t u32Version;
408
409     /**
410      * Retain the object.
411      *
412      * It will normally be called while owning the internal network semaphore.
413      *
414      * @param   pIfPort     Pointer to this structure.
415      *
416      * @remarks The caller may own any locks or none at all, we don't care.
417      */
418     DECLR0CALLBACKMEMBER(void, pfnRetain,(PINTNETTRUNKIFPORT pIfPort));
419
420     /**
421      * Releases the object.
422      *
423      * This must be called for every pfnRetain call.
424      *
425      *
426      * @param   pIfPort     Pointer to this structure.
427      *
428      * @remarks Only the out-bound trunk port lock, unless the caller is certain the
429      *          call is not going to cause destruction (wont happen).
430      */
431     DECLR0CALLBACKMEMBER(void, pfnRelease,(PINTNETTRUNKIFPORT pIfPort));
432
433     /**
434      * Disconnect from the switch and release the object.
435      *
436      * The is the counter action of the
437      * INTNETTRUNKNETFLTFACTORY::pfnCreateAndConnect method.
438      *
439      * @param   pIfPort     Pointer to this structure.
440      *
441      * @remarks Called holding the out-bound trunk port lock.
442      */
443     DECLR0CALLBACKMEMBER(void, pfnDisconnectAndRelease,(PINTNETTRUNKIFPORT pIfPort));
444
445     /**
446      * Changes the active state of the interface.
447      *
448      * The interface is created in the suspended (non-active) state and then activated
449      * when the VM/network is started. It may be suspended and re-activated later
450      * for various reasons. It will finally be suspended again before disconnecting
451      * the interface from the internal network, however, this might be done immediately
452      * before disconnecting and may leave an incoming frame waiting on the internal network
453      * semaphore. So, after the final suspend a pfnWaitForIdle is always called to make sure
454      * the interface is idle before pfnDisconnectAndRelease is called.
455      *
456      * A typical operation to performed by this method is to enable/disable promiscuous
457      * mode on the host network interface. (This is the reason we cannot call this when
458      * owning any semaphores.)
459      *
460      * @returns The previous state.
461      *
462      * @param   pIfPort     Pointer to this structure.
463      * @param   fActive     True if the new state is 'active', false if the new state is 'suspended'.
464      *
465      * @remarks Called holding the out-bound trunk port lock.
466      */
467     DECLR0CALLBACKMEMBER(bool, pfnSetActive,(PINTNETTRUNKIFPORT pIfPort, bool fActive));
468
469     /**
470      * Waits for the interface to become idle.
471      *
472      * This method must be called before disconnecting and releasing the
473      * object in order to prevent racing incoming/outgoing packets and
474      * device enabling/disabling.
475      *
476      * @returns IPRT status code (see RTSemEventWait).
477      * @param   pIfPort     Pointer to this structure.
478      * @param   cMillies    The number of milliseconds to wait. 0 means
479      *                      no waiting at all. Use RT_INDEFINITE_WAIT for
480      *                      an indefinite wait.
481      *
482      * @remarks Called holding the out-bound trunk port lock.
483      */
484     DECLR0CALLBACKMEMBER(int, pfnWaitForIdle,(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies));
485
486     /**
487      * Gets the MAC address of the host network interface that we're attached to.
488      *
489      * @param   pIfPort     Pointer to this structure.
490      * @param   pMac        Where to store the host MAC address.
491      *
492      * @remarks Called while owning the network and the out-bound trunk port semaphores.
493      */
494     DECLR0CALLBACKMEMBER(void, pfnGetMacAddress,(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac));
495
496     /**
497      * Tests if the mac address belongs to any of the host NICs
498      * and should take the host route.
499      *
500      * @returns true / false.
501      *
502      * @param   pIfPort     Pointer to this structure.
503      * @param   pMac        Pointer to the mac address.
504      *
505      * @remarks Called while owning the network and the out-bound trunk port semaphores.
506      *
507      * @remarks TAP and NAT will compare with their own MAC address and let all their
508      *          traffic take the host direction.
509      *
510      * @remarks This didn't quiet work out the way it should... perhaps obsolete this
511      *          with pfnGetHostMac?
512      */
513     DECLR0CALLBACKMEMBER(bool, pfnIsHostMac,(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac));
514
515     /**
516      * Tests whether the host is operating the interface is promiscuous mode.
517      *
518      * The default behavior of the internal networking 'switch' is to 'autodetect'
519      * promiscuous mode on the trunk port, which is when this method is used.
520      * For security reasons this default may of course be overridden so that the
521      * host cannot sniff at what's going on.
522      *
523      * Note that this differs from operating the trunk port on the switch in
524      * 'promiscuous' mode, because that relates to the bits going to the wire.
525      *
526      * @returns true / false.
527      *
528      * @param   pIfPort     Pointer to this structure.
529      *
530      * @remarks Called while owning the network and the out-bound trunk port semaphores.
531      */
532     DECLR0CALLBACKMEMBER(bool, pfnIsPromiscuous,(PINTNETTRUNKIFPORT pIfPort));
533
534     /**
535      * Transmit a frame.
536      *
537      * @return  VBox status code. Error generally means we'll drop the packet.
538      * @param   pIfPort     Pointer to this structure.
539      * @param   pSG         Pointer to the (scatter /) gather structure for the frame.
540      *                      This may or may not be a temporary buffer. If it's temporary
541      *                      the transmit operation(s) then it's required to make a copy
542      *                      of the frame unless it can be transmitted synchronously.
543      * @param   fDst        The destination mask. At least one bit will be set.
544      *
545      * @remarks Called holding the out-bound trunk port lock.
546      *
547      * @remarks TAP and NAT will use this interface for all their traffic, see pfnIsHostMac.
548      *
549      * @todo
550      */
551     DECLR0CALLBACKMEMBER(int, pfnXmit,(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst));
552
553     /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
554     uint32_t u32VersionEnd;
555 } INTNETTRUNKIFPORT;
556
557 /** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
558 #define INTNETTRUNKIFPORT_VERSION   UINT32_C(0xA2CDe001)
559
560
561 /**
562  * The component factory interface for create a network
563  * interface filter (like VBoxNetFlt).
564  */
565 typedef struct INTNETTRUNKFACTORY
566 {
567     /**
568      * Release this factory.
569      *
570      * SUPR0ComponentQueryFactory (SUPDRVFACTORY::pfnQueryFactoryInterface to be precise)
571      * will retain a reference to the factory and the caller has to call this method to
572      * release it once the pfnCreateAndConnect call(s) has been done.
573      *
574      * @param   pIfFactory          Pointer to this structure.
575      */
576     DECLR0CALLBACKMEMBER(void, pfnRelease,(struct INTNETTRUNKFACTORY *pIfFactory));
577
578     /**
579      * Create an instance for the specfied host interface and connects it
580      * to the internal network trunk port.
581      *
582      * The initial interface active state is false (suspended).
583      *
584      *
585      * @returns VBox status code.
586      * @retval  VINF_SUCCESS and *ppIfPort set on success.
587      * @retval  VERR_INTNET_FLT_IF_NOT_FOUND if the interface was not found.
588      * @retval  VERR_INTNET_FLT_IF_BUSY if the interface is already connected.
589      * @retval  VERR_INTNET_FLT_IF_FAILED if it failed for some other reason.
590      *
591      * @param   pIfFactory          Pointer to this structure.
592      * @param   pszName             The interface name (OS specific).
593      * @param   pSwitchPort         Pointer to the port interface on the switch that
594      *                              this interface is being connected to.
595      * @param   ppIfPort            Where to store the pointer to the interface port
596      *                              on success.
597      *
598      * @remarks Called while owning the network and the out-bound trunk semaphores.
599      */
600     DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(struct INTNETTRUNKFACTORY *pIfFactory, const char *pszName,
601                                                    PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort));
602 } INTNETTRUNKFACTORY;
603 /** Pointer to the trunk factory. */
604 typedef INTNETTRUNKFACTORY *PINTNETTRUNKFACTORY;
605
606 /** The UUID for the (current) trunk factory. (case sensitive) */
607 #define INTNETTRUNKFACTORY_UUID_STR     "ae8fcb95-280c-42f4-a8f1-09f84e3bdab3"
608
609
610 /**
611  * The trunk connection type.
612  *
613  * Used by INTNETR0Open and assoicated interfaces.
614  */
615 typedef enum INTNETTRUNKTYPE
616 {
617     /** Invalid trunk type. */
618     kIntNetTrunkType_Invalid = 0,
619     /** No trunk connection. */
620     kIntNetTrunkType_None,
621     /** We don't care which kind of trunk connection if the network exists,
622      * if it doesn't exist create it without a connection. */
623     kIntNetTrunkType_WhateverNone,
624     /** VirtualBox host network interface filter driver.
625      * The trunk name is the name of the host network interface. */
626     kIntNetTrunkType_NetFlt,
627     /** VirtualBox TAP host driver. */
628     kIntNetTrunkType_NetTap,
629     /** Nat service (ring-0). */
630     kIntNetTrunkType_SrvNat,
631     /** The end of valid types. */
632     kIntNetTrunkType_End,
633     /** The usual 32-bit hack. */
634     kIntNetTrunkType_32bitHack = 0x7fffffff
635 } INTNETTRUNKTYPE;
636
637 /** @name INTNETR0Open flags.
638  * @{ */
639 /** Share the MAC address with the host when sending something to the wire via the trunk.
640  * This is typically used when the trunk is a NetFlt for a wireless interface. */
641 #define INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE                    RT_BIT_32(0)
642 /** Whether new participants should be subjected to access check or not. */
643 #define INTNET_OPEN_FLAGS_PUBLIC                                RT_BIT_32(1)
644 /** Ignore any requests for promiscuous mode. */
645 #define INTNET_OPEN_FLAGS_IGNORE_PROMISC                        RT_BIT_32(2)
646 /** Ignore any requests for promiscuous mode, quietly applied/ignored on open. */
647 #define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC                RT_BIT_32(3)
648 /** Ignore any requests for promiscuous mode on the trunk wire connection. */
649 #define INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_WIRE             RT_BIT_32(4)
650 /** Ignore any requests for promiscuous mode on the trunk wire connection, quietly applied/ignored on open. */
651 #define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_WIRE     RT_BIT_32(5)
652 /** Ignore any requests for promiscuous mode on the trunk host connection. */
653 #define INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_HOST             RT_BIT_32(6)
654 /** Ignore any requests for promiscuous mode on the trunk host connection, quietly applied/ignored on open. */
655 #define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_HOST     RT_BIT_32(7)
656 /** The mask of flags which causes flag incompatibilities. */
657 #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))
658 /** The mask of flags is always ORed in, even on open. (the quiet stuff) */
659 #define INTNET_OPEN_FLAGS_SECURITY_OR_MASK                      (RT_BIT_32(3) | RT_BIT_32(5) | RT_BIT_32(7))
660 /** The mask of valid flags. */
661 #define INTNET_OPEN_FLAGS_MASK                                  UINT32_C(0x000000ff)
662 /** @} */
663
664 /** The maximum length of a network name. */
665 #define INTNET_MAX_NETWORK_NAME     128
666
667 /** The maximum length of a trunk name. */
668 #define INTNET_MAX_TRUNK_NAME       64
669
670
671 /**
672  * Request buffer for INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN.
673  * @see INTNETR0Open.
674  */
675 typedef struct INTNETOPENREQ
676 {
677     /** The request header. */
678     SUPVMMR0REQHDR  Hdr;
679     /** Alternative to passing the taking the session from the VM handle.
680      * Either use this member or use the VM handle, don't do both. */
681     PSUPDRVSESSION  pSession;
682     /** The network name. (input) */
683     char            szNetwork[INTNET_MAX_NETWORK_NAME];
684     /** What to connect to the trunk port. (input)
685      * This is specific to the trunk type below. */
686     char            szTrunk[INTNET_MAX_TRUNK_NAME];
687     /** The type of trunk link (NAT, Filter, TAP, etc). (input) */
688     INTNETTRUNKTYPE enmTrunkType;
689     /** Flags, see INTNET_OPEN_FLAGS_*. (input) */
690     uint32_t        fFlags;
691     /** The size of the send buffer. (input) */
692     uint32_t        cbSend;
693     /** The size of the receive buffer. (input) */
694     uint32_t        cbRecv;
695     /** The handle to the network interface. (output) */
696     INTNETIFHANDLE  hIf;
697 } INTNETOPENREQ;
698 /** Pointer to an INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN request buffer. */
699 typedef INTNETOPENREQ *PINTNETOPENREQ;
700
701 INTNETR0DECL(int) INTNETR0OpenReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETOPENREQ pReq);
702
703
704 /**
705  * Request buffer for INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE.
706  * @see INTNETR0IfClose.
707  */
708 typedef struct INTNETIFCLOSEREQ
709 {
710     /** The request header. */
711     SUPVMMR0REQHDR  Hdr;
712     /** Alternative to passing the taking the session from the VM handle.
713      * Either use this member or use the VM handle, don't do both. */
714     PSUPDRVSESSION  pSession;
715     /** The handle to the network interface. */
716     INTNETIFHANDLE  hIf;
717 } INTNETIFCLOSEREQ;
718 /** Pointer to an INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE request buffer. */
719 typedef INTNETIFCLOSEREQ *PINTNETIFCLOSEREQ;
720
721 INTNETR0DECL(int) INTNETR0IfCloseReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFCLOSEREQ pReq);
722
723
724 /**
725  * Request buffer for INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER.
726  * @see INTNETR0IfGetRing3Buffer.
727  */
728 typedef struct INTNETIFGETRING3BUFFERREQ
729 {
730     /** The request header. */
731     SUPVMMR0REQHDR  Hdr;
732     /** Alternative to passing the taking the session from the VM handle.
733      * Either use this member or use the VM handle, don't do both. */
734     PSUPDRVSESSION  pSession;
735     /** Handle to the interface. */
736     INTNETIFHANDLE  hIf;
737     /** The pointer to the ring3 buffer. (output) */
738     R3PTRTYPE(PINTNETBUF)   pRing3Buf;
739 } INTNETIFGETRING3BUFFERREQ;
740 /** Pointer to an INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER request buffer. */
741 typedef INTNETIFGETRING3BUFFERREQ *PINTNETIFGETRING3BUFFERREQ;
742
743 INTNETR0DECL(int) INTNETR0IfGetRing3BufferReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFGETRING3BUFFERREQ pReq);
744
745
746 /**
747  * Request buffer for INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE.
748  * @see INTNETR0IfSetPromiscuousMode.
749  */
750 typedef struct INTNETIFSETPROMISCUOUSMODEREQ
751 {
752     /** The request header. */
753     SUPVMMR0REQHDR  Hdr;
754     /** Alternative to passing the taking the session from the VM handle.
755      * Either use this member or use the VM handle, don't do both. */
756     PSUPDRVSESSION  pSession;
757     /** Handle to the interface. */
758     INTNETIFHANDLE  hIf;
759     /** The new promiscuous mode. */
760     bool            fPromiscuous;
761 } INTNETIFSETPROMISCUOUSMODEREQ;
762 /** Pointer to an INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE request buffer. */
763 typedef INTNETIFSETPROMISCUOUSMODEREQ *PINTNETIFSETPROMISCUOUSMODEREQ;
764
765 INTNETR0DECL(int) INTNETR0IfSetPromiscuousModeReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETPROMISCUOUSMODEREQ pReq);
766
767
768 /**
769  * Request buffer for INTNETR0IfSetMacAddressReq / VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS.
770  * @see INTNETR0IfSetMacAddress.
771  */
772 typedef struct INTNETIFSETMACADDRESSREQ
773 {
774     /** The request header. */
775     SUPVMMR0REQHDR  Hdr;
776     /** Alternative to passing the taking the session from the VM handle.
777      * Either use this member or use the VM handle, don't do both. */
778     PSUPDRVSESSION  pSession;
779     /** Handle to the interface. */
780     INTNETIFHANDLE  hIf;
781     /** The new MAC address. */
782     RTMAC           Mac;
783 } INTNETIFSETMACADDRESSREQ;
784 /** Pointer to an INTNETR0IfSetMacAddressReq / VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS request buffer. */
785 typedef INTNETIFSETMACADDRESSREQ *PINTNETIFSETMACADDRESSREQ;
786
787 INTNETR0DECL(int) INTNETR0IfSetMacAddressReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq);
788
789
790 /**
791  * Request buffer for INTNETR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE.
792  * @see INTNETR0IfSetActive.
793  */
794 typedef struct INTNETIFSETACTIVEREQ
795 {
796     /** The request header. */
797     SUPVMMR0REQHDR  Hdr;
798     /** Alternative to passing the taking the session from the VM handle.
799      * Either use this member or use the VM handle, don't do both. */
800     PSUPDRVSESSION  pSession;
801     /** Handle to the interface. */
802     INTNETIFHANDLE  hIf;
803     /** The new state. */
804     bool            fActive;
805 } INTNETIFSETACTIVEREQ;
806 /** Pointer to an INTNETR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE request buffer. */
807 typedef INTNETIFSETACTIVEREQ *PINTNETIFSETACTIVEREQ;
808
809 INTNETR0DECL(int) INTNETR0IfSetActiveReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq);
810
811
812 /**
813  * Request buffer for INTNETR0IfSendReq / VMMR0_DO_INTNET_IF_SEND.
814  * @see INTNETR0IfSend.
815  */
816 typedef struct INTNETIFSENDREQ
817 {
818     /** The request header. */
819     SUPVMMR0REQHDR  Hdr;
820     /** Alternative to passing the taking the session from the VM handle.
821      * Either use this member or use the VM handle, don't do both. */
822     PSUPDRVSESSION  pSession;
823     /** Handle to the interface. */
824     INTNETIFHANDLE  hIf;
825 } INTNETIFSENDREQ;
826 /** Pointer to an INTNETR0IfSend() argument package. */
827 typedef INTNETIFSENDREQ *PINTNETIFSENDREQ;
828
829 INTNETR0DECL(int) INTNETR0IfSendReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSENDREQ pReq);
830
831
832 /**
833  * Request buffer for INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT.
834  * @see INTNETR0IfWait.
835  */
836 typedef struct INTNETIFWAITREQ
837 {
838     /** The request header. */
839     SUPVMMR0REQHDR  Hdr;
840     /** Alternative to passing the taking the session from the VM handle.
841      * Either use this member or use the VM handle, don't do both. */
842     PSUPDRVSESSION  pSession;
843     /** Handle to the interface. */
844     INTNETIFHANDLE  hIf;
845     /** The number of milliseconds to wait. */
846     uint32_t        cMillies;
847 } INTNETIFWAITREQ;
848 /** Pointer to an INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT request buffer. */
849 typedef INTNETIFWAITREQ *PINTNETIFWAITREQ;
850
851 INTNETR0DECL(int) INTNETR0IfWaitReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFWAITREQ pReq);
852
853
854 #if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
855 /** @name
856  * @{
857  */
858
859 /**
860  * Create an instance of the Ring-0 internal networking service.
861  *
862  * @returns VBox status code.
863  * @param   ppIntNet    Where to store the instance pointer.
864  */
865 INTNETR0DECL(int) INTNETR0Create(PINTNET *ppIntNet);
866
867 /**
868  * Destroys an instance of the Ring-0 internal networking service.
869  *
870  * @param   pIntNet     Pointer to the instance data.
871  */
872