00001
00002
00005 #ifdef ENABLE_NETWORK
00006
00007 #include "../../stdafx.h"
00008 #include "../../debug.h"
00009 #include "os_abstraction.h"
00010 #include "../../core/alloc_func.hpp"
00011
00018 static int NetworkFindBroadcastIPsInternal(uint32 *broadcast, int limit);
00019
00020 #if defined(PSP)
00021 static int NetworkFindBroadcastIPsInternal(uint32 *broadcast, int limit)
00022 {
00023 return 0;
00024 }
00025
00026 #elif defined(BEOS_NET_SERVER)
00027
00028 int _netstat(int fd, char **output, int verbose);
00029
00030 int seek_past_header(char **pos, const char *header)
00031 {
00032 char *new_pos = strstr(*pos, header);
00033 if (new_pos == 0) {
00034 return B_ERROR;
00035 }
00036 *pos += strlen(header) + new_pos - *pos + 1;
00037 return B_OK;
00038 }
00039
00040 static int NetworkFindBroadcastIPsInternal(uint32 *broadcast, int limit)
00041 {
00042 int sock = socket(AF_INET, SOCK_DGRAM, 0);
00043
00044 if (sock < 0) {
00045 DEBUG(net, 0, "[core] error creating socket");
00046 return 0;
00047 }
00048
00049 char *output_pointer = NULL;
00050 int output_length = _netstat(sock, &output_pointer, 1);
00051 if (output_length < 0) {
00052 DEBUG(net, 0, "[core] error running _netstat");
00053 return 0;
00054 }
00055
00056 int index;
00057 char **output = &output_pointer;
00058 if (seek_past_header(output, "IP Interfaces:") == B_OK) {
00059 while (index != limit) {
00060
00061 uint32 n, fields, read;
00062 uint8 i1, i2, i3, i4, j1, j2, j3, j4;
00063 struct in_addr inaddr;
00064 uint32 ip;
00065 uint32 netmask;
00066
00067 fields = sscanf(*output, "%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n",
00068 &n, &i1, &i2, &i3, &i4, &j1, &j2, &j3, &j4, &read);
00069 read += 1;
00070 if (fields != 9) {
00071 break;
00072 }
00073
00074 ip = (uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4;
00075 netmask = (uint32)j1 << 24 | (uint32)j2 << 16 | (uint32)j3 << 8 | (uint32)j4;
00076
00077 if (ip != INADDR_LOOPBACK && ip != INADDR_ANY) {
00078 inaddr.s_addr = htonl(ip | ~netmask);
00079 broadcast[index] = inaddr.s_addr;
00080 index++;
00081 }
00082 if (read < 0) {
00083 break;
00084 }
00085 *output += read;
00086 }
00087 closesocket(sock);
00088 }
00089
00090 return index;
00091 }
00092
00093 #elif defined(HAVE_GETIFADDRS)
00094 static int NetworkFindBroadcastIPsInternal(uint32 *broadcast, int limit)
00095 {
00096 struct ifaddrs *ifap, *ifa;
00097
00098 if (getifaddrs(&ifap) != 0) return 0;
00099
00100 int index = 0;
00101 for (ifa = ifap; ifa != NULL && index != limit; ifa = ifa->ifa_next) {
00102 if (!(ifa->ifa_flags & IFF_BROADCAST)) continue;
00103 if (ifa->ifa_broadaddr == NULL) continue;
00104 if (ifa->ifa_broadaddr->sa_family != AF_INET) continue;
00105
00106 broadcast[index] = ((struct sockaddr_in*)ifa->ifa_broadaddr)->sin_addr.s_addr;
00107 index++;
00108 }
00109 freeifaddrs(ifap);
00110
00111 return index;
00112 }
00113
00114 #elif defined(WIN32)
00115 static int NetworkFindBroadcastIPsInternal(uint32 *broadcast, int limit)
00116 {
00117 SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
00118 if (sock == INVALID_SOCKET) return 0;
00119
00120 DWORD len = 0;
00121 INTERFACE_INFO *ifo = AllocaM(INTERFACE_INFO, limit);
00122 memset(ifo, 0, limit * sizeof(*ifo));
00123 if ((WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, &ifo[0], limit * sizeof(*ifo), &len, NULL, NULL)) != 0) {
00124 closesocket(sock);
00125 return 0;
00126 }
00127
00128 int index = 0;
00129 for (uint j = 0; j < len / sizeof(*ifo) && index != limit; j++) {
00130 if (ifo[j].iiFlags & IFF_LOOPBACK) continue;
00131 if (!(ifo[j].iiFlags & IFF_BROADCAST)) continue;
00132
00133
00134 broadcast[index++] = ifo[j].iiAddress.AddressIn.sin_addr.s_addr | ~ifo[j].iiNetmask.AddressIn.sin_addr.s_addr;
00135 }
00136
00137 closesocket(sock);
00138 return index;
00139 }
00140
00141 #else
00142
00143 #include "../../string_func.h"
00144
00145 static int NetworkFindBroadcastIPsInternal(uint32 *broadcast, int limit)
00146 {
00147 SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
00148 if (sock == INVALID_SOCKET) return 0;
00149
00150 char buf[4 * 1024];
00151 struct ifconf ifconf;
00152
00153 ifconf.ifc_len = sizeof(buf);
00154 ifconf.ifc_buf = buf;
00155 if (ioctl(sock, SIOCGIFCONF, &ifconf) == -1) {
00156 closesocket(sock);
00157 return 0;
00158 }
00159
00160 const char *buf_end = buf + ifconf.ifc_len;
00161 int index = 0;
00162 for (const char *p = buf; p < buf_end && index != limit;) {
00163 const struct ifreq *req = (const struct ifreq*)p;
00164
00165 if (req->ifr_addr.sa_family == AF_INET) {
00166 struct ifreq r;
00167
00168 strecpy(r.ifr_name, req->ifr_name, lastof(r.ifr_name));
00169 if (ioctl(sock, SIOCGIFFLAGS, &r) != -1 &&
00170 r.ifr_flags & IFF_BROADCAST &&
00171 ioctl(sock, SIOCGIFBRDADDR, &r) != -1) {
00172 broadcast[index++] = ((struct sockaddr_in*)&r.ifr_broadaddr)->sin_addr.s_addr;
00173 }
00174 }
00175
00176 p += sizeof(struct ifreq);
00177 #if defined(AF_LINK) && !defined(SUNOS)
00178 p += req->ifr_addr.sa_len - sizeof(struct sockaddr);
00179 #endif
00180 }
00181
00182 closesocket(sock);
00183
00184 return index;
00185 }
00186 #endif
00187
00193 void NetworkFindBroadcastIPs(uint32 *broadcast, int limit)
00194 {
00195 int count = NetworkFindBroadcastIPsInternal(broadcast, limit);
00196
00197
00198 broadcast[count] = 0;
00199
00200
00201 DEBUG(net, 3, "Detected broadcast addresses:");
00202 for (int i = 0; broadcast[i] != 0; i++) {
00203 DEBUG(net, 3, "%d) %s", i, inet_ntoa(*(struct in_addr *)&broadcast[i]));
00204 }
00205 }
00206
00207
00213 uint32 NetworkResolveHost(const char *hostname)
00214 {
00215
00216 in_addr_t ip = inet_addr(hostname);
00217
00218 if (ip != INADDR_NONE) return ip;
00219
00220
00221 struct in_addr addr;
00222 #if !defined(PSP)
00223 struct hostent *he = gethostbyname(hostname);
00224 if (he == NULL) {
00225 DEBUG(net, 0, "[NET] Cannot resolve %s", hostname);
00226 return 0;
00227 }
00228 addr = *(struct in_addr *)he->h_addr_list[0];
00229 #else
00230 int rid = -1;
00231 char buf[1024];
00232
00233
00234 if (sceNetResolverCreate(&rid, buf, sizeof(buf)) < 0) {
00235 DEBUG(net, 0, "[NET] Error connecting resolver");
00236 return 0;
00237 }
00238
00239
00240 if (sceNetResolverStartNtoA(rid, hostname, &addr, 2, 3) < 0) {
00241 DEBUG(net, 0, "[NET] Cannot resolve %s", hostname);
00242 sceNetResolverDelete(rid);
00243 return 0;
00244 }
00245 sceNetResolverDelete(rid);
00246 #endif
00247
00248 DEBUG(net, 1, "[NET] Resolved %s to %s", hostname, inet_ntoa(addr));
00249 ip = addr.s_addr;
00250 return ip;
00251 }
00252
00253 #endif