Line data Source code
1 : /*
2 : Copyright (c) 2007, Adobe Systems, Incorporated
3 : All rights reserved.
4 :
5 : Redistribution and use in source and binary forms, with or without
6 : modification, are permitted provided that the following conditions are
7 : met:
8 :
9 : * Redistributions of source code must retain the above copyright
10 : notice, this list of conditions and the following disclaimer.
11 :
12 : * Redistributions in binary form must reproduce the above copyright
13 : notice, this list of conditions and the following disclaimer in the
14 : documentation and/or other materials provided with the distribution.
15 :
16 : * Neither the name of Adobe Systems, Network Resonance nor the names of its
17 : contributors may be used to endorse or promote products derived from
18 : this software without specific prior written permission.
19 :
20 : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : */
32 :
33 :
34 : static char *RCSSTRING __UNUSED__="$Id: stun_msg.c,v 1.2 2008/04/28 18:21:30 ekr Exp $";
35 :
36 : #include <errno.h>
37 : #include <csi_platform.h>
38 :
39 : #ifdef WIN32
40 : #include <winsock2.h>
41 : #include <stdlib.h>
42 : #include <io.h>
43 : #include <time.h>
44 : #else /* UNIX */
45 : #include <string.h>
46 : #endif /* end UNIX */
47 : #include <assert.h>
48 :
49 : #include "stun.h"
50 :
51 :
52 : int
53 0 : nr_stun_message_create(nr_stun_message **msg)
54 : {
55 : int _status;
56 0 : nr_stun_message *m = 0;
57 :
58 0 : m = RCALLOC(sizeof(*m));
59 0 : if (!m)
60 0 : ABORT(R_NO_MEMORY);
61 :
62 0 : TAILQ_INIT(&m->attributes);
63 :
64 0 : *msg = m;
65 :
66 0 : _status=0;
67 : abort:
68 0 : return(_status);
69 : }
70 :
71 : int
72 0 : nr_stun_message_create2(nr_stun_message **msg, UCHAR *buffer, int length)
73 : {
74 : int r,_status;
75 0 : nr_stun_message *m = 0;
76 :
77 0 : if (length > sizeof(m->buffer)) {
78 0 : ABORT(R_BAD_DATA);
79 : }
80 :
81 0 : if ((r=nr_stun_message_create(&m)))
82 0 : ABORT(r);
83 :
84 0 : memcpy(m->buffer, buffer, length);
85 0 : m->length = length;
86 :
87 0 : *msg = m;
88 :
89 0 : _status=0;
90 : abort:
91 0 : return(_status);
92 : }
93 :
94 : int
95 0 : nr_stun_message_destroy(nr_stun_message **msg)
96 : {
97 : int _status;
98 : nr_stun_message_attribute_head *attrs;
99 : nr_stun_message_attribute *attr;
100 :
101 0 : if (msg && *msg) {
102 0 : attrs = &(*msg)->attributes;
103 0 : while (!TAILQ_EMPTY(attrs)) {
104 0 : attr = TAILQ_FIRST(attrs);
105 0 : nr_stun_message_attribute_destroy(*msg, &attr);
106 : }
107 :
108 0 : RFREE(*msg);
109 :
110 0 : *msg = 0;
111 : }
112 :
113 0 : _status=0;
114 : /* abort: */
115 0 : return(_status);
116 : }
117 :
118 : int
119 0 : nr_stun_message_attribute_create(nr_stun_message *msg, nr_stun_message_attribute **attr)
120 : {
121 : int _status;
122 0 : nr_stun_message_attribute *a = 0;
123 :
124 0 : a = RCALLOC(sizeof(*a));
125 0 : if (!a)
126 0 : ABORT(R_NO_MEMORY);
127 :
128 0 : TAILQ_INSERT_TAIL(&msg->attributes, a, entry);
129 :
130 0 : *attr = a;
131 :
132 0 : _status=0;
133 : abort:
134 0 : return(_status);
135 : }
136 :
137 : int
138 0 : nr_stun_message_attribute_destroy(nr_stun_message *msg, nr_stun_message_attribute **attr)
139 : {
140 : int _status;
141 0 : nr_stun_message_attribute *a = 0;
142 :
143 0 : if (attr && *attr) {
144 0 : a = *attr;
145 0 : TAILQ_REMOVE(&msg->attributes, a, entry);
146 :
147 0 : RFREE(a);
148 :
149 0 : *attr = 0;
150 : }
151 :
152 0 : _status=0;
153 : /* abort: */
154 0 : return(_status);
155 : }
156 :
157 : int
158 0 : nr_stun_message_has_attribute(nr_stun_message *msg, UINT2 type, nr_stun_message_attribute **attribute)
159 : {
160 0 : nr_stun_message_attribute *attr = 0;
161 :
162 0 : if (attribute)
163 0 : *attribute = 0;
164 :
165 0 : TAILQ_FOREACH(attr, &msg->attributes, entry) {
166 0 : if (attr->type == type)
167 0 : break;
168 : }
169 :
170 0 : if (!attr || attr->invalid)
171 0 : return 0; /* does not have */
172 :
173 0 : if (attribute)
174 0 : *attribute = attr;
175 :
176 0 : return 1; /* has */
177 : }
178 :
179 : #define NR_STUN_MESSAGE_ADD_ATTRIBUTE(__type, __code) \
180 : { \
181 : int r,_status; \
182 : nr_stun_message_attribute *attr = 0; \
183 : if ((r=nr_stun_message_attribute_create(msg, &attr))) \
184 : ABORT(r); \
185 : attr->type = (__type); \
186 : { __code } \
187 : _status=0; \
188 : abort: \
189 : if (_status){ \
190 : nr_stun_message_attribute_destroy(msg, &attr); \
191 : } \
192 : return(_status); \
193 : }
194 :
195 :
196 : int
197 0 : nr_stun_message_add_alternate_server_attribute(nr_stun_message *msg, nr_transport_addr *alternate_server)
198 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
199 : NR_STUN_ATTR_ALTERNATE_SERVER,
200 : {
201 : if ((r=nr_transport_addr_copy(&attr->u.alternate_server, alternate_server)))
202 : ABORT(r);
203 : }
204 : )
205 :
206 : int
207 0 : nr_stun_message_add_error_code_attribute(nr_stun_message *msg, UINT2 number, char *reason)
208 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
209 : NR_STUN_ATTR_ERROR_CODE,
210 : {
211 : attr->u.error_code.number = number;
212 : strlcpy(attr->u.error_code.reason, reason, sizeof(attr->u.error_code.reason));
213 : }
214 : )
215 :
216 : int
217 0 : nr_stun_message_add_fingerprint_attribute(nr_stun_message *msg)
218 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
219 : NR_STUN_ATTR_FINGERPRINT,
220 : {}
221 : )
222 :
223 : int
224 0 : nr_stun_message_add_message_integrity_attribute(nr_stun_message *msg, Data *password)
225 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
226 : NR_STUN_ATTR_MESSAGE_INTEGRITY,
227 : {
228 : if (sizeof(attr->u.message_integrity.password) < password->len)
229 : ABORT(R_BAD_DATA);
230 :
231 : memcpy(attr->u.message_integrity.password, password->data, password->len);
232 : attr->u.message_integrity.passwordlen = password->len;
233 : }
234 : )
235 :
236 : int
237 0 : nr_stun_message_add_nonce_attribute(nr_stun_message *msg, char *nonce)
238 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
239 : NR_STUN_ATTR_NONCE,
240 : { strlcpy(attr->u.nonce, nonce, sizeof(attr->u.nonce)); }
241 : )
242 :
243 : int
244 0 : nr_stun_message_add_realm_attribute(nr_stun_message *msg, char *realm)
245 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
246 : NR_STUN_ATTR_REALM,
247 : { strlcpy(attr->u.realm, realm, sizeof(attr->u.realm)); }
248 : )
249 :
250 : int
251 0 : nr_stun_message_add_server_attribute(nr_stun_message *msg, char *server_name)
252 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
253 : NR_STUN_ATTR_SERVER,
254 : { strlcpy(attr->u.server_name, server_name, sizeof(attr->u.server_name)); }
255 : )
256 :
257 : int
258 0 : nr_stun_message_add_unknown_attributes_attribute(nr_stun_message *msg, nr_stun_attr_unknown_attributes *unknown_attributes)
259 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
260 : NR_STUN_ATTR_UNKNOWN_ATTRIBUTES,
261 : { memcpy(&attr->u.unknown_attributes, unknown_attributes, sizeof(attr->u.unknown_attributes)); }
262 : )
263 :
264 : int
265 0 : nr_stun_message_add_username_attribute(nr_stun_message *msg, char *username)
266 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
267 : NR_STUN_ATTR_USERNAME,
268 : { strlcpy(attr->u.username, username, sizeof(attr->u.username)); }
269 : )
270 :
271 : int
272 0 : nr_stun_message_add_requested_transport_attribute(nr_stun_message *msg, UCHAR protocol)
273 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
274 : NR_STUN_ATTR_REQUESTED_TRANSPORT,
275 : { attr->u.requested_transport = protocol; }
276 : )
277 :
278 : int
279 0 : nr_stun_message_add_xor_mapped_address_attribute(nr_stun_message *msg, nr_transport_addr *mapped_address)
280 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
281 : NR_STUN_ATTR_XOR_MAPPED_ADDRESS,
282 : {
283 : if ((r=nr_transport_addr_copy(&attr->u.xor_mapped_address.unmasked, mapped_address)))
284 : ABORT(r);
285 : }
286 : )
287 :
288 : int
289 0 : nr_stun_message_add_xor_peer_address_attribute(nr_stun_message *msg, nr_transport_addr *peer_address)
290 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
291 : NR_STUN_ATTR_XOR_PEER_ADDRESS,
292 : {
293 : if ((r=nr_transport_addr_copy(&attr->u.xor_mapped_address.unmasked, peer_address)))
294 : ABORT(r);
295 : }
296 : )
297 :
298 : #ifdef USE_ICE
299 : int
300 0 : nr_stun_message_add_ice_controlled_attribute(nr_stun_message *msg, UINT8 ice_controlled)
301 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
302 : NR_STUN_ATTR_ICE_CONTROLLED,
303 : { attr->u.ice_controlled = ice_controlled; }
304 : )
305 :
306 : int
307 0 : nr_stun_message_add_ice_controlling_attribute(nr_stun_message *msg, UINT8 ice_controlling)
308 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
309 : NR_STUN_ATTR_ICE_CONTROLLING,
310 : { attr->u.ice_controlling = ice_controlling; }
311 : )
312 :
313 : int
314 0 : nr_stun_message_add_priority_attribute(nr_stun_message *msg, UINT4 priority)
315 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
316 : NR_STUN_ATTR_PRIORITY,
317 : { attr->u.priority = priority; }
318 : )
319 :
320 : int
321 0 : nr_stun_message_add_use_candidate_attribute(nr_stun_message *msg)
322 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
323 : NR_STUN_ATTR_USE_CANDIDATE,
324 : {}
325 : )
326 : #endif /* USE_ICE */
327 :
328 : #ifdef USE_TURN
329 : int
330 0 : nr_stun_message_add_data_attribute(nr_stun_message *msg, UCHAR *data, int length)
331 :
332 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
333 : NR_STUN_ATTR_DATA,
334 : {
335 : if (length > NR_STUN_MAX_MESSAGE_SIZE)
336 : ABORT(R_BAD_ARGS);
337 :
338 : memcpy(attr->u.data.data, data, length);
339 : attr->u.data.length=length;
340 : }
341 : )
342 :
343 : int
344 0 : nr_stun_message_add_lifetime_attribute(nr_stun_message *msg, UINT4 lifetime_secs)
345 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
346 : NR_STUN_ATTR_LIFETIME,
347 : { attr->u.lifetime_secs = lifetime_secs; }
348 : )
349 :
350 : #endif /* USE_TURN */
351 :
352 : #ifdef USE_STUND_0_96
353 : int
354 0 : nr_stun_message_add_change_request_attribute(nr_stun_message *msg, UINT4 change_request)
355 0 : NR_STUN_MESSAGE_ADD_ATTRIBUTE(
356 : NR_STUN_ATTR_OLD_CHANGE_REQUEST,
357 : { attr->u.change_request = change_request; }
358 : )
359 : #endif /* USE_STUND_0_96 */
360 :
|