00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define _SVID_SOURCE
00025 #define _DARWIN_C_SOURCE
00026
00027 #include "config.h"
00028 #include "avformat.h"
00029 #include "os_support.h"
00030
00031 #if CONFIG_NETWORK
00032 #include <fcntl.h>
00033 #include <unistd.h>
00034 #if !HAVE_POLL_H
00035 #include <sys/time.h>
00036 #if HAVE_WINSOCK2_H
00037 #include <winsock2.h>
00038 #elif HAVE_SYS_SELECT_H
00039 #include <sys/select.h>
00040 #endif
00041 #endif
00042
00043 #include "network.h"
00044
00045 #if !HAVE_INET_ATON
00046 #include <stdlib.h>
00047 #include <strings.h>
00048
00049 int ff_inet_aton (const char * str, struct in_addr * add)
00050 {
00051 unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0;
00052
00053 if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4)
00054 return 0;
00055
00056 if (!add1 || (add1|add2|add3|add4) > 255) return 0;
00057
00058 add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4);
00059
00060 return 1;
00061 }
00062 #else
00063 int ff_inet_aton (const char * str, struct in_addr * add)
00064 {
00065 return inet_aton(str, add);
00066 }
00067 #endif
00068
00069 #if !HAVE_GETADDRINFO
00070 int ff_getaddrinfo(const char *node, const char *service,
00071 const struct addrinfo *hints, struct addrinfo **res)
00072 {
00073 struct hostent *h = NULL;
00074 struct addrinfo *ai;
00075 struct sockaddr_in *sin;
00076
00077 #if HAVE_WINSOCK2_H
00078 int (WSAAPI *win_getaddrinfo)(const char *node, const char *service,
00079 const struct addrinfo *hints,
00080 struct addrinfo **res);
00081 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00082 win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");
00083 if (win_getaddrinfo)
00084 return win_getaddrinfo(node, service, hints, res);
00085 #endif
00086
00087 *res = NULL;
00088 sin = av_mallocz(sizeof(struct sockaddr_in));
00089 if (!sin)
00090 return EAI_FAIL;
00091 sin->sin_family = AF_INET;
00092
00093 if (node) {
00094 if (!ff_inet_aton(node, &sin->sin_addr)) {
00095 if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
00096 av_free(sin);
00097 return EAI_FAIL;
00098 }
00099 h = gethostbyname(node);
00100 if (!h) {
00101 av_free(sin);
00102 return EAI_FAIL;
00103 }
00104 memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
00105 }
00106 } else {
00107 if (hints && (hints->ai_flags & AI_PASSIVE)) {
00108 sin->sin_addr.s_addr = INADDR_ANY;
00109 } else
00110 sin->sin_addr.s_addr = INADDR_LOOPBACK;
00111 }
00112
00113
00114
00115 if (service)
00116 sin->sin_port = htons(atoi(service));
00117
00118 ai = av_mallocz(sizeof(struct addrinfo));
00119 if (!ai) {
00120 av_free(sin);
00121 return EAI_FAIL;
00122 }
00123
00124 *res = ai;
00125 ai->ai_family = AF_INET;
00126 ai->ai_socktype = hints ? hints->ai_socktype : 0;
00127 switch (ai->ai_socktype) {
00128 case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break;
00129 case SOCK_DGRAM: ai->ai_protocol = IPPROTO_UDP; break;
00130 default: ai->ai_protocol = 0; break;
00131 }
00132
00133 ai->ai_addr = (struct sockaddr *)sin;
00134 ai->ai_addrlen = sizeof(struct sockaddr_in);
00135 if (hints && (hints->ai_flags & AI_CANONNAME))
00136 ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
00137
00138 ai->ai_next = NULL;
00139 return 0;
00140 }
00141
00142 void ff_freeaddrinfo(struct addrinfo *res)
00143 {
00144 #if HAVE_WINSOCK2_H
00145 void (WSAAPI *win_freeaddrinfo)(struct addrinfo *res);
00146 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00147 win_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *res))
00148 GetProcAddress(ws2mod, "freeaddrinfo");
00149 if (win_freeaddrinfo) {
00150 win_freeaddrinfo(res);
00151 return;
00152 }
00153 #endif
00154
00155 av_free(res->ai_canonname);
00156 av_free(res->ai_addr);
00157 av_free(res);
00158 }
00159
00160 int ff_getnameinfo(const struct sockaddr *sa, int salen,
00161 char *host, int hostlen,
00162 char *serv, int servlen, int flags)
00163 {
00164 const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
00165
00166 #if HAVE_WINSOCK2_H
00167 int (WSAAPI *win_getnameinfo)(const struct sockaddr *sa, socklen_t salen,
00168 char *host, DWORD hostlen,
00169 char *serv, DWORD servlen, int flags);
00170 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00171 win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo");
00172 if (win_getnameinfo)
00173 return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
00174 #endif
00175
00176 if (sa->sa_family != AF_INET)
00177 return EAI_FAMILY;
00178 if (!host && !serv)
00179 return EAI_NONAME;
00180
00181 if (host && hostlen > 0) {
00182 struct hostent *ent = NULL;
00183 uint32_t a;
00184 if (!(flags & NI_NUMERICHOST))
00185 ent = gethostbyaddr((const char *)&sin->sin_addr,
00186 sizeof(sin->sin_addr), AF_INET);
00187
00188 if (ent) {
00189 snprintf(host, hostlen, "%s", ent->h_name);
00190 } else if (flags & NI_NAMERQD) {
00191 return EAI_NONAME;
00192 } else {
00193 a = ntohl(sin->sin_addr.s_addr);
00194 snprintf(host, hostlen, "%d.%d.%d.%d",
00195 ((a >> 24) & 0xff), ((a >> 16) & 0xff),
00196 ((a >> 8) & 0xff), ( a & 0xff));
00197 }
00198 }
00199
00200 if (serv && servlen > 0) {
00201 struct servent *ent = NULL;
00202 if (!(flags & NI_NUMERICSERV))
00203 ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp");
00204
00205 if (ent) {
00206 snprintf(serv, servlen, "%s", ent->s_name);
00207 } else
00208 snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
00209 }
00210
00211 return 0;
00212 }
00213
00214 const char *ff_gai_strerror(int ecode)
00215 {
00216 switch(ecode) {
00217 case EAI_FAIL : return "A non-recoverable error occurred";
00218 case EAI_FAMILY : return "The address family was not recognized or the address length was invalid for the specified family";
00219 case EAI_NONAME : return "The name does not resolve for the supplied parameters";
00220 }
00221
00222 return "Unknown error";
00223 }
00224 #endif
00225
00226 int ff_socket_nonblock(int socket, int enable)
00227 {
00228 #if HAVE_WINSOCK2_H
00229 return ioctlsocket(socket, FIONBIO, &enable);
00230 #else
00231 if (enable)
00232 return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
00233 else
00234 return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
00235 #endif
00236 }
00237
00238 #if !HAVE_POLL_H
00239 int poll(struct pollfd *fds, nfds_t numfds, int timeout)
00240 {
00241 fd_set read_set;
00242 fd_set write_set;
00243 fd_set exception_set;
00244 nfds_t i;
00245 int n;
00246 int rc;
00247
00248 #if HAVE_WINSOCK2_H
00249 if (numfds >= FD_SETSIZE) {
00250 errno = EINVAL;
00251 return -1;
00252 }
00253 #endif
00254
00255 FD_ZERO(&read_set);
00256 FD_ZERO(&write_set);
00257 FD_ZERO(&exception_set);
00258
00259 n = -1;
00260 for(i = 0; i < numfds; i++) {
00261 if (fds[i].fd < 0)
00262 continue;
00263 #if !HAVE_WINSOCK2_H
00264 if (fds[i].fd >= FD_SETSIZE) {
00265 errno = EINVAL;
00266 return -1;
00267 }
00268 #endif
00269
00270 if (fds[i].events & POLLIN) FD_SET(fds[i].fd, &read_set);
00271 if (fds[i].events & POLLOUT) FD_SET(fds[i].fd, &write_set);
00272 if (fds[i].events & POLLERR) FD_SET(fds[i].fd, &exception_set);
00273
00274 if (fds[i].fd > n)
00275 n = fds[i].fd;
00276 };
00277
00278 if (n == -1)
00279
00280 return 0;
00281
00282 if (timeout < 0)
00283 rc = select(n+1, &read_set, &write_set, &exception_set, NULL);
00284 else {
00285 struct timeval tv;
00286
00287 tv.tv_sec = timeout / 1000;
00288 tv.tv_usec = 1000 * (timeout % 1000);
00289 rc = select(n+1, &read_set, &write_set, &exception_set, &tv);
00290 };
00291
00292 if (rc < 0)
00293 return rc;
00294
00295 for(i = 0; i < numfds; i++) {
00296 fds[i].revents = 0;
00297
00298 if (FD_ISSET(fds[i].fd, &read_set)) fds[i].revents |= POLLIN;
00299 if (FD_ISSET(fds[i].fd, &write_set)) fds[i].revents |= POLLOUT;
00300 if (FD_ISSET(fds[i].fd, &exception_set)) fds[i].revents |= POLLERR;
00301 };
00302
00303 return rc;
00304 }
00305 #endif
00306 #endif