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
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 }
00097
00098
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
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
00132
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
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
00190
00191
00192
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
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 }
00306
00307 #endif // #if !defined(BLOCXX_WIN32) && !defined(BLOCXX_NETWARE)
00308