📄 sockets.cxx
字号:
//sin6_scope_id, should be taken into account for link local addresses
return;
#endif
case AF_INET:
if (ai_addrlen < (int)sizeof(sockaddr_in))
break;
version = 4;
v.four = ((struct sockaddr_in *)ai_addr)->sin_addr;
return;
}
version = 0;
}
#endif
#ifdef __NUCLEUS_NET__
PIPSocket::Address::Address(const struct id_struct & addr)
{
operator=(addr);
}
PIPSocket::Address & PIPSocket::Address::operator=(const struct id_struct & addr)
{
s_addr = (((unsigned long)addr.is_ip_addrs[0])<<24) +
(((unsigned long)addr.is_ip_addrs[1])<<16) +
(((unsigned long)addr.is_ip_addrs[2])<<8) +
(((unsigned long)addr.is_ip_addrs[3]));
return *this;
}
#endif
PIPSocket::Address & PIPSocket::Address::operator=(const in_addr & addr)
{
version = 4;
v.four = addr;
return *this;
}
#if P_HAS_IPV6
PIPSocket::Address & PIPSocket::Address::operator=(const in6_addr & addr)
{
version = 6;
v.six = addr;
return *this;
}
#endif
PObject::Comparison PIPSocket::Address::Compare(const PObject & obj) const
{
const PIPSocket::Address & other = (const PIPSocket::Address &)obj;
if (version < other.version)
return LessThan;
if (version > other.version)
return GreaterThan;
#if P_HAS_IPV6
if (version == 6) {
int result = memcmp(&v.six, &other.v.six, sizeof(v.six));
if (result < 0)
return LessThan;
if (result > 0)
return GreaterThan;
return EqualTo;
}
#endif
if ((DWORD)*this < other)
return LessThan;
if ((DWORD)*this > other)
return GreaterThan;
return EqualTo;
}
#if P_HAS_IPV6
bool PIPSocket::Address::operator*=(const PIPSocket::Address & addr) const
{
if (version == addr.version)
return operator==(addr);
if (this->GetVersion() == 6 && this->IsV4Mapped())
return PIPSocket::Address((*this)[12], (*this)[13], (*this)[14], (*this)[15]) == addr;
else if (addr.GetVersion() == 6 && addr.IsV4Mapped())
return *this == PIPSocket::Address(addr[12], addr[13], addr[14], addr[15]);
return PFalse;
}
bool PIPSocket::Address::operator==(in6_addr & addr) const
{
PIPSocket::Address a(addr);
return Compare(a) == EqualTo;
}
#endif
bool PIPSocket::Address::operator==(in_addr & addr) const
{
PIPSocket::Address a(addr);
return Compare(a) == EqualTo;
}
bool PIPSocket::Address::operator==(DWORD dw) const
{
if (dw != 0)
return (DWORD)*this == dw;
return !IsValid();
}
PIPSocket::Address & PIPSocket::Address::operator=(const PString & dotNotation)
{
version = 0;
memset(&v, 0, sizeof(v));
#if P_HAS_IPV6
struct addrinfo *res = NULL;
struct addrinfo hints = { AI_NUMERICHOST, PF_UNSPEC }; // Could be IPv4: x.x.x.x or IPv6: x:x:x:x::x
if (getaddrinfo((const char *)dotNotation, NULL , &hints, &res) == 0) {
if (res->ai_family == PF_INET6) {
// IPv6 addr
version = 6;
struct sockaddr_in6 * addr_in6 = (struct sockaddr_in6 *)res->ai_addr;
v.six = addr_in6->sin6_addr;
} else {
// IPv4 addr
version = 4;
struct sockaddr_in * addr_in = (struct sockaddr_in *)res->ai_addr;
v.four = addr_in->sin_addr;
}
freeaddrinfo(res);
}
#else //P_HAS_IPV6
DWORD iaddr;
if (dotNotation.FindSpan("0123456789.") == P_MAX_INDEX &&
(iaddr = ::inet_addr((const char *)dotNotation)) != (DWORD)INADDR_NONE) {
version = 4;
v.four.s_addr = iaddr;
}
#endif
else {
PINDEX percent = dotNotation.Find('%');
if (percent != P_MAX_INDEX) {
PString iface = dotNotation.Mid(percent+1);
if (!iface.IsEmpty()) {
PIPSocket::InterfaceTable interfaceTable;
if (PIPSocket::GetInterfaceTable(interfaceTable)) {
for (PINDEX i = 0; i < interfaceTable.GetSize(); i++) {
if (interfaceTable[i].GetName().NumCompare(iface) == EqualTo) {
*this = interfaceTable[i].GetAddress();
break;
}
}
}
}
}
}
return *this;
}
PString PIPSocket::Address::AsString() const
{
#if defined(P_VXWORKS)
char ipStorage[INET_ADDR_LEN];
inet_ntoa_b(v.four, ipStorage);
return ipStorage;
#else
# if defined(P_HAS_IPV6)
if (version == 6) {
PString str;
Psockaddr sa(*this, 0);
PAssertOS(getnameinfo(sa, sa.GetSize(), str.GetPointer(1024), 1024, NULL, 0, NI_NUMERICHOST) == 0);
PINDEX percent = str.Find('%'); // used for scoped address e.g. fe80::1%ne0, (ne0=network interface 0)
if (percent != P_MAX_INDEX)
str[percent] = '\0';
str.MakeMinimumSize();
return str;
}
#endif // P_HAS_IPV6
# if defined(P_HAS_INET_NTOP)
PString str;
if (inet_ntop(AF_INET, (const void *)&v.four, str.GetPointer(INET_ADDRSTRLEN), INET_ADDRSTRLEN) == NULL)
return PString::Empty();
str.MakeMinimumSize();
return str;
# else
static PCriticalSection x;
PWaitAndSignal m(x);
return inet_ntoa(v.four);
#endif // P_HAS_INET_NTOP
#endif // P_VXWORKS
}
PBoolean PIPSocket::Address::FromString(const PString & dotNotation)
{
(*this) = dotNotation;
return IsValid();
}
PIPSocket::Address::operator PString() const
{
return AsString();
}
PIPSocket::Address::operator in_addr() const
{
if (version != 4)
return inaddr_empty;
return v.four;
}
#if P_HAS_IPV6
PIPSocket::Address::operator in6_addr() const
{
if (version != 6)
return any6.v.six;
return v.six;
}
#endif
BYTE PIPSocket::Address::operator[](PINDEX idx) const
{
PASSERTINDEX(idx);
#if P_HAS_IPV6
if (version == 6) {
PAssert(idx <= 15, PInvalidParameter);
return v.six.s6_addr[idx];
}
#endif
PAssert(idx <= 3, PInvalidParameter);
return ((BYTE *)&v.four)[idx];
}
ostream & operator<<(ostream & s, const PIPSocket::Address & a)
{
return s << a.AsString();
}
istream & operator>>(istream & s, PIPSocket::Address & a)
{
/// Not IPv6 ready !!!!!!!!!!!!!
char dot1, dot2, dot3;
unsigned b1, b2, b3, b4;
s >> b1;
if (!s.fail()) {
if (s.peek() != '.')
a = htonl(b1);
else {
s >> dot1 >> b2 >> dot2 >> b3 >> dot3 >> b4;
if (!s.fail() && dot1 == '.' && dot2 == '.' && dot3 == '.')
a = PIPSocket::Address((BYTE)b1, (BYTE)b2, (BYTE)b3, (BYTE)b4);
}
}
return s;
}
PINDEX PIPSocket::Address::GetSize() const
{
switch (version) {
#if P_HAS_IPV6
case 6 :
return 16;
#endif
case 4 :
return 4;
}
return 0;
}
PBoolean PIPSocket::Address::IsValid() const
{
switch (version) {
#if P_HAS_IPV6
case 6 :
return memcmp(&v.six, &any6.v.six, sizeof(v.six)) != 0;
#endif
case 4 :
return (DWORD)*this != INADDR_ANY;
}
return PFalse;
}
PBoolean PIPSocket::Address::IsLoopback() const
{
#if P_HAS_IPV6
if (version == 6)
return IN6_IS_ADDR_LOOPBACK(&v.six);
#endif
return *this == loopback4;
}
PBoolean PIPSocket::Address::IsBroadcast() const
{
#if P_HAS_IPV6
if (version == 6) // In IPv6, no broadcast exist. Only multicast
return PFalse;
#endif
return *this == broadcast4;
}
PBoolean PIPSocket::Address::IsRFC1918() const
{
#if P_HAS_IPV6
if (version == 6) {
if (IN6_IS_ADDR_LINKLOCAL(&v.six) || IN6_IS_ADDR_SITELOCAL(&v.six))
return PTrue;
if (IsV4Mapped())
return PIPSocket::Address((*this)[12], (*this)[13], (*this)[14], (*this)[15]).IsRFC1918();
}
#endif
return (Byte1() == 10)
||
(
(Byte1() == 172)
&&
(Byte2() >= 16) && (Byte2() <= 31)
)
||
(
(Byte1() == 192)
&&
(Byte2() == 168)
);
}
PIPSocket::InterfaceEntry::InterfaceEntry()
: ipAddr(GetDefaultIpAny())
, netMask(GetDefaultIpAny())
{
}
PIPSocket::InterfaceEntry::InterfaceEntry(const PString & _name,
const Address & _addr,
const Address & _mask,
const PString & _macAddr
#if P_HAS_IPV6
,const PString & _ip6Addr
#endif
)
: name(_name.Trim()),
ipAddr(_addr),
netMask(_mask),
macAddr(_macAddr)
#if P_HAS_IPV6
, ip6Addr(_ip6Addr)
#endif
{
}
void PIPSocket::InterfaceEntry::PrintOn(ostream & strm) const
{
strm << ipAddr;
#if P_HAS_IPV6
if (!ip6Addr)
strm << " [" << ip6Addr << ']';
#endif
if (!macAddr)
strm << " <" << macAddr << '>';
if (!name)
strm << " (" << name << ')';
}
#ifdef __NUCLEUS_NET__
PBoolean PIPSocket::GetInterfaceTable(InterfaceTable & table)
{
InterfaceEntry *IE;
list<IPInterface>::iterator i;
for(i=Route4Configuration->Getm_IPInterfaceList().begin();
i!=Route4Configuration->Getm_IPInterfaceList().end();
i++)
{
char ma[6];
for(int j=0; j<6; j++) ma[j]=(*i).Getm_macaddr(j);
IE = new InterfaceEntry((*i).Getm_name().c_str(), (*i).Getm_ipaddr(), ma );
if(!IE) return false;
table.Append(IE);
}
return true;
}
#endif
PBoolean PIPSocket::GetNetworkInterface(PIPSocket::Address & addr)
{
PIPSocket::InterfaceTable interfaceTable;
if (PIPSocket::GetInterfaceTable(interfaceTable)) {
PINDEX i;
for (i = 0; i < interfaceTable.GetSize(); ++i) {
PIPSocket::Address localAddr = interfaceTable[i].GetAddress();
if (!localAddr.IsLoopback() && (!localAddr.IsRFC1918() || !addr.IsRFC1918()))
addr = localAddr;
}
}
return addr.IsValid();
}
PIPSocket::Address PIPSocket::GetRouteInterfaceAddress(PIPSocket::Address remoteAddress)
{
PIPSocket::InterfaceTable hostInterfaceTable;
PIPSocket::GetInterfaceTable(hostInterfaceTable);
PIPSocket::RouteTable hostRouteTable;
PIPSocket::GetRouteTable(hostRouteTable);
if (hostInterfaceTable.IsEmpty())
return PIPSocket::GetDefaultIpAny();
for (PINDEX IfaceIdx = 0; IfaceIdx < hostInterfaceTable.GetSize(); IfaceIdx++) {
if (remoteAddress == hostInterfaceTable[IfaceIdx].GetAddress()) {
PTRACE(5, "PWLib\tRoute packet for " << remoteAddress
<< " over interface " << hostInterfaceTable[IfaceIdx].GetName()
<< "[" << hostInterfaceTable[IfaceIdx].GetAddress() << "]");
return hostInterfaceTable[IfaceIdx].GetAddress();
}
}
PIPSocket::RouteEntry * route = NULL;
for (PINDEX routeIdx = 0; routeIdx < hostRouteTable.GetSize(); routeIdx++) {
PIPSocket::RouteEntry & routeEntry = hostRouteTable[routeIdx];
DWORD network = (DWORD) routeEntry.GetNetwork();
DWORD mask = (DWORD) routeEntry.GetNetMask();
if (((DWORD)remoteAddress & mask) == network) {
if (route == NULL)
route = &routeEntry;
else if ((DWORD)routeEntry.GetNetMask() > (DWORD)route->GetNetMask())
route = &routeEntry;
}
}
if (route != NULL) {
for (PINDEX IfaceIdx = 0; IfaceIdx < hostInterfaceTable.GetSize(); IfaceIdx++) {
if (route->GetInterface() == hostInterfaceTable[IfaceIdx].GetName()) {
PTRACE(5, "PWLib\tRoute packet for " << remoteAddress
<< " over interface " << hostInterfaceTable[IfaceIdx].GetName()
<< "[" << hostInterfaceTable[IfaceIdx].GetAddress() << "]");
return hostInterfaceTable[IfaceIdx].GetAddress();
}
}
}
return PIPSocket::GetDefaultIpAny();
}
//////////////////////////////////////////////////////////////////////////////
// PTCPSocket
PTCPSocket::PTCPSocket(WORD newPort)
{
SetPort(newPort);
}
PTCPSocket::PTCPSocket(const PString & service)
{
SetPort(service);
}
PTCPSocket::PTCPSocket(const PString & address, WORD newPort)
{
SetPort(newPort);
Connect(address);
}
PTCPSocket::PTCPSocket(const PString & address, const PString & service)
{
SetPort(service);
Connect(address);
}
PTCPSocket::PTCPSocket(PSocket & socket)
{
Accept(socket);
}
PTCPSocket::PTCPSocket(PTCPSocket & tcpSocket)
{
Accept(tcpSocket);
}
PObject * PTCPSocket::Clone() const
{
return new PTCPSocket(port);
}
// By default IPv4 only adresses
PBoolean PTCPSocket::OpenSocket()
{
return ConvertOSError(os_handle = os_socket(AF_INET, SOCK_STREAM, 0));
}
// ipAdressFamily should be AF_INET or AF_INET6
PBoolean PTCPSocket::OpenSocket(int ipAdressFamily)
{
return ConvertOSError(os_handle = os_socket(ipAdressFamily, SOCK_STREAM, 0));
}
const char * PTCPSocket::GetProtocolName() const
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -