/*
The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* <http://www.vovida.org/>.
*
*/
#ifdef HAVE_CONFIG_H
#include "ortp-config.h"
#endif
#ifndef _WIN32_WCE
#include <errno.h>
#endif
#include <assert.h>
#if defined(WIN32) || defined(_WIN32_WCE)
#include <winsock2.h>
#include <stdlib.h>
/* #include <io.h> */
#include <time.h>
#include <ctype.h> /*for isdigit() */
#else
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <net/if.h>
#endif
#if !defined(HAVE_OPENSSL_HMAC_H) || !defined(HAVE_OPENSSL_MD5_H)
#define NOSSL 1
#endif
#include "ortp/stun_udp.h"
#include "ortp/stun.h"
#include "ortp/ortp.h"
static char *ipaddr(const StunAddress4 *addr)
{
static char tmp[512];
struct in_addr inaddr;
char *atmp;
inaddr.s_addr = htonl(addr->addr);
atmp = (char *)inet_ntoa(inaddr);
snprintf(tmp, 512, "%s:%i", atmp, addr->port);
return tmp;
}
static bool_t
stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress4 *result )
{
if ( hdrLen != 8 )
{
ortp_error("stun: hdrLen wrong for Address\n");
return FALSE;
}
result->pad = *body++;
result->family = *body++;
if (result->family == IPv4Family)
{
uint16_t nport;
uint32_t naddr;
memcpy(&nport, body, 2); body+=2;
result->ipv4.port = ntohs(nport);
memcpy(&naddr, body, 4); body+=4;
result->ipv4.addr = ntohl(naddr);
return TRUE;
}
else if (result->family == IPv6Family)
{
ortp_error("stun: ipv6 not supported\n");
}
else
{
ortp_error("stun: bad address family: %i\n", result->family);
}
return FALSE;
}
static bool_t
stunParseAtrChangeRequest( char* body, unsigned int hdrLen, StunAtrChangeRequest *result )
{
if ( hdrLen != 4 )
{
/* ortp_error("stun: hdr length = %i expecting %i\n",hdrLen, sizeof(result)); */
ortp_error("stun: Incorrect size for SA_CHANGEREQUEST");
return FALSE;
}
else
{
memcpy(&result->value, body, 4);
result->value = ntohl(result->value);
return TRUE;
}
}
static bool_t
stunParseAtrError( char* body, unsigned int hdrLen, StunAtrError *result )
{
if ( hdrLen < 4 || hdrLen >= 128+4)
{
ortp_error("stun: Incorrect size for SA_ERRORCODE");
return FALSE;
}
else
{
memcpy(&result->pad, body, 2); body+=2;
result->pad = ntohs(result->pad);
result->errorClass = *body++;
result->number = *body++;
result->sizeReason = hdrLen - 4;
memcpy(&result->reason, body, result->sizeReason);
result->reason[result->sizeReason] = 0;
return TRUE;
}
}
static bool_t
stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown *result )
{
if ( hdrLen >= sizeof(*result) )
{
ortp_error("stun: Incorrect size for SA_UNKNOWNATTRIBUTE");
return FALSE;
}
else
{
int i;
if (hdrLen % 4 != 0) return FALSE;
result->numAttributes = hdrLen / 4;
for (i=0; i<result->numAttributes; i++)
{
memcpy(&result->attrType[i], body, 2); body+=2;
result->attrType[i] = ntohs(result->attrType[i]);
}
return TRUE;
}
}
static bool_t
stunParseAtrString( char* body, unsigned int hdrLen, StunAtrString *result )
{
if ( hdrLen >= STUN_MAX_STRING )
{
ortp_error("stun: String is too large");
return FALSE;
}
else
{
result->sizeValue = hdrLen;
memcpy(&result->value, body, hdrLen);
result->value[hdrLen] = 0;
return TRUE;
}
}
static bool_t
stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity *result )
{
if ( hdrLen != 20)
{
ortp_error("stun: SA_MESSAGEINTEGRITY must be 20 bytes");
return FALSE;
}
else
{
memcpy(&result->hash, body, hdrLen);
return TRUE;
}
}
static bool_t
turnParseAtrChannelNumber( char* body, unsigned int hdrLen, TurnAtrChannelNumber *result )
{
if ( hdrLen >= sizeof(*result) )
{
ortp_error("stun: Incorrect size for TA_CHANNELNUMBER");
return FALSE;
}
else
{
if (hdrLen % 4 != 0) return FALSE;
memcpy(&result->channelNumber, body, 2);
body+=2;
result->channelNumber = ntohs(result->channelNumber);
memcpy(&result->rffu, body, 2);
body+=2;
result->rffu = ntohs(result->rffu);
return TRUE;
}
}
static bool_t
turnParseAtrLifetime( char* body, unsigned int hdrLen, TurnAtrLifetime *result )
{
if ( hdrLen != sizeof(*result) )
{
ortp_error("stun: Incorrect size for TA_LIFETIME");
return FALSE;
}
else
{
memcpy(&result->
评论0
最新资源