VirtualBox

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

Last change on this file since 16658 was 16183, checked in by vboxsync, 16 years ago

#3419: Added fNoPromisc parameter to pfnCreateAndConnect to prevent going promisc on WiFi.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.2 KB
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. */
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 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. */
64typedef 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 */
72DECLINLINE(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 */
86DECLINLINE(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 */
97typedef 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. */
125typedef INTNETBUF *PINTNETBUF;
126/** Pointer to a const interface buffer. */
127typedef INTNETBUF const *PCINTNETBUF;
128
129/** Internal networking interface handle. */
130typedef uint32_t INTNETIFHANDLE;
131/** Pointer to an internal networking interface handle. */
132typedef 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)
154typedef 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.*/
168typedef INTNETHDR *PINTNETHDR;
169/** Pointer to a const packet header.*/
170typedef 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 */
183DECLINLINE(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 */
203DECLINLINE(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 */
224typedef 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. */
234typedef INTNETSEG *PINTNETSEG;
235/** Pointer to a internal networking packet segment. */
236typedef INTNETSEG const *PCINTNETSEG;
237
238
239/**
240 * Scatter / Gather list (internal networking).
241 *
242 * This is used when communicating with the trunk port.
243 */
244typedef 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. */
267typedef INTNETSG *PINTNETSG;
268/** Pointer to a const scatter / gather list. */
269typedef 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. */
302typedef 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 */
309typedef 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. */
392typedef 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 */
404typedef 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 */
565typedef 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 * @param fNoPromisc Do not put the interface into promiscuous mode.
598 *
599 * @remarks Called while owning the network and the out-bound trunk semaphores.
600 */
601 DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(struct INTNETTRUNKFACTORY *pIfFactory, const char *pszName,
602 PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort,
603 bool fNoPromisc));
604} INTNETTRUNKFACTORY;
605/** Pointer to the trunk factory. */
606typedef INTNETTRUNKFACTORY *PINTNETTRUNKFACTORY;
607
608/** The UUID for the (current) trunk factory. (case sensitive) */
609#define INTNETTRUNKFACTORY_UUID_STR "a200dee8-ad4a-4e32-b875-425f74103a22"
610
611
612/**
613 * The trunk connection type.
614 *
615 * Used by INTNETR0Open and assoicated interfaces.
616 */
617typedef enum INTNETTRUNKTYPE
618{
619 /** Invalid trunk type. */
620 kIntNetTrunkType_Invalid = 0,
621 /** No trunk connection. */
622 kIntNetTrunkType_None,
623 /** We don't care which kind of trunk connection if the network exists,
624 * if it doesn't exist create it without a connection. */
625 kIntNetTrunkType_WhateverNone,
626 /** VirtualBox host network interface filter driver.
627 * The trunk name is the name of the host network interface. */
628 kIntNetTrunkType_NetFlt,
629 /** VirtualBox TAP host driver. */
630 kIntNetTrunkType_NetTap,
631 /** Nat service (ring-0). */
632 kIntNetTrunkType_SrvNat,
633 /** The end of valid types. */
634 kIntNetTrunkType_End,
635 /** The usual 32-bit hack. */
636 kIntNetTrunkType_32bitHack = 0x7fffffff
637} INTNETTRUNKTYPE;
638
639/** @name INTNETR0Open flags.
640 * @{ */
641/** Share the MAC address with the host when sending something to the wire via the trunk.
642 * This is typically used when the trunk is a NetFlt for a wireless interface. */
643#define INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE RT_BIT_32(0)
644/** Whether new participants should be subjected to access check or not. */
645#define INTNET_OPEN_FLAGS_PUBLIC RT_BIT_32(1)
646/** Ignore any requests for promiscuous mode. */
647#define INTNET_OPEN_FLAGS_IGNORE_PROMISC RT_BIT_32(2)
648/** Ignore any requests for promiscuous mode, quietly applied/ignored on open. */
649#define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC RT_BIT_32(3)
650/** Ignore any requests for promiscuous mode on the trunk wire connection. */
651#define INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_WIRE RT_BIT_32(4)
652/** Ignore any requests for promiscuous mode on the trunk wire connection, quietly applied/ignored on open. */
653#define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_WIRE RT_BIT_32(5)
654/** Ignore any requests for promiscuous mode on the trunk host connection. */
655#define INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_HOST RT_BIT_32(6)
656/** Ignore any requests for promiscuous mode on the trunk host connection, quietly applied/ignored on open. */
657#define INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_HOST RT_BIT_32(7)
658/** The mask of flags which causes flag incompatibilities. */
659#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))
660/** The mask of flags is always ORed in, even on open. (the quiet stuff) */
661#define INTNET_OPEN_FLAGS_SECURITY_OR_MASK (RT_BIT_32(3) | RT_BIT_32(5) | RT_BIT_32(7))
662/** The mask of valid flags. */
663#define INTNET_OPEN_FLAGS_MASK UINT32_C(0x000000ff)
664/** @} */
665
666/** The maximum length of a network name. */
667#define INTNET_MAX_NETWORK_NAME 128
668
669/** The maximum length of a trunk name. */
670#define INTNET_MAX_TRUNK_NAME 64
671
672
673/**
674 * Request buffer for INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN.
675 * @see INTNETR0Open.
676 */
677typedef struct INTNETOPENREQ
678{
679 /** The request header. */
680 SUPVMMR0REQHDR Hdr;
681 /** Alternative to passing the taking the session from the VM handle.
682 * Either use this member or use the VM handle, don't do both. */
683 PSUPDRVSESSION pSession;
684 /** The network name. (input) */
685 char szNetwork[INTNET_MAX_NETWORK_NAME];
686 /** What to connect to the trunk port. (input)
687 * This is specific to the trunk type below. */
688 char szTrunk[INTNET_MAX_TRUNK_NAME];
689 /** The type of trunk link (NAT, Filter, TAP, etc). (input) */
690 INTNETTRUNKTYPE enmTrunkType;
691 /** Flags, see INTNET_OPEN_FLAGS_*. (input) */
692 uint32_t fFlags;
693 /** The size of the send buffer. (input) */
694 uint32_t cbSend;
695 /** The size of the receive buffer. (input) */
696 uint32_t cbRecv;
697 /** The handle to the network interface. (output) */
698 INTNETIFHANDLE hIf;
699} INTNETOPENREQ;
700/** Pointer to an INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN request buffer. */
701typedef INTNETOPENREQ *PINTNETOPENREQ;
702
703INTNETR0DECL(int) INTNETR0OpenReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETOPENREQ pReq);
704
705
706/**
707 * Request buffer for INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE.
708 * @see INTNETR0IfClose.
709 */
710typedef struct INTNETIFCLOSEREQ
711{
712 /** The request header. */
713 SUPVMMR0REQHDR Hdr;
714 /** Alternative to passing the taking the session from the VM handle.
715 * Either use this member or use the VM handle, don't do both. */
716 PSUPDRVSESSION pSession;
717 /** The handle to the network interface. */
718 INTNETIFHANDLE hIf;
719} INTNETIFCLOSEREQ;
720/** Pointer to an INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE request buffer. */
721typedef INTNETIFCLOSEREQ *PINTNETIFCLOSEREQ;
722
723INTNETR0DECL(int) INTNETR0IfCloseReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFCLOSEREQ pReq);
724
725
726/**
727 * Request buffer for INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER.
728 * @see INTNETR0IfGetRing3Buffer.
729 */
730typedef struct INTNETIFGETRING3BUFFERREQ
731{
732 /** The request header. */
733 SUPVMMR0REQHDR Hdr;
734 /** Alternative to passing the taking the session from the VM handle.
735 * Either use this member or use the VM handle, don't do both. */
736 PSUPDRVSESSION pSession;
737 /** Handle to the interface. */
738 INTNETIFHANDLE hIf;
739 /** The pointer to the ring3 buffer. (output) */
740 R3PTRTYPE(PINTNETBUF) pRing3Buf;
741} INTNETIFGETRING3BUFFERREQ;
742/** Pointer to an INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER request buffer. */
743typedef INTNETIFGETRING3BUFFERREQ *PINTNETIFGETRING3BUFFERREQ;
744
745INTNETR0DECL(int) INTNETR0IfGetRing3BufferReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFGETRING3BUFFERREQ pReq);
746
747
748/**
749 * Request buffer for INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE.
750 * @see INTNETR0IfSetPromiscuousMode.
751 */
752typedef struct INTNETIFSETPROMISCUOUSMODEREQ
753{
754 /** The request header. */
755 SUPVMMR0REQHDR Hdr;
756 /** Alternative to passing the taking the session from the VM handle.
757 * Either use this member or use the VM handle, don't do both. */
758 PSUPDRVSESSION pSession;
759 /** Handle to the interface. */
760 INTNETIFHANDLE hIf;
761 /** The new promiscuous mode. */
762 bool fPromiscuous;
763} INTNETIFSETPROMISCUOUSMODEREQ;
764/** Pointer to an INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE request buffer. */
765typedef INTNETIFSETPROMISCUOUSMODEREQ *PINTNETIFSETPROMISCUOUSMODEREQ;
766
767INTNETR0DECL(int) INTNETR0IfSetPromiscuousModeReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETPROMISCUOUSMODEREQ pReq);
768
769
770/**
771 * Request buffer for INTNETR0IfSetMacAddressReq / VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS.
772 * @see INTNETR0IfSetMacAddress.
773 */
774typedef struct INTNETIFSETMACADDRESSREQ
775{
776 /** The request header. */
777 SUPVMMR0REQHDR Hdr;
778 /** Alternative to passing the taking the session from the VM handle.
779 * Either use this member or use the VM handle, don't do both. */
780 PSUPDRVSESSION pSession;
781 /** Handle to the interface. */
782 INTNETIFHANDLE hIf;
783 /** The new MAC address. */
784 RTMAC Mac;
785} INTNETIFSETMACADDRESSREQ;
786/** Pointer to an INTNETR0IfSetMacAddressReq / VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS request buffer. */
787typedef INTNETIFSETMACADDRESSREQ *PINTNETIFSETMACADDRESSREQ;
788
789INTNETR0DECL(int) INTNETR0IfSetMacAddressReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq);
790
791
792/**
793 * Request buffer for INTNETR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE.
794 * @see INTNETR0IfSetActive.
795 */
796typedef struct INTNETIFSETACTIVEREQ
797{
798 /** The request header. */
799 SUPVMMR0REQHDR Hdr;
800 /** Alternative to passing the taking the session from the VM handle.
801 * Either use this member or use the VM handle, don't do both. */
802 PSUPDRVSESSION pSession;
803 /** Handle to the interface. */
804 INTNETIFHANDLE hIf;
805 /** The new state. */
806 bool fActive;
807} INTNETIFSETACTIVEREQ;
808/** Pointer to an INTNETR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE request buffer. */
809typedef INTNETIFSETACTIVEREQ *PINTNETIFSETACTIVEREQ;
810
811INTNETR0DECL(int) INTNETR0IfSetActiveReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq);
812
813
814/**
815 * Request buffer for INTNETR0IfSendReq / VMMR0_DO_INTNET_IF_SEND.
816 * @see INTNETR0IfSend.
817 */
818typedef struct INTNETIFSENDREQ
819{
820 /** The request header. */
821 SUPVMMR0REQHDR Hdr;
822 /** Alternative to passing the taking the session from the VM handle.
823 * Either use this member or use the VM handle, don't do both. */
824 PSUPDRVSESSION pSession;
825 /** Handle to the interface. */
826 INTNETIFHANDLE hIf;
827} INTNETIFSENDREQ;
828/** Pointer to an INTNETR0IfSend() argument package. */
829typedef INTNETIFSENDREQ *PINTNETIFSENDREQ;
830
831INTNETR0DECL(int) INTNETR0IfSendReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSENDREQ pReq);
832
833
834/**
835 * Request buffer for INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT.
836 * @see INTNETR0IfWait.
837 */
838typedef struct INTNETIFWAITREQ
839{
840 /** The request header. */
841 SUPVMMR0REQHDR Hdr;
842 /** Alternative to passing the taking the session from the VM handle.
843 * Either use this member or use the VM handle, don't do both. */
844 PSUPDRVSESSION pSession;
845 /** Handle to the interface. */
846 INTNETIFHANDLE hIf;
847 /** The number of milliseconds to wait. */
848 uint32_t cMillies;
849} INTNETIFWAITREQ;
850/** Pointer to an INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT request buffer. */
851typedef INTNETIFWAITREQ *PINTNETIFWAITREQ;
852
853INTNETR0DECL(int) INTNETR0IfWaitReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFWAITREQ pReq);
854
855
856#if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
857/** @name
858 * @{
859 */
860
861/**
862 * Create an instance of the Ring-0 internal networking service.
863 *
864 * @returns VBox status code.
865 * @param ppIntNet Where to store the instance pointer.
866 */
867INTNETR0DECL(int) INTNETR0Create(PINTNET *ppIntNet);
868
869/**
870 * Destroys an instance of the Ring-0 internal networking service.
871 *
872 * @param pIntNet Pointer to the instance data.
873 */
874INTNETR0DECL(void) INTNETR0Destroy(PINTNET pIntNet);
875
876/**
877 * Opens a network interface and connects it to the specified network.
878 *
879 * @returns VBox status code.
880 * @param pIntNet The internal network instance.
881 * @param pSession The session handle.
882 * @param pszNetwork The network name.
883 * @param enmTrunkType The trunk type.
884 * @param pszTrunk The trunk name. Its meaning is specfic to the type.
885 * @param fFlags Flags, see INTNET_OPEN_FLAGS_*.
886 * @param fRestrictAccess Whether new participants should be subjected to access check or not.
887 * @param cbSend The send buffer size.
888 * @param cbRecv The receive buffer size.
889 * @param phIf Where to store the handle to the network interface.
890 */
891INTNETR0DECL(int) INTNETR0Open(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork,
892 INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
893 unsigned cbSend, unsigned cbRecv, PINTNETIFHANDLE phIf);
894
895/**
896 * Close an interface.
897 *
898 * @returns VBox status code.
899 * @param pIntNet The instance handle.
900 * @param hIf The interface handle.
901 * @param pSession The caller's session.
902 */
903INTNETR0DECL(int) INTNETR0IfClose(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
904
905/**
906 * Gets the ring-0 address of the current buffer.
907 *
908 * @returns VBox status code.
909 * @param pIntNet The instance data.
910 * @param hIf The interface handle.
911 * @param pSession The caller's session.
912 * @param ppRing0Buf Where to store the address of the ring-3 mapping.
913 */
914INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF *ppRing0Buf);
915
916/**
917 * Maps the default buffer into ring 3.
918 *
919 * @returns VBox status code.
920 * @param pIntNet The instance data.
921 * @param hIf The interface handle.
922 * @param pSession The caller's session.
923 * @param ppRing3Buf Where to store the address of the ring-3 mapping.
924 */
925INTNETR0DECL(int) INTNETR0IfGetRing3Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, R3PTRTYPE(PINTNETBUF) *ppRing3Buf);
926
927/**
928 * Sets the promiscuous mode property of an interface.
929 *
930 * @returns VBox status code.
931 * @param pIntNet The instance handle.
932 * @param hIf The interface handle.
933 * @param pSession The caller's session.
934 * @param fPromiscuous Set if the interface should be in promiscuous mode, clear if not.
935 */
936INTNETR0DECL(int) INTNETR0IfSetPromiscuousMode( PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fPromiscuous);
937INTNETR0DECL(int) INTNETR0IfSetMacAddress( PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PCRTMAC pMac);
938INTNETR0DECL(int) INTNETR0IfSetActive( PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fActive);
939
940/**
941 * Sends one or more frames.
942 *
943 * The function will first the frame which is passed as the optional
944 * arguments pvFrame and cbFrame. These are optional since it also
945 * possible to chain together one or more frames in the send buffer
946 * which the function will process after considering it's arguments.
947 *
948 * @returns VBox status code.
949 * @param pIntNet The instance data.
950 * @param hIf The interface handle.
951 * @param pSession The caller's session.
952 * @param pvFrame Pointer to the frame. Optional, please don't use.
953 * @param cbFrame Size of the frame. Optional, please don't use.
954 */
955INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, const void *pvFrame, unsigned cbFrame);
956
957/**
958 * Wait for the interface to get signaled.
959 * The interface will be signaled when is put into the receive buffer.
960 *
961 * @returns VBox status code.
962 * @param pIntNet The instance handle.
963 * @param hIf The interface handle.
964 * @param pSession The caller's session.
965 * @param cMillies Number of milliseconds to wait. RT_INDEFINITE_WAIT should be
966 * used if indefinite wait is desired.
967 */
968INTNETR0DECL(int) INTNETR0IfWait(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, uint32_t cMillies);
969
970/** @} */
971#endif /* IN_RING0 */
972
973__END_DECLS
974
975#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