1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/mtransport/third_party/nICEr/src/stun/stun_hint.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,249 @@ 1.4 +/* 1.5 +Copyright (c) 2007, Adobe Systems, Incorporated 1.6 +All rights reserved. 1.7 + 1.8 +Redistribution and use in source and binary forms, with or without 1.9 +modification, are permitted provided that the following conditions are 1.10 +met: 1.11 + 1.12 +* Redistributions of source code must retain the above copyright 1.13 + notice, this list of conditions and the following disclaimer. 1.14 + 1.15 +* Redistributions in binary form must reproduce the above copyright 1.16 + notice, this list of conditions and the following disclaimer in the 1.17 + documentation and/or other materials provided with the distribution. 1.18 + 1.19 +* Neither the name of Adobe Systems, Network Resonance nor the names of its 1.20 + contributors may be used to endorse or promote products derived from 1.21 + this software without specific prior written permission. 1.22 + 1.23 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.24 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.25 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.26 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.27 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.28 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.29 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.30 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.31 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.32 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.33 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.34 +*/ 1.35 + 1.36 + 1.37 +static char *RCSSTRING __UNUSED__="$Id: stun_hint.c,v 1.2 2008/04/28 18:21:30 ekr Exp $"; 1.38 + 1.39 + 1.40 +#include <errno.h> 1.41 +#include <csi_platform.h> 1.42 + 1.43 +#ifdef WIN32 1.44 +#include <winsock2.h> 1.45 +#include <stdlib.h> 1.46 +#include <io.h> 1.47 +#include <time.h> 1.48 +#else /* UNIX */ 1.49 +#include <string.h> 1.50 +#endif /* end UNIX */ 1.51 +#include <assert.h> 1.52 + 1.53 +#include "stun.h" 1.54 + 1.55 + 1.56 +/* returns 0 if it's not a STUN message 1.57 + * 1 if it's likely to be a STUN message 1.58 + * 2 if it's super likely to be a STUN message 1.59 + * 3 if it really is a STUN message */ 1.60 +int 1.61 +nr_is_stun_message(UCHAR *buf, int len) 1.62 +{ 1.63 + const UINT4 cookie = htonl(NR_STUN_MAGIC_COOKIE); 1.64 + const UINT4 cookie2 = htonl(NR_STUN_MAGIC_COOKIE2); 1.65 +#if 0 1.66 + nr_stun_message msg; 1.67 +#endif 1.68 + UINT2 type; 1.69 + nr_stun_encoded_attribute* attr; 1.70 + unsigned int attrLen; 1.71 + int atrType; 1.72 + 1.73 + if (sizeof(nr_stun_message_header) > len) 1.74 + return 0; 1.75 + 1.76 + if ((buf[0] & (0x80|0x40)) != 0) 1.77 + return 0; 1.78 + 1.79 + memcpy(&type, buf, 2); 1.80 + type = ntohs(type); 1.81 + 1.82 + switch (type) { 1.83 + case NR_STUN_MSG_BINDING_REQUEST: 1.84 + case NR_STUN_MSG_BINDING_INDICATION: 1.85 + case NR_STUN_MSG_BINDING_RESPONSE: 1.86 + case NR_STUN_MSG_BINDING_ERROR_RESPONSE: 1.87 + 1.88 +#ifdef USE_TURN 1.89 + case NR_STUN_MSG_ALLOCATE_REQUEST: 1.90 + case NR_STUN_MSG_ALLOCATE_RESPONSE: 1.91 + case NR_STUN_MSG_ALLOCATE_ERROR_RESPONSE: 1.92 + case NR_STUN_MSG_REFRESH_REQUEST: 1.93 + case NR_STUN_MSG_REFRESH_RESPONSE: 1.94 + case NR_STUN_MSG_REFRESH_ERROR_RESPONSE: 1.95 + case NR_STUN_MSG_PERMISSION_REQUEST: 1.96 + case NR_STUN_MSG_PERMISSION_RESPONSE: 1.97 + case NR_STUN_MSG_PERMISSION_ERROR_RESPONSE: 1.98 + case NR_STUN_MSG_CHANNEL_BIND_REQUEST: 1.99 + case NR_STUN_MSG_CHANNEL_BIND_RESPONSE: 1.100 + case NR_STUN_MSG_CHANNEL_BIND_ERROR_RESPONSE: 1.101 + case NR_STUN_MSG_SEND_INDICATION: 1.102 + case NR_STUN_MSG_DATA_INDICATION: 1.103 +#ifdef NR_STUN_MSG_CONNECT_REQUEST 1.104 + case NR_STUN_MSG_CONNECT_REQUEST: 1.105 +#endif 1.106 +#ifdef NR_STUN_MSG_CONNECT_RESPONSE 1.107 + case NR_STUN_MSG_CONNECT_RESPONSE: 1.108 +#endif 1.109 +#ifdef NR_STUN_MSG_CONNECT_ERROR_RESPONSE 1.110 + case NR_STUN_MSG_CONNECT_ERROR_RESPONSE: 1.111 +#endif 1.112 +#ifdef NR_STUN_MSG_CONNECT_STATUS_INDICATION 1.113 + case NR_STUN_MSG_CONNECT_STATUS_INDICATION: 1.114 +#endif 1.115 +#endif /* USE_TURN */ 1.116 + 1.117 + /* ok so far, continue */ 1.118 + break; 1.119 + default: 1.120 + return 0; 1.121 + break; 1.122 + } 1.123 + 1.124 + if (!memcmp(&cookie2, &buf[4], sizeof(UINT4))) { 1.125 + /* return here because if it's an old-style message then there will 1.126 + * not be a fingerprint in the message */ 1.127 + return 1; 1.128 + } 1.129 + 1.130 + if (memcmp(&cookie, &buf[4], sizeof(UINT4))) 1.131 + return 0; 1.132 + 1.133 + /* the magic cookie was right, so it's pretty darn likely that what we've 1.134 + * got here is a STUN message */ 1.135 + 1.136 + attr = (nr_stun_encoded_attribute*)(buf + (len - 8)); 1.137 + attrLen = ntohs(attr->length); 1.138 + atrType = ntohs(attr->type); 1.139 + 1.140 + if (atrType != NR_STUN_ATTR_FINGERPRINT || attrLen != 4) 1.141 + return 1; 1.142 + 1.143 + /* the fingerprint is in the right place and looks sane, so we can be quite 1.144 + * sure we've got a STUN message */ 1.145 + 1.146 +#if 0 1.147 +/* nevermind this check ... there's a reasonable chance that a NAT has modified 1.148 + * the message (and thus the fingerprint check will fail), but it's still an 1.149 + * otherwise-perfectly-good STUN message, so skip the check since we're going 1.150 + * to return "true" whether the check succeeds or fails */ 1.151 + 1.152 + if (nr_stun_parse_attr_UINT4(buf + (len - 4), attrLen, &msg.fingerprint)) 1.153 + return 2; 1.154 + 1.155 + 1.156 + if (nr_stun_compute_fingerprint(buf, len - 8, &computedFingerprint)) 1.157 + return 2; 1.158 + 1.159 + if (msg.fingerprint.number != computedFingerprint) 1.160 + return 2; 1.161 + 1.162 + /* and the fingerprint is good, so it's gotta be a STUN message */ 1.163 +#endif 1.164 + 1.165 + return 3; 1.166 +} 1.167 + 1.168 +int 1.169 +nr_is_stun_request_message(UCHAR *buf, int len) 1.170 +{ 1.171 + UINT2 type; 1.172 + 1.173 + if (sizeof(nr_stun_message_header) > len) 1.174 + return 0; 1.175 + 1.176 + if (!nr_is_stun_message(buf, len)) 1.177 + return 0; 1.178 + 1.179 + memcpy(&type, buf, 2); 1.180 + type = ntohs(type); 1.181 + 1.182 + return NR_STUN_GET_TYPE_CLASS(type) == NR_CLASS_REQUEST; 1.183 +} 1.184 + 1.185 +int 1.186 +nr_is_stun_indication_message(UCHAR *buf, int len) 1.187 +{ 1.188 + UINT2 type; 1.189 + 1.190 + if (sizeof(nr_stun_message_header) > len) 1.191 + return 0; 1.192 + 1.193 + if (!nr_is_stun_message(buf, len)) 1.194 + return 0; 1.195 + 1.196 + memcpy(&type, buf, 2); 1.197 + type = ntohs(type); 1.198 + 1.199 + return NR_STUN_GET_TYPE_CLASS(type) == NR_CLASS_INDICATION; 1.200 +} 1.201 + 1.202 +int 1.203 +nr_is_stun_response_message(UCHAR *buf, int len) 1.204 +{ 1.205 + UINT2 type; 1.206 + 1.207 + if (sizeof(nr_stun_message_header) > len) 1.208 + return 0; 1.209 + 1.210 + if (!nr_is_stun_message(buf, len)) 1.211 + return 0; 1.212 + 1.213 + memcpy(&type, buf, 2); 1.214 + type = ntohs(type); 1.215 + 1.216 + return NR_STUN_GET_TYPE_CLASS(type) == NR_CLASS_RESPONSE 1.217 + || NR_STUN_GET_TYPE_CLASS(type) == NR_CLASS_ERROR_RESPONSE; 1.218 +} 1.219 + 1.220 +int 1.221 +nr_has_stun_cookie(UCHAR *buf, int len) 1.222 +{ 1.223 + static UINT4 cookie; 1.224 + 1.225 + cookie = htonl(NR_STUN_MAGIC_COOKIE); 1.226 + 1.227 + if (sizeof(nr_stun_message_header) > len) 1.228 + return 0; 1.229 + 1.230 + if (memcmp(&cookie, &buf[4], sizeof(UINT4))) 1.231 + return 0; 1.232 + 1.233 + return 1; 1.234 +} 1.235 + 1.236 +int 1.237 +nr_stun_message_length(UCHAR *buf, int buf_len, int *msg_len) 1.238 +{ 1.239 + nr_stun_message_header *hdr; 1.240 + 1.241 + if (!nr_is_stun_message(buf, buf_len)) 1.242 + return(R_BAD_DATA); 1.243 + 1.244 + hdr = (nr_stun_message_header *)buf; 1.245 + 1.246 + *msg_len = ntohs(hdr->length); 1.247 + 1.248 + return(0); 1.249 +} 1.250 + 1.251 + 1.252 +