====== Différences ====== Ci-dessous, les différences entre deux révisions de la page.
— |
misc:mumble_query [2011/10/31 15:55] (Version actuelle) |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ===== Query un serveur mumble en C ===== | ||
+ | ==== Doc ==== | ||
+ | mirroir de http://mumble.sourceforge.net/Protocol : | ||
+ | The Mumble Protocol is Open Source, just like Mumble itself. The source code for the current version can be found in the Git repository in the file [[https://github.com/mumble-voip/mumble/blob/master/src/Mumble.proto Mumble.proto]]. | ||
+ | |||
+ | === Protocol documentation ==== | ||
+ | |||
+ | A complete documentation about the protocol can be found at | ||
+ | [[https://github.com/mumble-voip/mumble/raw/master/doc/mumble-protocol.pdf mumble-protocol.pdf]]. | ||
+ | |||
+ | === UDP Ping packet === | ||
+ | |||
+ | Mumble supports querying the following data by sending a ping packet to the target server. Both the request and the response packets are formatted in Big Endian. | ||
+ | |||
+ | The ping request packet contains the following data: | ||
+ | |||
+ | ^ Width ^ Data type ^ Value ^ Comment ^ | ||
+ | | 4 bytes | int | 0 | Denotes the request type | | ||
+ | | 8 bytes | long long | ident | Used to identify the reponse. | | ||
+ | |||
+ | |||
+ | The response will then contain the following data: | ||
+ | |||
+ | ^ Width ^ Data type ^ Value ^ Comment ^ | ||
+ | | 4 bytes | int | Version | e.g., \x0\x1\x2\x3 for 1.2.3. Can be interpreted as one single int or four signed chars. | | ||
+ | | 8 bytes | long long | ident | the ident value sent with the request | | ||
+ | | 4 bytes | int | Currently connected users count | | | ||
+ | | 4 bytes | int | Maximum users (slot count) | | | ||
+ | | 4 bytes | int | Allowed bandwidth | | | ||
+ | |||
+ | |||
+ | The response will then contain the following data: [[https://gitorious.org/mumble-scripts/mumble-scripts/blobs/master/Non-RPC/mumble-ping.py|mumble-ping.py]] | ||
+ | |||
+ | ==== Source ==== | ||
+ | <file c qmumble.c> | ||
+ | #include <arpa/inet.h> | ||
+ | #include <netinet/in.h> | ||
+ | #include <sys/socket.h> | ||
+ | #include <stdio.h> | ||
+ | #include <sys/types.h> | ||
+ | #include <unistd.h> | ||
+ | #include <limits.h> | ||
+ | |||
+ | #define MUM_QUERY_LENGTH 12 | ||
+ | #define MUM_ANSWER_LENGTH 24 | ||
+ | #define MUMBLE_DEF_PORT 64738 | ||
+ | |||
+ | int query_mumble(char *ip, int port, int *client_nb, int *slots_nb) { | ||
+ | struct sockaddr_in addr; | ||
+ | int s; | ||
+ | |||
+ | char query[] = "\0\0\0\0z2f4590h"; | ||
+ | char answer[24]; | ||
+ | |||
+ | if (client_nb == NULL || slots_nb == NULL) return 0; | ||
+ | if (port == 0) port = MUMBLE_DEF_PORT; | ||
+ | |||
+ | addr.sin_family = AF_INET; | ||
+ | addr.sin_port = htons(port); | ||
+ | if (inet_aton(ip, &addr.sin_addr)==0) return -1; | ||
+ | if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) return -2; | ||
+ | |||
+ | if (sendto(s, query, MUM_QUERY_LENGTH, 0, &addr, sizeof(addr))==-1) return -3; | ||
+ | if (recv(s, answer, MUM_ANSWER_LENGTH, 0)==-1) return -4; | ||
+ | close(s); | ||
+ | |||
+ | *client_nb = *(answer+12) & 0xFF; *client_nb = *client_nb << 8; | ||
+ | *client_nb += *(answer+13) & 0xFF; *client_nb = *client_nb << 8; | ||
+ | *client_nb += *(answer+14) & 0xFF; *client_nb = *client_nb << 8; | ||
+ | *client_nb += *(answer+15) & 0xFF; | ||
+ | |||
+ | *slots_nb = *(answer+16) & 0xFF; *slots_nb = *slots_nb << 8; | ||
+ | *slots_nb += *(answer+17) & 0xFF; *slots_nb = *slots_nb << 8; | ||
+ | *slots_nb += *(answer+18) & 0xFF; *slots_nb = *slots_nb << 8; | ||
+ | *slots_nb += *(answer+19) & 0xFF; | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | int res, a, b; | ||
+ | res = query_mumble("88.191.129.216", 0, &a, &b); | ||
+ | printf("%d/%d connectés\n", a, b); | ||
+ | return res == 1 ? 0 : -1; | ||
+ | } | ||
+ | |||
+ | </file> |