1 /* Copyright (C) 2009, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 - Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15 - Neither the name of the Developers nor the names of its contributors may
16 be used to endorse or promote products derived from this software without
17 specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <arpa/inet.h>
43 void dumpmsg(uint8_t *data, int size);
45 void Msg_addPreamble(uint8_t *buffer, uint16_t type, uint32_t len)
47 uint16_t *msgType = (uint16_t *) &buffer[0];
48 uint32_t *msgLen = (uint32_t *) &buffer[2];
50 *msgType = htons(type);
54 static void Msg_getPreamble(uint8_t *buffer, int *type, int *len)
56 uint16_t *msgType = (uint16_t *) &buffer[0];
57 uint32_t *msgLen = (uint32_t *) &buffer[2];
59 *type = (int)ntohs(*msgType);
60 *len = (int)ntohl(*msgLen);
63 #define MAX_MSGSIZE (BUFSIZE - 6)
64 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
67 uint8_t *bufptr = buffer + 6;
69 Log_debug("To net: msg type %d", msg->messageType);
70 switch (msg->messageType) {
72 len = mumble_proto__version__get_packed_size(msg->payload.version);
73 if (len > MAX_MSGSIZE) {
74 Log_warn("Too big tx message. Discarding");
77 Msg_addPreamble(buffer, msg->messageType, len);
78 mumble_proto__version__pack(msg->payload.version, bufptr);
81 len = mumble_proto__udptunnel__get_packed_size(msg->payload.UDPTunnel);
82 if (len > MAX_MSGSIZE) {
83 Log_warn("Too big tx message. Discarding");
86 Msg_addPreamble(buffer, msg->messageType, len);
87 mumble_proto__udptunnel__pack(msg->payload.UDPTunnel, bufptr);
90 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
91 if (len > MAX_MSGSIZE) {
92 Log_warn("Too big tx message. Discarding");
95 Msg_addPreamble(buffer, msg->messageType, len);
96 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
99 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
100 if (len > MAX_MSGSIZE) {
101 Log_warn("Too big tx message. Discarding");
104 Msg_addPreamble(buffer, msg->messageType, len);
105 mumble_proto__ping__pack(msg->payload.ping, bufptr);
108 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
109 if (len > MAX_MSGSIZE) {
110 Log_warn("Too big tx message. Discarding");
113 Msg_addPreamble(buffer, msg->messageType, len);
114 mumble_proto__reject__pack(msg->payload.reject, bufptr);
117 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
118 if (len > MAX_MSGSIZE) {
119 Log_warn("Too big tx message. Discarding");
122 Msg_addPreamble(buffer, msg->messageType, len);
123 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
126 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
127 if (len > MAX_MSGSIZE) {
128 Log_warn("Too big tx message. Discarding");
131 Msg_addPreamble(buffer, msg->messageType, len);
132 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
134 case PermissionDenied:
135 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
136 if (len > MAX_MSGSIZE) {
137 Log_warn("Too big tx message. Discarding");
140 Msg_addPreamble(buffer, msg->messageType, len);
141 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
144 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
145 if (len > MAX_MSGSIZE) {
146 Log_warn("Too big tx message. Discarding");
149 Msg_addPreamble(buffer, msg->messageType, len);
150 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
153 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
154 if (len > MAX_MSGSIZE) {
155 Log_warn("Too big tx message. Discarding");
158 Msg_addPreamble(buffer, msg->messageType, len);
159 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
162 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
163 if (len > MAX_MSGSIZE) {
164 Log_warn("Too big tx message. Discarding");
167 Msg_addPreamble(buffer, msg->messageType, len);
168 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
171 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
172 if (len > MAX_MSGSIZE) {
173 Log_warn("Too big tx message. Discarding");
176 Msg_addPreamble(buffer, msg->messageType, len);
177 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
180 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
181 if (len > MAX_MSGSIZE) {
182 Log_warn("Too big tx message. Discarding");
185 Msg_addPreamble(buffer, msg->messageType, len);
186 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
189 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
190 if (len > MAX_MSGSIZE) {
191 Log_warn("Too big tx message. Discarding");
194 Msg_addPreamble(buffer, msg->messageType, len);
195 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
199 Log_warn("Unsupported message %d", msg->messageType);
205 message_t *Msg_create(messageType_t messageType)
207 message_t *msg = malloc(sizeof(message_t));
210 Log_fatal("Out of memory");
211 memset(msg, 0, sizeof(message_t));
213 msg->messageType = messageType;
214 init_list_entry(&msg->node);
216 switch (messageType) {
218 msg->payload.version = malloc(sizeof(MumbleProto__Version));
219 mumble_proto__version__init(msg->payload.version);
222 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
223 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
226 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
227 mumble_proto__authenticate__init(msg->payload.authenticate);
230 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
231 mumble_proto__ping__init(msg->payload.ping);
234 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
235 mumble_proto__reject__init(msg->payload.reject);
238 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
239 mumble_proto__server_sync__init(msg->payload.serverSync);
242 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
243 mumble_proto__text_message__init(msg->payload.textMessage);
245 case PermissionDenied:
246 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
247 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
250 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
251 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
254 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
255 mumble_proto__user_list__init(msg->payload.userList);
258 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
259 mumble_proto__user_state__init(msg->payload.userState);
262 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
263 mumble_proto__user_remove__init(msg->payload.userRemove);
266 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
267 mumble_proto__voice_target__init(msg->payload.voiceTarget);
270 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
271 mumble_proto__codec_version__init(msg->payload.codecVersion);
274 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
275 mumble_proto__channel_state__init(msg->payload.channelState);
279 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
286 void Msg_inc_ref(message_t *msg)
291 void Msg_free(message_t *msg)
293 if (msg->refcount) msg->refcount--;
294 if (msg->refcount > 0)
297 /* XXX - add free for locally generated messages too */
298 switch (msg->messageType) {
301 mumble_proto__version__free_unpacked(msg->payload.version, NULL);
303 free(msg->payload.version);
308 mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
310 free(msg->payload.UDPTunnel->packet.data);
311 free(msg->payload.UDPTunnel);
316 mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
320 mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
322 free(msg->payload.ping);
327 mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
329 free(msg->payload.reject->reason);
330 free(msg->payload.reject);
335 mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
337 free(msg->payload.serverSync->welcome_text);
338 free(msg->payload.serverSync);
343 mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
345 free(msg->payload.textMessage);
348 case PermissionDenied:
350 mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
352 free(msg->payload.permissionDenied->reason);
353 free(msg->payload.permissionDenied);
358 mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
360 free(msg->payload.cryptSetup);
365 mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
367 free(msg->payload.userList);
372 mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
374 free(msg->payload.userState->name);
375 free(msg->payload.userState);
380 mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
382 free(msg->payload.userRemove);
387 mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
389 free(msg->payload.voiceTarget);
394 mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
396 free(msg->payload.codecVersion);
401 mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
403 if (msg->payload.channelState->description)
404 free(msg->payload.channelState->description);
405 free(msg->payload.channelState->name);
406 free(msg->payload.channelState);
411 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
417 void dumpmsg(uint8_t *data, int size)
419 int i, r = 0, offset = 0;
422 while (r * 8 + i < size) {
423 for (i = 0; i < 8 && r * 8 + i < size; i++) {
424 offset += sprintf(buf + offset, "%x ", data[r * 8 + i]);
426 sprintf(buf + offset, "\n");
434 message_t *Msg_networkToMessage(uint8_t *data, int size)
436 message_t *msg = NULL;
437 uint8_t *msgData = &data[6];
438 int messageType, msgLen;
440 Msg_getPreamble(data, &messageType, &msgLen);
442 Log_debug("Message type %d size %d", messageType, msgLen);
445 switch (messageType) {
448 msg = Msg_create(Version);
449 msg->unpacked = true;
450 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
455 msg = Msg_create(UDPTunnel);
456 msg->unpacked = true;
457 msg->payload.UDPTunnel = mumble_proto__udptunnel__unpack(NULL, msgLen, msgData);
462 msg = Msg_create(Authenticate);
463 msg->unpacked = true;
464 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
469 msg = Msg_create(Ping);
470 msg->unpacked = true;
471 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
476 msg = Msg_create(Reject);
477 msg->unpacked = true;
478 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
483 msg = Msg_create(ServerSync);
484 msg->unpacked = true;
485 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
490 msg = Msg_create(TextMessage);
491 msg->unpacked = true;
492 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
495 case PermissionDenied:
497 msg = Msg_create(PermissionDenied);
498 msg->unpacked = true;
499 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
504 msg = Msg_create(CryptSetup);
505 msg->unpacked = true;
506 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
511 msg = Msg_create(UserList);
512 msg->unpacked = true;
513 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
518 msg = Msg_create(UserState);
519 msg->unpacked = true;
520 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
525 msg = Msg_create(VoiceTarget);
526 msg->unpacked = true;
527 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
532 msg = Msg_create(CodecVersion);
533 msg->unpacked = true;
534 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
539 Log_warn("Unsupported message %d", messageType);