VirtualBox

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

Last change on this file since 7581 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

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