// Custom includes
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <net/if.h>
#include "../Utils/Exception.hh"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ senf::NetdeviceController::NetdeviceController(std::string const & interface_name)
+ : sockfd_ (sockfd())
{
- openSocket();
struct ifreq ifr;
::memset( &ifr, 0, sizeof(ifr));
interface_name.copy( ifr.ifr_name, IFNAMSIZ);
}
prefix_ senf::NetdeviceController::NetdeviceController(int interface_index)
+ : sockfd_ (sockfd())
{
- openSocket();
ifindex_ = interface_index;
}
return std::string( ifr.ifr_name);
}
+prefix_ void senf::NetdeviceController::interfaceName(const std::string & newname)
+{
+ if (sizeof(newname) <= IFNAMSIZ) {
+ struct ifreq ifr;
+ ifrName(ifr);
+ strncpy(ifr. ifr_newname, newname.c_str(), IFNAMSIZ);
+ try {
+ doIoctl(ifr, SIOCSIFNAME);
+ } catch (senf::SystemException e) {
+ e << "Could not change the interface name. Is the interface really down?";
+ throw ;
+ }
+ }
+ return;
+}
+
prefix_ senf::MACAddress senf::NetdeviceController::hardwareAddress()
const
{
return senf::MACAddress::from_data( ifr.ifr_hwaddr.sa_data);
}
+prefix_ void senf::NetdeviceController::hardwareAddress(const MACAddress &newAddress) {
+ struct ifreq ifr;
+ ifrName( ifr);
+ ifr.ifr_hwaddr.sa_family = 1; // TODO: lookup named constant; PF_LOCAL ???
+ std::copy(newAddress.begin(), newAddress.end(), ifr.ifr_hwaddr.sa_data);
+ try {
+ doIoctl(ifr, SIOCSIFHWADDR);
+ } catch (senf::SystemException e) {
+ e << "Could not change the interface MAC address. Is the interface really down?";
+ throw ;
+ }
+}
+
prefix_ int senf::NetdeviceController::mtu()
const
{
}
prefix_ void senf::NetdeviceController::mtu(int new_mtu)
- const
{
struct ifreq ifr;
ifrName( ifr);
doIoctl( ifr, SIOCSIFMTU);
}
-prefix_ int senf::NetdeviceController::interfaceIndex()
+prefix_ bool senf::NetdeviceController::promisc()
const
{
- return ifindex_;
+ struct ifreq ifr;
+ ifrName( ifr);
+ doIoctl( ifr, SIOCGIFFLAGS);
+ return ifr.ifr_flags & IFF_PROMISC;
+}
+
+prefix_ void senf::NetdeviceController::promisc(bool mode)
+{
+ struct ifreq ifr;
+ ifrName( ifr);
+ doIoctl( ifr, SIOCGIFFLAGS);
+ if (mode)
+ ifr.ifr_flags |= IFF_PROMISC;
+ else
+ ifr.ifr_flags &= ~IFF_PROMISC;
+ doIoctl( ifr, SIOCSIFFLAGS);
+}
+
+prefix_ bool senf::NetdeviceController::isUp()
+ const
+{
+ struct ifreq ifr;
+ ifrName(ifr);
+ doIoctl(ifr, SIOCGIFFLAGS);
+ return ifr.ifr_flags & IFF_UP;
}
-prefix_ senf::NetdeviceController::~NetdeviceController()
+prefix_ void senf::NetdeviceController::up()
{
- close( sockfd_);
+ struct ifreq ifr;
+ ifrName(ifr);
+ doIoctl(ifr, SIOCGIFFLAGS);
+ ifr.ifr_flags |= IFF_UP;
+ doIoctl(ifr, SIOCSIFFLAGS);
}
-prefix_ void senf::NetdeviceController::openSocket()
+prefix_ void senf::NetdeviceController::down()
{
- sockfd_ = ::socket( PF_INET, SOCK_DGRAM, 0);
- if ( sockfd_ < 0)
- throw SystemException();
+ struct ifreq ifr;
+ ifrName(ifr);
+ doIoctl(ifr, SIOCGIFFLAGS);
+ ifr.ifr_flags &= ~IFF_UP;
+ doIoctl(ifr, SIOCSIFFLAGS);
+}
+
+prefix_ int senf::NetdeviceController::interfaceIndex()
+ const
+{
+ return ifindex_;
}
prefix_ void senf::NetdeviceController::ifrName(ifreq& ifr)
{
::memset( &ifr, 0, sizeof(ifr));
ifr.ifr_ifindex = ifindex_;
- if ( ::ioctl( sockfd_, SIOCGIFNAME, &ifr ) < 0 )
- throw SystemException();
+ if ( ::ioctl( sockfd_->fd, SIOCGIFNAME, &ifr ) < 0 )
+ SENF_THROW_SYSTEM_EXCEPTION("NetdeviceController")
+ << " could not discover the name of the interface with index " << ifindex_ << ".";
}
-
prefix_ void senf::NetdeviceController::doIoctl(ifreq& ifr, int request)
const
{
- if ( ::ioctl( sockfd_, request, &ifr ) < 0 )
- throw SystemException();
+ if ( ::ioctl( sockfd_->fd, request, &ifr ) < 0 )
+ SENF_THROW_SYSTEM_EXCEPTION("NetdeviceController::doIoctl failed.");
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::NetdeviceController::SockFd
+
+prefix_ senf::NetdeviceController::SockFd::SockFd()
+ : fd (::socket(PF_INET, SOCK_DGRAM, 0))
+{
+ if ( fd < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("Could not open socket for NetdeviceController.");
+}
+
+prefix_ senf::NetdeviceController::SockFd::~SockFd()
+{
+ ::close(fd);
+}
+
+prefix_ senf::NetdeviceController::SockFd::ptr senf::NetdeviceController::sockfd()
+{
+ static boost::weak_ptr<SockFd> sockfd;
+ SockFd::ptr p (sockfd.lock());
+ if (!p)
+ sockfd = p = SockFd::ptr(new SockFd());
+ return p;
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "NetdeviceController.mpp"
-\f
+
// Local Variables:
// mode: c++
// fill-column: 100