441 lines
18 KiB
C
Raw Normal View History

2022-05-25 19:03:06 +08:00
#ifndef HGL_NETWORK_IP_INCLUDE
#define HGL_NETWORK_IP_INCLUDE
#include<hgl/platform/Platform.h>
#if HGL_OS == HGL_OS_Windows
#include<ws2tcpip.h>
#if SOMAXCONN == 5
#error Please use <winsock2.h>
#endif//
typedef int socklen_t;
typedef ULONG in_addr_t;
#define GetLastSocketError() WSAGetLastError()
#ifndef SOCK_DCCP
#define SOCK_DCCP 6
#endif//SOCK_DCCP
#ifndef SOCK_PACKET
#define SOCK_PACKET 10
#endif//SOCK_PACKET
#ifndef IPPROTO_DCCP
#define IPPROTO_DCCP 33
#endif//IPPROTO_DCCP
#ifndef IPPROTO_UDPLITE
#define IPPROTO_UDPLITE 136
#endif//IPPROTO_UDPLITE
#else
#include<errno.h>
#include<sys/types.h>
#include<sys/ioctl.h>
#include<sys/socket.h>
#include<unistd.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#define GetLastSocketError() (errno)
#if HGL_OS == HGL_OS_Linux
#include<sys/sendfile.h>
inline int sendfile(int tfd,int sfd,size_t size)
{
return sendfile(tfd,sfd,nullptr,size);
}
#endif//HGL_OS == HGL_OS_Linux
#if HGL_OS == HGL_OS_FreeBSD
#include<sys/uio.h>
inline int sendfile(int tfd,int sfd,size_t size)
{
return sendfile(tfd,sfd,0,size,nullptr,nullptr,0);
}
#endif//HGL_OS == HGL_OS_FreeBSD
#if (HGL_OS == HGL_OS_macOS)||(HGL_OS == HGL_OS_iOS)
#ifndef IPPROTO_UDPLITE
#define IPPROTO_UDPLITE 136
#endif//IPPROTO_UDPLITE
#endif//
#endif//HGL_OS == HGL_OS_Windows
#include<hgl/type/DataType.h>
#include<hgl/type/List.h>
2023-07-15 00:46:34 +08:00
#include<hgl/type/String.h>
#include<hgl/type/StrChar.h>
2022-05-25 19:03:06 +08:00
namespace hgl
{
namespace network
{
/**
* IP类型枚举
*/
enum IPType
{
iptNone=0,
iptV4,
iptV6,
iptEnd
};//enum IPType
inline IPType CheckIPType(const char *name)
{
if(!name)return(iptNone);
while(*name)
{
if(*name==':')return(iptV6);
if(*name=='.')return(iptV4);
++name;
}
return(iptNone);
}
struct IPSupport
{
uint family; ///<协议家族AF_INET,AF_INET6,AF_NETBIOS
uint socktype; ///<Socket类型SOCK_STREAM,SOCK_DGRAM,SOCK_RAW,SOCK_RDM,SOCK_SEQPACKET
uint protocol; ///<协议类型IPPROTO_TCP,IPPROTO_UDP,IPPROTO_SCTP
union
{
sockaddr_in ipv4;
sockaddr_in6 ipv6;
};
union
{
char ipv4str[INET_ADDRSTRLEN+1];
char ipv6str[INET6_ADDRSTRLEN+1];
};
};
int GetIPSupport(List<IPSupport> &); ///<取得本机IP支持列表
bool CheckIPSupport(const List<IPSupport> &ips_list,uint family,uint socktype,uint protocol);
bool CheckIPSupport(uint family,uint socktype,uint protocol);
inline bool CheckIPv4SupportTCP (){return CheckIPSupport(AF_INET,SOCK_STREAM, IPPROTO_TCP );}
inline bool CheckIPv4SupportUDP (){return CheckIPSupport(AF_INET,SOCK_DGRAM, IPPROTO_UDP );}
inline bool CheckIPv4SupportUDPLite (){return CheckIPSupport(AF_INET,SOCK_DGRAM, IPPROTO_UDPLITE );}
inline bool CheckIPv4SupportSCTP (){return CheckIPSupport(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP );}
inline bool CheckIPv6SupportTCP (){return CheckIPSupport(AF_INET6,SOCK_STREAM, IPPROTO_TCP );}
inline bool CheckIPv6SupportUDP (){return CheckIPSupport(AF_INET6,SOCK_DGRAM, IPPROTO_UDP );}
inline bool CheckIPv6SupportUDPLite (){return CheckIPSupport(AF_INET6,SOCK_DGRAM, IPPROTO_UDPLITE );}
inline bool CheckIPv6SupportSCTP (){return CheckIPSupport(AF_INET6,SOCK_SEQPACKET,IPPROTO_SCTP );}
/**
* IP地址类
*/
class IPAddress
{
protected:
int socktype;
int protocol;
const char *protocol_name;
void RefreshProtocolName();
public:
IPAddress()
{
socktype=0;
protocol=0;
protocol_name=nullptr;
}
IPAddress(int s,int p)
{
socktype=s;
protocol=p;
RefreshProtocolName();
}
virtual ~IPAddress()=default;
virtual const int GetFamily()const=0; ///<返回网络家族
const int GetSocketType()const{return socktype;} ///<返回Socket类型
const int GetProtocol()const{return protocol;} ///<返回协议类型
virtual const uint GetIPSize()const=0; ///<取得IP地址的长度
virtual const uint GetSockAddrInSize()const=0; ///<取得SockAddrIn变量长度
virtual const uint GetIPStringMaxSize()const=0; ///<取得IP字符串最大长度
virtual const bool IsBoradcast()const=0; ///<是否为广播
virtual const char *GetProtocolName()const{return protocol_name;} ///<取得协议名称
/**
* IP地址
* @param _name
* @param _port
* @param socktype Socket类型(SOCK_STREAMSOCK_DGRAMSOCK_RAWSOCK_RDMSOCK_SEQPACKET等值),
* @param protocol (IPPROTO_TCPIPPROTO_UDPIPPROTO_SCTP),
*/
virtual bool Set(const char *_name,ushort _port,int socktype,int protocol)=0;
bool SetTCP (const char *_name,ushort _port){return Set(_name,_port,SOCK_STREAM, IPPROTO_TCP );}
bool SetUDP (const char *_name,ushort _port){return Set(_name,_port,SOCK_DGRAM, IPPROTO_UDP );}
bool SetUDPLite (const char *_name,ushort _port){return Set(_name,_port,SOCK_DGRAM, IPPROTO_UDPLITE );}
bool SetSCTP (const char *_name,ushort _port){return Set(_name,_port,SOCK_SEQPACKET, IPPROTO_SCTP );}
const bool IsTCP ()const{if(socktype!=SOCK_STREAM )return(false);if(protocol!=IPPROTO_TCP )return(false);return(true);}
const bool IsUDP ()const{if(socktype!=SOCK_DGRAM )return(false);if(protocol!=IPPROTO_UDP )return(false);return(true);}
const bool IsUDPLite ()const{if(socktype!=SOCK_DGRAM )return(false);if(protocol!=IPPROTO_UDPLITE )return(false);return(true);}
const bool IsSCTP ()const{if(socktype!=SOCK_SEQPACKET )return(false);if(protocol!=IPPROTO_SCTP )return(false);return(true);}
/**
*
*/
virtual void Set(ushort port)=0;
/**
* IP地址到一个socket上
* @param ThisSocket Socket号
* @param reuse IPtrue
*/
virtual bool Bind(int ThisSocket,int reuse=1)const=0;
/**
*
*/
virtual bool GetHostname(UTF8String &)const=0;
virtual sockaddr *GetSockAddr()=0;
virtual void *GetIP()=0;
/**
* IP信息
*/
virtual void GetIP(void *)=0;
/**
*
*/
virtual const ushort GetPort()const=0;
/**
* ,使GetIPStringMaxSize()
*/
virtual void ToString(char *,int)const=0;
/**
* delete[]
*/
virtual char *CreateString()const
{
const int max_size=GetIPStringMaxSize();
char *ipstr=new char[max_size+1];
ToString(ipstr,max_size);
return ipstr;
}
/**
*
*/
virtual IPAddress *CreateCopy()const=0;
/**
* IP地址副本
*/
virtual IPAddress *Create()const=0;
/**
* IP地址是否一样
*/
virtual bool Comp(const IPAddress *)const=0;
};//class IPAddress
/**
* IPv4地址
*/
class IPv4Address:public IPAddress
{
sockaddr_in addr;
public:
IPv4Address(){hgl_zero(addr);}
IPv4Address(const uint32 _addr,ushort port,int _socktype,int _protocol):IPAddress(_socktype,_protocol)
{
Set(_addr,port);
}
IPv4Address(const char *name,ushort port,int _socktype,int _protocol)
{
Set(name,port,_socktype,_protocol);
}
IPv4Address(ushort port,int _socktype,int _protocol)
{
Set(nullptr,port,_socktype,_protocol);
}
IPv4Address(const IPv4Address *src)
{
hgl_cpy(addr,src->addr);
socktype=src->socktype;
protocol=src->protocol;
}
const int GetFamily()const override{return AF_INET;}
const uint GetIPSize()const override{return sizeof(in_addr);}
const uint GetSockAddrInSize()const override{return sizeof(sockaddr_in);}
const uint GetIPStringMaxSize()const override{return INET_ADDRSTRLEN+6;}
const bool IsBoradcast()const override{return(addr.sin_addr.s_addr==htonl(INADDR_BROADCAST));}
bool Set(const char *name,ushort port,int _socktype,int _protocol) override;
void Set(const uint32 _addr,ushort port)
{
hgl_zero(addr);
addr.sin_family =AF_INET;
addr.sin_addr.s_addr=_addr;
addr.sin_port =htons(port);
}
void Set(ushort port) override;
bool Bind(int ThisSocket,int reuse=1)const override;
bool GetHostname(UTF8String &)const override;
sockaddr *GetSockAddr()override{return (sockaddr *)&addr;}
void *GetIP() override {return &(addr.sin_addr);}
void GetIP(void *data) override { memcpy(data,&(addr.sin_addr),sizeof(in_addr)); }
const uint32 GetInt32IP()const{return addr.sin_addr.s_addr;}
const ushort GetPort()const override;
static void ToString(char *str,const int,const in_addr *);
static void ToString(char *str,const int,const sockaddr_in *);
void ToString(char *str,const int)const override;
static int GetDomainIPList(List<in_addr> &addr_list,const char *domain,int _socktype,int _protocol); ///<取得当指定域名的IPv4地址列表
static int GetLocalIPList(List<in_addr> &addr_list,int _socktype,int _protocol); ///<取得本机的IPv4地址列表
IPAddress *CreateCopy()const override{return(new IPv4Address(this));}
IPAddress *Create()const override{return(new IPv4Address());}
bool Comp(const IPAddress *ipa)const override;
};//class IPv4Address
/**
* IPv6地址
*/
class IPv6Address:public IPAddress
{
sockaddr_in6 addr;
public:
IPv6Address(){hgl_zero(addr);}
IPv6Address(const in6_addr *ip,ushort port,int _socktype,int _protocol):IPAddress(_socktype,_protocol)
{
hgl_zero(addr);
addr.sin6_family=AF_INET6;
memcpy(&(addr.sin6_addr),ip,sizeof(in6_addr));
addr.sin6_port=htons(port);
}
IPv6Address(const char *name,ushort port,int _socktype,int _protocol)
{
Set(name,port,_socktype,_protocol);
}
IPv6Address(ushort port,int _socktype,int _protocol)
{
Set(nullptr,port,_socktype,_protocol);
}
IPv6Address(const IPv6Address *src)
{
hgl_cpy(addr,src->addr);
socktype=src->socktype;
protocol=src->protocol;
}
const int GetFamily()const override{return AF_INET6;}
const uint GetIPSize()const override{return sizeof(in6_addr);}
const uint GetSockAddrInSize()const override{return sizeof(sockaddr_in6);}
const uint GetIPStringMaxSize()const override{return INET6_ADDRSTRLEN+6;}
const bool IsBoradcast()const override{return(false);}
bool Set(const char *name,ushort port,int _socktype,int _protocol) override;
void Set(ushort port) override;
bool Bind(int ThisSocket,int reuse=1)const override;
bool GetHostname(UTF8String &)const override;
sockaddr *GetSockAddr() override{return (sockaddr *)&addr;}
void *GetIP() override {return &(addr.sin6_addr);}
void GetIP(void *data) override{memcpy(data,&(addr.sin6_addr),sizeof(in6_addr));}
const ushort GetPort()const override;
static void ToString(char *str,const int,const in6_addr *);
static void ToString(char *str,const int,const sockaddr_in6 *);
void ToString(char *str,const int)const override;
static int GetDomainIPList(List<in6_addr> &addr_list,const char *domain,int _socktype,int _protocol); ///<取得指定域名的IPv6地址列表
static int GetLocalIPList(List<in6_addr> &addr_list,int _socktype,int _protocol); ///<取得本机的IPv6地址列表
IPAddress *CreateCopy()const override{return(new IPv6Address(this));}
IPAddress *Create()const override{return(new IPv6Address());}
bool Comp(const IPAddress *ipa)const override;
};//class IPv6Address
inline IPv4Address *CreateIPv4TCP (const char *name,ushort port){return(new IPv4Address(name,port,SOCK_STREAM, IPPROTO_TCP));}
inline IPv6Address *CreateIPv6TCP (const char *name,ushort port){return(new IPv6Address(name,port,SOCK_STREAM, IPPROTO_TCP));}
inline IPv4Address *CreateIPv4UDP (const char *name,ushort port){return(new IPv4Address(name,port,SOCK_DGRAM, IPPROTO_UDP));}
inline IPv6Address *CreateIPv6UDP (const char *name,ushort port){return(new IPv6Address(name,port,SOCK_DGRAM, IPPROTO_UDP));}
inline IPv4Address *CreateIPv4UDPLite (const char *name,ushort port){return(new IPv4Address(name,port,SOCK_DGRAM, IPPROTO_UDPLITE));}
inline IPv6Address *CreateIPv6UDPLite (const char *name,ushort port){return(new IPv6Address(name,port,SOCK_DGRAM, IPPROTO_UDPLITE));}
inline IPv4Address *CreateIPv4SCTP (const char *name,ushort port){return(new IPv4Address(name,port,SOCK_SEQPACKET, IPPROTO_SCTP));}
inline IPv6Address *CreateIPv6SCTP (const char *name,ushort port){return(new IPv6Address(name,port,SOCK_SEQPACKET, IPPROTO_SCTP));}
inline IPv4Address *CreateIPv4TCP (const uint32 &ip,ushort port){return(new IPv4Address(ip,port,SOCK_STREAM, IPPROTO_TCP));}
inline IPv4Address *CreateIPv4UDP (const uint32 &ip,ushort port){return(new IPv4Address(ip,port,SOCK_DGRAM, IPPROTO_UDP));}
inline IPv4Address *CreateIPv4UDPLite (const uint32 &ip,ushort port){return(new IPv4Address(ip,port,SOCK_DGRAM, IPPROTO_UDPLITE));}
inline IPv4Address *CreateIPv4SCTP (const uint32 &ip,ushort port){return(new IPv4Address(ip,port,SOCK_SEQPACKET, IPPROTO_SCTP));}
inline IPv6Address *CreateIPv6TCP (const in6_addr *ip,ushort port){return(new IPv6Address(ip,port,SOCK_STREAM, IPPROTO_TCP));}
inline IPv6Address *CreateIPv6UDP (const in6_addr *ip,ushort port){return(new IPv6Address(ip,port,SOCK_DGRAM, IPPROTO_UDP));}
inline IPv6Address *CreateIPv6UDPLite (const in6_addr *ip,ushort port){return(new IPv6Address(ip,port,SOCK_DGRAM, IPPROTO_UDPLITE));}
inline IPv6Address *CreateIPv6SCTP (const in6_addr *ip,ushort port){return(new IPv6Address(ip,port,SOCK_SEQPACKET, IPPROTO_SCTP));}
inline IPv4Address *CreateIPv4TCP (ushort port){return(new IPv4Address(port,SOCK_STREAM, IPPROTO_TCP));}
inline IPv6Address *CreateIPv6TCP (ushort port){return(new IPv6Address(port,SOCK_STREAM, IPPROTO_TCP));}
inline IPv4Address *CreateIPv4UDP (ushort port){return(new IPv4Address(port,SOCK_DGRAM, IPPROTO_UDP));}
inline IPv6Address *CreateIPv6UDP (ushort port){return(new IPv6Address(port,SOCK_DGRAM, IPPROTO_UDP));}
inline IPv4Address *CreateIPv4UDPLite (ushort port){return(new IPv4Address(port,SOCK_DGRAM, IPPROTO_UDPLITE));}
inline IPv6Address *CreateIPv6UDPLite (ushort port){return(new IPv6Address(port,SOCK_DGRAM, IPPROTO_UDPLITE));}
inline IPv4Address *CreateIPv4SCTP (ushort port){return(new IPv4Address(port,SOCK_SEQPACKET, IPPROTO_SCTP));}
inline IPv6Address *CreateIPv6SCTP (ushort port){return(new IPv6Address(port,SOCK_SEQPACKET, IPPROTO_SCTP));}
inline IPv4Address *CreateIPv4UDPBoradcast (ushort port){return(new IPv4Address(htonl(INADDR_BROADCAST),port,SOCK_DGRAM, IPPROTO_UDP));}
inline IPv4Address *CreateIPv4UDPLiteBoradcast (ushort port){return(new IPv4Address(htonl(INADDR_BROADCAST),port,SOCK_DGRAM, IPPROTO_UDPLITE));}
}//namespace network
}//namespace hgl
#endif//HGL_NETWORK_IP_TOOL_INCLUDE