Skip to content
Snippets Groups Projects
Commit f54a4f64 authored by dw6's avatar dw6
Browse files

adding PF_INET[6], SOCK_RAW sockets called RawV[4|6]ClientSocketHandle while...

adding PF_INET[6], SOCK_RAW sockets called RawV[4|6]ClientSocketHandle while naming the files RawInet... to distinguish them from PF_PACKET SOCK_RAW sockets. see Wiki for more information
parent ae6155a1
No related branches found
No related tags found
No related merge requests found
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
// 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 2 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, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "RawInetProtocol.hh"
// Custom includes
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <linux/sockios.h> // for SIOCINQ / SIOCOUTQ
#include <net/if.h> // for if_nametoindex
#include "../../../Socket/SocketHandle.hh"
//#include "UDPProtocol.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ unsigned senf::RawInetProtocol::available()
const
{
int n;
if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
throwErrno();
return n;
}
prefix_ bool senf::RawInetProtocol::eof()
const
{
return false;
}
#undef prefix_
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
// 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 2 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, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef RAWINETPROTOCOL_HH_
#define RAWINETPROTOCOL_HH_
// Custom includes
#include "INetAddressing.hh"
#include "INetProtocol.hh"
#include "../../../Socket/Protocols/BSDSocketProtocol.hh"
#include "../../../Socket/FramingPolicy.hh"
#include "../../../Socket/CommunicationPolicy.hh"
#include "../../../Socket/ReadWritePolicy.hh"
#include "../../../Socket/BufferingPolicy.hh"
#include "../../../Socket/ProtocolClientSocketHandle.hh"
namespace senf {
/// \addtogroup protocol_facets_group
/// @{
/** \brief Protocol facat to support RAW operations upon IPv4/6
This protocol facet provides all those protocol functions,
which are available on a PF_INET[6]/RAW socket.
*/
class RawInetProtocol
: public virtual SocketProtocol
{
public:
///\name Abstract Interface Implementation
///@{
unsigned available() const;
bool eof() const;
///@}
};
/// @}
}
#endif /*RAWINETPROTOCOL_HH_*/
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
// 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 2 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, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "RawInetSocketHandle.hh"
// Custom includes
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include "../../../Utils/Exception.hh"
//#include "UDPSocketHandle.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::UDPv4SocketProtocol
prefix_ void senf::RawV4SocketProtocol::init_client()
const
{
init_client(IPPROTO_RAW);
}
prefix_ void
senf::RawV4SocketProtocol::init_client(int const & protocol)
const
{
int sock = ::socket(PF_INET, SOCK_RAW, protocol);
if (sock < 0)
throwErrno();
body().fd(sock);
}
prefix_ void
senf::RawV4SocketProtocol::init_client(int const & protocol, INet4SocketAddress const & address)
const
{
init_client(protocol);
bind(address);
}
prefix_ std::auto_ptr<senf::SocketProtocol> senf::RawV4SocketProtocol::clone()
const
{
return std::auto_ptr<SocketProtocol>(new RawV4SocketProtocol());
}
///////////////////////////////////////////////////////////////////////////
// senf::UDPv6SocketProtocol::
prefix_ void senf::RawV6SocketProtocol::init_client()
const
{
init_client(IPPROTO_RAW);
}
prefix_ void senf::RawV6SocketProtocol::init_client(int const & protocol)
const
{
int sock = ::socket(PF_INET6,SOCK_RAW,protocol);
if (sock < 0)
throwErrno();
body().fd(sock);
}
prefix_ void
senf::RawV6SocketProtocol::init_client(int const & protocol, INet6SocketAddress const & address)
const
{
init_client(protocol);
bind(address);
}
prefix_ std::auto_ptr<senf::SocketProtocol> senf::RawV6SocketProtocol::clone()
const
{
return std::auto_ptr<SocketProtocol>(new RawV6SocketProtocol());
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
// 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 2 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, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef RAWINETSOCKETHANDLE_HH_
#define RAWINETSOCKETHANDLE_HH_
// Custom includes
#include "INetProtocol.hh"
#include "RawInetProtocol.hh"
#include "../../../Socket/Protocols/BSDSocketProtocol.hh"
#include "../../../Socket/FramingPolicy.hh"
#include "../../../Socket/CommunicationPolicy.hh"
#include "../../../Socket/ReadWritePolicy.hh"
#include "../../../Socket/BufferingPolicy.hh"
#include "../../../Socket/ProtocolClientSocketHandle.hh"
//#include "UDPSocketHandle.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
/// \addtogroup concrete_protocol_group
/// @{
typedef MakeSocketPolicy<
INet4AddressingPolicy,
DatagramFramingPolicy,
UnconnectedCommunicationPolicy,
ReadablePolicy,
WriteablePolicy,
SocketBufferingPolicy
>::policy RawV4Socket_Policy; ///< Socket Policy of the RawV4 Protocol
/** \brief IPv4 RAW Socket Protocol
\par Socket Handle typedefs:
\ref RawV4ClientSocketHandle (ProtocolClientSocketHandle)
\par Policy Interface:
ClientSocketHandle::read(), ClientSocketHandle::readfrom(),
ClientSocketHandle::writeto(), ClientSocketHandle::bind(), ClientSocketHandle::local(),
ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf()
\par Address Type:
INet4Address
RawV4SocketProtocol provides an internet protocol raw socket based on IPv4 addressing.
This class is utilized as the protocol class of the ProtocolClientSocketHandle
via the Socket Handle typedefs above.
\see RawV6SocketProtocol
*/
class RawV4SocketProtocol
: public ConcreteSocketProtocol<RawV4Socket_Policy>,
public IPv4Protocol,
public RawInetProtocol,
public BSDSocketProtocol,
public AddressableBSDSocketProtocol//,
// public senf::pool_alloc_mixin<RawV4Socket_Policy>
{
public:
///////////////////////////////////////////////////////////////////////////
// internal interface
///\name Constructors
///@{
void init_client() const; ///< Create unconnected client socket for IPPROTO_RAW
/**< \note This member is implicitly called from the
ProtocolClientSocketHandle::ProtocolClientSocketHandle()
constructor */
void init_client(int const & protocol) const; ///< Create unconnected client socket for protocol
void init_client(int const & protocol, INet4SocketAddress const & address) const;
///< Create client socket and bind
/**< Creates a new client socket for the given protocol and binds to the given
address.
\param[in] protocol Layer 4 protocol to filter for / to send
\param[in] address local address to bind to */
///@}
///\name Abstract Interface Implementation
std::auto_ptr<SocketProtocol> clone() const;
///@}
};
typedef ProtocolClientSocketHandle<RawV4SocketProtocol> RawV4ClientSocketHandle;
//////////////////////////////////////////////////////////////////// Raw IPv6 Socket //////////////////////////////////////
typedef MakeSocketPolicy<
INet6AddressingPolicy,
DatagramFramingPolicy,
UnconnectedCommunicationPolicy,
ReadablePolicy,
WriteablePolicy,
SocketBufferingPolicy
>::policy RawV6Socket_Policy; ///< Socket Policy of the RawV6 Protocol
/** \brief IPv6 RAW Socket Protocol
\par Socket Handle typedefs:
\ref RawV6ClientSocketHandle (ProtocolClientSocketHandle)
\par Policy Interface:
ClientSocketHandle::read(), ClientSocketHandle::readfrom(),
ClientSocketHandle::writeto(), ClientSocketHandle::bind(), ClientSocketHandle::local(),
ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf()
\par Address Type:
INet6Address
RawV6SocketProtocol provides an internet protocol stream socket based on IPv6 addressing.
This class is utilized as the protocol class of the ProtocolClientSocketHandle
via the Socket Handle typedefs above.
\see RawV4SocketProtocol
*/
class RawV6SocketProtocol
: public ConcreteSocketProtocol<RawV6Socket_Policy>,
public IPv6Protocol,
public RawInetProtocol,
public BSDSocketProtocol,
public AddressableBSDSocketProtocol//,
// public senf::pool_alloc_mixin<RawV6SocketProtocol>
{
public:
///////////////////////////////////////////////////////////////////////////
// internal interface
///\name Constructors
///@{
void init_client() const; ///< Create unconnected client socket for IPPROTO_RAW
/**< \note This member is implicitly called from the
ProtocolClientSocketHandle::ProtocolClientSocketHandle()
constructor */
void init_client(int const & protocol) const; ///< Create unconnected client socket for protocol
void init_client(int const & protocol, INet6SocketAddress const & address) const;
///< Create client socket and bind
/**< Creates a new client socket for the given protocol and binds to the given
address.
\param[in] protocol Layer 4 protocol to filter for / to send
\param[in] address local address to bind to */
/**< \note This member is implicitly called from the
ProtocolClientSocketHandle::ProtocolClientSocketHandle()
constructor */
///@}
///\name Abstract Interface Implementation
std::auto_ptr<SocketProtocol> clone() const;
///@}
};
typedef ProtocolClientSocketHandle<RawV6SocketProtocol> RawV6ClientSocketHandle;
/// @}
}
#endif /*RAWINETSOCKETHANDLE_HH_*/
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
// 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 2 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, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief RawInetSocketHandle.test unit tests */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "RawInetSocketHandle.hh"
#include <iostream>
#include "../../../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp>
namespace {
void error(char const * fn, char const * proc="")
{
std::cerr << "\n" << proc << ((*proc)?": ":"") << fn << ": " << strerror(errno) << std::endl;
}
void fail(char const * proc, char const * fn)
{
error(fn,proc);
_exit(1);
}
int server_pid = 0;
void start(void (*fn)())
{
server_pid = ::fork();
if (server_pid < 0) BOOST_FAIL("fork()");
if (server_pid == 0) {
(*fn)();
_exit(0);
}
}
void wait()
{
int status;
if (waitpid(server_pid,&status,0)<0)
BOOST_FAIL("waitpid()");
BOOST_CHECK_EQUAL( status , 0 );
}
void stop()
{
if (server_pid) {
kill(server_pid,9);
wait();
server_pid = 0;
}
}
}
///////////////////////////////////////////////////////////////////////////
namespace {
void server_v4() //listen for packets with proto=47 (GRE) and resend them with proto=48
{
struct sockaddr_in sin;
::memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(0);
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
int sockrec = socket(PF_INET,SOCK_RAW,47);
if (sockrec<0) fail("server_v4","socket(rec)");
int socksend = socket(PF_INET,SOCK_RAW,48);
if (socksend<0) fail("server_v4","socket(send)");
char buffer[1024];
while (1) {
int n = read(sockrec,buffer,1024);
if (n == 20+4 )//&& strncmp(,"QUIT",4) == 0)
break;
sleep(1);
//jaja, fieses gehacke...
sendto(socksend,buffer+20,n-20,0,(struct sockaddr *)&sin,sizeof(sin));
}
if (close(sockrec) < 0) fail("server_v4","close(rec)");
if (close(socksend) < 0) fail("server_v4","close(send)");
}
void server_v6() //listen for packets with proto=47 (GRE) and resend them with proto=48
{
struct sockaddr_in6 sin;
::memset(&sin,0,sizeof(sin));
sin.sin6_family = AF_INET6;
sin.sin6_port = htons(0);
inet_pton(AF_INET6, "::1", &sin.sin6_addr);
int sockrec6 = socket(PF_INET6,SOCK_RAW,47);
if (sockrec6<0) fail("server_v6","socket(rec)");
int socksend6 = socket(PF_INET6,SOCK_RAW,48);
if (socksend6<0) fail("server_v6","socket(send)");
char buffer[1024];
while (1) {
int n = read(sockrec6,buffer,1024);
if (n<0) fail("server_v6","read(sockrec6)");
if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
break;
sleep(1);
//jaja, fieses gehacke...
n = sendto(socksend6,buffer,n,0,(struct sockaddr *)&sin,sizeof(sin));
if (n<0) fail("server_v6","sendto(socksend6)");
}
if (close(sockrec6) < 0) fail("server_v6","close(rec)");
if (close(socksend6) < 0) fail("server_v6","close(send)");
}
}
BOOST_AUTO_UNIT_TEST(RawV4ClientSocketHandle)
{
if (getuid() != 0) {
BOOST_WARN_MESSAGE(false, "Cannot test senf::RawV4SocketHandle as non-root user");
return;
}
try {
std::string test = "TEST-WRITE";
alarm(10);
start(server_v4);
senf::RawV4ClientSocketHandle sock(47); //IPPROTO_GRE
BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
BOOST_CHECK_NO_THROW( sock.sndbuf(2048) );
BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
BOOST_CHECK_NO_THROW( sock.writeto(senf::INet4SocketAddress("127.0.0.1:0"), test) );
senf::RawV4ClientSocketHandle sockrec(48); //IPPROTO_GRE+1
std::string in = sockrec.read();
BOOST_CHECK_EQUAL(in.substr(20), test);
BOOST_CHECK_NO_THROW( sock.writeto(senf::INet4SocketAddress("127.0.0.1:0"),"QUIT"));
//sock.close();
//sockrec.close();
alarm(0);
} catch (...) {
alarm(0);
throw;
}
}
BOOST_AUTO_UNIT_TEST(RawV6ClientSocketHandle)
{
if (getuid() != 0) {
BOOST_WARN_MESSAGE(false, "Cannot test senf::RawV6SocketHandle as non-root user");
return;
}
try {
std::string test = "TEST-WRITE";
alarm(5);
start(server_v6);
sleep(1);
senf::RawV6ClientSocketHandle sock(47); //IPPROTO_GRE
BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
BOOST_CHECK_NO_THROW( sock.sndbuf(2048) );
BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
BOOST_CHECK_NO_THROW( sock.writeto(senf::INet6SocketAddress("[::1]:0"), test) );
senf::RawV6ClientSocketHandle sockrec(48); //IPPROTO_GRE+1
std::string in = sockrec.read();
BOOST_CHECK_EQUAL(in, test);
BOOST_CHECK_NO_THROW( sock.writeto(senf::INet6SocketAddress("[::1]:0"),"QUIT"));
alarm(0);
} catch (...) {
alarm(0);
throw;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment