VirtualBox

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

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

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.2 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;
124typedef INTNETBUF *PINTNETBUF;
125
126/** Internal networking interface handle. */
127typedef uint32_t INTNETIFHANDLE;
128/** Pointer to an internal networking interface handle. */
129typedef INTNETIFHANDLE *PINTNETIFHANDLE;
130
131/** Or mask to obscure the handle index. */
132#define INTNET_HANDLE_MAGIC 0x88880000
133/** Mask to extract the handle index. */
134#define INTNET_HANDLE_INDEX_MASK 0xffff
135/** The maximum number of handles (exclusive) */
136#define INTNET_HANDLE_MAX 0xffff
137/** Invalid handle. */
138#define INTNET_HANDLE_INVALID (0)
139
140
141/**
142 * The packet header.
143 *
144 * The header is intentionally 8 bytes long. It will always
145 * start at an 8 byte aligned address. Assuming that the buffer
146 * size is a multiple of 8 bytes, that means that we can guarantee
147 * that the entire header is contiguous in both virtual and physical
148 * memory.
149 */
150#pragma pack(1)
151typedef struct INTNETHDR
152{
153 /** Header type. This is currently serving as a magic, it
154 * can be extended later to encode special command packets and stuff.. */
155 uint16_t u16Type;
156 /** The size of the frame. */
157 uint16_t cbFrame;
158 /** The offset from the start of this header to where the actual frame starts.
159 * This is used to keep the frame it self continguous in virtual memory and
160 * thereby both simplify reading and */
161 int32_t offFrame;
162} INTNETHDR, *PINTNETHDR;
163#pragma pack()
164
165/** INTNETHDR::u16Type value for normal frames. */
166#define INTNETHDR_TYPE_FRAME 0x2442
167
168
169/**
170 * Calculates the pointer to the frame.
171 *
172 * @returns Pointer to the start of the frame.
173 * @param pHdr Pointer to the packet header
174 * @param pBuf The buffer the header is within. Only used in strict builds.
175 */
176DECLINLINE(void *) INTNETHdrGetFramePtr(PINTNETHDR pHdr, PINTNETBUF pBuf)
177{
178 uint8_t *pu8 = (uint8_t *)pHdr + pHdr->offFrame;
179#ifdef VBOX_STRICT
180 const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf;
181 Assert(pHdr->u16Type == INTNETHDR_TYPE_FRAME);
182 Assert(off < pBuf->cbBuf);
183 Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
184#endif
185 NOREF(pBuf);
186 return pu8;
187}
188
189
190/**
191 * Skips to the next (read) frame in the buffer.
192 *
193 * @param pBuf The buffer.
194 * @param pRingBuf The ring buffer in question.
195 */
196DECLINLINE(void) INTNETRingSkipFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf)
197{
198 Assert(pRingBuf->offRead < pBuf->cbBuf);
199 Assert(pRingBuf->offRead >= pRingBuf->offStart);
200 Assert(pRingBuf->offRead < pRingBuf->offEnd);
201 uint32_t offRead = pRingBuf->offRead;
202 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offRead);
203
204 /* skip the frame */
205 offRead += pHdr->offFrame + pHdr->cbFrame;
206 offRead = RT_ALIGN_32(offRead, sizeof(INTNETHDR));
207 Assert(offRead <= pRingBuf->offEnd && offRead >= pRingBuf->offStart);
208 if (offRead >= pRingBuf->offEnd)
209 offRead = pRingBuf->offStart;
210 ASMAtomicXchgU32(&pRingBuf->offRead, offRead);
211}
212
213/** The maximum length of a network name. */
214#define INTNET_MAX_NETWORK_NAME 128
215
216
217/**
218 * Request buffer for INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN.
219 * @see INTNETR0Open.
220 */
221typedef struct INTNETOPENREQ
222{
223 /** The request header. */
224 SUPVMMR0REQHDR Hdr;
225 /** The network name. (input) */
226 char szNetwork[INTNET_MAX_NETWORK_NAME];
227 /** The size of the send buffer. (input) */
228 uint32_t cbSend;
229 /** The size of the receive buffer. (input) */
230 uint32_t cbRecv;
231 /** Whether new participants should be subjected to access check or not. */
232 bool fRestrictAccess;
233 /** The handle to the network interface. (output) */
234 INTNETIFHANDLE hIf;
235} INTNETOPENREQ;
236/** Pointer to an INTNETR0OpenReq / VMMR0_DO_INTNET_OPEN request buffer. */
237typedef INTNETOPENREQ *PINTNETOPENREQ;
238
239INTNETR0DECL(int) INTNETR0OpenReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETOPENREQ pReq);
240
241
242/**
243 * Request buffer for INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE.
244 * @see INTNETR0IfClose.
245 */
246typedef struct INTNETIFCLOSEREQ
247{
248 /** The request header. */
249 SUPVMMR0REQHDR Hdr;
250 /** The handle to the network interface. */
251 INTNETIFHANDLE hIf;
252} INTNETIFCLOSEREQ;
253/** Pointer to an INTNETR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE request buffer. */
254typedef INTNETIFCLOSEREQ *PINTNETIFCLOSEREQ;
255
256INTNETR0DECL(int) INTNETR0IfCloseReq(PINTNET pIntNet, PINTNETIFCLOSEREQ pReq);
257
258
259/**
260 * Request buffer for INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER.
261 * @see INTNETR0IfGetRing3Buffer.
262 */
263typedef struct INTNETIFGETRING3BUFFERREQ
264{
265 /** The request header. */
266 SUPVMMR0REQHDR Hdr;
267 /** Handle to the interface. */
268 INTNETIFHANDLE hIf;
269 /** The pointer to the ring3 buffer. (output) */
270 R3PTRTYPE(PINTNETBUF) pRing3Buf;
271} INTNETIFGETRING3BUFFERREQ;
272/** Pointer to an INTNETR0IfGetRing3BufferReq / VMMR0_DO_INTNET_IF_GET_RING3_BUFFER request buffer. */
273typedef INTNETIFGETRING3BUFFERREQ *PINTNETIFGETRING3BUFFERREQ;
274
275INTNETR0DECL(int) INTNETR0IfGetRing3BufferReq(PINTNET pIntNet, PINTNETIFGETRING3BUFFERREQ pReq);
276
277
278/**
279 * Request buffer for INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE.
280 * @see INTNETR0IfSetPromiscuousMode.
281 */
282typedef struct INTNETIFSETPROMISCUOUSMODEREQ
283{
284 /** The request header. */
285 SUPVMMR0REQHDR Hdr;
286 /** Handle to the interface. */
287 INTNETIFHANDLE hIf;
288 /** The new promiscuous mode. */
289 bool fPromiscuous;
290} INTNETIFSETPROMISCUOUSMODEREQ;
291/** Pointer to an INTNETR0IfSetPromiscuousModeReq / VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE request buffer. */
292typedef INTNETIFSETPROMISCUOUSMODEREQ *PINTNETIFSETPROMISCUOUSMODEREQ;
293
294INTNETR0DECL(int) INTNETR0IfSetPromiscuousModeReq(PINTNET pIntNet, PINTNETIFSETPROMISCUOUSMODEREQ pReq);
295
296
297/**
298 * Request buffer for INTNETR0IfSendReq / VMMR0_DO_INTNET_IF_SEND.
299 * @see INTNETR0IfSend.
300 */
301typedef struct INTNETIFSENDREQ
302{
303 /** The request header. */
304 SUPVMMR0REQHDR Hdr;
305 /** Handle to the interface. */
306 INTNETIFHANDLE hIf;
307} INTNETIFSENDREQ;
308/** Pointer to an INTNETR0IfSend() argument package. */
309typedef INTNETIFSENDREQ *PINTNETIFSENDREQ;
310
311INTNETR0DECL(int) INTNETR0IfSendReq(PINTNET pIntNet, PINTNETIFSENDREQ pReq);
312
313
314/**
315 * Request buffer for INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT.
316 * @see INTNETR0IfWait.
317 */
318typedef struct INTNETIFWAITREQ
319{
320 /** The request header. */
321 SUPVMMR0REQHDR Hdr;
322 /** Handle to the interface. */
323 INTNETIFHANDLE hIf;
324 /** The number of milliseconds to wait. */
325 uint32_t cMillies;
326} INTNETIFWAITREQ;
327/** Pointer to an INTNETR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT request buffer. */
328typedef INTNETIFWAITREQ *PINTNETIFWAITREQ;
329
330INTNETR0DECL(int) INTNETR0IfWaitReq(PINTNET pIntNet, PINTNETIFWAITREQ pReq);
331
332
333#if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
334/** @name
335 * @{
336 */
337
338/**
339 * Create an instance of the Ring-0 internal networking service.
340 *
341 * @returns VBox status code.
342 * @param ppIntNet Where to store the instance pointer.
343 */
344INTNETR0DECL(int) INTNETR0Create(PINTNET *ppIntNet);
345
346/**
347 * Destroys an instance of the Ring-0 internal networking service.
348 *
349 * @param pIntNet Pointer to the instance data.
350 */
351INTNETR0DECL(void) INTNETR0Destroy(PINTNET pIntNet);
352
353/**
354 * Opens a network interface and attaches it to the specified network.
355 *
356 * @returns VBox status code.
357 * @param pIntNet The internal network instance.
358 * @param pSession The session handle.
359 * @param pszNetwork The network name.
360 * @param cbSend The send buffer size.
361 * @param cbRecv The receive buffer size.
362 * @param fRestrictAccess Whether new participants should be subjected to access check or not.
363 * @param phIf Where to store the handle to the network interface.
364 */
365INTNETR0DECL(int) INTNETR0Open(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, unsigned cbSend, unsigned cbRecv, bool fRestrictAccess, PINTNETIFHANDLE phIf);
366
367/**
368 * Close an interface.
369 *
370 * @returns VBox status code.
371 * @param pIntNet The instance handle.
372 * @param hIf The interface handle.
373 */
374INTNETR0DECL(int) INTNETR0IfClose(PINTNET pIntNet, INTNETIFHANDLE hIf);
375
376/**
377 * Gets the ring-0 address of the current buffer.
378 *
379 * @returns VBox status code.
380 * @param pIntNet The instance data.
381 * @param hIF The interface handle.
382 * @param ppRing0Buf Where to store the address of the ring-3 mapping.
383 */
384INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing0Buf);
385
386/**
387 * Maps the default buffer into ring 3.
388 *
389 * @returns VBox status code.
390 * @param pIntNet The instance data.
391 * @param hIF The interface handle.
392 * @param ppRing3Buf Where to store the address of the ring-3 mapping.
393 */
394INTNETR0DECL(int) INTNETR0IfGetRing3Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, R3PTRTYPE(PINTNETBUF) *ppRing3Buf);
395
396/**
397 * Sets the promiscuous mode property of an interface.
398 *
399 * @returns VBox status code.
400 * @param pIntNet The instance handle.
401 * @param hIf The interface handle.
402 * @param fPromiscuous Set if the interface should be in promiscuous mode, clear if not.
403 */
404INTNETR0DECL(int) INTNETR0IfSetPromiscuousMode(PINTNET pIntNet, INTNETIFHANDLE hIf, bool fPromiscuous);
405
406/**
407 * Sends one or more frames.
408 *
409 * The function will first the frame which is passed as the optional
410 * arguments pvFrame and cbFrame. These are optional since it also
411 * possible to chain together one or more frames in the send buffer
412 * which the function will process after considering it's arguments.
413 *
414 * @returns VBox status code.
415 * @param pIntNet The instance data.
416 * @param hIF The interface handle.
417 * @param pvFrame Pointer to the frame.
418 * @param cbFrame Size of the frame.
419 */
420INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, const void *pvFrame, unsigned cbFrame);
421
422/**
423 * Wait for the interface to get signaled.
424 * The interface will be signaled when is put into the receive buffer.
425 *
426 * @returns VBox status code.
427 * @param pIntNet The instance handle.
428 * @param hIf The interface handle.
429 * @param cMillies Number of milliseconds to wait. RT_INDEFINITE_WAIT should be
430 * used if indefinite wait is desired.
431 */
432INTNETR0DECL(int) INTNETR0IfWait(PINTNET pIntNet, INTNETIFHANDLE hIf, uint32_t cMillies);
433
434/** @} */
435#endif /* IN_RING0 */
436
437__END_DECLS
438
439#endif
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use