VirtualBox

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

Last change on this file since 1599 was 1599, checked in by vboxsync, 18 years ago

added RestrictAccess key to allow to disable the policy that only VMs of the same user may attach to an internal network

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1/** @file
2 * INETNET - Internal Networking.
3 */
4
5/*
6 * Copyright (C) 2006 InnoTek Systemberatung GmbH
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.215389.xyz. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License as published by the Free Software Foundation,
12 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
13 * distribution. VirtualBox OSE is distributed in the hope that it will
14 * be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * If you received this file as part of a commercial VirtualBox
17 * distribution, then only the terms of your commercial VirtualBox
18 * license agreement apply instead of the previous paragraph.
19 */
20
21#ifndef __VBox_intnet_h__
22#define __VBox_intnet_h__
23
24#include <VBox/types.h>
25#include <VBox/stam.h>
26#include <iprt/assert.h>
27#include <iprt/asm.h>
28
29__BEGIN_DECLS
30
31
32/**
33 * Generic two-sided ring buffer.
34 *
35 * The deal is that there is exactly one writer and one reader.
36 * When offRead equals offWrite the buffer is empty. In the other
37 * extreme the writer will not use the last free byte in the buffer.
38 */
39typedef struct INTNETRINGBUF
40{
41 /** The start of the buffer offset relative to the. (inclusive) */
42 uint32_t offStart;
43 /** The offset to the end of the buffer. (exclusive) */
44 uint32_t offEnd;
45 /** The current read offset. */
46 uint32_t volatile offRead;
47 /** The current write offset. */
48 uint32_t volatile offWrite;
49} INTNETRINGBUF;
50/** Pointer to a ring buffer. */
51typedef INTNETRINGBUF *PINTNETRINGBUF;
52
53/**
54 * Get the amount of space available for writing.
55 *
56 * @returns Number of available bytes.
57 * @param pRingBuf The ring buffer.
58 */
59DECLINLINE(uint32_t) INTNETRingGetWritable(PINTNETRINGBUF pRingBuf)
60{
61 return pRingBuf->offRead <= pRingBuf->offWrite
62 ? pRingBuf->offEnd - pRingBuf->offWrite + pRingBuf->offRead - pRingBuf->offStart - 1
63 : pRingBuf->offRead - pRingBuf->offWrite - 1;
64}
65
66
67/**
68 * Get the amount of data ready for reading.
69 *
70 * @returns Number of ready bytes.
71 * @param pRingBuf The ring buffer.
72 */
73DECLINLINE(uint32_t) INTNETRingGetReadable(PINTNETRINGBUF pRingBuf)
74{
75 return pRingBuf->offRead <= pRingBuf->offWrite
76 ? pRingBuf->offWrite - pRingBuf->offRead
77 : pRingBuf->offEnd - pRingBuf->offRead + pRingBuf->offWrite - pRingBuf->offStart;
78}
79
80
81/**
82 * A interface buffer.
83 */
84typedef struct INTNETBUF
85{
86 /** The size of the entire buffer. */
87 uint32_t cbBuf;
88 /** The size of the send area. */
89 uint32_t cbSend;
90 /** The size of the receive area. */
91 uint32_t cbRecv;
92 /** The receive buffer. */
93 INTNETRINGBUF Recv;
94 /** The send buffer. */
95 INTNETRINGBUF Send;
96 /** Number of times yields help solve an overflow. */
97 STAMCOUNTER cStatYieldsOk;
98 /** Number of times yields didn't help solve an overflow. */
99 STAMCOUNTER cStatYieldsNok;
100 /** Number of lost packets due to overflows. */
101 STAMCOUNTER cStatLost;
102 /** Number of packets received (not counting lost ones). */
103 STAMCOUNTER cStatRecvs;
104 /** Number of frame bytes received (not couting lost frames). */
105 STAMCOUNTER cbStatRecv;
106 /** Number of packets received. */
107 STAMCOUNTER cStatSends;
108 /** Number of frame bytes sent. */
109 STAMCOUNTER cbStatSend;
110} INTNETBUF;
111typedef INTNETBUF *PINTNETBUF;
112
113/** Internal networking interface handle. */
114typedef uint32_t INTNETIFHANDLE;
115/** Pointer to an internal networking interface handle. */
116typedef INTNETIFHANDLE *PINTNETIFHANDLE;
117
118/** Or mask to obscure the handle index. */
119#define INTNET_HANDLE_MAGIC 0x88880000
120/** Mask to extract the handle index. */
121#define INTNET_HANDLE_INDEX_MASK 0xffff
122/** The maximum number of handles (exclusive) */
123#define INTNET_HANDLE_MAX 0xffff
124/** Invalid handle. */
125#define INTNET_HANDLE_INVALID (0)
126
127
128/**
129 * The packet header.
130 *
131 * The header is intentionally 8 bytes long. It will always
132 * start at an 8 byte aligned address. Assuming that the buffer
133 * size is a multiple of 8 bytes, that means that we can guarantee
134 * that the entire header is contiguous in both virtual and physical
135 * memory.
136 */
137#pragma pack(1)
138typedef struct INTNETHDR
139{
140 /** Header type. This is currently serving as a magic, it
141 * can be extended later to encode special command packets and stuff.. */
142 uint16_t u16Type;
143 /** The size of the frame. */
144 uint16_t cbFrame;
145 /** The offset from the start of this header to where the actual frame starts.
146 * This is used to keep the frame it self continguous in virtual memory and
147 * thereby both simplify reading and */
148 int32_t offFrame;
149} INTNETHDR, *PINTNETHDR;
150#pragma pack()
151
152/** INTNETHDR::u16Type value for normal frames. */
153#define INTNETHDR_TYPE_FRAME 0x2442
154
155
156/**
157 * Calculates the pointer to the frame.
158 *
159 * @returns Pointer to the start of the frame.
160 * @param pHdr Pointer to the packet header
161 * @param pBuf The buffer the header is within. Only used in strict builds.
162 */
163DECLINLINE(void *) INTNETHdrGetFramePtr(PINTNETHDR pHdr, PINTNETBUF pBuf)
164{
165 uint8_t *pu8 = (uint8_t *)pHdr + pHdr->offFrame;
166#ifdef VBOX_STRICT
167 const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf;
168 Assert(pHdr->u16Type == INTNETHDR_TYPE_FRAME);
169 Assert(off < pBuf->cbBuf);
170 Assert(off + pHdr->cbFrame < pBuf->cbBuf);
171#endif
172 NOREF(pBuf);
173 return pu8;
174}
175
176
177/**
178 * Skips to the next (read) frame in the buffer.
179 *
180 * @param pBuf The buffer.
181 * @param pRingBuf The ring buffer in question.
182 */
183DECLINLINE(void) INTNETRingSkipFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf)
184{
185 Assert(pRingBuf->offRead < pBuf->cbBuf);
186 Assert(pRingBuf->offRead >= pRingBuf->offStart);
187 Assert(pRingBuf->offRead < pRingBuf->offEnd);
188 uint32_t offRead = pRingBuf->offRead;
189 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offRead);
190
191 /* skip the frame */
192 offRead += pHdr->offFrame + pHdr->cbFrame;
193 offRead = RT_ALIGN_32(offRead, sizeof(INTNETHDR));
194 Assert(offRead <= pRingBuf->offEnd && offRead >= pRingBuf->offStart);
195 if (offRead >= pRingBuf->offEnd)
196 offRead = pRingBuf->offStart;
197 ASMAtomicXchgU32(&pRingBuf->offRead, offRead);
198}
199
200/** The maximum length of a network name. */
201#define INTNET_MAX_NETWORK_NAME 128
202
203
204
205/**
206 * The packed down arguments of INTNETR0Open().
207 * @see INTNETR0Open()
208 */
209typedef struct INTNETOPENARGS
210{
211 /** The network name. (input) */
212 char szNetwork[INTNET_MAX_NETWORK_NAME];
213 /** The size of the send buffer. (input) */
214 uint32_t cbSend;
215 /** The size of the receive buffer. (input) */
216 uint32_t cbRecv;
217 /** check access? */
218 bool fRestrictAccess;
219 /** The handle to the network interface. (output) */
220 INTNETIFHANDLE hIf;
221} INTNETOPENARGS;
222/** Pointer to an INTNETR0Open() argument package. */
223typedef INTNETOPENARGS *PINTNETOPENARGS;
224
225
226/**
227 * The packed down arguments of INTNETR0IfClose().
228 * @see INTNETR0IfClose()
229 */
230typedef struct INTNETCLOSEARGS
231{
232 /** The handle to the network interface. */
233 INTNETIFHANDLE hIf;
234} INTNETIFCLOSEARGS;
235/** Pointer to an INTNETR0Open() argument package. */
236typedef INTNETIFCLOSEARGS *PINTNETIFCLOSEARGS;
237
238
239/**
240 * Argument buffer for calling INTNETR0IfGetRing3Buffer().
241 * @see INTNETR0IfGetRing3Buffer()
242 */
243typedef struct INTNETIFGETRING3BUFFERARGS
244{
245 /** Handle to the interface. */
246 INTNETIFHANDLE hIf;
247 /** The pointer to the ring3 buffer. (output) */
248 PINTNETBUF pRing3Buf;
249} INTNETIFGETRING3BUFFERARGS;
250/** Pointer to an INTNETR0IfGetRing3Buffer() argument package. */
251typedef INTNETIFGETRING3BUFFERARGS *PINTNETIFGETRING3BUFFERARGS;
252
253/**
254 * Argument buffer for calling INTNETR0IfSetPromiscuousMode().
255 * @see INTNETR0IfSetPromiscuousMode()
256 */
257typedef struct INTNETIFSETPROMISCUOUSMODEARGS
258{
259 /** Handle to the interface. */
260 INTNETIFHANDLE hIf;
261 /** The new promiscuous mode. */
262 bool fPromiscuous;
263} INTNETIFSETPROMISCUOUSMODEARGS;
264/** Pointer to an INTNETR0IfSetPromiscuousMode() argument package. */
265typedef INTNETIFSETPROMISCUOUSMODEARGS *PINTNETIFSETPROMISCUOUSMODEARGS;
266
267
268/**
269 * Argument buffer for calling INTNETR0IfSend().
270 * @see INTNETR0IfSend()
271 */
272typedef struct INTNETIFSENDARGS
273{
274 /** Handle to the interface. */
275 INTNETIFHANDLE hIf;
276 /** Pointer to the frame. (Optional) */
277 const void *pvFrame;
278 /** The size of the frame. (Optional) */
279 uint32_t cbFrame;
280} INTNETIFSENDARGS;
281/** Pointer to an INTNETR0IfSend() argument package. */
282typedef INTNETIFSENDARGS *PINTNETIFSENDARGS;
283
284
285/**
286 * Argument buffer for calling INTNETR0IfWait().
287 * @see INTNETR0IfWait()
288 */
289typedef struct INTNETIFWAITARGS
290{
291 /** Handle to the interface. */
292 INTNETIFHANDLE hIf;
293 /** The number of milliseconds to wait. */
294 unsigned cMillies;
295} INTNETSENDARGS;
296/** Pointer to an INTNETR0IfWait() argument package. */
297typedef INTNETIFWAITARGS *PINTNETIFWAITARGS;
298
299
300#if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
301/** @name
302 * @{
303 */
304
305/** Pointer to an internal network ring-0 instance. */
306typedef struct INTNET *PINTNET;
307
308/**
309 * Create an instance of the Ring-0 internal networking service.
310 *
311 * @returns VBox status code.
312 * @param ppIntNet Where to store the instance pointer.
313 */
314INTNETR0DECL(int) INTNETR0Create(PINTNET *ppIntNet);
315
316/**
317 * Destroys an instance of the Ring-0 internal networking service.
318 *
319 * @param pIntNet Pointer to the instance data.
320 */
321INTNETR0DECL(void) INTNETR0Destroy(PINTNET pIntNet);
322
323/**
324 * Opens a network interface and attaches it to the specified network.
325 *
326 * @returns VBox status code.
327 * @param pIntNet The
328 */
329INTNETR0DECL(int) INTNETR0Open(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, unsigned cbSend, unsigned cbRecv, bool fRestrictAccess, PINTNETIFHANDLE phIf);
330
331/**
332 * Close an interface.
333 *
334 * @returns VBox status code.
335 * @param pIntNet The instance handle.
336 * @param hIf The interface handle.
337 */
338INTNETR0DECL(int) INTNETR0IfClose(PINTNET pIntNet, INTNETIFHANDLE hIf);
339
340/**
341 * Gets the ring-0 address of the current buffer.
342 *
343 * @returns VBox status code.
344 * @param pIntNet The instance data.
345 * @param hIF The interface handle.
346 * @param ppRing0Buf Where to store the address of the ring-3 mapping.
347 */
348INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing0Buf);
349
350/**
351 * Maps the default buffer into ring 3.
352 *
353 * @returns VBox status code.
354 * @param pIntNet The instance data.
355 * @param hIF The interface handle.
356 * @param ppRing3Buf Where to store the address of the ring-3 mapping.
357 */
358INTNETR0DECL(int) INTNETR0IfGetRing3Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing3Buf);
359
360/**
361 * Sets the promiscuous mode property of an interface.
362 *
363 * @returns VBox status code.
364 * @param pIntNet The instance handle.
365 * @param hIf The interface handle.
366 * @param fPromiscuous Set if the interface should be in promiscuous mode, clear if not.
367 */
368INTNETR0DECL(int) INTNETR0IfSetPromiscuousMode(PINTNET pIntNet, INTNETIFHANDLE hIf, bool fPromiscuous);
369
370/**
371 * Sends one or more frames.
372 *
373 * The function will first the frame which is passed as the optional
374 * arguments pvFrame and cbFrame. These are optional since it also
375 * possible to chain together one or more frames in the send buffer
376 * which the function will process after considering it's arguments.
377 *
378 * @returns VBox status code.
379 * @param pIntNet The instance data.
380 * @param hIF The interface handle.
381 * @param pvFrame Pointer to the frame.
382 * @param cbFrame Size of the frame.
383 */
384INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, const void *pvFrame, unsigned cbFrame);
385
386/**
387 * Wait for the interface to get signaled.
388 * The interface will be signaled when is put into the receive buffer.
389 *
390 * @returns VBox status code.
391 * @param pIntNet The instance handle.
392 * @param hIf The interface handle.
393 * @param cMillies Number of milliseconds to wait. RT_INDEFINITE_WAIT should be
394 * used if indefinite wait is desired.
395 */
396INTNETR0DECL(int) INTNETR0IfWait(PINTNET pIntNet, INTNETIFHANDLE hIf, unsigned cMillies);
397
398/** @} */
399#endif /* IN_RING0 */
400
401__END_DECLS
402
403#endif
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette