SWITCH_STUN_DATA_INDICATION = 0x0115
} switch_stun_message_t;
+#define STUN_MAGIC_COOKIE 0x2112A442
+
typedef enum {
SWITCH_STUN_ATTR_MAPPED_ADDRESS = 0x0001, /* Address */
SWITCH_STUN_ATTR_RESPONSE_ADDRESS = 0x0002, /* Address */
SWITCH_STUN_ATTR_DESTINATION_ADDRESS = 0x0011, /* Address */
SWITCH_STUN_ATTR_SOURCE_ADDRESS2 = 0x0012, /* Address */
SWITCH_STUN_ATTR_DATA = 0x0013, /* ByteString */
- SWITCH_STUN_ATTR_OPTIONS = 0x8001 /* UInt32 */
+ SWITCH_STUN_ATTR_OPTIONS = 0x8001, /* UInt32 */
+ SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS = 0x0020, /* Address */
} switch_stun_attribute_t;
typedef enum {
typedef struct {
uint16_t type;
uint16_t length;
- char id[16];
+ uint32_t cookie;
+ char id[12];
} switch_stun_packet_header_t;
typedef struct {
\return true or false
*/
SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_username(switch_stun_packet_t *packet, char *username, uint16_t ulen);
+SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_password(switch_stun_packet_t *packet, char *password, uint16_t ulen);
/*!
\return true or false
*/
SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port);
+SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_xor_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port);
/*!
\brief Perform a stun lookup
* we don't want the upper layers to have to deal with attributes without a value
* (or worse: invalid length)
*/
- return NULL;
}
/*
header = (switch_stun_packet_header_t *) buf;
header->type = htons(type);
header->length = 0;
+ header->cookie = htonl(STUN_MAGIC_COOKIE);
if (id) {
- memcpy(header->id, id, 16);
+ memcpy(header->id, id, 12);
} else {
- switch_stun_random_string(header->id, 16, NULL);
+ switch_stun_random_string(header->id, 12, NULL);
}
return (switch_stun_packet_t *) buf;
}
}
+ packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
+
+ return 1;
+}
+
+SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_xor_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port)
+{
+ switch_stun_packet_attribute_t *attribute;
+ switch_stun_ip_t *ip;
+ uint8_t *i, x;
+ char *p = ipstr;
+
+ attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
+ attribute->type = htons(SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS);
+ attribute->length = htons(8);
+ ip = (switch_stun_ip_t *) attribute->value;
+
+ ip->port = htons(port ^ (STUN_MAGIC_COOKIE >> 16));
+ ip->family = 1;
+ i = (uint8_t *) & ip->address;
+
+ for (x = 0; x < 4; x++) {
+ i[x] = (uint8_t) atoi(p);
+ if ((p = strchr(p, '.'))) {
+ p++;
+ } else {
+ break;
+ }
+ }
+
+ ip->address = htonl(ntohl(ip->address) ^ STUN_MAGIC_COOKIE);
+
packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
return 1;
}
return 1;
}
+SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_password(switch_stun_packet_t *packet, char *password, uint16_t ulen)
+{
+ switch_stun_packet_attribute_t *attribute;
+
+ if (ulen % 4 != 0) {
+ return 0;
+ }
+ attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
+ attribute->type = htons(SWITCH_STUN_ATTR_PASSWORD);
+ attribute->length = htons(ulen);
+ if (password) {
+ memcpy(attribute->value, password, ulen);
+ } else {
+ switch_stun_random_string(attribute->value, ulen, NULL);
+ }
+
+ packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
+ return 1;
+}
+
SWITCH_DECLARE(char *) switch_stun_host_lookup(const char *host, switch_memory_pool_t *pool)
{
switch_sockaddr_t *addr = NULL;