Add functions for sending messages to clients with different Mumble versions.
[umurmur.git] / src / messages.c
1 /* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
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.
18
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.
30 */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <arpa/inet.h>
36
37 #include "messages.h"
38 #include "client.h"
39 #include "pds.h"
40 #include "log.h"
41
42 #define PREAMBLE_SIZE 6
43
44 static message_t *Msg_create_nopayload(messageType_t messageType);
45
46 static void Msg_addPreamble(uint8_t *buffer, uint16_t type, uint32_t len)
47 {       
48         buffer[1] = (type) & 0xff;
49         buffer[0] = (type >> 8) & 0xff;
50         
51         buffer[5] = (len) & 0xff;
52         buffer[4] = (len >> 8) & 0xff;
53         buffer[3] = (len >> 16) & 0xff;
54         buffer[2] = (len >> 24) & 0xff; 
55 }
56
57 static void Msg_getPreamble(uint8_t *buffer, int *type, int *len)
58 {
59         uint16_t msgType;
60         uint32_t msgLen;
61         
62         msgType = buffer[1] | (buffer[0] << 8);
63         msgLen = buffer[5] | (buffer[4] << 8) | (buffer[3] << 16) | (buffer[2] << 24);
64         *type = (int)msgType;
65         *len = (int)msgLen;
66 }
67
68 #define MAX_MSGSIZE (BUFSIZE - PREAMBLE_SIZE)
69 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
70 {
71         int len;
72         uint8_t *bufptr = buffer + PREAMBLE_SIZE;
73                 
74         Log_debug("To net: msg type %d", msg->messageType);
75         switch (msg->messageType) {
76         case Version:
77                 len = mumble_proto__version__get_packed_size(msg->payload.version);
78                 if (len > MAX_MSGSIZE) {
79                         Log_warn("Too big tx message. Discarding");
80                         break;
81                 }
82                 Msg_addPreamble(buffer, msg->messageType, len);
83                 mumble_proto__version__pack(msg->payload.version, bufptr);
84                 break;
85         case UDPTunnel: /* Non-standard handling of tunneled voice traffic. */
86                 if (msg->payload.UDPTunnel->packet.len > MAX_MSGSIZE) {
87                         Log_warn("Too big tx message. Discarding");
88                         break;
89                 }
90                 len = msg->payload.UDPTunnel->packet.len;
91                 Msg_addPreamble(buffer, msg->messageType, msg->payload.UDPTunnel->packet.len);
92                 memcpy(bufptr, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
93                 break;
94         case Authenticate:
95                 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
96                 if (len > MAX_MSGSIZE) {
97                         Log_warn("Too big tx message. Discarding");
98                         break;
99                         }
100                 Msg_addPreamble(buffer, msg->messageType, len);
101                 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
102                 break;
103         case Ping:
104                 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
105                 if (len > MAX_MSGSIZE) {
106                         Log_warn("Too big tx message. Discarding");
107                         break;
108                         }
109                 Msg_addPreamble(buffer, msg->messageType, len);
110                 mumble_proto__ping__pack(msg->payload.ping, bufptr);
111                 break;
112         case Reject:
113                 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
114                 if (len > MAX_MSGSIZE) {
115                         Log_warn("Too big tx message. Discarding");
116                         break;
117                         }
118                 Msg_addPreamble(buffer, msg->messageType, len);
119                 mumble_proto__reject__pack(msg->payload.reject, bufptr);
120                 break;
121         case ServerSync:
122                 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
123                 if (len > MAX_MSGSIZE) {
124                         Log_warn("Too big tx message. Discarding");
125                         break;
126                         }
127                 Msg_addPreamble(buffer, msg->messageType, len);
128                 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
129                 break;
130         case TextMessage:
131                 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
132                 if (len > MAX_MSGSIZE) {
133                         Log_warn("Too big tx message. Discarding");
134                         break;
135                         }
136                 Msg_addPreamble(buffer, msg->messageType, len);
137                 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
138                 break;
139         case PermissionDenied:
140                 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
141                 if (len > MAX_MSGSIZE) {
142                         Log_warn("Too big tx message. Discarding");
143                         break;
144                         }
145                 Msg_addPreamble(buffer, msg->messageType, len);
146                 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
147                 break;
148         case CryptSetup:
149                 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
150                 if (len > MAX_MSGSIZE) {
151                         Log_warn("Too big tx message. Discarding");
152                         break;
153                         }
154                 Msg_addPreamble(buffer, msg->messageType, len);
155                 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
156                 break;
157         case UserList:
158                 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
159                 if (len > MAX_MSGSIZE) {
160                         Log_warn("Too big tx message. Discarding");
161                         break;
162                         }
163                 Msg_addPreamble(buffer, msg->messageType, len);
164                 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
165                 break;
166         case UserState:
167                 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
168                 if (len > MAX_MSGSIZE) {
169                         Log_warn("Too big tx message. Discarding");
170                         break;
171                         }
172                 Msg_addPreamble(buffer, msg->messageType, len);
173                 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
174                 break;
175         case UserRemove:
176                 len = mumble_proto__user_remove__get_packed_size(msg->payload.userRemove);
177                 if (len > MAX_MSGSIZE) {
178                         Log_warn("Too big tx message. Discarding");
179                         break;
180                         }
181                 Msg_addPreamble(buffer, msg->messageType, len);
182                 mumble_proto__user_remove__pack(msg->payload.userRemove, bufptr);
183                 break;
184         case ChannelState:
185                 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
186                 if (len > MAX_MSGSIZE) {
187                         Log_warn("Too big tx message. Discarding");
188                         break;
189                         }
190                 Msg_addPreamble(buffer, msg->messageType, len);
191                 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
192                 break;
193         case VoiceTarget:
194                 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
195                 if (len > MAX_MSGSIZE) {
196                         Log_warn("Too big tx message. Discarding");
197                         break;
198                         }
199                 Msg_addPreamble(buffer, msg->messageType, len);
200                 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
201                 break;
202         case CodecVersion:
203                 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
204                 if (len > MAX_MSGSIZE) {
205                         Log_warn("Too big tx message. Discarding");
206                         break;
207                         }
208                 Msg_addPreamble(buffer, msg->messageType, len);
209                 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
210                 break;
211         case PermissionQuery:
212                 len = mumble_proto__permission_query__get_packed_size(msg->payload.permissionQuery);
213                 if (len > MAX_MSGSIZE) {
214                         Log_warn("Too big tx message. Discarding");
215                         break;
216                         }
217                 Msg_addPreamble(buffer, msg->messageType, len);
218                 mumble_proto__permission_query__pack(msg->payload.permissionQuery, bufptr);
219                 break;
220         case ChannelRemove:
221                 len = mumble_proto__channel_remove__get_packed_size(msg->payload.channelRemove);
222                 if (len > MAX_MSGSIZE) {
223                         Log_warn("Too big tx message. Discarding");
224                         break;
225                         }
226                 Msg_addPreamble(buffer, msg->messageType, len);
227                 mumble_proto__channel_remove__pack(msg->payload.channelRemove, bufptr);
228                 break;
229         case UserStats:
230         {               
231                 len = mumble_proto__user_stats__get_packed_size(msg->payload.userStats);
232                 if (len > MAX_MSGSIZE) {
233                         Log_warn("Too big tx message. Discarding");
234                         break;
235                         }
236                 Msg_addPreamble(buffer, msg->messageType, len);
237                 mumble_proto__user_stats__pack(msg->payload.userStats, bufptr);
238                 break;
239         }
240         case ServerConfig:
241                 len = mumble_proto__server_config__get_packed_size(msg->payload.serverConfig);
242                 if (len > MAX_MSGSIZE) {
243                         Log_warn("Too big tx message. Discarding");
244                         break;
245                         }
246                 Msg_addPreamble(buffer, msg->messageType, len);
247                 mumble_proto__server_config__pack(msg->payload.serverConfig, bufptr);
248                 break;
249
250         default:
251                 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
252                 return 0;
253         }
254         return len + PREAMBLE_SIZE;
255 }
256
257 static message_t *Msg_create_nopayload(messageType_t messageType)
258 {
259         message_t *msg = malloc(sizeof(message_t));
260
261         if (msg == NULL)
262                 Log_fatal("Out of memory");
263         memset(msg, 0, sizeof(message_t));
264         msg->refcount = 1;
265         msg->messageType = messageType;
266         init_list_entry(&msg->node);
267         return msg;
268 }
269
270 message_t *Msg_create(messageType_t messageType)
271 {
272         message_t *msg = Msg_create_nopayload(messageType);
273         
274         switch (messageType) {
275         case Version:
276                 msg->payload.version = malloc(sizeof(MumbleProto__Version));
277                 mumble_proto__version__init(msg->payload.version);
278                 break;
279         case UDPTunnel:
280                 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
281                 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
282                 break;
283         case Authenticate:
284                 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
285                 mumble_proto__authenticate__init(msg->payload.authenticate);
286                 break;
287         case Ping:
288                 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
289                 mumble_proto__ping__init(msg->payload.ping);
290                 break;
291         case Reject:
292                 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
293                 mumble_proto__reject__init(msg->payload.reject);
294                 break;
295         case ServerSync:
296                 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
297                 mumble_proto__server_sync__init(msg->payload.serverSync);
298                 break;
299         case TextMessage:
300                 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
301                 mumble_proto__text_message__init(msg->payload.textMessage);
302                 break;
303         case PermissionDenied:
304                 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
305                 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
306                 break;
307         case CryptSetup:
308                 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
309                 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
310                 break;
311         case UserList:
312                 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
313                 mumble_proto__user_list__init(msg->payload.userList);
314                 break;
315         case UserState:
316                 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
317                 mumble_proto__user_state__init(msg->payload.userState);
318                 break;
319         case ChannelState:
320                 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
321                 mumble_proto__channel_state__init(msg->payload.channelState);
322                 break;
323         case UserRemove:
324                 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
325                 mumble_proto__user_remove__init(msg->payload.userRemove);
326                 break;
327         case VoiceTarget:
328                 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
329                 mumble_proto__voice_target__init(msg->payload.voiceTarget);
330                 break;
331         case CodecVersion:
332                 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
333                 mumble_proto__codec_version__init(msg->payload.codecVersion);
334                 break;
335         case PermissionQuery:
336                 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
337                 mumble_proto__permission_query__init(msg->payload.permissionQuery);
338                 break;
339         case ChannelRemove:
340                 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
341                 mumble_proto__channel_remove__init(msg->payload.channelRemove);
342                 break;
343         case UserStats:
344                 msg->payload.userStats = malloc(sizeof(MumbleProto__UserStats));
345                 mumble_proto__user_stats__init(msg->payload.userStats);
346                 
347                 msg->payload.userStats->from_client = malloc(sizeof(MumbleProto__UserStats__Stats));
348                 mumble_proto__user_stats__stats__init(msg->payload.userStats->from_client);
349
350                 msg->payload.userStats->from_server = malloc(sizeof(MumbleProto__UserStats__Stats));
351                 mumble_proto__user_stats__stats__init(msg->payload.userStats->from_server);
352
353                 msg->payload.userStats->version = malloc(sizeof(MumbleProto__Version));
354                 mumble_proto__version__init(msg->payload.userStats->version);
355                 
356                 if (!msg->payload.userStats || !msg->payload.userStats->from_client ||
357                         !msg->payload.userStats->from_server || !msg->payload.userStats->version)
358                         Log_fatal("Out of memory");
359                 break;
360         case ServerConfig:
361                 msg->payload.serverConfig = malloc(sizeof(MumbleProto__ServerConfig));
362                 mumble_proto__server_config__init(msg->payload.serverConfig);
363                 break;
364
365         default:
366                 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
367                 break;
368         }
369
370         return msg;
371 }
372
373 void Msg_inc_ref(message_t *msg)
374 {
375         msg->refcount++;
376 }
377
378 void Msg_free(message_t *msg)
379 {
380         if (msg->refcount) msg->refcount--;
381         if (msg->refcount > 0)
382                 return;
383
384         switch (msg->messageType) {
385         case Version:
386                 if (msg->unpacked)
387                         mumble_proto__version__free_unpacked(msg->payload.version, NULL);
388                 else {
389                         if (msg->payload.version->release)
390                                 free(msg->payload.version->release);
391                         if (msg->payload.version->os)
392                                 free(msg->payload.version->os);
393                         if (msg->payload.version->os_version)
394                                 free(msg->payload.version->os_version);
395                         free(msg->payload.version);
396                 }
397                 break;
398         case UDPTunnel:
399                 if (msg->unpacked)
400                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
401                 else {
402                         free(msg->payload.UDPTunnel->packet.data);
403                         free(msg->payload.UDPTunnel);
404                 }
405                 break;
406         case Authenticate:
407                 if (msg->unpacked)
408                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
409                 else
410                         free(msg->payload.authenticate);
411                 break;
412         case Ping:
413                 if (msg->unpacked)
414                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
415                 else {
416                         free(msg->payload.ping);
417                 }
418                 break;
419         case Reject:
420                 if (msg->unpacked)
421                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
422                 else {
423                         free(msg->payload.reject->reason);
424                         free(msg->payload.reject);
425                 }
426                 break;
427         case ServerSync:
428                 if (msg->unpacked)
429                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
430                 else {
431                         free(msg->payload.serverSync->welcome_text);
432                         free(msg->payload.serverSync);
433                 }
434                 break;
435         case TextMessage:
436                 if (msg->unpacked)
437                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
438                 else {
439                         if (msg->payload.textMessage->message)
440                                 free(msg->payload.textMessage->message);
441                         if (msg->payload.textMessage->session)
442                                 free(msg->payload.textMessage->session);
443                         if (msg->payload.textMessage->channel_id)
444                                 free(msg->payload.textMessage->channel_id);
445                         if (msg->payload.textMessage->tree_id)
446                                 free(msg->payload.textMessage->tree_id);
447                         free(msg->payload.textMessage);
448                 }
449                 break;
450         case PermissionDenied:
451                 if (msg->unpacked)
452                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
453                 else {
454                         free(msg->payload.permissionDenied->reason);
455                         free(msg->payload.permissionDenied);
456                 }
457                 break;
458         case CryptSetup:
459                 if (msg->unpacked)
460                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
461                 else {
462                         free(msg->payload.cryptSetup);
463                 }
464                 break;
465         case UserList:
466                 if (msg->unpacked)
467                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
468                 else {
469                         free(msg->payload.userList);
470                 }
471                 break;
472         case UserState:
473                 if (msg->unpacked)
474                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
475                 else {
476                         free(msg->payload.userState->name);
477                         free(msg->payload.userState);
478                 }
479                 break;
480         case ChannelState:
481                 if (msg->unpacked)
482                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
483                 else {
484                         if (msg->payload.channelState->name)
485                                 free(msg->payload.channelState->name);
486                         if (msg->payload.channelState->description)
487                                 free(msg->payload.channelState->description);
488                         if (msg->payload.channelState->links)
489                                 free(msg->payload.channelState->links);
490                         free(msg->payload.channelState);
491                 }
492                 break;
493         case UserRemove:
494                 if (msg->unpacked)
495                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
496                 else {
497                         free(msg->payload.userRemove);
498                 }
499                 break;
500         case VoiceTarget:
501                 if (msg->unpacked)
502                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
503                 else {
504                         free(msg->payload.voiceTarget);
505                 }
506                 break;
507         case CodecVersion:
508                 if (msg->unpacked)
509                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
510                 else {
511                         free(msg->payload.codecVersion);
512                 }
513                 break;
514         case PermissionQuery:
515                 if (msg->unpacked)
516                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
517                 else {
518                         free(msg->payload.permissionQuery);
519                 }
520                 break;
521         case ChannelRemove:
522                 if (msg->unpacked)
523                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
524                 else {
525                         free(msg->payload.channelRemove);
526                 }
527                 break;
528         case UserStats:
529                 if (msg->unpacked)
530                         mumble_proto__user_stats__free_unpacked(msg->payload.userStats, NULL);
531                 else {
532                         if (msg->payload.userStats->from_client)
533                                 free(msg->payload.userStats->from_client);
534                         if (msg->payload.userStats->from_server)
535                                 free(msg->payload.userStats->from_server);
536                         if (msg->payload.userStats->version) {
537                                 if (msg->payload.userStats->version->release)
538                                         free(msg->payload.userStats->version->release);
539                                 if (msg->payload.userStats->version->os)
540                                         free(msg->payload.userStats->version->os);
541                                 if (msg->payload.userStats->version->os_version)
542                                         free(msg->payload.userStats->version->os_version);
543
544                                 free(msg->payload.userStats->version);
545                         }
546                         if (msg->payload.userStats->celt_versions)
547                                 free(msg->payload.userStats->celt_versions);
548                         if (msg->payload.userStats->certificates) {
549                                 if (msg->payload.userStats->certificates->data)
550                                         free(msg->payload.userStats->certificates->data);
551                                 free(msg->payload.userStats->certificates);
552                         }
553                         if (msg->payload.userStats->address.data)
554                                 free(msg->payload.userStats->address.data);
555
556                         free(msg->payload.userStats);
557                 }
558                 break;
559         case ServerConfig:
560                 if (msg->unpacked)
561                         mumble_proto__server_config__free_unpacked(msg->payload.serverConfig, NULL);
562                 else {
563                         free(msg->payload.serverConfig);
564                 }
565                 break;
566
567         default:
568                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
569                 break;
570         }
571         free(msg);
572 }
573
574 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
575 {
576         message_t *msg = NULL;
577         
578         msg = Msg_create_nopayload(UDPTunnel);
579         msg->unpacked = false;
580         msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
581         if (msg->payload.UDPTunnel == NULL)
582                 Log_fatal("Out of memory");
583         msg->payload.UDPTunnel->packet.data = malloc(size);
584         if (msg->payload.UDPTunnel->packet.data == NULL)
585                 Log_fatal("Out of memory");
586         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
587         msg->payload.UDPTunnel->packet.len = size;
588         return msg;
589 }
590
591 message_t *Msg_networkToMessage(uint8_t *data, int size)
592 {
593         message_t *msg = NULL;
594         uint8_t *msgData = &data[6];
595         int messageType, msgLen;
596
597         Msg_getPreamble(data, &messageType, &msgLen);
598
599         Log_debug("Message type %d size %d", messageType, msgLen);
600         //dumpmsg(data, size);
601         
602         switch (messageType) {
603         case Version:
604         {
605                 msg = Msg_create_nopayload(Version);
606                 msg->unpacked = true;
607                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
608                 if (msg->payload.version == NULL)
609                         goto err_out;
610                 break;
611         }
612         case UDPTunnel: /* Non-standard handling of tunneled voice data */
613         {
614                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
615                 break;
616         }
617         case Authenticate:
618         {
619                 msg = Msg_create_nopayload(Authenticate);
620                 msg->unpacked = true;
621                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
622                 if (msg->payload.authenticate == NULL)
623                         goto err_out;
624                 break;
625         }
626         case Ping:
627         {
628                 msg = Msg_create_nopayload(Ping);
629                 msg->unpacked = true;
630                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
631                 if (msg->payload.ping == NULL)
632                         goto err_out;
633                 break;
634         }
635         case Reject:
636         {
637                 msg = Msg_create_nopayload(Reject);
638                 msg->unpacked = true;
639                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
640                 if (msg->payload.reject == NULL)
641                         goto err_out;
642                 break;
643         }
644         case ServerSync:
645         {
646                 msg = Msg_create_nopayload(ServerSync);
647                 msg->unpacked = true;
648                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
649                 if (msg->payload.serverSync == NULL)
650                         goto err_out;
651                 break;
652         }
653         case TextMessage:
654         {
655                 msg = Msg_create_nopayload(TextMessage);
656                 msg->unpacked = true;
657                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
658                 if (msg->payload.textMessage == NULL)
659                         goto err_out;
660                 break;
661         }
662         case PermissionDenied:
663         {
664                 msg = Msg_create_nopayload(PermissionDenied);
665                 msg->unpacked = true;
666                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
667                 if (msg->payload.permissionDenied == NULL)
668                         goto err_out;
669                 break;
670         }
671         case CryptSetup:
672         {
673                 msg = Msg_create_nopayload(CryptSetup);
674                 msg->unpacked = true;
675                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
676                 if (msg->payload.cryptSetup == NULL)
677                         goto err_out;
678                 break;
679         }
680         case UserList:
681         {
682                 msg = Msg_create_nopayload(UserList);
683                 msg->unpacked = true;
684                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
685                 if (msg->payload.userList == NULL)
686                         goto err_out;
687                 break;
688         }
689         case UserState:
690         {
691                 msg = Msg_create_nopayload(UserState);
692                 msg->unpacked = true;
693                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
694                 if (msg->payload.userState == NULL)
695                         goto err_out;
696                 break;
697         }
698         case ChannelState:
699         {
700                 msg = Msg_create_nopayload(ChannelState);
701                 msg->unpacked = true;
702                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
703                 if (msg->payload.channelState == NULL)
704                         goto err_out;
705                 break;
706         }
707         case VoiceTarget:
708         {
709                 msg = Msg_create_nopayload(VoiceTarget);
710                 msg->unpacked = true;
711                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
712                 if (msg->payload.voiceTarget == NULL)
713                         goto err_out;
714                 break;
715         }
716         case CodecVersion:
717         {
718                 msg = Msg_create_nopayload(CodecVersion);
719                 msg->unpacked = true;
720                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
721                 if (msg->payload.codecVersion == NULL)
722                         goto err_out;
723                 break;
724         }
725         case PermissionQuery:
726         {
727                 msg = Msg_create_nopayload(PermissionQuery);
728                 msg->unpacked = true;
729                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
730                 if (msg->payload.permissionQuery == NULL)
731                         goto err_out;
732                 break;
733         }
734         case ChannelRemove:
735         {
736                 msg = Msg_create_nopayload(ChannelRemove);
737                 msg->unpacked = true;
738                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
739                 if (msg->payload.channelRemove == NULL)
740                         goto err_out;
741                 break;
742         }
743         case UserStats:
744         {
745                 msg = Msg_create_nopayload(UserStats);
746                 msg->unpacked = true;
747                 msg->payload.userStats = mumble_proto__user_stats__unpack(NULL, msgLen, msgData);
748                 if (msg->payload.userStats == NULL)
749                         goto err_out;
750                 break;
751         }
752
753         default:
754                 Log_warn("Unsupported message %d", messageType);
755                 break;
756         }
757         return msg;
758         
759 err_out:
760         free(msg);
761         return NULL;
762 }