1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* SocketAddress.cpp
* Represents a sockaddr structure.
* Copyright (C) 2012 Simon Newton
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> // Required by FreeBSD
#endif // HAVE_NETINET_IN_H
#include <assert.h>
#include <ola/Logging.h>
#include <ola/StringUtils.h>
#include <ola/network/NetworkUtils.h>
#include <ola/network/SocketAddress.h>
#include <string.h>
#include <string>
namespace ola {
namespace network {
using std::string;
string IPV4SocketAddress::ToString() const {
std::ostringstream str;
str << Host() << ":" << Port();
return str.str();
}
/**
* Copy this IPV4SocketAddress into a sockaddr.
*/
bool IPV4SocketAddress::ToSockAddr(struct sockaddr *addr,
unsigned int size) const {
if (size < sizeof(struct sockaddr_in)) {
OLA_FATAL << "Length passed to ToSockAddr is too small.";
return false;
}
struct sockaddr_in *v4_addr = reinterpret_cast<struct sockaddr_in*>(addr);
memset(v4_addr, 0, size);
v4_addr->sin_family = AF_INET;
v4_addr->sin_port = HostToNetwork(m_port);
v4_addr->sin_addr.s_addr = m_host.AsInt();
return true;
}
/**
* Extract a IPV4SocketAddress from a string.
*/
bool IPV4SocketAddress::FromString(const string &input,
IPV4SocketAddress *socket_address) {
size_t pos = input.find_first_of(":");
if (pos == string::npos)
return false;
IPV4Address address;
if (!IPV4Address::FromString(input.substr(0, pos), &address))
return false;
uint16_t port;
if (!StringToInt(input.substr(pos + 1), &port))
return false;
*socket_address = IPV4SocketAddress(address, port);
return true;
}
IPV4SocketAddress IPV4SocketAddress::FromStringOrDie(
const string &address) {
IPV4SocketAddress socket_address;
assert(FromString(address, &socket_address));
return socket_address;
}
bool GenericSocketAddress::IsValid() const {
return Family() != AF_UNSPEC;
}
string GenericSocketAddress::ToString() const {
switch (Family()) {
case AF_INET:
return V4Addr().ToString();
case AF_INET6:
default:
std::ostringstream str;
str << "Generic sockaddr of type: " << m_addr.sa_family;
return str.str();
}
}
/**
* Convert the sockaddr to a sockaddr_in.
* The caller should check that Family() is AF_INET before calling this.
*/
IPV4SocketAddress GenericSocketAddress::V4Addr() const {
if (Family() == AF_INET) {
const struct sockaddr_in *v4_addr =
reinterpret_cast<const struct sockaddr_in*>(&m_addr);
return IPV4SocketAddress(IPV4Address(v4_addr->sin_addr.s_addr),
NetworkToHost(v4_addr->sin_port));
} else {
OLA_FATAL << "Invalid conversion of socket family " << Family();
return IPV4SocketAddress(IPV4Address(), 0);
}
}
} // namespace network
} // namespace ola
|