📄 ksockaddr.cpp
字号:
/* * This file is part of the KDE libraries * Copyright (C) 2000,2001 Thiago Macieira <thiagom@mail.com> * * $Id: ksockaddr.cpp,v 1.17.2.2 2001/10/25 21:02:38 waba Exp $ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. **/#include <config.h>#include <sys/types.h>#include <arpa/inet.h>#include <netinet/in.h>#include <limits.h>#include <stdlib.h>#include <string.h>#include <sys/un.h>#include <unistd.h>#include <qglobal.h>#include <qfile.h>#include "kdebug.h"#include "klocale.h"#include "ksockaddr.h"//#include "kextsock.h"#ifndef HAVE_SOCKADDR_IN6// The system doesn't have sockaddr_in6// But we can tell netsupp.h to define it for us, according to the RFC#define CLOBBER_IN6#endif#ifndef IN6_IS_ADDR_V4MAPPED#define NEED_IN6_TESTS#endif#include "netsupp.h"#define V6_CAN_CONVERT_TO_V4(addr) (IN6_IS_ADDR_V4MAPPED(addr) || IN6_IS_ADDR_V4COMPAT(addr))#ifdef HAVE_SOCKADDR_SA_LEN# define MY_MAX(a, b) ((a) > (b) ? (a) : (b))# define MIN_SOCKADDR_LEN MY_MAX(offsetof(sockaddr, sa_family) + sizeof(((sockaddr*)0)->sa_family), \ offsetof(sockaddr, sa_len) + sizeof(((sockaddr*)0)->sa_len))#else# define MIN_SOCKADDR_LEN (offsetof(sockaddr, sa_family) + sizeof(((sockaddr*)0)->sa_family))#endif#ifdef offsetof#undef offsetof#endif#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)// This is how it is// 46 == strlen("1234:5678:9abc:def0:1234:5678:255.255.255.255")#ifndef INET6_ADDRSTRLEN#define INET6_ADDRSTRLEN 46#endif/** * Class KSocketAddress */KSocketAddress::KSocketAddress(){ data = NULL; datasize = 0; owndata = false;}KSocketAddress::KSocketAddress(const sockaddr* sa, ksocklen_t size){ if (sa != NULL) { data = (sockaddr*)malloc(size); if (data == NULL) return; memcpy(data, sa, size); datasize = size; owndata = true; } else { datasize = 0; owndata = false; }}KSocketAddress::~KSocketAddress(){ if (owndata && data != NULL) free(data);}QString KSocketAddress::pretty() const{ return i18n("<unknown socket>"); }int KSocketAddress::family() const{ if (data != NULL) return data->sa_family; return AF_UNSPEC;}// This creates a new KSocketAddress with given sockaddrKSocketAddress* KSocketAddress::newAddress(const struct sockaddr* sa, ksocklen_t size){ if (size == 0) { kdWarning() << "KSocketAddress::newAddress called with size = 0!\n"; return NULL; } // make sure we have the right stuff if (size < MIN_SOCKADDR_LEN) { kdWarning() << "KSocketAddress::newAddress called with invalid size\n"; return NULL; } switch (sa->sa_family) { case AF_INET: if (size >= sizeof(sockaddr_in)) return new KInetSocketAddress((const sockaddr_in*)sa, size); return NULL; #ifdef AF_INET6 case AF_INET6: if (size >= sizeof(sockaddr_in6)) return new KInetSocketAddress((const sockaddr_in6*)sa, size); return NULL;#endif case AF_UNIX: // AF_LOCAL return new KUnixSocketAddress((const sockaddr_un*)sa, size); } return new KSocketAddress(sa, size);}bool KSocketAddress::isEqual(const KSocketAddress& other) const{ switch(family()) { case AF_INET: return KInetSocketAddress::areEqualInet(*this, other, false);#ifdef AF_INET6 case AF_INET6: return KInetSocketAddress::areEqualInet6(*this, other, false);#endif case AF_UNIX: // AF_LOCAL return KUnixSocketAddress::areEqualUnix(*this, other, false); } return false;}bool KSocketAddress::isCoreEqual(const KSocketAddress& other) const{ switch(family()) { case AF_INET: return KInetSocketAddress::areEqualInet(*this, other, true);#ifdef AF_INET6 case AF_INET6: return KInetSocketAddress::areEqualInet6(*this, other, true);#endif case AF_UNIX: // AF_LOCAL return KUnixSocketAddress::areEqualUnix(*this, other, true); } return false;}QString KSocketAddress::nodeName() const{ return QString::null;}QString KSocketAddress::serviceName() const{ return QString::null;}int KSocketAddress::ianaFamily(int af){ switch (af) { case AF_INET: return 1;#ifdef AF_INET6 case AF_INET6: return 2;#endif default: return 0; }}int KSocketAddress::fromIanaFamily(int iana){ switch (iana) { case 1: return AF_INET;#ifdef AF_INET6 case 2: return AF_INET6;#endif default: return AF_UNSPEC; }}/** * class KInetSocketAddress */class KInetSocketAddress::Private{public: int sockfamily; sockaddr_in sin;#ifdef AF_INET6 sockaddr_in6 sin6;#endif Private() : sockfamily(AF_UNSPEC) { sin.sin_family = AF_INET; sin.sin_port = 0;#ifdef HAVE_SOCKADDR_SA_LEN sin.sin_len = sizeof(sin);#endif#ifdef AF_INET6 sin6.sin6_family = AF_INET6; sin6.sin6_port = 0; sin6.sin6_flowinfo = 0;# ifdef HAVE_SOCKADDR_IN6_SCOPE_ID sin6.sin6_scope_id = 0;# endif# ifdef HAVE_SOCKADDR_SA_LEN sin6.sin6_len = sizeof(sin6);# endif#endif } };KInetSocketAddress::KInetSocketAddress() : d(new Private){ }KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress &other) : KSocketAddress(), d(new Private){ setAddress(other);}KInetSocketAddress::KInetSocketAddress(const sockaddr_in* sin, ksocklen_t len) : d(new Private){ setAddress(sin, len); }KInetSocketAddress::KInetSocketAddress(const sockaddr_in6* sin6, ksocklen_t len) : d(new Private){ setAddress(sin6, len); }KInetSocketAddress::KInetSocketAddress(const in_addr& addr, unsigned short port) : d(new Private){ setAddress(addr, port);}KInetSocketAddress::KInetSocketAddress(const in6_addr& addr, unsigned short port) : d(new Private){ setAddress(addr, port);}KInetSocketAddress::KInetSocketAddress(const QString& addr, unsigned short port, int family) : d(new Private){ setAddress(addr, port, family);}KInetSocketAddress::~KInetSocketAddress(){ delete d; // KSocketAddress::~KSocketAddress();}bool KInetSocketAddress::setAddress(const KInetSocketAddress &other){ if (other.family() == AF_INET) return setAddress(other.addressV4(), other.size());#ifdef AF_INET6 else if (other.family() == AF_INET6) return setAddress(other.addressV6(), other.size());#endif return false;}bool KInetSocketAddress::setAddress(const sockaddr_in* sin, ksocklen_t len){ // This is supposed to be a AF_INET socket if ((len < sizeof(sockaddr_in)) || (sin->sin_family != AF_INET)) { kdWarning() << "KInetSocketAddress::setAddress(sockaddr_in*) called with invalid sockaddr_in\n"; return false; } return setHost(sin->sin_addr) && setPort(ntohs(sin->sin_port));}bool KInetSocketAddress::setAddress(const sockaddr_in6* sin6, ksocklen_t len){#ifdef AF_INET6 // should be family AF_INET6 if ((len < (offsetof(sockaddr_in6, sin6_addr) + sizeof(sin6->sin6_addr))) || (sin6->sin6_family != AF_INET6)) { kdWarning() << "KInetSocketAddress::setAddress(sockaddr_in6*) called with invalid sockaddr_in6\n"; return 0; } memset(&d->sin6, 0, sizeof(d->sin6)); if (len > sizeof(d->sin6)) len = sizeof(d->sin6); memcpy(&d->sin6, sin6, len); /* Now make a sanity check */ d->sockfamily = d->sin6.sin6_family = AF_INET6;# ifdef HAVE_SOCKADDR_SA_LEN d->sin6.sin6_len = sizeof(d->sin6);# endif fromV6(); return true;#else return false;#endif}bool KInetSocketAddress::setAddress(const in_addr& addr, unsigned short port){ return setHost(addr) && setPort(port);}bool KInetSocketAddress::setAddress(const in6_addr& addr, unsigned short port){ return setHost(addr) && setPort(port);}bool KInetSocketAddress::setAddress(const QString& addr, unsigned short port, int family){ return setHost(addr, family) && setPort(port); }bool KInetSocketAddress::setHost(const in_addr& addr){ d->sockfamily = AF_INET; // set address to IPv4 type d->sin.sin_addr = addr; fromV4(); return true;}bool KInetSocketAddress::setHost(const in6_addr& addr){#ifdef AF_INET6 d->sockfamily = AF_INET6; // set address to IPv6 type d->sin6.sin6_addr = addr; fromV6(); return true;#else return false;#endif}bool KInetSocketAddress::setHost(const QString& addr, int family){ // if family == -1, we'll try to guess the host name if ((family != -1) && (family != AF_INET)#ifdef AF_INET6 && (family != AF_INET6)#endif ) { kdWarning() << "KInetSocketAddress::setHost(QString, int) called with unknown family address\n"; return false; } if (family == -1) { // guess the family type#ifdef AF_INET6 // IPv6 addresses MUST contain colons (:) and IPv4 addresses must not if (addr.find(':') != -1) family = AF_INET6; else family = AF_INET;#else // There's only one guess: family = AF_INET;#endif } /* * FIXME! What is the decoding process for hostnames? */ if (family == AF_INET) { inet_pton(family, addr.latin1(), (void*)&(d->sin.sin_addr)); fromV4();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -