VirtualBox

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

Last change on this file since 10273 was 10169, checked in by vboxsync, 16 years ago

Some pfnXmit clearification (the SG must be retained if used asyncly). Rediscovery on interface disconnection. Reviewed most of the VBoxNetFlt code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.3 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/** @} */
282
283
284/**
285 * Initializes a scatter / gather buffer from a internal networking packet.
286 *
287 * @returns Pointer to the start of the frame.
288 * @param pSG Pointer to the scatter / gather structure.
289 * (The pvOwnerData, fFlags, cUsers, and cSegsAlloc members are left untouched.)
290 * @param pHdr Pointer to the packet header.
291 * @param pBuf The buffer the header is within. Only used in strict builds.
292 * @remarks Perhaps move this...
293 */
294DECLINLINE(void) INTNETSgInitFromPkt(PINTNETSG pSG, PCINTNETHDR pPktHdr, PCINTNETBUF pBuf)
295{
296 pSG->cSegsUsed = 1;
297 pSG->cbTotal = pSG->aSegs[0].cb = pPktHdr->cbFrame;
298 pSG->aSegs[0].pv = INTNETHdrGetFramePtr(pPktHdr, pBuf);
299 pSG->aSegs[0].Phys = NIL_RTHCPHYS;
300}
301
302
303/** @name Direction (packet source or destination)
304 * @{ */
305/** To/From the wire. */
306#define INTNETTRUNKDIR_WIRE RT_BIT_32(1)
307/** To/From the host. */
308#define INTNETTRUNKDIR_HOST RT_BIT_32(2)
309/** Mask of valid bits. */
310#define INTNETTRUNKDIR_VALID_MASK UINT32_C(0x3)
311/** @} */
312
313
314/** Pointer to the switch side of a trunk port. */
315typedef struct INTNETTRUNKSWPORT *PINTNETTRUNKSWPORT;
316/**
317 * This is the port on the internal network 'switch', i.e.
318 * what the driver is connected to.
319 *
320 * This is only used for the in-kernel trunk connections.
321 */
322typedef struct INTNETTRUNKSWPORT
323{
324 /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
325 uint32_t u32Version;
326
327 /**
328 * Selects whether outgoing SGs should have their physical address set.
329 *
330 * By enabling physical addresses in the scatter / gather segments it should
331 * be possible to save some unnecessary address translation and memory locking
332 * in the network stack. (Internal networking knows the physical address for
333 * all the INTNETBUF data and that it's locked memory.) There is a negative
334 * side effects though, frames that crosses page boundraries will require
335 * multiple scather / gather segments.
336 *
337 * @returns The old setting.
338 *
339 * @param pIfPort Pointer to this structure.
340 * @param fEnable Whether to enable or disable it.
341 *
342 * @remarks Will grab the network semaphore.
343 */
344 DECLR0CALLBACKMEMBER(bool, pfnSetSGPhys,(PINTNETTRUNKSWPORT pIfPort, bool fEnable));
345
346 /**
347 * Incoming frame.
348 *
349 * @returns true if we've handled it and it should be dropped.
350 * false if it should hit the wire.
351 *
352 * @param pIfPort Pointer to this structure.
353 * @param pSG The (scatter /) gather structure for the frame.
354 * This will only be use during the call, so a temporary one can
355 * be used. The Phys member will not be used.
356 * @param fSrc Where this frame comes from. Only one bit should be set!
357 *
358 * @remarks Will grab the network semaphore.
359 *
360 * @remark NAT and TAP will use this interface.
361 */
362 DECLR0CALLBACKMEMBER(bool, pfnRecv,(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG, uint32_t fSrc));
363
364 /**
365 * Retain a SG.
366 *
367 * @param pIfPort Pointer to this structure.
368 * @param pSG Pointer to the (scatter /) gather structure.
369 *
370 * @remarks Will not grab any locks.
371 */
372 DECLR0CALLBACKMEMBER(void, pfnSGRetain,(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG));
373
374 /**
375 * Release a SG.
376 *
377 * This is called by the pfnXmit code when done with a SG. This may safe
378 * be done in an asynchronous manner.
379 *
380 * @param pIfPort Pointer to this structure.
381 * @param pSG Pointer to the (scatter /) gather structure.
382 *
383 * @remarks Will grab the network semaphore.
384 */
385 DECLR0CALLBACKMEMBER(void, pfnSGRelease,(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG));
386
387 /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
388 uint32_t u32VersionEnd;
389} INTNETTRUNKSWPORT;
390
391/** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
392#define INTNETTRUNKSWPORT_VERSION UINT32_C(0xA2CDf001)
393
394
395/** Pointer to the interface side of a trunk port. */
396typedef struct INTNETTRUNKIFPORT *PINTNETTRUNKIFPORT;
397/**
398 * This is the port on the trunk interface, i.e. the driver
399 * side which the internal network is connected to.
400 *
401 * This is only used for the in-kernel trunk connections.
402 *
403 * @remarks The internal network side is responsible for serializing all calls
404 * to this interface. This is (assumed) to be implemented using a lock
405 * that is only ever taken before a call to this interface. The lock
406 * is referred to as the out-bound trunk port lock.
407 */
408typedef struct INTNETTRUNKIFPORT
409{
410 /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
411 uint32_t u32Version;
412
413 /**
414 * Retain the object.
415 *
416 * It will normally be called while owning the internal network semaphore.
417 *
418 * @param pIfPort Pointer to this structure.
419 *
420 * @remarks The caller may own any locks or none at all, we don't care.
421 */
422 DECLR0CALLBACKMEMBER(void, pfnRetain,(PINTNETTRUNKIFPORT pIfPort));
423
424 /**
425 * Releases the object.
426 *
427 * This must be called for every pfnRetain call.
428 *
429 *
430 * @param pIfPort Pointer to this structure.
431 *
432 * @remarks Only the out-bound trunk port lock, unless the caller is certain the
433 * call is not going to cause destruction (wont happen).
434 */
435 DECLR0CALLBACKMEMBER(void, pfnRelease,(PINTNETTRUNKIFPORT pIfPort));
436
437 /**
438 * Disconnect from the switch and release the object.
439 *
440 * The is the counter action of the
441 * INTNETTRUNKNETFLTFACTORY::pfnCreateAndConnect method.
442 *
443 * @param pIfPort Pointer to this structure.
444 *
445 * @remarks Called holding the out-bound trunk port lock.
446 */
447 DECLR0CALLBACKMEMBER(void, pfnDisconnectAndRelease,(PINTNETTRUNKIFPORT pIfPort));
448
449 /**
450 * Changes the active state of the interface.
451 *
452 * The interface is created in the suspended (non-active) state and then activated
453 * when the VM/network is started. It may be suspended and re-activated later
454 * for various reasons. It will finally be suspended again before disconnecting
455 * the interface from the internal network, however, this might be done immediately
456 * before disconnecting and may leave an incoming frame waiting on the internal network
457 * semaphore. So, after the final suspend a pfnWaitForIdle is always called to make sure
458 * the interface is idle before pfnDisconnectAndRelease is called.
459 *
460 * A typical operation to performed by this method is to enable/disable promiscuous
461 * mode on the host network interface. (This is the reason we cannot call this when
462 * owning any semaphores.)
463 *
464 * @returns The previous state.
465 *
466 * @param pIfPort Pointer to this structure.
467 * @param fActive True if the new state is 'active', false if the new state is 'suspended'.
468 *
469 * @remarks Called holding the out-bound trunk port lock.
470 */
471 DECLR0CALLBACKMEMBER(bool, pfnSetActive,(PINTNETTRUNKIFPORT pIfPort, bool fActive));
472
473 /**
474 * Waits for the interface to become idle.
475 *
476 * This method must be called before disconnecting and releasing the
477 * object in order to prevent racing incoming/outgoing packets and
478 * device enabling/disabling.
479 *
480 * @returns IPRT status code (see RTSemEventWait).
481 * @param pIfPort Pointer to this structure.
482 * @param cMillies The number of milliseconds to wait. 0 means
483 * no waiting at all. Use RT_INDEFINITE_WAIT for
484 * an indefinite wait.
485 *
486 * @remarks Called holding the out-bound trunk port lock.
487 */
488 DECLR0CALLBACKMEMBER(int, pfnWaitForIdle,(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies));
489
490 /**
491 * Tests if the mac address belongs to any of the host NICs
492 * and should take the host route.
493 *
494 * @returns true / false.
495 *
496 * @param pIfPort Pointer to this structure.
497 * @param pMac Pointer to the mac address.
498 *
499 * @remarks Called while owning the network and the out-bound trunk port semaphores.
500 *
501 * @remarks TAP and NAT will compare with their own MAC address and let all their
502 * traffic take the host direction.
503 */
504 DECLR0CALLBACKMEMBER(bool, pfnIsHostMac,(PINTNETTRUNKIFPORT pIfPort, PCPDMMAC pMac));
505
506 /**
507 * Tests whether the host is operating the interface is promiscuous mode.
508 *
509 * The default behavior of the internal networking 'switch' is to 'autodetect'
510 * promiscuous mode on the trunk port, which is when this method is used.
511 * For security reasons this default may of course be overridden so that the
512 * host cannot sniff at what's going on.
513 *
514 * Note that this differs from operating the trunk port on the switch in
515 * 'promiscuous' mode, because that relates to the bits going to the wire.
516 *
517 * @returns true / false.
518 *
519 * @param pIfPort Pointer to this structure.
520 *
521 * @remarks Called while owning the network and the out-bound trunk port semaphores.
522 */
523 DECLR0CALLBACKMEMBER(bool, pfnIsPromiscuous,(PINTNETTRUNKIFPORT pIfPort));
524
525 /**
526 * Transmit a frame.
527 *
528 * @return VBox status code. Error generally means we'll drop the packet.
529 * @param pIfPort Pointer to this structure.
530 * @param pSG Pointer to the (scatter /) gather structure for the frame.
531 * This will never be a temporary one, so, it's safe to retain
532 * it and do an asynchronous request to avoid copying.
533 * @param fDst The destination mask. At least one bit will be set.
534 *
535 * @remarks Called holding the out-bound trunk port lock.
536 *
537 * @remarks TAP and NAT will use this interface for all their traffic, see pfnIsHostMac.
538 */
539 DECLR0CALLBACKMEMBER(int, pfnXmit,(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst));
540
541 /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
542 uint32_t u32VersionEnd;
543} INTNETTRUNKIFPORT;
544
545/** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
546#define INTNETTRUNKIFPORT_VERSION UINT32_C(0xA2CDe001)
547
548
549/**
550 * The component factory interface for create a network
551 * interface filter (like VBoxNetFlt).
552 */
553typedef struct INTNETTRUNKNETFLTFACTORY
554{
555 /**
556 * Create an instance for the specfied host interface and connects it
557 * to the internal network trunk port.
558 *
559 * The initial interface active state is false (suspended).
560 *
561 *
562 * @returns VBox status code.
563 * @retval VINF_SUCCESS and *ppIfPort set on success.
564 * @retval VERR_INTNET_FLT_IF_NOT_FOUND if the interface was not found.
565 * @retval VERR_INTNET_FLT_IF_BUSY if the interface is already connected.
566 * @retval VERR_INTNET_FLT_IF_FAILED if it failed for some other reason.
567 *
568 * @param pIfFactory Pointer to this structure.
569 * @param pszName The interface name (OS specific).
570 * @param pSwitchPort Pointer to the port interface on the switch that
571 * this interface is being connected to.
572 * @param ppIfPort Where to store the pointer to the interface port
573 * on success.
574 *
575 * @remarks Called while owning the network and the out-bound trunk semaphores.
576 */
577 DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(struct INTNETTRUNKNETFLTFACTORY *pIfFactory, const char *pszName,
578 PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort));
579} INTNETTRUNKNETFLTFACTORY;
580/** Pointer to the trunk factory. */
581typedef INTNETTRUNKNETFLTFACTORY *PINTNETTRUNKNETFLTFACTORY;
582
583/** The UUID for the current network interface filter factory. */
584#define INTNETTRUNKNETFLTFACTORY_UUID_STR "0e32db7d-165d-4fc9-9bce-acb2798ce7fb"
585
586
587
588
589/** The maximum length of a network name. */
590#define INTNET_MAX_NETWORK_NAME 128
591
592
593/**
594 * Request buffer for INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN.
595 * @see INTNETR0Open.
596 */
597typedef struct INTNETOPENREQ
598{
599 /** The request header. */
600 SUPVMMR0REQHDR Hdr;
601 /** The network name. (input) */
602 char szNetwork[INTNET_MAX_NETWORK_NAME];
603 /** The size of the send buffer. (input) */
604 uint32_t cbSend;
605 /** The size of the receive buffer. (input) */
606 uint32_t cbRecv;
607 /** Whether new participants should be subjected to access check or not. */
608 bool fRestrictAccess;
609 /** The handle to the network interface. (output) */
610 INTNETIFHANDLE hIf;
611} INTNETOPENREQ;
612/** Pointer to an INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN request buffer. */
613typedef INTNETOPENREQ *PINTNETOPENREQ;
614
615INTNETR0DECL(int) INTNETR0OpenReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETOPENREQ pReq);
616
617
618/**
619 * Request buffer for INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE.
620 * @see INTNETR0IfClose.
621 */
622typedef struct INTNETIFCLOSEREQ
623{
624 /** The request header. */
625 SUPVMMR0REQHDR Hdr;
626 /** The handle to the network interface. */
627 INTNETIFHANDLE hIf;
628} INTNETIFCLOSEREQ;
629/** Pointer to an INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE request buffer. */
630typedef INTNETIFCLOSEREQ *PINTNETIFCLOSEREQ;
631
632INTNETR0DECL(int) INTNETR0IfCloseReq(PINTNET pIntNet, PINTNETIFCLOSEREQ pReq);
633
634
635/**
636 * Request buffer for INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER.
637 * @see INTNETR0IfGetRing3Buffer.
638 */
639typedef struct INTNETIFGETRING3BUFFERREQ
640{
641 /** The request header. */
642 SUPVMMR0REQHDR Hdr;
643 /** Handle to the interface. */
644 INTNETIFHANDLE hIf;
645 /** The pointer to the ring3 buffer. (output) */
646 R3PTRTYPE(PINTNETBUF) pRing3Buf;
647} INTNETIFGETRING3BUFFERREQ;
648/** Pointer to an INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER request buffer. */
649typedef INTNETIFGETRING3BUFFERREQ *PINTNETIFGETRING3BUFFERREQ;
650
651INTNETR0DECL(int) INTNETR0IfGetRing3BufferReq(PINTNET pIntNet, PINTNETIFGETRING3BUFFERREQ pReq);
652
653
654/**
655 * Request buffer for INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE.
656 * @see INTNETR0IfSetPromiscuousMode.
657 */
658typedef struct INTNETIFSETPROMISCUOUSMODEREQ
659{
660 /** The request header. */
661 SUPVMMR0REQHDR Hdr;
662 /** Handle to the interface. */
663 INTNETIFHANDLE hIf;
664 /** The new promiscuous mode. */
665 bool fPromiscuous;
666} INTNETIFSETPROMISCUOUSMODEREQ;
667/** Pointer to an INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE request buffer. */
668typedef INTNETIFSETPROMISCUOUSMODEREQ *PINTNETIFSETPROMISCUOUSMODEREQ;
669
670INTNETR0DECL(int) INTNETR0IfSetPromiscuousModeReq(PINTNET pIntNet, PINTNETIFSETPROMISCUOUSMODEREQ pReq);
671
672
673/**
674 * Request buffer for INTNETR0IfSendReq / VMMR0_DO_INTNET_IF_SEND.
675 * @see INTNETR0IfSend.
676 */
677typedef struct INTNETIFSENDREQ
678{
679 /** The request header. */
680 SUPVMMR0REQHDR Hdr;
681 /** Handle to the interface. */
682 INTNETIFHANDLE hIf;
683} INTNETIFSENDREQ;
684/** Pointer to an INTNETR0IfSend() argument package. */
685typedef INTNETIFSENDREQ *PINTNETIFSENDREQ;
686
687INTNETR0DECL(int) INTNETR0IfSendReq(PINTNET pIntNet, PINTNETIFSENDREQ pReq);
688
689
690/**
691 * Request buffer for INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT.
692 * @see INTNETR0IfWait.
693 */
694typedef struct INTNETIFWAITREQ
695{
696 /** The request header. */
697 SUPVMMR0REQHDR Hdr;
698 /** Handle to the interface. */
699 INTNETIFHANDLE hIf;
700 /** The number of milliseconds to wait. */
701 uint32_t cMillies;
702} INTNETIFWAITREQ;
703/** Pointer to an INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT request buffer. */
704typedef INTNETIFWAITREQ *PINTNETIFWAITREQ;
705
706INTNETR0DECL(int) INTNETR0IfWaitReq(PINTNET pIntNet, PINTNETIFWAITREQ pReq);
707
708
709#if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
710/** @name
711 * @{
712 */
713
714/**
715 * Create an instance of the Ring-0 internal networking service.
716 *
717 * @returns VBox status code.
718 * @param ppIntNet Where to store the instance pointer.
719 */
720INTNETR0DECL(int) INTNETR0Create(PINTNET *ppIntNet);
721
722/**
723 * Destroys an instance of the Ring-0 internal networking service.
724 *
725 * @param pIntNet Pointer to the instance data.
726 */
727INTNETR0DECL(void) INTNETR0Destroy(PINTNET pIntNet);
728
729/**
730 * Opens a network interface and connects it to the specified network.
731 *
732 * @returns VBox status code.
733 * @param pIntNet The internal network instance.
734 * @param pSession The session handle.
735 * @param pszNetwork The network name.
736 * @param cbSend The send buffer size.
737 * @param cbRecv The receive buffer size.
738 * @param fRestrictAccess Whether new participants should be subjected to access check or not.
739 * @param phIf Where to store the handle to the network interface.
740 */
741INTNETR0DECL(int) INTNETR0Open(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, unsigned cbSend, unsigned cbRecv, bool fRestrictAccess, PINTNETIFHANDLE phIf);
742
743/**
744 * Close an interface.
745 *
746 * @returns VBox status code.
747 * @param pIntNet The instance handle.
748 * @param hIf The interface handle.
749 */
750INTNETR0DECL(int) INTNETR0IfClose(PINTNET pIntNet, INTNETIFHANDLE hIf);
751
752/**
753 * Gets the ring-0 address of the current buffer.
754 *
755 * @returns VBox status code.
756 * @param pIntNet The instance data.
757 * @param hIF The interface handle.
758 * @param ppRing0Buf Where to store the address of the ring-3 mapping.
759 */
760INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing0Buf);
761
762/**
763 * Maps the default buffer into ring 3.
764 *
765 * @returns VBox status code.
766 * @param pIntNet The instance data.
767 * @param hIF The interface handle.
768 * @param ppRing3Buf Where to store the address of the ring-3 mapping.
769 */
770INTNETR0DECL(int) INTNETR0IfGetRing3Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, R3PTRTYPE(PINTNETBUF) *ppRing3Buf);
771
772/**
773 * Sets the promiscuous mode property of an interface.
774 *
775 * @returns VBox status code.
776 * @param pIntNet The instance handle.
777 * @param hIf The interface handle.
778 * @param fPromiscuous Set if the interface should be in promiscuous mode, clear if not.
779 */
780INTNETR0DECL(int) INTNETR0IfSetPromiscuousMode(PINTNET pIntNet, INTNETIFHANDLE hIf, bool fPromiscuous);
781
782/**
783 * Sends one or more frames.
784 *
785 * The function will first the frame which is passed as the optional
786 * arguments pvFrame and cbFrame. These are optional since it also
787 * possible to chain together one or more frames in the send buffer
788 * which the function will process after considering it's arguments.
789 *
790 * @returns VBox status code.
791 * @param pIntNet The instance data.
792 * @param hIF The interface handle.
793 * @param pvFrame Pointer to the frame.
794 * @param cbFrame Size of the frame.
795 */
796INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, const void *pvFrame, unsigned cbFrame);
797
798/**
799 * Wait for the interface to get signaled.
800 * The interface will be signaled when is put into the receive buffer.
801 *
802 * @returns VBox status code.
803 * @param pIntNet The instance handle.
804 * @param hIf The interface handle.
805 * @param cMillies Number of milliseconds to wait. RT_INDEFINITE_WAIT should be
806 * used if indefinite wait is desired.
807 */
808INTNETR0DECL(int) INTNETR0IfWait(PINTNET pIntNet, INTNETIFHANDLE hIf, uint32_t cMillies);
809
810/** @} */
811#endif /* IN_RING0 */
812
813__END_DECLS
814
815#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