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

changeset 0
6474c204b198
     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 +

mercurial