media/mtransport/third_party/nICEr/src/stun/stun_hint.c

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:4c48e29e318c
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_hint.c,v 1.2 2008/04/28 18:21:30 ekr Exp $";
35
36
37 #include <errno.h>
38 #include <csi_platform.h>
39
40 #ifdef WIN32
41 #include <winsock2.h>
42 #include <stdlib.h>
43 #include <io.h>
44 #include <time.h>
45 #else /* UNIX */
46 #include <string.h>
47 #endif /* end UNIX */
48 #include <assert.h>
49
50 #include "stun.h"
51
52
53 /* returns 0 if it's not a STUN message
54 * 1 if it's likely to be a STUN message
55 * 2 if it's super likely to be a STUN message
56 * 3 if it really is a STUN message */
57 int
58 nr_is_stun_message(UCHAR *buf, int len)
59 {
60 const UINT4 cookie = htonl(NR_STUN_MAGIC_COOKIE);
61 const UINT4 cookie2 = htonl(NR_STUN_MAGIC_COOKIE2);
62 #if 0
63 nr_stun_message msg;
64 #endif
65 UINT2 type;
66 nr_stun_encoded_attribute* attr;
67 unsigned int attrLen;
68 int atrType;
69
70 if (sizeof(nr_stun_message_header) > len)
71 return 0;
72
73 if ((buf[0] & (0x80|0x40)) != 0)
74 return 0;
75
76 memcpy(&type, buf, 2);
77 type = ntohs(type);
78
79 switch (type) {
80 case NR_STUN_MSG_BINDING_REQUEST:
81 case NR_STUN_MSG_BINDING_INDICATION:
82 case NR_STUN_MSG_BINDING_RESPONSE:
83 case NR_STUN_MSG_BINDING_ERROR_RESPONSE:
84
85 #ifdef USE_TURN
86 case NR_STUN_MSG_ALLOCATE_REQUEST:
87 case NR_STUN_MSG_ALLOCATE_RESPONSE:
88 case NR_STUN_MSG_ALLOCATE_ERROR_RESPONSE:
89 case NR_STUN_MSG_REFRESH_REQUEST:
90 case NR_STUN_MSG_REFRESH_RESPONSE:
91 case NR_STUN_MSG_REFRESH_ERROR_RESPONSE:
92 case NR_STUN_MSG_PERMISSION_REQUEST:
93 case NR_STUN_MSG_PERMISSION_RESPONSE:
94 case NR_STUN_MSG_PERMISSION_ERROR_RESPONSE:
95 case NR_STUN_MSG_CHANNEL_BIND_REQUEST:
96 case NR_STUN_MSG_CHANNEL_BIND_RESPONSE:
97 case NR_STUN_MSG_CHANNEL_BIND_ERROR_RESPONSE:
98 case NR_STUN_MSG_SEND_INDICATION:
99 case NR_STUN_MSG_DATA_INDICATION:
100 #ifdef NR_STUN_MSG_CONNECT_REQUEST
101 case NR_STUN_MSG_CONNECT_REQUEST:
102 #endif
103 #ifdef NR_STUN_MSG_CONNECT_RESPONSE
104 case NR_STUN_MSG_CONNECT_RESPONSE:
105 #endif
106 #ifdef NR_STUN_MSG_CONNECT_ERROR_RESPONSE
107 case NR_STUN_MSG_CONNECT_ERROR_RESPONSE:
108 #endif
109 #ifdef NR_STUN_MSG_CONNECT_STATUS_INDICATION
110 case NR_STUN_MSG_CONNECT_STATUS_INDICATION:
111 #endif
112 #endif /* USE_TURN */
113
114 /* ok so far, continue */
115 break;
116 default:
117 return 0;
118 break;
119 }
120
121 if (!memcmp(&cookie2, &buf[4], sizeof(UINT4))) {
122 /* return here because if it's an old-style message then there will
123 * not be a fingerprint in the message */
124 return 1;
125 }
126
127 if (memcmp(&cookie, &buf[4], sizeof(UINT4)))
128 return 0;
129
130 /* the magic cookie was right, so it's pretty darn likely that what we've
131 * got here is a STUN message */
132
133 attr = (nr_stun_encoded_attribute*)(buf + (len - 8));
134 attrLen = ntohs(attr->length);
135 atrType = ntohs(attr->type);
136
137 if (atrType != NR_STUN_ATTR_FINGERPRINT || attrLen != 4)
138 return 1;
139
140 /* the fingerprint is in the right place and looks sane, so we can be quite
141 * sure we've got a STUN message */
142
143 #if 0
144 /* nevermind this check ... there's a reasonable chance that a NAT has modified
145 * the message (and thus the fingerprint check will fail), but it's still an
146 * otherwise-perfectly-good STUN message, so skip the check since we're going
147 * to return "true" whether the check succeeds or fails */
148
149 if (nr_stun_parse_attr_UINT4(buf + (len - 4), attrLen, &msg.fingerprint))
150 return 2;
151
152
153 if (nr_stun_compute_fingerprint(buf, len - 8, &computedFingerprint))
154 return 2;
155
156 if (msg.fingerprint.number != computedFingerprint)
157 return 2;
158
159 /* and the fingerprint is good, so it's gotta be a STUN message */
160 #endif
161
162 return 3;
163 }
164
165 int
166 nr_is_stun_request_message(UCHAR *buf, int len)
167 {
168 UINT2 type;
169
170 if (sizeof(nr_stun_message_header) > len)
171 return 0;
172
173 if (!nr_is_stun_message(buf, len))
174 return 0;
175
176 memcpy(&type, buf, 2);
177 type = ntohs(type);
178
179 return NR_STUN_GET_TYPE_CLASS(type) == NR_CLASS_REQUEST;
180 }
181
182 int
183 nr_is_stun_indication_message(UCHAR *buf, int len)
184 {
185 UINT2 type;
186
187 if (sizeof(nr_stun_message_header) > len)
188 return 0;
189
190 if (!nr_is_stun_message(buf, len))
191 return 0;
192
193 memcpy(&type, buf, 2);
194 type = ntohs(type);
195
196 return NR_STUN_GET_TYPE_CLASS(type) == NR_CLASS_INDICATION;
197 }
198
199 int
200 nr_is_stun_response_message(UCHAR *buf, int len)
201 {
202 UINT2 type;
203
204 if (sizeof(nr_stun_message_header) > len)
205 return 0;
206
207 if (!nr_is_stun_message(buf, len))
208 return 0;
209
210 memcpy(&type, buf, 2);
211 type = ntohs(type);
212
213 return NR_STUN_GET_TYPE_CLASS(type) == NR_CLASS_RESPONSE
214 || NR_STUN_GET_TYPE_CLASS(type) == NR_CLASS_ERROR_RESPONSE;
215 }
216
217 int
218 nr_has_stun_cookie(UCHAR *buf, int len)
219 {
220 static UINT4 cookie;
221
222 cookie = htonl(NR_STUN_MAGIC_COOKIE);
223
224 if (sizeof(nr_stun_message_header) > len)
225 return 0;
226
227 if (memcmp(&cookie, &buf[4], sizeof(UINT4)))
228 return 0;
229
230 return 1;
231 }
232
233 int
234 nr_stun_message_length(UCHAR *buf, int buf_len, int *msg_len)
235 {
236 nr_stun_message_header *hdr;
237
238 if (!nr_is_stun_message(buf, buf_len))
239 return(R_BAD_DATA);
240
241 hdr = (nr_stun_message_header *)buf;
242
243 *msg_len = ntohs(hdr->length);
244
245 return(0);
246 }
247
248
249

mercurial