FreeSWITCH API Documentation  1.7.0
switch_stun.h
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  *
28  *
29  * switch_stun.h STUN (Simple Traversal of UDP over NAT)
30  *
31  */
32 /*!
33  \defgroup stun1 STUN code
34  \ingroup core1
35  \{
36 */
37 #ifndef FREESWITCH_STUN_PARSER_H
38 #define FREESWITCH_STUN_PARSER_H
39 
41 #define SWITCH_STUN_DEFAULT_PORT 3478
42 #define SWITCH_STUN_PACKET_MIN_LEN 20
43 #define SWITCH_STUN_ATTRIBUTE_MIN_LEN 8
44  typedef enum {
59 
60 #define STUN_MAGIC_COOKIE 0x2112A442
61 
62 typedef enum {
63  SWITCH_STUN_ATTR_MAPPED_ADDRESS = 0x0001, /* Address */
64  SWITCH_STUN_ATTR_RESPONSE_ADDRESS = 0x0002, /* Address */
65  SWITCH_STUN_ATTR_CHANGE_REQUEST = 0x0003, /* UInt32 */
66  SWITCH_STUN_ATTR_SOURCE_ADDRESS = 0x0004, /* Address */
67  SWITCH_STUN_ATTR_CHANGED_ADDRESS = 0x0005, /* Address */
68  SWITCH_STUN_ATTR_USERNAME = 0x0006, /* ByteString, multiple of 4 bytes */
69  SWITCH_STUN_ATTR_PASSWORD = 0x0007, /* ByteString, multiple of 4 bytes */
70  SWITCH_STUN_ATTR_MESSAGE_INTEGRITY = 0x0008, /* ByteString, 20 bytes */
71  SWITCH_STUN_ATTR_ERROR_CODE = 0x0009, /* ErrorCode */
72  SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000a, /* UInt16List */
73  SWITCH_STUN_ATTR_REFLECTED_FROM = 0x000b, /* Address */
74  SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES = 0x000c, /* TransportPrefs */
75  SWITCH_STUN_ATTR_LIFETIME = 0x000d, /* UInt32 */
76  SWITCH_STUN_ATTR_ALTERNATE_SERVER = 0x000e, /* Address */
77  SWITCH_STUN_ATTR_MAGIC_COOKIE = 0x000f, /* ByteString, 4 bytes */
78  SWITCH_STUN_ATTR_BANDWIDTH = 0x0010, /* UInt32 */
79  SWITCH_STUN_ATTR_DESTINATION_ADDRESS = 0x0011, /* Address */
80  SWITCH_STUN_ATTR_SOURCE_ADDRESS2 = 0x0012, /* Address */
81  SWITCH_STUN_ATTR_DATA = 0x0013, /* ByteString */
82  SWITCH_STUN_ATTR_OPTIONS = 0x8001, /* UInt32 */
83  SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS = 0x0020, /* Address */
84 
85  /* ice crap */
86 
98 
100 
101 typedef enum {
112 
113 typedef enum {
118 
119 typedef struct {
120  uint16_t type;
121  uint16_t length;
122  uint32_t cookie;
123  char id[12];
125 
126 typedef struct {
127  uint16_t type;
128  uint16_t length;
129  char value[];
131 
132 typedef struct {
134  uint8_t first_attribute[];
136 
137 typedef struct {
138  uint8_t wasted;
139  uint8_t family;
140  uint16_t port;
141  uint32_t address;
143 
144 #if SWITCH_BYTE_ORDER == __BIG_ENDIAN
145 
146 typedef struct {
147  unsigned padding:21;
148  unsigned code:3;
149  unsigned number:8;
150  char reason[764];
152 
153 #else
154 
155 typedef struct {
156  unsigned number:8;
157  unsigned code:3;
158  unsigned padding:21;
159  char reason[764];
161 
162 #endif
163 
164 
165 /*!
166  \brief Writes random characters into a buffer
167  \param buf the buffer
168  \param len the length of the data
169  \param set the set of chars to use (NULL for auto)
170 */
171 SWITCH_DECLARE(void) switch_stun_random_string(char *buf, uint16_t len, char *set);
172 
173 /*!
174  \brief Prepare a raw packet for parsing
175  \param buf the raw data
176  \param len the length of the data
177  \return a stun packet pointer to buf to use as an access point
178 */
179 SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, uint32_t len);
180 
181 /*!
182  \brief Obtain a printable string form of a given value
183  \param type the type of message
184  \param value the value to look up
185  \return a sring version of value
186 */
187 SWITCH_DECLARE(const char *) switch_stun_value_to_name(int32_t type, uint32_t value);
188 
190 
191 /*!
192  \brief Extract a mapped address (IP:PORT) from a packet attribute
193  \param attribute the attribute from which to extract
194  \param ipstr a buffer to write the string representation of the ip
195  \param port the port
196  \return true or false
197 */
200 
201 
202 /*!
203  \brief Extract a username from a packet attribute
204  \param attribute the attribute from which to extract
205  \param username a buffer to write the string representation of the username
206  \param len the maximum size of the username buffer
207  \return a pointer to the username or NULL
208 */
209 SWITCH_DECLARE(char *) switch_stun_packet_attribute_get_username(switch_stun_packet_attribute_t *attribute, char *username, uint16_t len);
210 
211 
212 /*!
213  \brief Prepare a new outbound packet of a certian type and id
214  \param id id to use (NULL for an auto generated id)
215  \param type the stun packet type
216  \param buf a pointer to data to use for the packet
217  \return a pointer to a ready-to-use stun packet
218 */
220 
221 /*!
222  \brief Add a username packet attribute
223  \param packet the packet to add the attribute to
224  \param username the string representation of the username
225  \param ulen the length of the username
226  \return true or false
227 */
228 SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_username(switch_stun_packet_t *packet, char *username, uint16_t ulen);
229 SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_password(switch_stun_packet_t *packet, char *password, uint16_t ulen);
230 SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_software(switch_stun_packet_t *packet, char *software, uint16_t ulen);
231 
232 /*!
233  \brief Add a binded address packet attribute
234  \param packet the packet to add the attribute to
235  \param ipstr the string representation of the ip
236  \param port the port of the mapped address
237  \return true or false
238 */
239 SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family);
240 SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_xor_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family);
242 SWITCH_DECLARE(uint32_t) switch_crc32_8bytes(const void* data, size_t length);
248 
249 /*!
250  \brief Perform a stun lookup
251  \param ip the local ip to use (replaced with stun results)
252  \param port the local port to use (replaced with stun results)
253  \param stunip the ip of the stun server
254  \param stunport the port of the stun server
255  \param err a pointer to describe errors
256  \param pool the memory pool to use
257  \return SUCCESS or FAIL
258 */
260  switch_port_t *port, char *stunip, switch_port_t stunport, char **err, switch_memory_pool_t *pool);
261 
262 
263 /*!
264  \brief Obtain the padded length of an attribute's value
265  \param attribute the attribute
266  \return the padded size in bytes
267 */
268 #define switch_stun_attribute_padded_length(attribute) (int16_t)((attribute->length & 0x3) ? 0x4 + (attribute->length & ~0x3) : attribute->length)
269 #define switch_stun_attribute_padded_length_hbo(attribute) (int16_t)((ntohs(attribute->length) & 0x3) ? 0x4 + (ntohs(attribute->length) & ~0x3) : ntohs(attribute->length))
270 
271 
272 /*!
273  \brief set a switch_stun_packet_attribute_t pointer to point at the first attribute in a packet
274  \param packet the packet in question
275  \param attribute the pointer to set up
276 */
277 #define switch_stun_packet_first_attribute(packet, attribute) attribute = (switch_stun_packet_attribute_t *)(&packet->first_attribute);
278 
279 /*!
280  \brief Increment an attribute pointer to the next attribute in it's packet
281  \param attribute the pointer to increment
282  \param end pointer to the end of the buffer
283  \return true or false depending on if there are any more attributes
284 */
285 
286 #define switch_stun_packet_next_attribute(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length(attribute))) && ((void *)attribute < end) && attribute->type && (((switch_byte_t *)attribute + switch_stun_attribute_padded_length(attribute)) < (switch_byte_t *)end))
287 
288 #define switch_stun_packet_next_attribute_hbo(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length_hbo(attribute))) && ((void *)attribute < end) && attribute->type && (((switch_byte_t *)attribute + switch_stun_attribute_padded_length_hbo(attribute)) < (switch_byte_t *)end))
289 
290 /*!
291  \brief Obtain the correct length in bytes of a stun packet
292  \param packet the packet in question
293  \return the size in bytes (host order) of the entire packet
294 */
295 #define switch_stun_packet_length(packet) ntohs(packet->header.length) + (sizeof(switch_stun_packet_header_t))
296 ///\}
297 
299 #endif
300 /* For Emacs:
301  * Local Variables:
302  * mode:c
303  * indent-tabs-mode:t
304  * tab-width:4
305  * c-basic-offset:4
306  * End:
307  * For VIM:
308  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
309  */
uint8_t switch_stun_packet_attribute_add_software(switch_stun_packet_t *packet, char *software, uint16_t ulen)
Definition: switch_stun.c:640
switch_stun_attribute_t
Definition: switch_stun.h:62
uint8_t switch_stun_packet_attribute_add_priority(switch_stun_packet_t *packet, uint32_t priority)
Definition: switch_stun.c:521
uint8_t switch_stun_packet_attribute_add_fingerprint(switch_stun_packet_t *packet)
Definition: switch_stun.c:552
uint8_t switch_stun_packet_attribute_add_controlling(switch_stun_packet_t *packet)
Definition: switch_stun.c:585
uint32_t address
Definition: switch_stun.h:141
#define SWITCH_END_EXTERN_C
Definition: switch.h:43
uint32_t switch_crc32_8bytes(const void *data, size_t length)
Definition: switch_stun.c:1140
switch_memory_pool_t * pool
char * switch_stun_host_lookup(const char *host, switch_memory_pool_t *pool)
Definition: switch_stun.c:688
switch_stun_packet_t * switch_stun_packet_build_header(switch_stun_message_t type, char *id, uint8_t *buf)
Prepare a new outbound packet of a certian type and id.
Definition: switch_stun.c:431
uint8_t switch_stun_packet_attribute_add_use_candidate(switch_stun_packet_t *packet)
Definition: switch_stun.c:574
uint8_t switch_stun_packet_attribute_add_username(switch_stun_packet_t *packet, char *username, uint16_t ulen)
Add a username packet attribute.
Definition: switch_stun.c:616
switch_byte_t switch_byte_t * buf
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125
uintptr_t switch_size_t
uint16_t switch_port_t
switch_stun_packet_header_t header
Definition: switch_stun.h:133
uint8_t switch_stun_packet_attribute_add_password(switch_stun_packet_t *packet, char *password, uint16_t ulen)
Definition: switch_stun.c:664
char * switch_stun_packet_attribute_get_username(switch_stun_packet_attribute_t *attribute, char *username, uint16_t len)
Extract a username from a packet attribute.
Definition: switch_stun.c:423
switch_status_t
Common return values.
uint8_t switch_stun_packet_attribute_get_xor_mapped_address(switch_stun_packet_attribute_t *attribute, switch_stun_packet_header_t *header, char *ipstr, switch_size_t iplen, uint16_t *port)
Definition: switch_stun.c:394
switch_stun_packet_t * switch_stun_packet_parse(uint8_t *buf, uint32_t len)
Prepare a raw packet for parsing.
Definition: switch_stun.c:144
#define SWITCH_DECLARE(type)
switch_stun_message_t
Definition: switch_stun.h:44
uint8_t switch_stun_packet_attribute_add_controlled(switch_stun_packet_t *packet)
Definition: switch_stun.c:600
struct apr_pool_t switch_memory_pool_t
switch_stun_type_t
Definition: switch_stun.h:113
uint8_t switch_stun_packet_attribute_add_xor_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family)
Definition: switch_stun.c:485
const char * switch_stun_value_to_name(int32_t type, uint32_t value)
Obtain a printable string form of a given value.
Definition: switch_stun.c:347
switch_stun_error_t
Definition: switch_stun.h:101
uint8_t switch_stun_packet_attribute_add_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family)
Add a binded address packet attribute.
Definition: switch_stun.c:451
uint8_t switch_stun_packet_attribute_get_mapped_address(switch_stun_packet_attribute_t *attribute, char *ipstr, switch_size_t iplen, uint16_t *port)
Extract a mapped address (IP:PORT) from a packet attribute.
Definition: switch_stun.c:377
switch_status_t switch_stun_lookup(char **ip, switch_port_t *port, char *stunip, switch_port_t stunport, char **err, switch_memory_pool_t *pool)
Perform a stun lookup.
Definition: switch_stun.c:698
uint8_t switch_stun_packet_attribute_add_integrity(switch_stun_packet_t *packet, const char *pass)
Definition: switch_stun.c:535
#define SWITCH_BEGIN_EXTERN_C
Definition: switch.h:42