1 /*
2 * Copyright 2009 VMware, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /*
26 * This file holds the function implementation for one of the rbug extensions.
27 * Prototypes and declerations of functions and structs is in the same folder
28 * in the header file matching this file's name.
29 *
30 * The functions starting rbug_send_* encodes a call to the write format and
31 * sends that to the supplied connection, while functions starting with
32 * rbug_demarshal_* demarshal data in the wire protocol.
33 *
34 * Functions ending with _reply are replies to requests.
35 */
36
37 #include "rbug_internal.h"
38 #include "rbug_core.h"
39
rbug_send_noop(struct rbug_connection * __con,uint32_t * __serial)40 int rbug_send_noop(struct rbug_connection *__con,
41 uint32_t *__serial)
42 {
43 uint32_t __len = 0;
44 uint32_t __pos = 0;
45 uint8_t *__data = NULL;
46 int __ret = 0;
47
48 LEN(8); /* header */
49
50 /* align */
51 PAD(__len, 8);
52
53 __data = (uint8_t*)MALLOC(__len);
54 if (!__data)
55 return -ENOMEM;
56
57 WRITE(4, int32_t, ((int32_t)RBUG_OP_NOOP));
58 WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
59
60 /* final pad */
61 PAD(__pos, 8);
62
63 if (__pos != __len) {
64 __ret = -EINVAL;
65 } else {
66 rbug_connection_send_start(__con, RBUG_OP_NOOP, __len);
67 rbug_connection_write(__con, __data, __len);
68 __ret = rbug_connection_send_finish(__con, __serial);
69 }
70
71 FREE(__data);
72 return __ret;
73 }
74
rbug_send_ping(struct rbug_connection * __con,uint32_t * __serial)75 int rbug_send_ping(struct rbug_connection *__con,
76 uint32_t *__serial)
77 {
78 uint32_t __len = 0;
79 uint32_t __pos = 0;
80 uint8_t *__data = NULL;
81 int __ret = 0;
82
83 LEN(8); /* header */
84
85 /* align */
86 PAD(__len, 8);
87
88 __data = (uint8_t*)MALLOC(__len);
89 if (!__data)
90 return -ENOMEM;
91
92 WRITE(4, int32_t, ((int32_t)RBUG_OP_PING));
93 WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
94
95 /* final pad */
96 PAD(__pos, 8);
97
98 if (__pos != __len) {
99 __ret = -EINVAL;
100 } else {
101 rbug_connection_send_start(__con, RBUG_OP_PING, __len);
102 rbug_connection_write(__con, __data, __len);
103 __ret = rbug_connection_send_finish(__con, __serial);
104 }
105
106 FREE(__data);
107 return __ret;
108 }
109
rbug_send_error(struct rbug_connection * __con,uint32_t error,uint32_t * __serial)110 int rbug_send_error(struct rbug_connection *__con,
111 uint32_t error,
112 uint32_t *__serial)
113 {
114 uint32_t __len = 0;
115 uint32_t __pos = 0;
116 uint8_t *__data = NULL;
117 int __ret = 0;
118
119 LEN(8); /* header */
120 LEN(4); /* error */
121
122 /* align */
123 PAD(__len, 8);
124
125 __data = (uint8_t*)MALLOC(__len);
126 if (!__data)
127 return -ENOMEM;
128
129 WRITE(4, int32_t, ((int32_t)RBUG_OP_ERROR));
130 WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
131 WRITE(4, uint32_t, error); /* error */
132
133 /* final pad */
134 PAD(__pos, 8);
135
136 if (__pos != __len) {
137 __ret = -EINVAL;
138 } else {
139 rbug_connection_send_start(__con, RBUG_OP_ERROR, __len);
140 rbug_connection_write(__con, __data, __len);
141 __ret = rbug_connection_send_finish(__con, __serial);
142 }
143
144 FREE(__data);
145 return __ret;
146 }
147
rbug_send_ping_reply(struct rbug_connection * __con,uint32_t serial,uint32_t * __serial)148 int rbug_send_ping_reply(struct rbug_connection *__con,
149 uint32_t serial,
150 uint32_t *__serial)
151 {
152 uint32_t __len = 0;
153 uint32_t __pos = 0;
154 uint8_t *__data = NULL;
155 int __ret = 0;
156
157 LEN(8); /* header */
158 LEN(4); /* serial */
159
160 /* align */
161 PAD(__len, 8);
162
163 __data = (uint8_t*)MALLOC(__len);
164 if (!__data)
165 return -ENOMEM;
166
167 WRITE(4, int32_t, ((int32_t)RBUG_OP_PING_REPLY));
168 WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
169 WRITE(4, uint32_t, serial); /* serial */
170
171 /* final pad */
172 PAD(__pos, 8);
173
174 if (__pos != __len) {
175 __ret = -EINVAL;
176 } else {
177 rbug_connection_send_start(__con, RBUG_OP_PING_REPLY, __len);
178 rbug_connection_write(__con, __data, __len);
179 __ret = rbug_connection_send_finish(__con, __serial);
180 }
181
182 FREE(__data);
183 return __ret;
184 }
185
rbug_send_error_reply(struct rbug_connection * __con,uint32_t serial,uint32_t error,uint32_t * __serial)186 int rbug_send_error_reply(struct rbug_connection *__con,
187 uint32_t serial,
188 uint32_t error,
189 uint32_t *__serial)
190 {
191 uint32_t __len = 0;
192 uint32_t __pos = 0;
193 uint8_t *__data = NULL;
194 int __ret = 0;
195
196 LEN(8); /* header */
197 LEN(4); /* serial */
198 LEN(4); /* error */
199
200 /* align */
201 PAD(__len, 8);
202
203 __data = (uint8_t*)MALLOC(__len);
204 if (!__data)
205 return -ENOMEM;
206
207 WRITE(4, int32_t, ((int32_t)RBUG_OP_ERROR_REPLY));
208 WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
209 WRITE(4, uint32_t, serial); /* serial */
210 WRITE(4, uint32_t, error); /* error */
211
212 /* final pad */
213 PAD(__pos, 8);
214
215 if (__pos != __len) {
216 __ret = -EINVAL;
217 } else {
218 rbug_connection_send_start(__con, RBUG_OP_ERROR_REPLY, __len);
219 rbug_connection_write(__con, __data, __len);
220 __ret = rbug_connection_send_finish(__con, __serial);
221 }
222
223 FREE(__data);
224 return __ret;
225 }
226
rbug_demarshal_noop(struct rbug_proto_header * header)227 struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header)
228 {
229 struct rbug_proto_noop *ret;
230
231 if (!header)
232 return NULL;
233 if (header->opcode != (int32_t)RBUG_OP_NOOP)
234 return NULL;
235
236 ret = MALLOC(sizeof(*ret));
237 if (!ret)
238 return NULL;
239
240 ret->header.__message = header;
241 ret->header.opcode = header->opcode;
242
243 return ret;
244 }
245
rbug_demarshal_ping(struct rbug_proto_header * header)246 struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header)
247 {
248 struct rbug_proto_ping *ret;
249
250 if (!header)
251 return NULL;
252 if (header->opcode != (int32_t)RBUG_OP_PING)
253 return NULL;
254
255 ret = MALLOC(sizeof(*ret));
256 if (!ret)
257 return NULL;
258
259 ret->header.__message = header;
260 ret->header.opcode = header->opcode;
261
262 return ret;
263 }
264
rbug_demarshal_error(struct rbug_proto_header * header)265 struct rbug_proto_error * rbug_demarshal_error(struct rbug_proto_header *header)
266 {
267 uint32_t len = 0;
268 uint32_t pos = 0;
269 uint8_t *data = NULL;
270 struct rbug_proto_error *ret;
271
272 if (!header)
273 return NULL;
274 if (header->opcode != (int32_t)RBUG_OP_ERROR)
275 return NULL;
276
277 pos = 0;
278 len = header->length * 4;
279 data = (uint8_t*)&header[1];
280 ret = MALLOC(sizeof(*ret));
281 if (!ret)
282 return NULL;
283
284 ret->header.__message = header;
285 ret->header.opcode = header->opcode;
286
287 READ(4, uint32_t, error); /* error */
288
289 return ret;
290 }
291
rbug_demarshal_ping_reply(struct rbug_proto_header * header)292 struct rbug_proto_ping_reply * rbug_demarshal_ping_reply(struct rbug_proto_header *header)
293 {
294 uint32_t len = 0;
295 uint32_t pos = 0;
296 uint8_t *data = NULL;
297 struct rbug_proto_ping_reply *ret;
298
299 if (!header)
300 return NULL;
301 if (header->opcode != (int32_t)RBUG_OP_PING_REPLY)
302 return NULL;
303
304 pos = 0;
305 len = header->length * 4;
306 data = (uint8_t*)&header[1];
307 ret = MALLOC(sizeof(*ret));
308 if (!ret)
309 return NULL;
310
311 ret->header.__message = header;
312 ret->header.opcode = header->opcode;
313
314 READ(4, uint32_t, serial); /* serial */
315
316 return ret;
317 }
318
rbug_demarshal_error_reply(struct rbug_proto_header * header)319 struct rbug_proto_error_reply * rbug_demarshal_error_reply(struct rbug_proto_header *header)
320 {
321 uint32_t len = 0;
322 uint32_t pos = 0;
323 uint8_t *data = NULL;
324 struct rbug_proto_error_reply *ret;
325
326 if (!header)
327 return NULL;
328 if (header->opcode != (int32_t)RBUG_OP_ERROR_REPLY)
329 return NULL;
330
331 pos = 0;
332 len = header->length * 4;
333 data = (uint8_t*)&header[1];
334 ret = MALLOC(sizeof(*ret));
335 if (!ret)
336 return NULL;
337
338 ret->header.__message = header;
339 ret->header.opcode = header->opcode;
340
341 READ(4, uint32_t, serial); /* serial */
342 READ(4, uint32_t, error); /* error */
343
344 return ret;
345 }
346