VirtualBox

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

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

Corrected some more log statements and synced some function docs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 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.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 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 /** Whether new participants should be subjected to access check or not. */
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 internal network instance.
328 * @param pSession The session handle.
329 * @param pszNetwork The network name.
330 * @param cbSend The send buffer size.
331 * @param cbRecv The receive buffer size.
332 * @param fRestrictAccess Whether new participants should be subjected to access check or not.
333 * @param phIf Where to store the handle to the network interface.
334 */
335INTNETR0DECL(int) INTNETR0Open(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, unsigned cbSend, unsigned cbRecv, bool fRestrictAccess, PINTNETIFHANDLE phIf);
336
337/**
338 * Close an interface.
339 *
340 * @returns VBox status code.
341 * @param pIntNet The instance handle.
342 * @param hIf The interface handle.
343 */
344INTNETR0DECL(int) INTNETR0IfClose(PINTNET pIntNet, INTNETIFHANDLE hIf);
345
346/**
347 * Gets the ring-0 address of the current buffer.
348 *
349 * @returns VBox status code.
350 * @param pIntNet The instance data.
351 * @param hIF The interface handle.
352 * @param ppRing0Buf Where to store the address of the ring-3 mapping.
353 */
354INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing0Buf);
355
356/**
357 * Maps the default buffer into ring 3.
358 *
359 * @returns VBox status code.
360 * @param pIntNet The instance data.
361 * @param hIF The interface handle.
362 * @param ppRing3Buf Where to store the address of the ring-3 mapping.
363 */
364INTNETR0DECL(int) INTNETR0IfGetRing3Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing3Buf);
365
366/**
367 * Sets the promiscuous mode property of an interface.
368 *
369 * @returns VBox status code.
370 * @param pIntNet The instance handle.
371 * @param hIf The interface handle.
372 * @param fPromiscuous Set if the interface should be in promiscuous mode, clear if not.
373 */
374INTNETR0DECL(int) INTNETR0IfSetPromiscuousMode(PINTNET pIntNet, INTNETIFHANDLE hIf, bool fPromiscuous);
375
376/**
377 * Sends one or more frames.
378 *
379 * The function will first the frame which is passed as the optional
380 * arguments pvFrame and cbFrame. These are optional since it also
381 * possible to chain together one or more frames in the send buffer
382 * which the function will process after considering it's arguments.
383 *
384 * @returns VBox status code.
385 * @param pIntNet The instance data.
386 * @param hIF The interface handle.
387 * @param pvFrame Pointer to the frame.
388 * @param cbFrame Size of the frame.
389 */
390INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, const void *pvFrame, unsigned cbFrame);
391
392/**
393 * Wait for the interface to get signaled.
394 * The interface will be signaled when is put into the receive buffer.
395 *
396 * @returns VBox status code.
397 * @param pIntNet The instance handle.
398 * @param hIf The interface handle.
399 * @param cMillies Number of milliseconds to wait. RT_INDEFINITE_WAIT should be
400 * used if indefinite wait is desired.
401 */
402INTNETR0DECL(int) INTNETR0IfWait(PINTNET pIntNet, INTNETIFHANDLE hIf, unsigned cMillies);
403
404/** @} */
405#endif /* IN_RING0 */
406
407__END_DECLS
408
409#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