00001 #include "headers.h"
00002
00007
00008 Interface::Interface() {
00009 m_broadcastsSupported = false;
00010 m_multicastsSupported = false;
00011 m_isLoopback = false;
00012 m_isPointToPoint = false;
00013 m_isUp = false;
00014 }
00015
00016
00017 void
00018 Interface::toStream(std::ostream& out) {
00019 out << "IP: " << m_ipAddr << "\n";
00020 out << " SubnetMask: " << m_subnetMask << "\n";
00021 out << " Broadcast Address: " << m_broadcastAddress << "\n";
00022
00023 if (m_isUp) {
00024 out << " This interface is up.\n";
00025 }
00026 if (m_broadcastsSupported) {
00027 out << " Broadcasts are supported\n";
00028 }
00029 if (m_multicastsSupported) {
00030 out << " Multicasts are supported\n";
00031 }
00032 if (m_isLoopback) {
00033 out << " This is a loopback interface.\n";
00034 }
00035 if (m_isPointToPoint) {
00036 out << " This is a point-to-point link.\n";
00037 }
00038 if (m_ipAddr.isLanIp()) {
00039 out << " This is a LAN IP address.\n";
00040 }
00041 }
00042
00043
00048 Interfaces::Interfaces() {
00049 init();
00050 }
00051
00052
00057 IpAddress
00058 Interfaces::getPublicIp()
00059 {
00060 vector<Interface>::const_iterator iter;
00061 IpAddress returnValue((unsigned long)0);
00062
00063 for (iter = m_interface.begin(); iter != m_interface.end(); ++iter) {
00064
00065 IpAddress ip((*iter).m_ipAddr);
00066 if (!((*iter).m_isLoopback) && !(ip.isLanIp())) {
00067 return (*iter).m_ipAddr;
00068 }
00069
00070 else if (ip.isLanIp()) {
00071 returnValue = (*iter).m_ipAddr;
00072 }
00073
00074 else if (returnValue.isZero()) {
00075 returnValue = (*iter).m_ipAddr;
00076 }
00077 }
00078
00079 return returnValue;
00080 }
00081
00082
00083 void
00084 Interfaces::toStream(std::ostream& out) {
00085
00086
00087 vector<Interface>::iterator interfaceIterator;
00088
00089 for (interfaceIterator = m_interface.begin(); interfaceIterator != m_interface.end(); interfaceIterator++) {
00090 interfaceIterator->toStream(out);
00091 }
00092 }
00093
00094
00095 #ifdef WIN32
00096
00097 void
00098 Interfaces::init() {
00099 int wsError;
00100 OS_SPEC_SOCKET_TYPE s = OS_SPEC_INVALID_SOCKET;
00101 DWORD bytesReturned;
00102 u_long SetFlags;
00103 INTERFACE_INFO localAddr[32];
00104 int numLocalAddr;
00105
00106 if((s = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0)) == OS_SPEC_INVALID_SOCKET) {
00107 debug(DEBUG_INTF, "Socket creation failed:\n%s\n", printWsaErrorCode());
00108 return;
00109 }
00110
00111
00112 wsError = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, &localAddr,
00113 sizeof(localAddr), &bytesReturned, NULL, NULL);
00114
00115 OS_SPEC_SOCKETCLOSE(s);
00116
00117 if (wsError == SOCKET_ERROR) {
00118 debug(DEBUG_INTF, "WSAIoctl Error: %d\n", GetLastError());
00119 return;
00120 }
00121
00122
00123 numLocalAddr = (bytesReturned/sizeof(INTERFACE_INFO));
00124 for (int i = 0; i < numLocalAddr; i++) {
00125 Interface tmp;
00126 tmp.m_ipAddr.setIpAddress(((SOCKADDR_IN*)&localAddr[i].iiAddress)->sin_addr);
00127 tmp.m_subnetMask.setIpAddress(((SOCKADDR_IN*)&localAddr[i].iiNetmask)->sin_addr);
00128 tmp.m_broadcastAddress.setIpAddress(((SOCKADDR_IN*)&localAddr[i].iiBroadcastAddress)->sin_addr);
00129
00130 SetFlags = localAddr[i].iiFlags;
00131
00132 tmp.m_isUp = (SetFlags & IFF_UP);
00133 tmp.m_broadcastsSupported = (SetFlags & IFF_BROADCAST) == 1;
00134 tmp.m_multicastsSupported = (SetFlags & IFF_MULTICAST) == 1;
00135 tmp.m_isLoopback = ((SetFlags & IFF_LOOPBACK) == 1) | tmp.m_ipAddr.isLoopback();
00136 tmp.m_isPointToPoint = (SetFlags & IFF_POINTTOPOINT) == 1;
00137 m_interface.push_back(tmp);
00138 }
00139 }
00140
00141 #endif
00142
00143 #ifdef LINUX
00144 #include <net/if.h>
00145 #include <sys/ioctl.h>
00146
00147 void
00148 Interfaces::init()
00149 {
00150
00151 int fd, nipaddr;
00152 #ifdef HAVE_SOCKADDR_SA_LEN
00153 int n;
00154 #endif
00155 struct ifreq *ifrp, *ifend, *ifnext, *mp;
00156 struct sockaddr_in *addr;
00157 struct ifconf ifc;
00158 struct ifreq ibuf[32], ifr;
00159
00160 fd = socket(AF_INET, SOCK_DGRAM, 0);
00161
00162 if(fd < 0) {
00163 debug(DEBUG_ERR, "Socket creation failed\n");
00164 return;
00165 }
00166
00167 ifc.ifc_len = sizeof(ibuf);
00168 ifc.ifc_buf = (caddr_t) ibuf;
00169
00170 if(ioctl(fd, SIOCGIFCONF, (char *) &ifc)
00171 < 0 || ifc.ifc_len < (int) sizeof(struct ifreq))
00172 {
00173 debug(DEBUG_ERR, "ioctl SIOCGIFCONF failed\n");
00174 close(fd);
00175 return;
00176 }
00177
00178 ifrp = ibuf;
00179 ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
00180
00181 mp = NULL;
00182 nipaddr = 0;
00183
00184 for(;ifrp < ifend; ifrp = ifnext) {
00185 Interface newInterface;
00186 #ifdef HAVE_SOCKADDR_SA_LEN
00187 n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
00188 if (n < sizeof(*ifrp)) {
00189 ifnext = ifrp + 1;
00190 }
00191 else {
00192 ifnext = (struct ifreq *)((char *)ifrp + n);
00193 }
00194
00195 if(ifrp->ifr_addr.sa_family != AF_INET) {
00196 continue;
00197 }
00198 #else
00199 ifnext = ifrp + 1;
00200 #endif
00201
00202 strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
00203
00204 if(ioctl(fd, SIOCGIFADDR, (char *) &ifr) < 0) {
00205 debug(DEBUG_ERR, "ioctl SIOCGIFADDR failed\n");
00206 close(fd);
00207 return;
00208 }
00209
00210 addr = (struct sockaddr_in *) &ifr.ifr_addr;
00211
00212 if(addr->sin_addr.s_addr) {
00213 newInterface.m_ipAddr.setIpAddress(addr->sin_addr.s_addr);
00214 }
00215
00216 if(ioctl(fd, SIOCGIFNETMASK, (char *) &ifr) < 0) {
00217 debug(DEBUG_ERR, "ioctl SIOCGIFNETMASK failed\n");
00218 close(fd);
00219 return;
00220 }
00221
00222 addr = (struct sockaddr_in *) &ifr.ifr_addr;
00223 newInterface.m_subnetMask.setIpAddress(addr->sin_addr);
00224 if(ioctl(fd, SIOCGIFBRDADDR, (char *) &ifr) < 0) {
00225 debug(DEBUG_ERR, "ioctl SIOCGIFBRDADDR failed\n");
00226 close(fd);
00227 return;
00228 }
00229
00230 addr = (struct sockaddr_in *) &ifr.ifr_addr;
00231 newInterface.m_broadcastAddress.setIpAddress(addr->sin_addr);
00232
00233 if(ioctl(fd, SIOCGIFFLAGS, (char *) &ifr) < 0) {
00234 if(errno == ENXIO) {
00235 continue;
00236 }
00237 debug(DEBUG_ERR, "ioctl SIOCGIFFLAGS failed\n");
00238 close(fd);
00239 return;
00240 }
00241
00242
00243 newInterface.m_isUp = (ifr.ifr_flags & IFF_UP);
00244
00245 newInterface.m_broadcastsSupported = (ifr.ifr_flags & IFF_BROADCAST);
00246
00247 newInterface.m_multicastsSupported = (ifr.ifr_flags & IFF_MULTICAST);
00248
00249 newInterface.m_isLoopback = (ifr.ifr_flags & IFF_LOOPBACK);
00250
00251 m_interface.push_back(newInterface);
00252 }
00253
00254 close(fd);
00255 return;
00256 }
00257 #endif // #ifdef LINUX
00258