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

📄 inaddr.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//  // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program 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 General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however    // invalidate any other reasons why the executable file might be covered by// the GNU General Public License.    //// This exception applies only to the code released under the name GNU// Common C++.  If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include <cc++/config.h>#include <cc++/export.h>#include <cc++/address.h>#include "private.h"#include <cstdlib>#ifdef	CCXX_NAMESPACESnamespace ost {#endif#ifndef WIN32Mutex IPV4Address::mutex;#endifconst IPV4MulticastValidator IPV4Multicast::validator;void IPV4MulticastValidator::operator()(const in_addr address) const{#ifdef	CCXX_EXCEPTIONS	// "0.0.0.0" is always accepted, as it is an "empty" address.	if ( (address.s_addr != INADDR_ANY) &&	     (address.s_addr & MCAST_VALID_MASK) != MCAST_VALID_VALUE ) {		throw "Multicast address not in the valid range: from 224.0.0.1 through 239.255.255.255";	}#endif}IPV4Address::IPV4Address(const IPV4Validator *_validator) 	: validator(_validator), ipaddr(NULL), addr_count(0), hostname(NULL){	*this = (long unsigned int)INADDR_ANY;}IPV4Address::IPV4Address(const char *address, const IPV4Validator *_validator) : 	validator(_validator), ipaddr(NULL), addr_count(0), hostname(NULL){	if ( this->validator )		this->validator = validator;	if(address == 0 || !strcmp(address, "*"))		setAddress(NULL);	else		setAddress(address);}IPV4Address::IPV4Address(struct in_addr addr, const IPV4Validator *_validator) : 	validator(_validator), ipaddr(NULL), hostname(NULL){	if ( this->validator ){		this->validator = validator;		(*validator)(addr);	}	addr_count = 1;	ipaddr = new struct in_addr[1];	ipaddr[0] = addr;}IPV4Address::IPV4Address(const IPV4Address &rhs) : validator(rhs.validator), addr_count(rhs.addr_count), hostname(NULL){	ipaddr = new struct in_addr[addr_count];	memcpy(ipaddr, rhs.ipaddr, sizeof(struct in_addr) * addr_count);}IPV4Address::~IPV4Address(){	if(ipaddr)	{		delete[] ipaddr;		ipaddr = NULL;	}	if(hostname)	{		delString(hostname);		hostname = NULL;	}}struct in_addr IPV4Address::getAddress(void) const{	return ipaddr[0];}struct in_addr IPV4Address::getAddress(size_t i) const{	return (i < addr_count ? ipaddr[i] : ipaddr[0]);}bool IPV4Address::isInetAddress(void) const{	struct in_addr addr;	memset(&addr, 0, sizeof(addr));	if(memcmp(&addr, &ipaddr[0], sizeof(addr)))		return true;	return false;}IPV4Address &IPV4Address::operator=(const char *str){	if(str == 0 || !strcmp(str, "*"))		str = "0.0.0.0";	setAddress(str);	return *this;}IPV4Address &IPV4Address::operator=(struct in_addr addr){	if(ipaddr)		delete[] ipaddr;	if ( validator )		(*validator)(addr);	addr_count = 1;	ipaddr = new struct in_addr[1];	ipaddr[0] = addr;	if(hostname)		delString(hostname);	hostname = NULL;	return *this;}IPV4Address &IPV4Address::operator=(unsigned long addr){	if ( validator )		(*validator)(*reinterpret_cast<in_addr*>(&addr));	if(ipaddr)		delete[] ipaddr;	addr_count = 1;	ipaddr = new struct in_addr[1];        memcpy(ipaddr, &addr, sizeof(struct in_addr));	if(hostname)		delString(hostname);	hostname = NULL;	return *this;        }IPV4Address &IPV4Address::operator=(const IPV4Address &rhs){	if(this == &rhs) return *this;	addr_count = rhs.addr_count;	if(ipaddr)		delete[] ipaddr;	ipaddr = new struct in_addr[addr_count];	memcpy(ipaddr, rhs.ipaddr, sizeof(struct in_addr) * addr_count);	validator = rhs.validator;	if(hostname)		delString(hostname);	hostname = NULL;	return *this;}bool IPV4Address::operator==(const IPV4Address &a) const{	const IPV4Address *smaller, *larger;	size_t s, l;		if(addr_count > a.addr_count)	{		smaller = &a;		larger  = this;	}	else	{		smaller = this;		larger  = &a;	}	// Loop through all addr's in the smaller and make sure	// that they are all in the larger	for(s = 0; s < smaller->addr_count; s++)	{		// bool found = false;		for(l = 0; l < larger->addr_count && 			memcmp((char *)&ipaddr[s], (char *)&a.ipaddr[l], sizeof(struct in_addr)); l++);		if(l == larger->addr_count) return false;	}	return true;}bool IPV4Address::operator!=(const IPV4Address &a) const{	// Impliment in terms of operator==	return (*this == a ? false : true);}IPV4Host &IPV4Host::operator&=(const IPV4Mask &ma){	for(size_t i = 0; i < addr_count; i++)	{				struct in_addr mask = ma.getAddress();		unsigned char *a = (unsigned char *)&ipaddr[i];		unsigned char *m = (unsigned char *)&mask;				for(size_t j = 0; j < sizeof(struct in_addr); ++j)			*(a++) &= *(m++);	}	if(hostname)		delString(hostname);	hostname = NULL;	return *this;}	IPV4Host::IPV4Host(struct in_addr addr) :IPV4Address(addr) {}IPV4Host::IPV4Host(const char *host) : IPV4Address(host){	char namebuf[256];	if(!host)	{		gethostname(namebuf, 256);		setAddress(namebuf);	}}bool IPV4Address::setIPAddress(const char *host){	if(!host)		return false;#if defined(WIN32)	struct sockaddr_in addr;		addr.sin_addr.s_addr = inet_addr(host);	if ( validator )		(*validator)(addr.sin_addr);	if(addr.sin_addr.s_addr == INADDR_NONE)		return false;	*this = addr.sin_addr.s_addr;#else	struct in_addr l_addr;		int ok = inet_aton(host, &l_addr);	if ( validator )		(*validator)(l_addr);	if ( !ok )		return false;	*this = l_addr;#endif	return true;}void IPV4Address::setAddress(const char *host){		if(hostname)		delString(hostname);	hostname = NULL;	if(!host)  // The way this is currently used, this can never happen	{		*this = (long unsigned int)htonl(INADDR_ANY);		return;	}#ifdef	WIN32	if(!stricmp(host, "localhost"))	{		*this = (long unsigned int)inet_addr("127.0.0.1");		return;	}#endif	if(!setIPAddress(host))	{		struct hostent *hp;		struct in_addr **bptr;#if defined(__GLIBC__)		char   hbuf[8192];		struct hostent hb;		int    rtn;		if(gethostbyname_r(host, &hb, hbuf, sizeof(hbuf), &hp, &rtn))			hp = NULL;#elif defined(sun)		char   hbuf[8192];		struct hostent hb;		int    rtn;		hp = gethostbyname_r(host, &hb, hbuf, sizeof(hbuf), &rtn);#elif (defined(__osf__) || defined(WIN32))		hp = gethostbyname(host);#else		mutex.enterMutex();		hp = gethostbyname(host);		mutex.leaveMutex();#endif		if(!hp)		{			if(ipaddr)				delete[] ipaddr;			ipaddr = new struct in_addr[1];			memset((void *)&ipaddr[0], 0, sizeof(ipaddr));			return;		}				// Count the number of IP addresses returned		addr_count = 0;		for(bptr = (struct in_addr **)hp->h_addr_list; *bptr != NULL; bptr++)		{			addr_count++;		}		// Allocate enough memory		if(ipaddr)			delete[] ipaddr;	// Cause this was allocated in base		ipaddr = new struct in_addr[addr_count];		// Now go through the list again assigning to 		// the member ipaddr;		bptr = (struct in_addr **)hp->h_addr_list;		for(unsigned int i = 0; i < addr_count; i++)		{			if ( validator )				(*validator)(*bptr[i]);			ipaddr[i] = *bptr[i];		}	}}IPV4Broadcast::IPV4Broadcast(const char *net) : IPV4Address(net){}IPV4Mask::IPV4Mask(const char *mask){	unsigned long x = 0xffffffff;	int l = 32 - atoi(mask);	if(setIPAddress(mask))		return;	if(l < 1 || l > 32)	{#ifdef	CCXX_EXCEPTIONS		if(Thread::getException() == Thread::throwObject)			throw((IPV4Address *)this);#endif		return;	}	*this = htonl(x << l);}const char *IPV4Address::getHostname(void) const{	struct hostent *hp = NULL;	struct in_addr addr0;	memset(&addr0, 0, sizeof(addr0));	if(!memcmp(&addr0, &ipaddr[0], sizeof(addr0)))		return NULL;#ifdef	WIN32	memset(&addr0, 0xff, sizeof(addr0));	if(!memcmp(&addr0, &ipaddr[0], sizeof(addr0)))		return "255.255.255.255";	long a = inet_addr("127.0.0.1");	if(!memcmp(&a, &ipaddr[0], sizeof(a)))		return "localhost";#endif#if defined(__GLIBC__)	char   hbuf[8192];	struct hostent hb;	int    rtn;	if(gethostbyaddr_r((char *)&ipaddr[0], sizeof(addr0), AF_INET, &hb, hbuf, sizeof(hbuf), &hp, &rtn))		hp = NULL;#elif defined(sun)	char   hbuf[8192];	struct hostent hb;	int    rtn;	hp = gethostbyaddr_r((char *)&ipaddr[0], (int)sizeof(addr0), (int)AF_INET, &hb, hbuf, (int)sizeof(hbuf), &rtn);#elif defined(__osf__) || defined(WIN32)	hp = gethostbyaddr((char *)&ipaddr[0], sizeof(addr0), AF_INET);#else	mutex.enterMutex();	hp = gethostbyaddr((char *)&ipaddr[0], sizeof(addr0), AF_INET);	mutex.leaveMutex();#endif	if(hp) {		if(hostname)			delString(hostname);		hostname = newString(hp->h_name);		return hostname;	} else {		return inet_ntoa(ipaddr[0]);	}}	IPV4Host operator&(const IPV4Host &addr, const IPV4Mask &mask){	IPV4Host temp = addr;	temp &= mask;	return temp;}IPV4Multicast::IPV4Multicast() : 	IPV4Address(&validator){ }IPV4Multicast::IPV4Multicast(const struct in_addr address) : 	IPV4Address(address,&validator){ }IPV4Multicast::IPV4Multicast(const char *address) :	IPV4Address(address,&validator){ }#ifdef	CCXX_NAMESPACES}#endif/** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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