2020-04-05 21:16:16 +02:00
|
|
|
// ftpd is a server implementation based on the following:
|
|
|
|
// - RFC 959 (https://tools.ietf.org/html/rfc959)
|
|
|
|
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
|
|
|
|
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
|
|
|
|
//
|
|
|
|
// Copyright (C) 2020 Michael Theall
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program 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 General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#include "sockAddr.h"
|
|
|
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
|
|
#include <cassert>
|
2020-04-06 07:36:03 +02:00
|
|
|
#include <cstdlib>
|
2020-04-05 21:16:16 +02:00
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
SockAddr::~SockAddr () = default;
|
|
|
|
|
|
|
|
SockAddr::SockAddr () = default;
|
|
|
|
|
|
|
|
SockAddr::SockAddr (SockAddr const &that_) = default;
|
|
|
|
|
|
|
|
SockAddr::SockAddr (SockAddr &&that_) = default;
|
|
|
|
|
|
|
|
SockAddr &SockAddr::operator= (SockAddr const &that_) = default;
|
|
|
|
|
|
|
|
SockAddr &SockAddr::operator= (SockAddr &&that_) = default;
|
|
|
|
|
|
|
|
SockAddr::SockAddr (struct sockaddr const &addr_)
|
|
|
|
{
|
|
|
|
switch (addr_.sa_family)
|
|
|
|
{
|
|
|
|
case AF_INET:
|
|
|
|
std::memcpy (&m_addr, &addr_, sizeof (struct sockaddr_in));
|
|
|
|
break;
|
|
|
|
|
2020-04-17 22:32:39 +02:00
|
|
|
#ifndef NO_IPV6
|
2020-04-05 21:16:16 +02:00
|
|
|
case AF_INET6:
|
|
|
|
std::memcpy (&m_addr, &addr_, sizeof (struct sockaddr_in6));
|
|
|
|
break;
|
|
|
|
#endif
|
2020-04-06 07:36:03 +02:00
|
|
|
|
|
|
|
default:
|
|
|
|
std::abort ();
|
|
|
|
break;
|
2020-04-05 21:16:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr::SockAddr (struct sockaddr_in const &addr_)
|
|
|
|
: SockAddr (reinterpret_cast<struct sockaddr const &> (addr_))
|
|
|
|
{
|
2020-04-06 07:36:03 +02:00
|
|
|
assert (m_addr.ss_family == AF_INET);
|
2020-04-05 21:16:16 +02:00
|
|
|
}
|
|
|
|
|
2023-11-19 13:55:58 +01:00
|
|
|
#if !defined(__3DS__) && !defined(__WIIU__)
|
2020-04-05 21:16:16 +02:00
|
|
|
SockAddr::SockAddr (struct sockaddr_in6 const &addr_)
|
|
|
|
: SockAddr (reinterpret_cast<struct sockaddr const &> (addr_))
|
|
|
|
{
|
2020-04-06 07:36:03 +02:00
|
|
|
assert (m_addr.ss_family == AF_INET6);
|
2020-04-05 21:16:16 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SockAddr::SockAddr (struct sockaddr_storage const &addr_)
|
|
|
|
: SockAddr (reinterpret_cast<struct sockaddr const &> (addr_))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr::operator struct sockaddr_in const & () const
|
|
|
|
{
|
|
|
|
assert (m_addr.ss_family == AF_INET);
|
|
|
|
return reinterpret_cast<struct sockaddr_in const &> (m_addr);
|
|
|
|
}
|
|
|
|
|
2023-11-19 13:55:58 +01:00
|
|
|
#if !defined(__3DS__) && !defined(__WIIU__)
|
2020-04-05 21:16:16 +02:00
|
|
|
SockAddr::operator struct sockaddr_in6 const & () const
|
|
|
|
{
|
|
|
|
assert (m_addr.ss_family == AF_INET6);
|
|
|
|
return reinterpret_cast<struct sockaddr_in6 const &> (m_addr);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SockAddr::operator struct sockaddr_storage const & () const
|
|
|
|
{
|
|
|
|
return m_addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr::operator struct sockaddr * ()
|
|
|
|
{
|
|
|
|
return reinterpret_cast<struct sockaddr *> (&m_addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr::operator struct sockaddr const * () const
|
|
|
|
{
|
|
|
|
return reinterpret_cast<struct sockaddr const *> (&m_addr);
|
|
|
|
}
|
|
|
|
|
2020-12-12 02:15:33 +01:00
|
|
|
bool SockAddr::setPort (std::uint16_t const port_)
|
|
|
|
{
|
|
|
|
switch (m_addr.ss_family)
|
|
|
|
{
|
|
|
|
case AF_INET:
|
|
|
|
reinterpret_cast<struct sockaddr_in *> (&m_addr)->sin_port = htons (port_);
|
|
|
|
return true;
|
|
|
|
|
|
|
|
#ifndef NO_IPV6
|
|
|
|
case AF_INET6:
|
|
|
|
reinterpret_cast<struct sockaddr_in6 *> (&m_addr)->sin6_port = htons (port_);
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
default:
|
|
|
|
std::abort ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-05 21:16:16 +02:00
|
|
|
std::uint16_t SockAddr::port () const
|
|
|
|
{
|
|
|
|
switch (m_addr.ss_family)
|
|
|
|
{
|
|
|
|
case AF_INET:
|
|
|
|
return ntohs (reinterpret_cast<struct sockaddr_in const *> (&m_addr)->sin_port);
|
|
|
|
|
2020-04-17 22:32:39 +02:00
|
|
|
#ifndef NO_IPV6
|
2020-04-05 21:16:16 +02:00
|
|
|
case AF_INET6:
|
|
|
|
return ntohs (reinterpret_cast<struct sockaddr_in6 const *> (&m_addr)->sin6_port);
|
|
|
|
#endif
|
|
|
|
|
2020-04-06 07:36:03 +02:00
|
|
|
default:
|
|
|
|
std::abort ();
|
|
|
|
break;
|
|
|
|
}
|
2020-04-05 21:16:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
char const *SockAddr::name (char *buffer_, std::size_t size_) const
|
|
|
|
{
|
|
|
|
switch (m_addr.ss_family)
|
|
|
|
{
|
|
|
|
case AF_INET:
|
2020-04-17 22:32:39 +02:00
|
|
|
#ifdef NDS
|
|
|
|
return inet_ntoa (reinterpret_cast<struct sockaddr_in const *> (&m_addr)->sin_addr);
|
|
|
|
#else
|
2020-04-05 21:16:16 +02:00
|
|
|
return inet_ntop (AF_INET,
|
|
|
|
&reinterpret_cast<struct sockaddr_in const *> (&m_addr)->sin_addr,
|
|
|
|
buffer_,
|
|
|
|
size_);
|
2020-04-17 22:32:39 +02:00
|
|
|
#endif
|
2020-04-05 21:16:16 +02:00
|
|
|
|
2020-04-17 22:32:39 +02:00
|
|
|
#ifndef NO_IPV6
|
2020-04-05 21:16:16 +02:00
|
|
|
case AF_INET6:
|
|
|
|
return inet_ntop (AF_INET6,
|
|
|
|
&reinterpret_cast<struct sockaddr_in6 const *> (&m_addr)->sin6_addr,
|
|
|
|
buffer_,
|
|
|
|
size_);
|
|
|
|
#endif
|
|
|
|
|
2020-04-06 07:36:03 +02:00
|
|
|
default:
|
|
|
|
std::abort ();
|
|
|
|
break;
|
|
|
|
}
|
2020-04-05 21:16:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
char const *SockAddr::name () const
|
|
|
|
{
|
2023-11-19 13:55:58 +01:00
|
|
|
#if defined(NDS) || defined(__WIIU__)
|
2020-04-17 22:32:39 +02:00
|
|
|
return inet_ntoa (reinterpret_cast<struct sockaddr_in const *> (&m_addr)->sin_addr);
|
|
|
|
#else
|
|
|
|
#ifdef NO_IPV6
|
2020-04-05 21:16:16 +02:00
|
|
|
thread_local static char buffer[INET_ADDRSTRLEN];
|
|
|
|
#else
|
|
|
|
thread_local static char buffer[INET6_ADDRSTRLEN];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return name (buffer, sizeof (buffer));
|
2020-04-17 22:32:39 +02:00
|
|
|
#endif
|
2020-04-05 21:16:16 +02:00
|
|
|
}
|