📄 rvhost.c
字号:
/***********************************************************************
Filename : rvhost.c
Description: host related functions
************************************************************************
Copyright (c) 2001 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 "rvstdio.h"
#include "rvhost.h"
#if (RV_OS_TYPE == RV_OS_TYPE_LINUX) || (RV_OS_TYPE == RV_OS_TYPE_EMBLINUX) || (RV_OS_TYPE == RV_OS_TYPE_SOLARIS)
#include <netdb.h>
#include <sys/socket.h>
#elif (RV_OS_TYPE == RV_OS_TYPE_TRU64)
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#elif (RV_OS_TYPE == RV_OS_TYPE_HPUX)
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#elif (RV_OS_TYPE == RV_OS_TYPE_UNIXWARE)
#include <netdb.h>
#elif (RV_OS_TYPE == RV_OS_TYPE_WIN32)
#pragma warning (push,3)
#include <winsock2.h>
#pragma warning (pop)
#elif (RV_OS_TYPE == RV_OS_TYPE_WINCE)
#pragma warning (push,3)
#include <winsock.h>
#pragma warning (pop)
#elif (RV_OS_TYPE == RV_OS_TYPE_VXWORKS)
#include "resolvLib.h"
#include <netinet/in.h>
#include <netinet/in_var.h>
#define IPLIST_MAX_LENGTH 10
static RvUint8 LOCAL_IP_BUF[] = {0x7f, 0x00, 0x00, 0x01};
#elif (RV_OS_TYPE == RV_OS_TYPE_PSOS)
#include <pna.h>
#include <pnacfg.h>
extern pNA_CT PnaCfg;
#define satosin(sa) ((struct sockaddr_in *)(sa))
#define IPLIST_MAX_LENGTH 10
static RvUint8 LOCAL_IP_BUF[] = {0x7f, 0x00, 0x00, 0x01};
RvInt gethostname(RvChar *buf, int size)
{
strncpy(buf, PnaCfg.nc_hostname, (RvSize_t)size);
return 0;
}
#elif (RV_OS_TYPE == RV_OS_TYPE_OSE)
#include <netdb.h>
#elif (RV_OS_TYPE == RV_OS_TYPE_NUCLEUS)
#include <nucleus.h>
#include <socketd.h>
static RvChar nuHostBuf[256];
struct hostent {
char* h_name;
char** h_aliases;
short h_addrtype;
short h_length;
char** h_addr_list;
};
#endif
/* Lets make error codes a little easier to type */
#define RvHostErrorCode(_e) RvErrorCode(RV_ERROR_LIBCODE_CCORE, RV_CCORE_MODULE_HOST, (_e))
/* Host's name - allocated statically */
static RvChar rvHostLocalName[RV_HOST_MAX_NAMESIZE];
#if (RV_HOST_HAS_STATIC_ADDR == 1)
/* List of host addresses - allocated statically */
static RvUint32 rvHostLocalIpList[RV_HOST_MAX_ADDRS];
static RvUint32 rvHostLocalNumOfIps;
static RvBool rvHostLocalListInitialized = RV_FALSE;
#endif
/********************************************************************************************
*
* Private functions
*
********************************************************************************************/
#if (RV_OS_TYPE == RV_OS_TYPE_OSE)
/* since there is no host name in OSE, get it from the environment. */
/* host name should be set in environment prior to stack init (check readme file) */
int gethostname(char *buf, size_t size)
{
char *result;
result = get_env(current_process(), "HOSTNAME");
if(result == NULL) {
result = get_env(get_bid(current_process()), "HOSTNAME"); /* try block environment */
if(result == NULL) {
*buf = '\0';
return -1;
}
}
strncpy(buf, result, size);
free_buf((union SIGNAL **)&result);
return 0;
}
#endif /* (RV_OS_TYPE == RV_OS_TYPE_OSE) */
#if (RV_OS_TYPE == RV_OS_TYPE_NUCLEUS)
/********************************************************************************************
* gethostbyname
* purpose : Get host address corresponding to the host name.
* input : host - host name.
* buf - buffer workspace holds the memory of the result.
* size - size of buf.
* output : none
* return : a pointer to the hostent sturcture with the host address.
********************************************************************************************/
static struct hostent* gethostbyname(const RvChar* host, RvChar* buf, RvSize_t size)
{
struct hostent *h;
RvChar *resultbuf;
RvSize_t hostbufsize, resultbufsize;
NU_HOSTENT nuc_h;
RvChar **data;
/* Make sure eveything is aligned right */
h = (struct hostent *)rvAlign(buf); /* aligned hostent */
hostbufsize = size - (size_t)((char *)h - buf); /* size of buffer with hostent */
resultbuf = (char *)h + sizeof(struct hostent); /* start of remaining buffer */
resultbufsize = size - (size_t)(resultbuf - buf); /* size of buffer without hostent */
/* Nucleus never uses h_aliases and only allows one address (h_addr) */
/* Also, name and address are not re-entrant, they point to internal */
/* structures which can change out from underneath you. */
/* Set up target result structure and data tables */
data = (char **)resultbuf;
*data = NULL; /* Empty alias table, has 1 null item */
h->h_aliases = data; /* set alias pointer to the table */
data++;
h->h_addr_list = data; /* set address pointer to address table */
data++;
*data = NULL; /* end of address pointer table */
data++;
if(NU_Get_Host_By_Name((char *)host, &nuc_h) != NU_SUCCESS)
{
return(NULL);
}
if(resultbufsize < (strlen(nuc_h.h_name) + 1 + (sizeof(char *) * 4))) /* make sure we have enough space */
{
return (NULL);
}
*h->h_addr_list = memcpy((char *)data, nuc_h.h_addr, nuc_h.h_length); /* copy address and set ptr */
data++;
h->h_name = strcpy((char *)data, nuc_h.h_name); /* copy name string and set h_hname */
h->h_addrtype = nuc_h.h_addrtype;
h->h_length = nuc_h.h_length;
return h;
}
#endif
/********************************************************************************************
* RvHostFindLocalName
*
* purpose : Get the name of the local host and initialize it. This function is called from
* RvHostInit and is not guaranteed to be thread-safe.
* input : nameLength - Length of the name buffer in bytes
* output : name - Null terminated name of the local host
* return : RV_OK on success
* Other values on failure
********************************************************************************************/
static RvStatus RvHostFindLocalName(
IN RvSize_t nameLength,
OUT RvChar* name)
{
RvStatus ret = RV_OK;
#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)
if (gethostname(name, (int)nameLength) != 0)
ret = RvHostErrorCode(RV_ERROR_UNKNOWN);
#else
if (NU_Get_Host_Name(name, (int)nameLength) != 0)
ret = RvHostErrorCode(RV_ERROR_UNKNOWN);
#endif
return ret;
}
/********************************************************************************************
* RvHostGetIpList
*
* purpose : Get the IP list of a host. This is done for IPv4 addresses only.
* input : hostName - Name of host to look for
* numOfIps - Maximum number of IPs to get
* output : numOfIps - Number of IPs we got
* ipList - List of IPs we got
* return : RV_OK on success
* Other values on failure
********************************************************************************************/
static RvStatus RvHostGetIpList(
IN RvChar* hostName,
INOUT RvUint32* numOfIps,
OUT RvUint32* ipList)
{
RvUint32** addrs;
struct hostent* host;
RvUint32 i = 0;
#if (RV_OS_TYPE == RV_OS_TYPE_PSOS) /* todo: verify proper result for the PSOS implementation otherwise use the old implementation (as in lowunix...) */
RvUint32 *ipListPtrs[IPLIST_MAX_LENGTH];
int s;
RvUint32 rc = 0;
struct ifreq ifr;
/* create any type of socket */
s = socket(AF_INET, SOCK_DGRAM, 0);
for (ifr.ifr_ifno = 1, i = 0; !rc; ifr.ifr_ifno++) /* Start from 1, not from 0 - from debugging */
{
satosin(&ifr.ifr_addr)->sin_family = AF_INET;
rc = ioctl(s, SIOCGIFADDR, (RvChar *)&ifr); /* Get the IP address of the pNA+ interface */
if (!rc)
{
if ( satosin(&ifr.ifr_addr)->sin_addr.s_addr != (*(RvUint32*)LOCAL_IP_BUF))
{
ipList[i]= satosin(&ifr.ifr_addr)->sin_addr.s_addr;
ipListPtrs[i]=&ipList[i];
i++;
}
}
}
close(s);
ipListPtrs[i]=NULL;
*numOfIps = i;
addrs = (RvUint32**)ipListPtrs;
#elif (RV_OS_TYPE == RV_OS_TYPE_VXWORKS)
RvUint32 *ipListPtrs[IPLIST_MAX_LENGTH];
FAST struct in_ifaddr *ia = 0;
struct sockaddr_in *tmpAddr;
for (ia=in_ifaddr; ia != NULL; ia=ia->ia_next)
{
tmpAddr = IA_SIN(ia);
if ( (tmpAddr->sin_addr).s_addr != (*(UINT32*)LOCAL_IP_BUF))
{
ipList[i]= (tmpAddr->sin_addr).s_addr;
ipListPtrs[i]=&ipList[i];
i++;
}
}
ipListPtrs[i]=NULL;
*numOfIps = i;
addrs = (RvUint32**)ipListPtrs;
#else
/* Other OS's implementation */
#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)
host = (struct hostent*) gethostbyname(hostName);
#else
host = (struct hostent*) gethostbyname(hostName, nuHostBuf, sizeof(host));
#endif
if (host == NULL)
{
*numOfIps = 0;
return RvHostErrorCode(RV_ERROR_UNKNOWN);
}
addrs = (RvUint32**)(host->h_addr_list);
for (i = 0; (i < *numOfIps) && (addrs[i] != NULL); i++)
ipList[i] = *addrs[i];
#endif
*numOfIps = i;
return RV_OK;
}
/********************************************************************************************
*
* Public functions
*
********************************************************************************************/
RvStatus RvHostInit(void)
{
return RvHostFindLocalName(sizeof(rvHostLocalName), rvHostLocalName);
}
RvStatus RvHostEnd(void)
{
#if (RV_HOST_HAS_STATIC_ADDR == 1)
rvHostLocalListInitialized = RV_FALSE;
#endif
return RV_OK;
}
/********************************************************************************************
* RvHostLocalGetName
*
* purpose : Get the name of the local host.
* input : nameLength - Length of the name buffer in bytes
* output : name - Null terminated name of the local host
* return : RV_OK on success
* Other values on failure
********************************************************************************************/
RVCOREAPI RvStatus RVCALLCONV RvHostLocalGetName(
IN RvSize_t nameLength,
OUT RvChar* name)
{
#if defined(RV_NULLCHECK)
if (name == NULL)
return RvHostErrorCode(RV_ERROR_NULLPTR);
#endif
if (strlen(rvHostLocalName) > nameLength)
return RvHostErrorCode(RV_ERROR_OUTOFRANGE);
strncpy(name, rvHostLocalName, nameLength);
return RV_OK;
}
/********************************************************************************************
* RvHostLocalGetAddress
*
* purpose : Get the addresses of the local host.
* input : numberOfAddresses - Maximum number of addresses to get
* addresses - Array of addresses to fill in
* output : NumberOfAddresses - Number of addresses filled in
* addresses - Constructed addresses. These addresses should be destructed
* using RvAddressDestruct() when not needed anymore.
* return : RV_OK on success
* Other values on failure
********************************************************************************************/
RVCOREAPI RvStatus RVCALLCONV RvHostLocalGetAddress(
INOUT RvUint32* numberOfAddresses,
INOUT RvAddress* addresses)
{
RvBool obtainIpList = RV_TRUE;
RvStatus ret = RV_OK;
RvUint32 i;
#if (RV_HOST_HAS_STATIC_ADDR == 0)
/* List of host addresses - allocated dynamically on the stack */
RvUint32 rvHostLocalIpList[RV_HOST_MAX_ADDRS];
RvUint32 rvHostLocalNumOfIps = RV_HOST_MAX_ADDRS;
#elif (RV_HOST_HAS_STATIC_ADDR == 1)
/* Static IP list - see if we already have it */
obtainIpList = (rvHostLocalListInitialized == RV_FALSE);
#endif
#if defined(RV_NULLCHECK)
if ((numberOfAddresses == NULL) || (addresses == NULL))
return RvHostErrorCode(RV_ERROR_NULLPTR);
#endif
if (obtainIpList)
{
/* We need to get the list of addresses for the local host */
rvHostLocalNumOfIps = RV_HOST_MAX_ADDRS;
ret = RvHostGetIpList(rvHostLocalName, &rvHostLocalNumOfIps, rvHostLocalIpList);
#if (RV_HOST_HAS_STATIC_ADDR == 1)
if (ret == RV_OK)
rvHostLocalListInitialized == RV_TRUE;
#endif
}
if (ret == RV_OK)
{
RvInt IpOffset = 0;
#if 0
#if (RV_OS_TYPE == RV_OS_TYPE_WINCE)
/* COMPAQ iPAQ: real IP is *SECOND* on the list, retreived from gethostbyname().
so to make the fix as minor as possible, increment the array pointer.
The first number on the list, is most likly the USB interface identifier,
when the device is USB-connected to the desktop computer. */
IpOffset = 1;
#endif
#endif
/* We have a lot of addresses - convert them into RvAddress structures */
*numberOfAddresses = RvMin(rvHostLocalNumOfIps, *numberOfAddresses);
for (i = 0; i < (*numberOfAddresses); i++)
{
RvAddressConstructIpv4(addresses+i, rvHostLocalIpList[IpOffset+i],
RV_ADDRESS_IPV4_ANYPORT);
}
}
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -