/*
* vim: softtabstop=4 shiftwidth=4 cindent foldmethod=marker expandtab
*
* $LastChangedDate$
* $Revision$
* $LastChangedBy$
* $URL$
*
* Copyright 2009-2011 Eric Connell
*
* This file is part of Mangler.
*
* Mangler is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Mangler is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Mangler. If not, see .
*/
#ifndef _LIBVENTRILO3_MESSAGE_H
#define _LIBVENTRILO3_MESSAGE_H
#include
#include
#include
#include "ventrilo3.h"
#define V3_CLIENT_VERSION "3.0.5"
#define V3_PROTO_VERSION "3.0.0"
/*
* This file contains structures for each message type received by the Ventrilo3
* protocol. Each type is broken up into subtypes where applicable. For
* example:
*
* _v3_net_message_0x5d_0x04 is message type 0x5d subtype 0x04
*
* Where further breakdown is necessary (for instance user and channel
* information messages), structures are defined specifically for that data.
* That data (so far) is identical for any subtype. Therefore, a user
* definition in message type 0x5d subtype 0x04 is identical to a user
* definition in type 0x5d subtype 0x01.
*
* To parse a packet, a smaller structure (i.e. a "type") will be recast as a
* larger structure depending on the subtype.
*
* In cases where a particular value is unknown, it is marked by a name of
* (unknown_#). The number is arbitrary and subject to change. If an unknown
* value is identified, it should be pulled out of the unknown pool and named
* appropriately.
*
* For questions or comments, join irc://irc.freenode.net channel #mangler
*
* Better documentation on these messages can be found at our wiki:
* http://www.mangler.org/trac/wiki/ProtocolDocumentation
*/
typedef struct _v3_net_message_0x00 {/*{{{*/
uint32_t type;
char version[16];
char salt1[32];
char salt2[32];
} __attribute__ ((__packed__)) _v3_msg_0x00;
_v3_net_message *_v3_put_0x00(void);/*}}}*/
typedef struct _v3_net_message_0x06 {/*{{{*/
uint32_t type; // 0
uint16_t unknown_1; // 4
uint16_t error_id; // 6
uint32_t subtype; // 8
uint8_t unknown_2; // 12 - variable length starts here
uint8_t *encryption_key;
} __attribute__ ((__packed__)) _v3_msg_0x06;
int _v3_get_0x06(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x33 {/*{{{*/
uint32_t type; // 0
uint8_t unkonwn[48]; // 4
uint16_t channel_id_count; // 52
uint16_t *channel_ids; // 54 - array of uint16_t - variable length starts list
} __attribute__ ((__packed__)) _v3_msg_0x33;
int _v3_get_0x33(_v3_net_message *msg);
int _v3_destroy_0x33(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x36 {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t error_id; // 6
uint16_t unknown_1; // 8
uint16_t rank_count; // 10
uint16_t unknown_2; // 12
uint16_t unknown_3; // 14
_v3_msg_rank *rank_list;
} __attribute__ ((__packed__)) _v3_msg_0x36;
int _v3_get_0x36(_v3_net_message *msg);
_v3_net_message *_v3_put_0x36(uint16_t subtype, v3_rank *rank);
int _v3_destroy_0x36(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x37 {/*{{{*/
uint32_t type; // 0
uint16_t user_id; // 4
uint16_t sequence; // 6
uint16_t ping; // 8
uint16_t inactivity; // 10
} __attribute__ ((__packed__)) _v3_msg_0x37;
int _v3_get_0x37(_v3_net_message *msg);
_v3_net_message *_v3_put_0x37(int sequence);/*}}}*/
typedef struct _v3_net_message_0x3a {/*{{{*/
uint32_t type; // 0
uint32_t user_id; // 4
uint16_t msglen; // 8
char * msg; // 10 - variable length starts here
} __attribute__ ((__packed__)) _v3_msg_0x3a;/*}}}*/
int _v3_get_0x3a(_v3_net_message *msg);
_v3_net_message *_v3_put_0x3a(char *message);
typedef struct _v3_net_message_0x3b {/*{{{*/
uint32_t type; // 0
uint16_t id; // 4
uint16_t channel_id; // 6
uint32_t error_id; // 8
} __attribute__ ((__packed__)) _v3_msg_0x3b;
int _v3_get_0x3b(_v3_net_message *msg);
_v3_net_message *_v3_put_0x3b(uint16_t id, uint16_t channel_id);/*}}}*/
typedef struct _v3_net_message_0x3c {/*{{{*/
uint32_t type; // 0
uint8_t unknown1[4]; // 4
uint16_t codec; // 8
uint16_t codec_format; // 10
uint8_t unknown2[12]; // 12
} __attribute__ ((__packed__)) _v3_msg_0x3c;
int _v3_get_0x3c(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x3f {/*{{{*/
uint32_t type; // 0
uint32_t user_id; // 4
uint16_t msglen; // 8
char * msg; // 10 - variable length starts here
} __attribute__ ((__packed__)) _v3_msg_0x3f;/*}}}*/
int _v3_get_0x3f(_v3_net_message *msg);
_v3_net_message *_v3_put_0x3f(char *message);
typedef struct _v3_net_message_0x42 {/*{{{*/
uint32_t type; // 0
uint16_t user_id; // 4
uint16_t subtype; // 6
uint32_t unknown; // 8
uint16_t msglen; // 12 - variable length starts here
char * msg; // 14
} __attribute__ ((__packed__)) _v3_msg_0x42;
int _v3_get_0x42(_v3_net_message *msg);
_v3_net_message *_v3_put_0x42(uint16_t subtype, uint16_t user_id, char *message);/*}}}*/
typedef struct _v3_net_message_0x46 {/*{{{*/
uint32_t type; // 0
uint16_t user_id; // 4
uint16_t setting; // 6
uint32_t value; // 8
} __attribute__ ((__packed__)) _v3_msg_0x46;
int _v3_get_0x46(_v3_net_message *msg);
_v3_net_message *_v3_put_0x46(uint16_t user_id, uint16_t setting, uint16_t value);/*}}}*/
typedef struct _v3_net_message_0x48 {/*{{{*/
uint32_t type; // 0
uint32_t subtype; // 4
uint32_t unknown_1; // 8
uint32_t server_ip; // 12
uint16_t portmask; // 16
uint16_t show_login_name; // 18
uint16_t unknown_2; // 20
uint16_t auth_server_index; // 22
char handshake[16]; // 24
char client_version[16];// 40
uint8_t unknown_3[48]; // 56
char proto_version[16]; // 104
char password_hash[32]; // 120
char username[32]; // 152
char phonetic[32]; // 184
char os[64]; // 216
} __attribute__ ((__packed__)) _v3_msg_0x48;
int _v3_get_0x48(_v3_net_message *msg);
_v3_net_message *_v3_put_0x48(void);/*}}}*/
typedef struct _v3_net_message_0x49 {/*{{{*/
uint32_t type; // 0
uint16_t user_id; // 4
uint16_t subtype; // 6
uint8_t hash_password[32]; // 8
v3_channel *channel; // 40 - variable length starts here
} __attribute__ ((__packed__)) _v3_msg_0x49;
int _v3_get_0x49(_v3_net_message *msg);
_v3_net_message *_v3_put_0x49(uint16_t subtype, uint16_t user_id, char *channel_password, _v3_msg_channel *channel);/*}}}*/
typedef struct _v3_net_message_0x4a {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t error_id; // 6
uint16_t unknown_1; // 8
uint16_t count; // 10
uint16_t start_id; // 12
uint16_t end_id; // 14
uint32_t unknown_2; // 16
} __attribute__ ((__packed__)) _v3_msg_0x4a;
typedef struct _v3_net_message_0x4a_account {
_v3_msg_0x4a header; // 0
int acct_list_count;
v3_account **acct_list;
} __attribute__ ((__packed__)) _v3_msg_0x4a_account;
typedef struct _v3_net_message_0x4a_perms {
_v3_msg_0x4a header; // 0
v3_permissions perms; // 20
} __attribute__ ((__packed__)) _v3_msg_0x4a_perms;
int _v3_get_0x4a(_v3_net_message *msg);
_v3_net_message *_v3_put_0x4a(uint8_t subtype, v3_account *account, v3_account *account2);
int _v3_destroy_0x4a(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x4b {/*{{{*/
uint32_t type; // 0
uint32_t timestamp; // 4
uint32_t empty; // 8
} __attribute__ ((__packed__)) _v3_msg_0x4b;
_v3_net_message *_v3_put_0x4b(void);/*}}}*/
typedef struct _v3_net_message_0x4c {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t property; // 6
uint16_t ack; // 8
uint16_t transaction_id; // 10
char * value; // 12
} __attribute__ ((__packed__)) _v3_msg_0x4c;
int _v3_get_0x4c(_v3_net_message *msg);
_v3_net_message *_v3_put_0x4c(uint16_t subtype, uint16_t property, uint16_t transaction_id, char *value);/*}}}*/
typedef struct _v3_net_message_0x50 {/*{{{*/
uint32_t type; // 0
uint32_t timestamp; // 4
uint16_t guest_motd_flag; // 8
uint16_t message_num; // 10
uint16_t message_id; // 12
uint16_t message_size; // 14
uint8_t message[256]; // 16
} __attribute__ ((__packed__)) _v3_msg_0x50;
int _v3_get_0x50(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x52 {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t user_id; // 6
uint16_t codec; // 8
uint16_t codec_format; // 10
uint16_t send_type; // 12
uint16_t unknown_1; // 14
uint32_t data_length; // 16
uint32_t pcm_length; // 20
} __attribute__ ((__packed__)) _v3_msg_0x52;/*}}}*/
typedef struct _v3_net_message_0x52_0x00 {/*{{{*/
_v3_msg_0x52 header; // 0
uint16_t unknown_4; // 24
uint16_t unknown_5; // 26
uint16_t unknown_6; // 28
uint16_t unknown_7; // 30
} __attribute__ ((__packed__)) _v3_msg_0x52_0x00;/*}}}*/
typedef struct _v3_net_message_0x52_0x01_in {/*{{{*/
_v3_msg_0x52 header; // 0
uint16_t unknown_4; // 24
uint16_t unknown_5; // 26
void * data; // 28 - variable length starts here
} __attribute__ ((__packed__)) _v3_msg_0x52_0x01_in;/*}}}*/
typedef struct _v3_net_message_0x52_0x01_out {/*{{{*/
_v3_msg_0x52 header; // 0
uint16_t unknown_4; // 24
uint16_t unknown_5; // 26
uint16_t unknown_6; // 28
uint16_t unknown_7; // 30
} __attribute__ ((__packed__)) _v3_msg_0x52_0x01_out;/*}}}*/
typedef struct _v3_net_message_0x52_0x02 {/*{{{*/
_v3_msg_0x52 header; // 0
uint16_t unknown_4; // 24
uint16_t unknown_5; // 26
} __attribute__ ((__packed__)) _v3_msg_0x52_0x02;/*}}}*/
typedef struct _v3_net_message_0x52_0x03 {/*{{{*/
_v3_msg_0x52 header; // 0
} __attribute__ ((__packed__)) _v3_msg_0x52_0x03;/*}}}*/
int _v3_get_0x52(_v3_net_message *msg);
_v3_net_message *_v3_put_0x52(uint8_t subtype, uint16_t codec, uint16_t codec_format, uint32_t pcmlength, uint32_t length, void *data);
int _v3_destroy_0x52(_v3_net_message *msg);
typedef struct _v3_net_message_0x53 {/*{{{*/
uint32_t type; // 0
uint16_t user_id; // 2
uint16_t channel_id; // 4
} __attribute__ ((__packed__)) _v3_msg_0x53;
int _v3_get_0x53(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x57 {/*{{{*/
uint32_t type; // 0
uint16_t unknown_1; // 4
uint16_t is_licensed; // 6
uint16_t port; // 8
uint16_t max_clients; // 10
uint16_t connected_clients; // 12
uint16_t unknown_2[3]; // 14
uint8_t _pad[8]; // 20
char name[32]; // 28
char version[16]; // 60
char unknown_3[32]; // 76
} __attribute__ ((__packed__)) _v3_msg_0x57;
int _v3_get_0x57(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x58 {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t error_id; // 6
uint16_t unknown1; // 8
uint16_t real_user_id; // 10
uint16_t phantom_user_id; // 12
uint16_t channel_id; // 14
uint16_t log_error; // 16
uint16_t unknown2; // 18
} __attribute__ ((__packed__)) _v3_msg_0x58;
int _v3_get_0x58(_v3_net_message *msg);
_v3_net_message *_v3_put_0x58(uint16_t subtype, uint16_t channel, uint16_t phantom_user_id);/*}}}*/
typedef struct _v3_net_message_0x59 {/*{{{*/
uint32_t type; // 0
uint16_t error; // 4
uint16_t minutes_banned; // 6
uint16_t log_error; // 8
uint16_t close_connection; // 10
uint16_t unknown_[4]; // 12
char * message; // 20
} __attribute__ ((__packed__)) _v3_msg_0x59;
int _v3_get_0x59(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x5a {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t error; // 6
uint16_t user1; // 8
uint16_t user2; // 8
uint16_t msglen; // 12 - variable length starts here
char * msg; // 14
} __attribute__ ((__packed__)) _v3_msg_0x5a;
int _v3_get_0x5a(_v3_net_message *msg);
_v3_net_message *_v3_put_0x5a(uint16_t subtype, uint16_t user1, uint16_t user2, char *message);/*}}}*/
typedef struct _v3_net_message_0x5c {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t sum_1; // 6
uint32_t sum_2; // 8
} __attribute__ ((__packed__)) _v3_msg_0x5c;
int _v3_get_0x5c(_v3_net_message *msg);
_v3_net_message *_v3_put_0x5c(uint8_t subtype);
uint32_t _v3_msg5c_scramble(uint8_t* in);
uint32_t _v3_msg5c_gensum(uint32_t seed, uint32_t iterations);/*}}}*/
typedef struct _v3_net_message_0x5d {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t user_count; // 6
_v3_msg_user *lobby; // 8 - variable length starts here
_v3_msg_user *user_list;
} __attribute__ ((__packed__)) _v3_msg_0x5d;
_v3_net_message *_v3_put_0x5d(uint16_t subtype, uint16_t count, v3_user *user);
int _v3_get_0x5d(_v3_net_message *msg);
int _v3_destroy_0x5d(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x60 {/*{{{*/
uint32_t type; // 0
uint32_t channel_count; // 4
_v3_msg_channel *channel_list; // 8 - variable length stats here
} __attribute__ ((__packed__)) _v3_msg_0x60;
int _v3_get_0x60(_v3_net_message *msg);
int _v3_destroy_0x60(_v3_net_message *msg);/*}}}*/
typedef struct _v3_net_message_0x61 {/*{{{*/
uint32_t type; // 0
uint32_t subtype; // 4
uint32_t bitmask_id; // 8
uint32_t ip_address; // 12
uint16_t ban_count; // 16
uint16_t ban_id; // 18
char banned_user[32]; // 20
char banned_by[32]; // 52
char ban_reason[128]; // 84
} __attribute__ ((__packed__)) _v3_msg_0x61;
int _v3_get_0x61(_v3_net_message *msg);
_v3_net_message *_v3_put_0x61(uint32_t subtype, uint32_t bitmask_id, uint32_t ip_address, char *banned_user, char *ban_reason);/*}}}*/
typedef struct _v3_net_message_0x62 {/*{{{*/
uint32_t type; // 0
uint16_t user_id_to; // 4
uint16_t user_id_from; // 6
uint32_t error_id; // 8
} __attribute__ ((__packed__)) _v3_msg_0x62;
int _v3_get_0x62(_v3_net_message *msg);
_v3_net_message *_v3_put_0x62(uint16_t user_id);/*}}}*/
typedef struct _v3_net_message_0x63 {/*{{{*/
uint32_t type; // 0
uint16_t subtype; // 4
uint16_t user_id; // 6
uint32_t unused; // 8
union { // 12
uint8_t password_hash[0x20];
char reason[0x80];
} __attribute__ ((__packed__)) t;
} __attribute__ ((__packed__)) _v3_msg_0x63;
_v3_net_message *_v3_put_0x63(uint16_t subtype, uint16_t user_id, char *string);/*}}}*/
char * _v3_get_msg_string(void *offset, uint16_t *len);
int _v3_put_msg_string(void *buffer, char *string);
uint16_t * _v3_get_msg_uint16_array(void *offset, uint16_t *len);
int _v3_put_msg_uint16_array(void *buffer, uint16_t len, uint16_t *array);
int _v3_get_msg_channel(void *offset, _v3_msg_channel *channel);
int _v3_put_msg_channel(void *buffer, _v3_msg_channel *channel);
int _v3_get_msg_user(void *offset, _v3_msg_user *user);
int _v3_put_msg_user(void *buf, _v3_msg_user *user);
int _v3_get_msg_account(void *offset, _v3_msg_account *account);
int _v3_put_msg_account(void *buf, _v3_msg_account *account);
int _v3_parse_filter(v3_sp_filter *f, char *value);
int _v3_strip_c0_set(char *s);
#endif // _LIBVENTRILO3_MESSAGE_H