1
/*********************************************************
2
* Copyright (C) 2007 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the
6
* Free Software Foundation version 2 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* You should have received a copy of the GNU General Public License along
14
* with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
*********************************************************/
22
* Packet constants, types and functions.
25
#if defined(_WIN32) || defined(VMKERNEL)
26
# include "vsockOSInt.h"
28
# define VSockOS_ClearMemory(_dst, _sz) memset(_dst, 0, _sz)
29
# define VSockOS_Memcpy(_dst, _src, _sz) memcpy(_dst, _src, _sz)
33
#ifndef _VSOCK_PACKET_H_
34
#define _VSOCK_PACKET_H_
37
/* If the packet format changes in a release then this should change too. */
38
#define VSOCK_PACKET_VERSION 1
40
/* The resource ID on which control packets are sent. */
41
#define VSOCK_PACKET_RID 1
43
/* Assert that the given packet is valid. */
44
#define VSOCK_PACKET_ASSERT(_p) \
46
ASSERT((_p)->type < VSOCK_PACKET_TYPE_MAX); \
47
ASSERT(0 == (_p)->_reserved1); \
48
ASSERT(0 == (_p)->_reserved2)
51
typedef enum VSockPacketType {
52
VSOCK_PACKET_TYPE_INVALID = 0, // Invalid type.
53
VSOCK_PACKET_TYPE_REQUEST, // Connection request.
54
VSOCK_PACKET_TYPE_NEGOTIATE, // Connection negotiate.
55
VSOCK_PACKET_TYPE_OFFER, // Connection offer queue pair.
56
VSOCK_PACKET_TYPE_ATTACH, // Connection attach.
57
VSOCK_PACKET_TYPE_WROTE, // Wrote data to queue pair.
58
VSOCK_PACKET_TYPE_READ, // Read data from queue pair.
59
VSOCK_PACKET_TYPE_RST, // Reset.
60
VSOCK_PACKET_TYPE_SHUTDOWN, // Shutdown the connection.
61
VSOCK_PACKET_TYPE_WAITING_WRITE, // Notify peer we are waiting to write.
62
VSOCK_PACKET_TYPE_WAITING_READ, // Notify peer we are waiting to read.
63
VSOCK_PACKET_TYPE_MAX // Last message.
66
typedef struct VSockWaitingInfo {
67
uint64 generation; // Generation of the queue.
68
uint64 offset; // Offset within the queue.
72
* Control packet type for STREAM sockets. DGRAMs have no control packets
73
* nor special packet header for data packets, they are just raw VMCI DGRAM
74
* messages. For STREAMs, control packets are sent over the control channel
75
* while data is written and read directly from queue pairs with no packet
78
typedef struct VSockPacket {
79
VMCIDatagram dg; // Datagram header.
80
uint8 version; // Version.
81
uint8 type; // Type of message.
82
uint16 _reserved1; // Reserved.
83
uint32 srcPort; // Source port.
84
uint32 dstPort; // Destination port.
85
uint32 _reserved2; // Reserved.
87
uint64 size; // Size of queue pair for request/negotiation.
88
uint64 mode; // Mode of shutdown for shutdown.
89
VMCIHandle handle; // Queue pair handle once size negotiated.
90
VSockWaitingInfo wait; // Information provided for wait notifications.
95
MY_ASSERTS(VSockPacketAsserts,
96
ASSERT_ON_COMPILE(sizeof (VSockPacket) == 56);
101
*-----------------------------------------------------------------------------
103
* VSockPacket_Init --
105
* Initialize the given packet. The packet version is set and the fields
106
* are filled out. Reserved fields are cleared.
114
*-----------------------------------------------------------------------------
118
VSockPacket_Init(VSockPacket *pkt, // OUT
119
struct sockaddr_vm *src, // IN
120
struct sockaddr_vm *dst, // IN
124
VSockWaitingInfo *wait, // IN
125
VMCIHandle handle) // IN
128
VSOCK_ADDR_NOFAMILY_ASSERT(src);
129
VSOCK_ADDR_NOFAMILY_ASSERT(dst);
131
pkt->dg.src = VMCI_MAKE_HANDLE(src->svm_cid, VSOCK_PACKET_RID);
132
pkt->dg.dst = VMCI_MAKE_HANDLE(dst->svm_cid, VSOCK_PACKET_RID);
133
pkt->dg.payloadSize = sizeof *pkt - sizeof pkt->dg;
134
pkt->version = VSOCK_PACKET_VERSION;
136
pkt->srcPort = src->svm_port;
137
pkt->dstPort = dst->svm_port;
138
VSockOS_ClearMemory(&pkt->_reserved1, sizeof pkt->_reserved1);
139
VSockOS_ClearMemory(&pkt->_reserved2, sizeof pkt->_reserved2);
142
case VSOCK_PACKET_TYPE_INVALID:
146
case VSOCK_PACKET_TYPE_REQUEST:
147
case VSOCK_PACKET_TYPE_NEGOTIATE:
151
case VSOCK_PACKET_TYPE_OFFER:
152
case VSOCK_PACKET_TYPE_ATTACH:
153
pkt->u.handle = handle;
156
case VSOCK_PACKET_TYPE_WROTE:
157
case VSOCK_PACKET_TYPE_READ:
158
case VSOCK_PACKET_TYPE_RST:
162
case VSOCK_PACKET_TYPE_SHUTDOWN:
166
case VSOCK_PACKET_TYPE_WAITING_READ:
167
case VSOCK_PACKET_TYPE_WAITING_WRITE:
169
VSockOS_Memcpy(&pkt->u.wait, wait, sizeof pkt->u.wait);
173
VSOCK_PACKET_ASSERT(pkt);
178
*-----------------------------------------------------------------------------
180
* VSockPacket_Validate --
182
* Validate the given packet.
185
* 0 on success, EFAULT if the address is invalid, EINVAL if the packet
186
* fields are invalid.
191
*-----------------------------------------------------------------------------
195
VSockPacket_Validate(VSockPacket *pkt)
204
if (VMCI_HANDLE_INVALID(pkt->dg.src)) {
208
if (VMCI_HANDLE_INVALID(pkt->dg.dst)) {
212
if (VMCI_INVALID_ID == pkt->dstPort || VMCI_INVALID_ID == pkt->srcPort) {
216
if (VSOCK_PACKET_VERSION != pkt->version) {
220
if (0 != pkt->_reserved1 || 0 != pkt->_reserved2) {
225
case VSOCK_PACKET_TYPE_INVALID:
226
if (0 != pkt->u.size) {
231
case VSOCK_PACKET_TYPE_REQUEST:
232
case VSOCK_PACKET_TYPE_NEGOTIATE:
233
if (0 == pkt->u.size) {
238
case VSOCK_PACKET_TYPE_OFFER:
239
case VSOCK_PACKET_TYPE_ATTACH:
240
if (VMCI_HANDLE_INVALID(pkt->u.handle)) {
245
case VSOCK_PACKET_TYPE_WROTE:
246
case VSOCK_PACKET_TYPE_READ:
247
case VSOCK_PACKET_TYPE_RST:
248
if (0 != pkt->u.size) {
257
return sockerr2err(err);
262
*-----------------------------------------------------------------------------
264
* VSockPacket_GetAddresses --
266
* Get the local and remote addresses from the given packet.
274
*-----------------------------------------------------------------------------
278
VSockPacket_GetAddresses(VSockPacket *pkt, // IN
279
struct sockaddr_vm *local, // OUT
280
struct sockaddr_vm *remote) // OUT
282
VSOCK_PACKET_ASSERT(pkt);
283
VSockAddr_Init(local, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst),
285
VSockAddr_Init(remote, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src),
290
#endif // _VSOCK_PACKET_H_