1#include "SocketUtils.h"
2#include "SimpleSocket.h"
23 temp_socket() : SimpleSocket( AF_INET, SOCK_DGRAM, 0) {}
26 in_addr ipv4Address(
const sockaddr& sa)
28 sockaddr_in addr = {};
29 std::memcpy( &addr, &sa,
sizeof(addr));
33 void assign_ipv4( sockaddr& sa, std::string_view address)
35 static_assert(
sizeof(sockaddr_in) <=
sizeof(sockaddr),
36 "sockaddr must be large enough for an IPv4 address");
38 std::string address_z(address);
39 sockaddr_in addr = {};
40 addr.sin_family = AF_INET;
42 if( inet_aton( address_z.c_str(), &addr.sin_addr) == 0)
45 std::memcpy( &sa, &addr,
sizeof(addr));
49 void assign_ifreq(
struct ifreq& ifr, std::string_view interface)
51 const size_t len = interface.length();
53 if( len >= IF_NAMESIZE)
57 ifr.ifr_addr.sa_family = AF_INET;
58 std::memcpy( ifr.ifr_name, interface.data(), len);
59 ifr.ifr_name[len] = 0;
63std::string NET::resolveHostname(
const std::string& hostname)
66 hints.ai_family = AF_INET;
68 addrinfo* result =
nullptr;
69 int status = getaddrinfo( hostname.c_str(),
nullptr, &hints, &result);
70 if( status != 0 || result ==
nullptr)
71 throw SocketException(
"Failed to resolve address (getaddrinfo)",
false);
73 std::unique_ptr<addrinfo,
decltype(&::freeaddrinfo)>
74 result_guard(result, &::freeaddrinfo);
76 if( result->ai_addr ==
nullptr || result->ai_addrlen <
sizeof(sockaddr_in))
77 throw SocketException(
"Resolver returned an invalid IPv4 address",
false);
79 sockaddr_in addr = {};
80 std::memcpy( &addr, result->ai_addr,
sizeof(addr));
81 return inet_ntoa( addr.sin_addr);
84uint16_t NET::resolveService(
const std::string& service,
const std::string& protocol)
88 serv = getservbyname( service.c_str(),
nullptr);
90 serv = getservbyname( service.c_str(), protocol.c_str());
93 return ntohs(
static_cast<uint16_t
>(serv->s_port));
114std::vector<std::string> NET::getNetworkInterfaces()
116 std::vector<std::string> ret;
118 char data[32 *
sizeof(
struct ifreq)];
122 conf.ifc_len =
sizeof(data);
123 conf.ifc_buf = (caddr_t) data;
126 if( ioctl( sock.nativeHandle(), SIOCGIFCONF, &conf) < 0)
129 ifr = (
struct ifreq*)data;
130 while( (
char*)ifr < data+conf.ifc_len)
132 switch(ifr->ifr_addr.sa_family)
135 ret.emplace_back( ifr->ifr_name);
140 printf(
"%s : %s\n", ifr->ifr_name, inet_ntop(ifr->ifr_addr.sa_family, &((
struct sockaddr_in6*)&ifr->ifr_addr)->sin6_addr, addrbuf,
sizeof(addrbuf)));
151std::string NET::getInterfaceAddress( std::string_view interface)
154 assign_ifreq( ifr, interface);
157 if( ioctl( sock.nativeHandle(), SIOCGIFADDR, &ifr) < 0)
160 return inet_ntoa( ipv4Address(ifr.ifr_addr));
163void NET::setInterfaceAddress( std::string_view interface, std::string_view address)
166 assign_ifreq( ifr, interface);
167 assign_ipv4( ifr.ifr_addr, address);
170 if( ioctl( sock.nativeHandle(), SIOCSIFADDR, &ifr) < 0)
174std::string NET::getBroadcastAddress( std::string_view interface)
177 assign_ifreq( ifr, interface);
180 if( ioctl( sock.nativeHandle(), SIOCGIFBRDADDR, &ifr) < 0)
183 return inet_ntoa( ipv4Address(ifr.ifr_broadaddr));
186void NET::setBroadcastAddress( std::string_view interface, std::string_view address)
189 assign_ifreq( ifr, interface);
190 assign_ipv4( ifr.ifr_broadaddr, address);
193 if( ioctl( sock.nativeHandle(), SIOCSIFBRDADDR, &ifr) < 0)
197std::string NET::getNetmask( std::string_view interface)
200 assign_ifreq( ifr, interface);
203 if( ioctl( sock.nativeHandle(), SIOCGIFNETMASK, &ifr) < 0)
206 return inet_ntoa( ipv4Address(ifr.ifr_netmask));
209void NET::setNetmask( std::string_view interface, std::string_view address)
212 assign_ifreq( ifr, interface);
213 assign_ipv4( ifr.ifr_netmask, address);
216 if( ioctl( sock.nativeHandle(), SIOCSIFNETMASK, &ifr) < 0)
220std::string NET::getDestinationAddress( std::string_view interface)
223 assign_ifreq( ifr, interface);
226 if( ioctl( sock.nativeHandle(), SIOCGIFDSTADDR, &ifr) < 0)
229 return inet_ntoa( ipv4Address(ifr.ifr_dstaddr));
232void NET::setDestinationAddress( std::string_view interface, std::string_view address)
235 assign_ifreq( ifr, interface);
236 assign_ipv4( ifr.ifr_dstaddr, address);
239 if( ioctl( sock.nativeHandle(), SIOCSIFDSTADDR, &ifr) < 0)
243int NET::getMTU( std::string_view interface)
246 assign_ifreq( ifr, interface);
249 if( ioctl( sock.nativeHandle(), SIOCGIFMTU, &ifr) < 0)
255void NET::setMTU( std::string_view interface,
int mtu)
258 assign_ifreq( ifr, interface);
263 if( ioctl( sock.nativeHandle(), SIOCSIFMTU, &ifr) < 0)
267std::string NET::getHardwareAddress( std::string_view interface)
270 assign_ifreq( ifr, interface);
273 if( ioctl( sock.nativeHandle(), SIOCGIFHWADDR, &ifr) < 0)
276 switch( ifr.ifr_hwaddr.sa_family) {
289 auto addr =
reinterpret_cast<unsigned char*
>( ifr.ifr_addr.sa_data);
290 int len = sprintf(mac,
"%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
291 return std::string(mac,
static_cast<size_t>(len));
A socket representing a basic communication endpoint.
Signals a problem with the execution of a socket call.