00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039 #include "blocxx/BLOCXX_config.h"
00040
00041 #if !defined(BLOCXX_WIN32) && !defined(BLOCXX_NETWARE)
00042
00043 extern "C"
00044 {
00045 #ifdef BLOCXX_HAVE_UNISTD_H
00046 #include <unistd.h>
00047 #endif
00048
00049 #include <stdlib.h>
00050 #include <stdio.h>
00051 #include <sys/types.h>
00052
00053 #ifdef BLOCXX_HAVE_SYS_SOCKET_H
00054 #include <sys/socket.h>
00055 #endif
00056
00057 #include <arpa/inet.h>
00058 #include <errno.h>
00059
00060 #ifdef BLOCXX_GNU_LINUX
00061 #include <sys/ioctl.h>
00062 #include <linux/if.h>
00063 #include <string.h>
00064
00065 #elif defined (BLOCXX_OPENSERVER)
00066 #include <string.h>
00067 #include <stropts.h>
00068 #include <net/if.h>
00069 #include <netinet/in.h>
00070 #include <strings.h>
00071 #include <arpa/inet.h>
00072 #include <fcntl.h>
00073 #include <paths.h>
00074 #include <sys/mdi.h>
00075
00076 #elif defined (BLOCXX_DARWIN)
00077 #include <net/if.h>
00078 #include <sys/ioctl.h>
00079 #else
00080
00081 #ifdef BLOCXX_HAVE_STROPTS_H
00082 #include <stropts.h>
00083 #endif
00084
00085 #include <net/if.h>
00086 #include <netinet/in.h>
00087
00088 #if defined (BLOCXX_HAVE_SYS_SOCKIO_H)
00089 #include <sys/sockio.h>
00090 #endif
00091
00092 #include <strings.h>
00093 #include <fcntl.h>
00094 #endif
00095
00096 #include <string.h>
00097 }
00098
00099
00100 #include "blocxx/NwIface.hpp"
00101 #include "blocxx/String.hpp"
00102 #include "blocxx/Exception.hpp"
00103 #include "blocxx/SocketUtils.hpp"
00104
00105 namespace BLOCXX_NAMESPACE
00106 {
00107
00109 NwIface::NwIface()
00110 {
00111 int s, lerrno;
00112 struct ifreq ifr;
00113 struct sockaddr_in *sin(0);
00114 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
00115 {
00116 BLOCXX_THROW(SocketException, "socket");
00117 }
00118 getInterfaceName(s);
00119 bzero(&ifr, sizeof(ifr));
00120 strncpy(ifr.ifr_name, m_name.c_str(), sizeof(ifr.ifr_name));
00122
00123 if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
00124 {
00125 lerrno = errno;
00126 close(s);
00127 BLOCXX_THROW(SocketException, "ioctl:SIOCGIFADDR");
00128 }
00129 sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_addr);
00130 m_addr = sin->sin_addr.s_addr;
00132
00133
00134 if (ioctl(s, SIOCGIFBRDADDR, &ifr) < 0)
00135 {
00136 lerrno = errno;
00137 close(s);
00138 BLOCXX_THROW(SocketException, "ioctl:SIOCGIFBRDADDR");
00139 }
00140 sin = reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_broadaddr);
00141 m_bcastAddr = sin->sin_addr.s_addr;
00143
00144 if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0)
00145 {
00146 lerrno = errno;
00147 close(s);
00148 BLOCXX_THROW(SocketException, "ioctl:SIOCGIFNETMASK");
00149 }
00150 #ifdef BLOCXX_GNU_LINUX
00151 sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_netmask);
00152 #else
00153 sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_broadaddr);
00154 #endif
00155 m_netmask = sin->sin_addr.s_addr;
00156 close(s);
00157 }
00159 String
00160 NwIface::getName()
00161 {
00162 return m_name;
00163 }
00165 unsigned long
00166 NwIface::getIPAddress()
00167 {
00168 return m_addr;
00169 }
00171 String
00172 NwIface::getIPAddressString()
00173 {
00174 return SocketUtils::inetAddrToString(m_addr);
00175 }
00177 unsigned long
00178 NwIface::getBroadcastAddress()
00179 {
00180 return m_bcastAddr;
00181 }
00183 String
00184 NwIface::getBroadcastAddressString()
00185 {
00186 return SocketUtils::inetAddrToString(m_bcastAddr);
00187 }
00189
00190
00191
00192
00193
00194
00195
00197 unsigned long
00198 NwIface::getNetmask()
00199 {
00200 return m_netmask;
00201 }
00203 String
00204 NwIface::getNetmaskString()
00205 {
00206 return SocketUtils::inetAddrToString(m_netmask);
00207 }
00209 bool
00210 NwIface::sameNetwork(unsigned long addr)
00211 {
00212 return ((addr & m_netmask) == (m_addr & m_netmask));
00213 }
00215 bool
00216 NwIface::sameNetwork(const String& straddr)
00217 {
00218 return sameNetwork(stringToAddress(straddr));
00219 }
00221 unsigned long
00222 NwIface::stringToAddress(const String& straddr)
00223 {
00224 return inet_addr(straddr.c_str());
00225 }
00227 void
00228 NwIface::getInterfaceName(SocketHandle_t sockfd)
00229 {
00230 char *p(0);
00231 int numreqs = 30;
00232 struct ifconf ifc;
00233 struct ifreq *ifr(0);
00234 struct ifreq ifrcopy;
00235 int n;
00236 int oldlen = -1;
00237 int lerrno = 0;
00238 const char* appliesTo(0);
00239 ifc.ifc_buf = NULL;
00240 for (;;)
00241 {
00242 ifc.ifc_len = sizeof(struct ifreq) * numreqs;
00243 if (ifc.ifc_buf == NULL)
00244 {
00245 ifc.ifc_buf = new char[ifc.ifc_len];
00246 }
00247 else
00248 {
00249 p = new char[ifc.ifc_len];
00250 memmove(p, ifc.ifc_buf, oldlen);
00251 delete [] ifc.ifc_buf;
00252 ifc.ifc_buf = p;
00253 }
00254 oldlen = ifc.ifc_len;
00255 if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
00256 {
00257 lerrno = errno;
00258 appliesTo = "ioctl:SIOCGIFCONF";
00259 break;
00260 }
00261 if (ifc.ifc_len == static_cast<int>(sizeof(struct ifreq) * numreqs))
00262 {
00263
00264 numreqs += 10;
00265 continue;
00266 }
00267 break;
00268 }
00269 if (lerrno == 0)
00270 {
00271 lerrno = ENODEV;
00272 appliesTo = "No interfaces found";
00273 ifr = ifc.ifc_req;
00274 for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq))
00275 {
00276 ifrcopy = *ifr;
00277 if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
00278 {
00279 lerrno = errno;
00280 appliesTo = "ioctl:SIOCGIFFLAGS";
00281 break;
00282 }
00283 #ifdef BLOCXX_GNU_LINUX
00284 if ((ifrcopy.ifr_flags & IFF_UP) && !(ifrcopy.ifr_flags & (IFF_LOOPBACK | IFF_DYNAMIC)))
00285 #else
00286 if ((ifrcopy.ifr_flags & IFF_UP))
00287 #endif
00288 {
00289 m_name = ifr->ifr_name;
00290 lerrno = 0;
00291 break;
00292 }
00293 ifr++;
00294 }
00295 }
00296 if (ifc.ifc_buf != NULL)
00297 {
00298 delete [] ifc.ifc_buf;
00299 }
00300 if (lerrno != 0)
00301 {
00302 BLOCXX_THROW(SocketException, "NwIface::getInterfaceName");
00303 }
00304 }
00305
00306 }
00307
00308 #endif // #if !defined(BLOCXX_WIN32) && !defined(BLOCXX_NETWARE)
00309