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 Log_debug("To net: Version->release: %s Version->os: %s",
79 msg->payload.version->release, msg->payload.version->os);
80 mumble_proto__version__pack(msg->payload.version, bufptr);
83 len = mumble_proto__udptunnel__get_packed_size(msg->payload.UDPTunnel);
84 if (len > MAX_MSGSIZE) {
85 Log_warn("Too big tx message. Discarding");
88 Msg_addPreamble(buffer, msg->messageType, len);
89 mumble_proto__udptunnel__pack(msg->payload.UDPTunnel, bufptr);
92 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
93 if (len > MAX_MSGSIZE) {
94 Log_warn("Too big tx message. Discarding");
97 Msg_addPreamble(buffer, msg->messageType, len);
98 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
101 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
102 if (len > MAX_MSGSIZE) {
103 Log_warn("Too big tx message. Discarding");
106 Msg_addPreamble(buffer, msg->messageType, len);
107 mumble_proto__ping__pack(msg->payload.ping, bufptr);
110 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
111 if (len > MAX_MSGSIZE) {
112 Log_warn("Too big tx message. Discarding");
115 Msg_addPreamble(buffer, msg->messageType, len);
116 mumble_proto__reject__pack(msg->payload.reject, bufptr);
119 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
120 if (len > MAX_MSGSIZE) {
121 Log_warn("Too big tx message. Discarding");
124 Msg_addPreamble(buffer, msg->messageType, len);
125 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
128 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
129 if (len > MAX_MSGSIZE) {
130 Log_warn("Too big tx message. Discarding");
133 Msg_addPreamble(buffer, msg->messageType, len);
134 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
136 case PermissionDenied:
137 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
138 if (len > MAX_MSGSIZE) {
139 Log_warn("Too big tx message. Discarding");
142 Msg_addPreamble(buffer, msg->messageType, len);
143 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
146 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
147 if (len > MAX_MSGSIZE) {
148 Log_warn("Too big tx message. Discarding");
151 Msg_addPreamble(buffer, msg->messageType, len);
152 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
155 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
156 if (len > MAX_MSGSIZE) {
157 Log_warn("Too big tx message. Discarding");
160 Msg_addPreamble(buffer, msg->messageType, len);
161 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
164 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
165 if (len > MAX_MSGSIZE) {
166 Log_warn("Too big tx message. Discarding");
169 Msg_addPreamble(buffer, msg->messageType, len);
170 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
173 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
174 if (len > MAX_MSGSIZE) {
175 Log_warn("Too big tx message. Discarding");
178 Msg_addPreamble(buffer, msg->messageType, len);
179 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
182 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
183 if (len > MAX_MSGSIZE) {
184 Log_warn("Too big tx message. Discarding");
187 Msg_addPreamble(buffer, msg->messageType, len);
188 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
191 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
192 if (len > MAX_MSGSIZE) {
193 Log_warn("Too big tx message. Discarding");
196 Msg_addPreamble(buffer, msg->messageType, len);
197 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
201 Log_warn("Unsupported message %d", msg->messageType);
207 message_t *Msg_create(messageType_t messageType)
209 message_t *msg = malloc(sizeof(message_t));
212 Log_fatal("Out of memory");
213 memset(msg, 0, sizeof(message_t));
215 msg->messageType = messageType;
216 init_list_entry(&msg->node);
218 switch (messageType) {
220 msg->payload.version = malloc(sizeof(MumbleProto__Version));
221 mumble_proto__version__init(msg->payload.version);
224 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
225 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
228 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
229 mumble_proto__authenticate__init(msg->payload.authenticate);
232 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
233 mumble_proto__ping__init(msg->payload.ping);
236 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
237 mumble_proto__reject__init(msg->payload.reject);
240 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
241 mumble_proto__server_sync__init(msg->payload.serverSync);
244 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
245 mumble_proto__text_message__init(msg->payload.textMessage);
247 case PermissionDenied:
248 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
249 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
252 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
253 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
256 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
257 mumble_proto__user_list__init(msg->payload.userList);
260 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
261 mumble_proto__user_state__init(msg->payload.userState);
264 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
265 mumble_proto__user_remove__init(msg->payload.userRemove);
268 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
269 mumble_proto__voice_target__init(msg->payload.voiceTarget);
272 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
273 mumble_proto__codec_version__init(msg->payload.codecVersion);
276 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
277 mumble_proto__channel_state__init(msg->payload.channelState);
281 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
288 void Msg_inc_ref(message_t *msg)
293 void Msg_free(message_t *msg)
295 if (msg->refcount) msg->refcount--;
296 if (msg->refcount > 0)
299 switch (msg->messageType) {
302 mumble_proto__version__free_unpacked(msg->payload.version, NULL);
304 if (msg->payload.version->release)
305 free(msg->payload.version->release);
306 if (msg->payload.version->os)
307 free(msg->payload.version->os);
308 if (msg->payload.version->os_version)
309 free(msg->payload.version->os_version);
310 free(msg->payload.version);
315 mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
317 free(msg->payload.UDPTunnel->packet.data);
318 free(msg->payload.UDPTunnel);
323 mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
327 mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
329 free(msg->payload.ping);
334 mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
336 free(msg->payload.reject->reason);
337 free(msg->payload.reject);
342 mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
344 free(msg->payload.serverSync->welcome_text);
345 free(msg->payload.serverSync);
350 mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
352 free(msg->payload.textMessage);
355 case PermissionDenied:
357 mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
359 free(msg->payload.permissionDenied->reason);
360 free(msg->payload.permissionDenied);
365 mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
367 free(msg->payload.cryptSetup);
372 mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
374 free(msg->payload.userList);
379 mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
381 free(msg->payload.userState->name);
382 free(msg->payload.userState);
387 mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
389 free(msg->payload.userRemove);
394 mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
396 free(msg->payload.voiceTarget);
401 mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
403 free(msg->payload.codecVersion);
408 mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
410 if (msg->payload.channelState->description)
411 free(msg->payload.channelState->description);
412 free(msg->payload.channelState->name);
413 free(msg->payload.channelState);
418 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
424 void dumpmsg(uint8_t *data, int size)
426 int i, r = 0, offset = 0;
429 while (r * 8 + i < size) {
430 for (i = 0; i < 8 && r * 8 + i < size; i++) {
431 offset += sprintf(buf + offset, "%x ", data[r * 8 + i]);
433 sprintf(buf + offset, "\n");
441 message_t *Msg_networkToMessage(uint8_t *data, int size)
443 message_t *msg = NULL;
444 uint8_t *msgData = &data[6];
445 int messageType, msgLen;
447 Msg_getPreamble(data, &messageType, &msgLen);
449 Log_debug("Message type %d size %d", messageType, msgLen);
452 switch (messageType) {
455 msg = Msg_create(Version);
456 msg->unpacked = true;
457 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
462 msg = Msg_create(UDPTunnel);
463 msg->unpacked = true;
464 msg->payload.UDPTunnel = mumble_proto__udptunnel__unpack(NULL, msgLen, msgData);
469 msg = Msg_create(Authenticate);
470 msg->unpacked = true;
471 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
476 msg = Msg_create(Ping);
477 msg->unpacked = true;
478 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
483 msg = Msg_create(Reject);
484 msg->unpacked = true;
485 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
490 msg = Msg_create(ServerSync);
491 msg->unpacked = true;
492 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
497 msg = Msg_create(TextMessage);
498 msg->unpacked = true;
499 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
502 case PermissionDenied:
504 msg = Msg_create(PermissionDenied);
505 msg->unpacked = true;
506 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
511 msg = Msg_create(CryptSetup);
512 msg->unpacked = true;
513 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
518 msg = Msg_create(UserList);
519 msg->unpacked = true;
520 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
525 msg = Msg_create(UserState);
526 msg->unpacked = true;
527 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
532 msg = Msg_create(VoiceTarget);
533 msg->unpacked = true;
534 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
539 msg = Msg_create(CodecVersion);
540 msg->unpacked = true;
541 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
546 Log_warn("Unsupported message %d", messageType);