NwIface.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2005 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 
00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 *******************************************************************************/
00031 
00032 
00038 #include "blocxx/BLOCXX_config.h"
00039 
00040 #if !defined(BLOCXX_WIN32) && !defined(BLOCXX_NETWARE)
00041 
00042 extern "C"
00043 {
00044 #ifdef BLOCXX_HAVE_UNISTD_H
00045   #include <unistd.h>
00046 #endif
00047 
00048 #include <stdlib.h>
00049 #include <stdio.h>
00050 #include <sys/types.h>
00051 
00052 #ifdef BLOCXX_HAVE_SYS_SOCKET_H
00053   #include <sys/socket.h>
00054 #endif
00055 
00056 #include <arpa/inet.h>
00057 #include <errno.h>
00058 
00059 #ifdef BLOCXX_GNU_LINUX
00060   #include <sys/ioctl.h>
00061   #include <linux/if.h>
00062   #include <string.h>
00063 
00064 #elif defined (BLOCXX_OPENSERVER)
00065   #include <string.h>
00066   #include <stropts.h>
00067   #include <net/if.h>
00068   #include <netinet/in.h>
00069   #include <strings.h>
00070   #include <arpa/inet.h>
00071   #include <fcntl.h>
00072   #include <paths.h>
00073   #include <sys/mdi.h>
00074 
00075 #elif defined (BLOCXX_DARWIN)
00076   #include <net/if.h>
00077   #include <sys/ioctl.h>
00078 #else
00079 
00080   #ifdef BLOCXX_HAVE_STROPTS_H
00081     #include <stropts.h>
00082   #endif
00083 
00084   #include <net/if.h>
00085   #include <netinet/in.h>
00086 
00087   #if defined (BLOCXX_HAVE_SYS_SOCKIO_H)
00088     #include <sys/sockio.h>
00089   #endif
00090 
00091   #include <strings.h>
00092   #include <fcntl.h>
00093 #endif
00094 
00095 #include <string.h>
00096 } // extern "C"
00097 // These need to be after the system includes because of some weird openserver
00098 // include order problem
00099 #include "blocxx/NwIface.hpp"
00100 #include "blocxx/String.hpp"
00101 #include "blocxx/Exception.hpp"
00102 #include "blocxx/SocketUtils.hpp"
00103 
00104 namespace BLOCXX_NAMESPACE
00105 {
00106 
00108 NwIface::NwIface()
00109 {
00110    int s, lerrno;
00111    struct ifreq ifr;
00112    struct sockaddr_in *sin(0);
00113    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
00114    {
00115       BLOCXX_THROW(SocketException, "socket");
00116    }
00117    getInterfaceName(s);
00118    bzero(&ifr, sizeof(ifr));
00119    strncpy(ifr.ifr_name, m_name.c_str(), sizeof(ifr.ifr_name));
00121    // Get IP address
00122    if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
00123    {
00124       lerrno = errno;
00125       close(s);
00126       BLOCXX_THROW(SocketException, "ioctl:SIOCGIFADDR");
00127    }
00128    sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_addr);
00129    m_addr = sin->sin_addr.s_addr;
00131    // Get the broadcast address
00132    // Testing
00133    if (ioctl(s, SIOCGIFBRDADDR, &ifr) < 0)
00134    {
00135       lerrno = errno;
00136       close(s);
00137       BLOCXX_THROW(SocketException, "ioctl:SIOCGIFBRDADDR");
00138    }
00139    sin = reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_broadaddr);
00140    m_bcastAddr = sin->sin_addr.s_addr;
00142    // Get net mask
00143    if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0)
00144    {
00145       lerrno = errno;
00146       close(s);
00147       BLOCXX_THROW(SocketException, "ioctl:SIOCGIFNETMASK");
00148    }
00149 #ifdef BLOCXX_GNU_LINUX
00150    sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_netmask);
00151 #else
00152    sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_broadaddr);
00153 #endif
00154    m_netmask = sin->sin_addr.s_addr;
00155    close(s);
00156 }
00158 String
00159 NwIface::getName()
00160 {
00161    return m_name;
00162 }
00164 unsigned long
00165 NwIface::getIPAddress()
00166 {
00167    return m_addr;
00168 }
00170 String
00171 NwIface::getIPAddressString()
00172 {
00173    return SocketUtils::inetAddrToString(m_addr);
00174 }
00176 unsigned long
00177 NwIface::getBroadcastAddress()
00178 {
00179    return m_bcastAddr;
00180 }
00182 String
00183 NwIface::getBroadcastAddressString()
00184 {
00185    return SocketUtils::inetAddrToString(m_bcastAddr);
00186 }
00188 /*
00189 String
00190 NwIface::getMACAddressString()
00191 {
00192    return m_macAddress;
00193 }
00194 */
00196 unsigned long
00197 NwIface::getNetmask()
00198 {
00199    return m_netmask;
00200 }
00202 String
00203 NwIface::getNetmaskString()
00204 {
00205    return SocketUtils::inetAddrToString(m_netmask);
00206 }
00208 bool
00209 NwIface::sameNetwork(unsigned long addr)
00210 {
00211    return ((addr & m_netmask) == (m_addr & m_netmask));
00212 }
00214 bool
00215 NwIface::sameNetwork(const String& straddr)
00216 {
00217    return sameNetwork(stringToAddress(straddr));
00218 }
00220 unsigned long
00221 NwIface::stringToAddress(const String& straddr)
00222 {
00223    return inet_addr(straddr.c_str());
00224 }
00226 void
00227 NwIface::getInterfaceName(SocketHandle_t sockfd)
00228 {
00229    char *p(0);
00230    int numreqs = 30;
00231    struct ifconf ifc;
00232    struct ifreq *ifr(0);
00233    struct ifreq ifrcopy;
00234    int n;
00235    int oldlen = -1;
00236    int lerrno = 0;
00237    const char* appliesTo(0);
00238    ifc.ifc_buf = NULL;
00239    for (;;)
00240    {
00241       ifc.ifc_len = sizeof(struct ifreq) * numreqs;
00242       if (ifc.ifc_buf == NULL)
00243       {
00244          ifc.ifc_buf = new char[ifc.ifc_len];
00245       }
00246       else
00247       {
00248          p = new char[ifc.ifc_len];
00249          memmove(p, ifc.ifc_buf, oldlen);
00250          delete [] ifc.ifc_buf;
00251          ifc.ifc_buf = p;
00252       }
00253       oldlen = ifc.ifc_len;
00254       if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
00255       {
00256          lerrno = errno;
00257          appliesTo = "ioctl:SIOCGIFCONF";
00258          break;
00259       }
00260       if (ifc.ifc_len == static_cast<int>(sizeof(struct ifreq) * numreqs))
00261       {
00262          /* assume it overflowed and try again */
00263          numreqs += 10;
00264          continue;
00265       }
00266       break;
00267    }
00268    if (lerrno == 0)
00269    {
00270       lerrno = ENODEV;
00271       appliesTo = "No interfaces found";
00272       ifr = ifc.ifc_req;
00273       for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq))
00274       {
00275          ifrcopy = *ifr;
00276          if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
00277          {
00278             lerrno = errno;
00279             appliesTo = "ioctl:SIOCGIFFLAGS";
00280             break;
00281          }
00282 #ifdef BLOCXX_GNU_LINUX
00283          if ((ifrcopy.ifr_flags & IFF_UP) && !(ifrcopy.ifr_flags & (IFF_LOOPBACK | IFF_DYNAMIC)))
00284 #else
00285          if ((ifrcopy.ifr_flags & IFF_UP))
00286 #endif
00287          {
00288             m_name = ifr->ifr_name;
00289             lerrno = 0;
00290             break;
00291          }
00292          ifr++;
00293       }
00294    }
00295    if (ifc.ifc_buf != NULL)
00296    {
00297       delete [] ifc.ifc_buf;
00298    }
00299    if (lerrno != 0)
00300    {
00301       BLOCXX_THROW(SocketException, "NwIface::getInterfaceName");
00302    }
00303 }
00304 
00305 } // end namespace BLOCXX_NAMESPACE
00306 
00307 #endif   // #if !defined(BLOCXX_WIN32) && !defined(BLOCXX_NETWARE)
00308 

Generated on Fri Jun 16 15:39:08 2006 for blocxx by  doxygen 1.4.6