⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvaddress.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************************************
Filename   : rvaddress.c
Description: Network address manipulation
************************************************************************
      Copyright (c) 2001,2002 RADVISION Inc. and RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Inc. and RADVISION Ltd.. No part of this document may be
reproduced in any form whatsoever without written prior approval by
RADVISION Inc. or RADVISION Ltd..

RADVISION Inc. and RADVISION Ltd. reserve the right to revise this
publication and make changes without obligation to notify any person of
such revisions or changes.
***********************************************************************/
#include "rvaddress.h"
#include "rvansi.h"
#include <string.h>

/* This whole module could eventually be done with plug-ins but we'll */
/* keep it simple and fast for now. */

static RvChar *Rv_inet_ntop4(const RvUint8 *src, RvChar *dst, RvSize_t size);
static RvChar *Rv_inet_ntop6(const RvUint8 *src, RvChar *dst, RvSize_t size);
static RvBool Rv_inet_pton4(const RvChar *src, RvUint8 *dst);
static RvBool Rv_inet_pton6(const RvChar *src, RvUint8 *dst);

RVCOREAPI RvAddress * RVCALLCONV RvAddressConstruct(RvAddress *addr, RvInt addrtype)
{
	RvUint8 ip6anyaddress[RV_ADDRESS_IPV6_ADDRSIZE];

#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return NULL;
#endif
#if defined(RV_RANGECHECK)
	if((addrtype != RV_ADDRESS_TYPE_NONE) && (addrtype != RV_ADDRESS_TYPE_IPV4) && (addrtype != RV_ADDRESS_TYPE_IPV6))
		return NULL;
#endif

	addr->addrtype = addrtype;
	switch(addrtype) {
		case RV_ADDRESS_TYPE_NONE: return addr; /* No data for address type NONE. */
		case RV_ADDRESS_TYPE_IPV4: if(RvAddressIpv4Construct(&addr->data.ipv4, RV_ADDRESS_IPV4_ANYADDRESS, RV_ADDRESS_IPV4_ANYPORT) != NULL)
									   return addr;
								   break;
		case RV_ADDRESS_TYPE_IPV6: memset(ip6anyaddress, 0, RV_ADDRESS_IPV6_ADDRSIZE);
								   if(RvAddressIpv6Construct(&addr->data.ipv6, ip6anyaddress, RV_ADDRESS_IPV6_ANYPORT) != NULL)
									   return addr;
								   break;
	}
	return NULL;
}

RVCOREAPI RvInt RVCALLCONV RvAddressGetType(const RvAddress *addr)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return RvIntConst(-1);
#endif
	return addr->addrtype;
}

RvAddress *RvAddressCopy(RvAddress *result, const RvAddress *source)
{
#if defined(RV_NULLCHECK)
	if((result == NULL) || (source == NULL))
		return NULL;
#endif

	memcpy(result, source, sizeof(RvAddress));
	return result;
}

RvBool RvAddressCompare(const RvAddress *addr1, const RvAddress *addr2, RvInt comparetype)
{
#if defined(RV_NULLCHECK)
	if((addr1 == NULL) || (addr2 == NULL))
		return RV_FALSE;
#endif
#if defined(RV_RANGECHECK)
	if((comparetype != RV_ADDRESS_FULLADDRESS) && (comparetype != RV_ADDRESS_BASEADDRESS))
		return RV_FALSE;
#endif

	if(addr1->addrtype != addr2->addrtype)
		return RV_FALSE;
	switch(addr1->addrtype) {
		case RV_ADDRESS_TYPE_NONE: return RV_TRUE;
		case RV_ADDRESS_TYPE_IPV4: return RvAddressIpv4Compare(&addr1->data.ipv4, &addr2->data.ipv4, comparetype);
		case RV_ADDRESS_TYPE_IPV6: return RvAddressIpv6Compare(&addr1->data.ipv6, &addr2->data.ipv6, comparetype);
	}
	return RV_FALSE;
}

RVCOREAPI RvChar * RVCALLCONV RvAddressGetString(const RvAddress *addr, RvChar *buf, RvSize_t bufsize)
{
#if defined(RV_NULLCHECK)
	if((addr == NULL) || (buf == NULL))
		return RV_FALSE;
#endif
#if defined(RV_RANGECHECK)
	if(bufsize < 1)
		return NULL;
#endif

	switch(addr->addrtype) {
		case RV_ADDRESS_TYPE_NONE: *buf = '\0';
								   return buf;
		case RV_ADDRESS_TYPE_IPV4: return RvAddressIpv4GetString(&addr->data.ipv4, buf, bufsize);
		case RV_ADDRESS_TYPE_IPV6: return RvAddressIpv6GetString(&addr->data.ipv6, buf, bufsize);
	}
	return NULL;
}

RVCOREAPI RvAddress * RVCALLCONV RvAddressSetString(RvAddress *addr, const RvChar *buf)
{
#if defined(RV_NULLCHECK)
	if((addr == NULL) || (buf == NULL))
		return RV_FALSE;
#endif

	switch(addr->addrtype) {
		case RV_ADDRESS_TYPE_NONE: return NULL;
		case RV_ADDRESS_TYPE_IPV4: if(RvAddressIpv4SetString(&addr->data.ipv4, buf) != NULL)
									   return addr;
								   break;
		case RV_ADDRESS_TYPE_IPV6: if(RvAddressIpv6SetString(&addr->data.ipv6, buf) != NULL)
									   return addr;
								   break;
	}
	return NULL;
}


/* Functions for IPV4 and IPV6 */
RVCOREAPI RvUint16 RVCALLCONV RvAddressGetIpPort(const RvAddress *addr)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return RvUint16Const(0);
#endif
	switch(addr->addrtype) {
		case RV_ADDRESS_TYPE_IPV4: return RvAddressIpv4GetPort(&addr->data.ipv4);
		case RV_ADDRESS_TYPE_IPV6: return RvAddressIpv6GetPort(&addr->data.ipv6);
	}
	return RvUint16Const(0);
}

RVCOREAPI RvAddress * RVCALLCONV RvAddressSetIpPort(RvAddress *addr, RvUint16 port)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return NULL;
#endif
	switch(addr->addrtype) {
		case RV_ADDRESS_TYPE_IPV4: if(RvAddressIpv4SetPort(&addr->data.ipv4, port) != NULL)
									   return addr;
		case RV_ADDRESS_TYPE_IPV6: if(RvAddressIpv6SetPort(&addr->data.ipv6, port) != NULL)
									   return addr;
	}
	return NULL;
}

/* Return RV_TRUE if addr is a multicast address. */
RVCOREAPI RvBool RVCALLCONV RvAddressIsMulticastIp(const RvAddress *addr)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return RV_FALSE;
#endif

	switch(addr->addrtype) {
		case RV_ADDRESS_TYPE_IPV4: return RvAddressIpv4IsMulticast(&addr->data.ipv4);
		case RV_ADDRESS_TYPE_IPV6: return RvAddressIpv6IsMulticast(&addr->data.ipv6);
	}
	return RV_FALSE;
}

/* IPV4 specific functions. */

RVCOREAPI RvAddress * RVCALLCONV RvAddressConstructIpv4(RvAddress *addr, RvUint32 ip, RvUint16 port)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return NULL;
#endif

	addr->addrtype = RV_ADDRESS_TYPE_IPV4;
	if(RvAddressIpv4Construct(&addr->data.ipv4, ip, port) == NULL)
		return NULL;
	return addr;
}

RvChar *RvAddressIpv4ToString(RvChar *buf, RvSize_t bufsize, RvUint32 ip)
{
#if defined(RV_NULLCHECK)
	if(buf == NULL)
		return NULL;
#endif
	return Rv_inet_ntop4((RvUint8 *)&ip, buf, bufsize);
}

RvBool RvAddressStringToIpv4(RvUint32 *ip, const RvChar *buf)
{
#if defined(RV_NULLCHECK)
	if((ip == NULL) || (buf == NULL))
		return RV_FALSE;
#endif
	return Rv_inet_pton4(buf, (RvUint8 *)ip);
}

RVCOREAPI const RvAddressIpv4 * RVCALLCONV RvAddressGetIpv4(const RvAddress *addr)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return NULL;
#endif
#if defined(RV_OTHERCHECK)
	if(addr->addrtype != RV_ADDRESS_TYPE_IPV4)
		return NULL;
#endif

	return &addr->data.ipv4;
}

RvAddressIpv4 *RvAddressIpv4Construct(RvAddressIpv4 *addr, RvUint32 ip, RvUint16 port)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return NULL;
#endif

	addr->ip = ip;
	addr->port = port;
	return addr;
}

RvBool RvAddressIpv4Compare(const RvAddressIpv4 *addr1, const RvAddressIpv4 *addr2, RvInt comparetype)
{
#if defined(RV_NULLCHECK)
	if((addr1 == NULL) || (addr2 == NULL))
		return RV_FALSE;
#endif
#if defined(RV_RANGECHECK)
	if((comparetype != RV_ADDRESS_FULLADDRESS) && (comparetype != RV_ADDRESS_BASEADDRESS))
		return RV_FALSE;
#endif

	/* Check base IP address. */
	if(addr1->ip != addr2->ip)
		return RV_FALSE;

	/* Check full address, which means the port too. */
	if((comparetype == RV_ADDRESS_FULLADDRESS) && (addr1->port != addr2->port))
		return RV_FALSE;

	return RV_TRUE;
}

RvChar *RvAddressIpv4GetString(const RvAddressIpv4 *addr, RvChar *buf, RvSize_t bufsize)
{

#if defined(RV_NULLCHECK)
	if((addr == NULL) || (buf == NULL))
		return NULL;
#endif

	return Rv_inet_ntop4((RvUint8 *)&addr->ip, buf, bufsize);
}

RvAddressIpv4 *RvAddressIpv4SetString(RvAddressIpv4 *addr, const RvChar *buf)
{
#if defined(RV_NULLCHECK)
	if((addr == NULL) || (buf == NULL))
		return NULL;
#endif

	if(Rv_inet_pton4(buf, (RvUint8 *)&addr->ip) == RV_FALSE)
		return NULL;
	return addr;
}

RVCOREAPI RvUint32 RVCALLCONV RvAddressIpv4GetIp(const RvAddressIpv4 *addr)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return RvUint32Const(0);
#endif

	return addr->ip;
}

RVCOREAPI RvAddressIpv4 * RVCALLCONV RvAddressIpv4SetIp(RvAddressIpv4 *addr, RvUint32 ip)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return NULL;
#endif

	addr->ip = ip;
	return addr;
}

RvUint16 RvAddressIpv4GetPort(const RvAddressIpv4 *addr)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return RvUint16Const(0);
#endif

	return addr->port;
}

RvAddressIpv4 *RvAddressIpv4SetPort(RvAddressIpv4 *addr, RvUint16 port)
{
#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return NULL;
#endif

	addr->port = port;
	return addr;
}

RvBool RvAddressIpv4IsMulticast(const RvAddressIpv4 *addr)
{
	RvUint8 *addrbytes;

#if defined(RV_NULLCHECK)
	if(addr == NULL)
		return RV_FALSE;
#endif

	addrbytes = (RvUint8 *)&addr->ip;
	if((addrbytes[0] & RvUint8Const(0xF0)) == RvUint8Const(0xE0)) /* 224..239 */
	   return RV_TRUE;
	return RV_FALSE;
}


/* IPV6 specific functions */

/* The ip address points to a 16 byte IP6 address. */
RvAddress *RvAddressConstructIpv6(RvAddress *addr, const RvUint8 *ip, RvUint16 port)
{
#if defined(RV_NULLCHECK)
	if((addr == NULL) || (ip == NULL))
		return NULL;
#endif

	addr->addrtype = RV_ADDRESS_TYPE_IPV6;
	if(RvAddressIpv6Construct(&addr->data.ipv6, ip, port) == NULL)
		return NULL;
	return addr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -