Fix byte order confusion which broke on big endian platforms
[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
230         default:
231                 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
232                 return 0;
233         }
234         return len + PREAMBLE_SIZE;
235 }
236
237 static message_t *Msg_create_nopayload(messageType_t messageType)
238 {
239         message_t *msg = malloc(sizeof(message_t));
240
241         if (msg == NULL)
242                 Log_fatal("Out of memory");
243         memset(msg, 0, sizeof(message_t));
244         msg->refcount = 1;
245         msg->messageType = messageType;
246         init_list_entry(&msg->node);
247         return msg;
248 }
249
250 message_t *Msg_create(messageType_t messageType)
251 {
252         message_t *msg = Msg_create_nopayload(messageType);
253         
254         switch (messageType) {
255         case Version:
256                 msg->payload.version = malloc(sizeof(MumbleProto__Version));
257                 mumble_proto__version__init(msg->payload.version);
258                 break;
259         case UDPTunnel:
260                 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
261                 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
262                 break;
263         case Authenticate:
264                 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
265                 mumble_proto__authenticate__init(msg->payload.authenticate);
266                 break;
267         case Ping:
268                 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
269                 mumble_proto__ping__init(msg->payload.ping);
270                 break;
271         case Reject:
272                 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
273                 mumble_proto__reject__init(msg->payload.reject);
274                 break;
275         case ServerSync:
276                 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
277                 mumble_proto__server_sync__init(msg->payload.serverSync);
278                 break;
279         case TextMessage:
280                 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
281                 mumble_proto__text_message__init(msg->payload.textMessage);
282                 break;
283         case PermissionDenied:
284                 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
285                 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
286                 break;
287         case CryptSetup:
288                 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
289                 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
290                 break;
291         case UserList:
292                 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
293                 mumble_proto__user_list__init(msg->payload.userList);
294                 break;
295         case UserState:
296                 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
297                 mumble_proto__user_state__init(msg->payload.userState);
298                 break;
299         case ChannelState:
300                 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
301                 mumble_proto__channel_state__init(msg->payload.channelState);
302                 break;
303         case UserRemove:
304                 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
305                 mumble_proto__user_remove__init(msg->payload.userRemove);
306                 break;
307         case VoiceTarget:
308                 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
309                 mumble_proto__voice_target__init(msg->payload.voiceTarget);
310                 break;
311         case CodecVersion:
312                 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
313                 mumble_proto__codec_version__init(msg->payload.codecVersion);
314                 break;
315         case PermissionQuery:
316                 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
317                 mumble_proto__permission_query__init(msg->payload.permissionQuery);
318                 break;
319         case ChannelRemove:
320                 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
321                 mumble_proto__channel_remove__init(msg->payload.channelRemove);
322                 break;
323
324         default:
325                 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
326                 break;
327         }
328
329         return msg;
330 }
331
332 void Msg_inc_ref(message_t *msg)
333 {
334         msg->refcount++;
335 }
336
337 void Msg_free(message_t *msg)
338 {
339         if (msg->refcount) msg->refcount--;
340         if (msg->refcount > 0)
341                 return;
342
343         switch (msg->messageType) {
344         case Version:
345                 if (msg->unpacked)
346                         mumble_proto__version__free_unpacked(msg->payload.version, NULL);
347                 else {
348                         if (msg->payload.version->release)
349                                 free(msg->payload.version->release);
350                         if (msg->payload.version->os)
351                                 free(msg->payload.version->os);
352                         if (msg->payload.version->os_version)
353                                 free(msg->payload.version->os_version);
354                         free(msg->payload.version);
355                 }
356                 break;
357         case UDPTunnel:
358                 if (msg->unpacked)
359                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
360                 else {
361                         free(msg->payload.UDPTunnel->packet.data);
362                         free(msg->payload.UDPTunnel);
363                 }
364                 break;
365         case Authenticate:
366                 if (msg->unpacked)
367                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
368                 else
369                         free(msg->payload.authenticate);
370                 break;
371         case Ping:
372                 if (msg->unpacked)
373                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
374                 else {
375                         free(msg->payload.ping);
376                 }
377                 break;
378         case Reject:
379                 if (msg->unpacked)
380                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
381                 else {
382                         free(msg->payload.reject->reason);
383                         free(msg->payload.reject);
384                 }
385                 break;
386         case ServerSync:
387                 if (msg->unpacked)
388                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
389                 else {
390                         free(msg->payload.serverSync->welcome_text);
391                         free(msg->payload.serverSync);
392                 }
393                 break;
394         case TextMessage:
395                 if (msg->unpacked)
396                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
397                 else {
398                         free(msg->payload.textMessage);
399                 }
400                 break;
401         case PermissionDenied:
402                 if (msg->unpacked)
403                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
404                 else {
405                         free(msg->payload.permissionDenied->reason);
406                         free(msg->payload.permissionDenied);
407                 }
408                 break;
409         case CryptSetup:
410                 if (msg->unpacked)
411                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
412                 else {
413                         free(msg->payload.cryptSetup);
414                 }
415                 break;
416         case UserList:
417                 if (msg->unpacked)
418                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
419                 else {
420                         free(msg->payload.userList);
421                 }
422                 break;
423         case UserState:
424                 if (msg->unpacked)
425                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
426                 else {
427                         free(msg->payload.userState->name);
428                         free(msg->payload.userState);
429                 }
430                 break;
431         case ChannelState:
432                 if (msg->unpacked)
433                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
434                 else {
435                         if (msg->payload.channelState->name)
436                                 free(msg->payload.channelState->name);
437                         if (msg->payload.channelState->description)
438                                 free(msg->payload.channelState->description);
439                         if (msg->payload.channelState->links)
440                                 free(msg->payload.channelState->links);
441                         free(msg->payload.channelState);
442                 }
443                 break;
444         case UserRemove:
445                 if (msg->unpacked)
446                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
447                 else {
448                         free(msg->payload.userRemove);
449                 }
450                 break;
451         case VoiceTarget:
452                 if (msg->unpacked)
453                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
454                 else {
455                         free(msg->payload.voiceTarget);
456                 }
457                 break;
458         case CodecVersion:
459                 if (msg->unpacked)
460                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
461                 else {
462                         free(msg->payload.codecVersion);
463                 }
464                 break;
465         case PermissionQuery:
466                 if (msg->unpacked)
467                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
468                 else {
469                         free(msg->payload.permissionQuery);
470                 }
471                 break;
472         case ChannelRemove:
473                 if (msg->unpacked)
474                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
475                 else {
476                         free(msg->payload.channelRemove);
477                 }
478                 break;
479
480         default:
481                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
482                 break;
483         }
484         free(msg);
485 }
486
487 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
488 {
489         message_t *msg = NULL;
490         
491         msg = Msg_create_nopayload(UDPTunnel);
492         msg->unpacked = false;
493         msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
494         if (msg->payload.UDPTunnel == NULL)
495                 Log_fatal("Out of memory");
496         msg->payload.UDPTunnel->packet.data = malloc(size);
497         if (msg->payload.UDPTunnel->packet.data == NULL)
498                 Log_fatal("Out of memory");
499         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
500         msg->payload.UDPTunnel->packet.len = size;
501         return msg;
502 }
503
504 message_t *Msg_networkToMessage(uint8_t *data, int size)
505 {
506         message_t *msg = NULL;
507         uint8_t *msgData = &data[6];
508         int messageType, msgLen;
509
510         Msg_getPreamble(data, &messageType, &msgLen);
511
512         Log_debug("Message type %d size %d", messageType, msgLen);
513         //dumpmsg(data, size);
514         
515         switch (messageType) {
516         case Version:
517         {
518                 msg = Msg_create_nopayload(Version);
519                 msg->unpacked = true;
520                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
521                 if (msg->payload.version == NULL)
522                         goto err_out;
523                 break;
524         }
525         case UDPTunnel: /* Non-standard handling of tunneled voice data */
526         {
527                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
528                 break;
529         }
530         case Authenticate:
531         {
532                 msg = Msg_create_nopayload(Authenticate);
533                 msg->unpacked = true;
534                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
535                 if (msg->payload.authenticate == NULL)
536                         goto err_out;
537                 break;
538         }
539         case Ping:
540         {
541                 msg = Msg_create_nopayload(Ping);
542                 msg->unpacked = true;
543                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
544                 if (msg->payload.ping == NULL)
545                         goto err_out;
546                 break;
547         }
548         case Reject:
549         {
550                 msg = Msg_create_nopayload(Reject);
551                 msg->unpacked = true;
552                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
553                 if (msg->payload.reject == NULL)
554                         goto err_out;
555                 break;
556         }
557         case ServerSync:
558         {
559                 msg = Msg_create_nopayload(ServerSync);
560                 msg->unpacked = true;
561                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
562                 if (msg->payload.serverSync == NULL)
563                         goto err_out;
564                 break;
565         }
566         case TextMessage:
567         {
568                 msg = Msg_create_nopayload(TextMessage);
569                 msg->unpacked = true;
570                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
571                 if (msg->payload.textMessage == NULL)
572                         goto err_out;
573                 break;
574         }
575         case PermissionDenied:
576         {
577                 msg = Msg_create_nopayload(PermissionDenied);
578                 msg->unpacked = true;
579                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
580                 if (msg->payload.permissionDenied == NULL)
581                         goto err_out;
582                 break;
583         }
584         case CryptSetup:
585         {
586                 msg = Msg_create_nopayload(CryptSetup);
587                 msg->unpacked = true;
588                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
589                 if (msg->payload.cryptSetup == NULL)
590                         goto err_out;
591                 break;
592         }
593         case UserList:
594         {
595                 msg = Msg_create_nopayload(UserList);
596                 msg->unpacked = true;
597                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
598                 if (msg->payload.userList == NULL)
599                         goto err_out;
600                 break;
601         }
602         case UserState:
603         {
604                 msg = Msg_create_nopayload(UserState);
605                 msg->unpacked = true;
606                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
607                 if (msg->payload.userState == NULL)
608                         goto err_out;
609                 break;
610         }
611         case ChannelState:
612         {
613                 msg = Msg_create_nopayload(ChannelState);
614                 msg->unpacked = true;
615                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
616                 if (msg->payload.channelState == NULL)
617                         goto err_out;
618                 break;
619         }
620         case VoiceTarget:
621         {
622                 msg = Msg_create_nopayload(VoiceTarget);
623                 msg->unpacked = true;
624                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
625                 if (msg->payload.voiceTarget == NULL)
626                         goto err_out;
627                 break;
628         }
629         case CodecVersion:
630         {
631                 msg = Msg_create_nopayload(CodecVersion);
632                 msg->unpacked = true;
633                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
634                 if (msg->payload.codecVersion == NULL)
635                         goto err_out;
636                 break;
637         }
638         case PermissionQuery:
639         {
640                 msg = Msg_create_nopayload(PermissionQuery);
641                 msg->unpacked = true;
642                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
643                 if (msg->payload.permissionQuery == NULL)
644                         goto err_out;
645                 break;
646         }
647         case ChannelRemove:
648         {
649                 msg = Msg_create_nopayload(ChannelRemove);
650                 msg->unpacked = true;
651                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
652                 if (msg->payload.channelRemove == NULL)
653                         goto err_out;
654                 break;
655         }
656
657         default:
658                 Log_warn("Unsupported message %d", messageType);
659                 break;
660         }
661         return msg;
662         
663 err_out:
664         free(msg);
665         return NULL;
666 }