Utils/Termlib: Extend the completion API
[senf.git] / Socket / NetdeviceController.cc
index 345679b..a8f6a19 100644 (file)
@@ -37,8 +37,8 @@
 ///////////////////////////////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);
@@ -47,8 +47,8 @@ prefix_ senf::NetdeviceController::NetdeviceController(std::string const & inter
 }
 
 prefix_ senf::NetdeviceController::NetdeviceController(int interface_index)
+    : sockfd_ (sockfd())
 {
-    openSocket();
     ifindex_ = interface_index;
 }
 
@@ -136,22 +136,37 @@ prefix_ void senf::NetdeviceController::promisc(bool mode)
     doIoctl( ifr, SIOCSIFFLAGS);
 }
 
-prefix_ int senf::NetdeviceController::interfaceIndex()
+prefix_ bool senf::NetdeviceController::isUp()
     const
 {
-    return ifindex_;
+    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)
-        SENF_THROW_SYSTEM_EXCEPTION("Could not open socket for NetdeviceController.");
+    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)
@@ -159,7 +174,7 @@ prefix_ void senf::NetdeviceController::ifrName(ifreq& ifr)
 {
     ::memset( &ifr, 0, sizeof(ifr));
     ifr.ifr_ifindex = ifindex_;
-    if ( ::ioctl( sockfd_, SIOCGIFNAME, &ifr ) < 0 )
+    if ( ::ioctl( sockfd_->fd, SIOCGIFNAME, &ifr ) < 0 )
         SENF_THROW_SYSTEM_EXCEPTION("NetdeviceController")
         << " could not discover the name of the interface with index " << ifindex_ << ".";
 }
@@ -167,10 +182,36 @@ prefix_ void senf::NetdeviceController::ifrName(ifreq& ifr)
 prefix_ void senf::NetdeviceController::doIoctl(ifreq& ifr, int request)
     const
 {
-    if ( ::ioctl( sockfd_, request, &ifr ) < 0 )
+    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.");
+    std::cerr << ">>Made SockFd: " << fd << std::endl;
+}
+
+prefix_ senf::NetdeviceController::SockFd::~SockFd()
+{
+    std::cerr << ">>Dispose SockFd: " << fd << std::endl;
+    ::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"