VirtualBox

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

Last change on this file since 4878 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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