Allow IPv6 address entry in tools>ping - Loosens valid character check
[tomato/davidwu.git] / release / src / router / shared / UdpLib.c
blobd8d8d75f490ec01cc68f7f7022b660330996bbd1
1 /*
2 * hostapd / Wi-Fi Simple Configuration
3 * Code copied from Intel SDK
4 * Copyright (C) 2008, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 * $Id: UdpLib.c,v 1.7 2008/05/15 09:10:57 Exp $
12 * Copyright (c) 2005 Intel Corporation. All rights reserved.
13 * Contact Information: Harsha Hegde <harsha.hegde@intel.com>
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
19 * Alternatively, this software may be distributed under the terms of BSD
20 * license.
22 * See README, README_WSC and COPYING for more details.
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <unistd.h>
29 #include <errno.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
35 /* Linux specific headers */
36 #if defined(linux) || defined(__ECOS)
37 #include <sys/time.h>
38 #endif /* linux */
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #include <UdpLib.h>
44 /* Comment out the next line if debug strings are not needed */
45 /* #define U_DEBUG */
47 void DEBUGF(char *, ...);
51 * udp_open()
53 * This function opens a UDP socket and returns the socket to the calling
54 * application. The application will use this socket in any subsequent calls.
56 * Returns socket handle on success or -1 if there is an error.
58 int udp_open()
60 int new_sock; /* temporary socket handle */
61 #ifdef _WIN32_REAL
62 int retval;
63 WSADATA wsa_data;
64 #endif // _WIN32_REAL
66 DEBUGF("Entered udp_open\n");
68 #ifdef _WIN32_REAL
69 retval = WSAStartup(MAKEWORD(2, 0), &wsa_data);
70 if (retval != 0)
72 DEBUGF("WSAStartup call failed.\n");
73 return -1;
75 #endif /* _WIN32_REAL */
77 /* create INTERNET, udp datagram socket */
78 new_sock = (int) socket(AF_INET, SOCK_DGRAM, 0);
80 if (new_sock < 0) {
81 DEBUGF("socket call failed.\n");
82 return -1;
85 DEBUGF("Socket open successful, sd: %d\n", new_sock);
87 return new_sock;
92 * udp_bind(int fd, int portno)
94 * This call is used typically by the server application to establish a
95 * well known port.
97 * Returns 1 if succeeds and returns -1 in case of an error.
99 int udp_bind(int fd, int portno)
101 char *p;
102 struct sockaddr_in binder;
104 DEBUGF("Entered udp_bind\n");
106 binder.sin_family = AF_INET;
107 if ((p = getenv("UDP_BIND_IP")) && *p)
108 binder.sin_addr.s_addr = inet_addr(p);
109 else
110 binder.sin_addr.s_addr = INADDR_ANY;
111 binder.sin_port = htons(portno);
113 /* bind protocol to socket */
114 if (bind(fd, (struct sockaddr *)&binder, sizeof(binder)))
116 DEBUGF("bind call for socket [%d] failed.\n", fd);
117 return -1;
120 DEBUGF("Binding successful for socket [%d]\n", fd);
122 return 1;
127 * udp_close(int fd)
129 * Closes a UDP session. Closes the socket and returns.
131 void udp_close(int fd)
133 DEBUGF("Entered udp_close\n");
135 #ifdef _WIN32_REAL
136 WSACleanup();
137 closesocket(fd);
138 #endif // _WIN32_REAL
140 #if defined(__linux__) || defined(__ECOS)
141 close(fd);
142 #endif
144 return;
149 * udp_write(int fd, char * buf, int len, struct sockaddr_in * to)
151 * This function is called by the application to send data.
152 * fd - socket handle
153 * buf - data buffer
154 * len - byte count of data in buf
155 * to - socket address structure that contains remote ip address and port
156 * where the data is to be sent
158 * Returns bytesSent if succeeded. If there is an error -1 is returned
160 int udp_write(int fd, char * buf, int len, struct sockaddr_in * to)
162 int bytes_sent;
164 DEBUGF("Entered udp_write: len %d\n", len);
165 bytes_sent = sendto(fd, buf, len, 0,
166 (struct sockaddr *) to,
167 sizeof(struct sockaddr_in));
168 if (bytes_sent < 0)
170 DEBUGF("sendto on socket %d failed\n", fd);
171 return -1;
173 return bytes_sent;
178 * udp_read(int fd, char * buf, int len, struct sockaddr_in * from)
180 * This function is called by the application to receive data.
181 * fd - socket handle
182 * buf - data buffer in which the received data will be put
183 * len - size of buf in bytes
184 * from - socket address structure that contains remote ip address and port
185 * from where the data is received
187 * Returns bytes received if succeeded. If there is an error -1 is returned
189 int udp_read(int fd, char * buf, int len, struct sockaddr_in * from)
191 int bytes_recd = 0;
192 unsigned int fromlen = 0;
193 fd_set fdvar;
194 int sel_ret;
196 DEBUGF("Entered udp_read\n");
198 FD_ZERO(&fdvar);
199 /* we have to wait for only one descriptor */
200 FD_SET(fd, &fdvar);
202 sel_ret = select(fd + 1, &fdvar, (fd_set *) 0, (fd_set *) 0, NULL);
204 /* if select returns negative value, system error */
205 if (sel_ret < 0)
207 DEBUGF("select call failed; system error\n");
208 return -1;
211 /* Otherwise Read notification might has come, since we are
212 waiting for only one fd we need not check the bit. Go ahead
213 and read the packet
215 fromlen = sizeof(struct sockaddr_in);
216 bytes_recd = recvfrom(fd, buf, len, 0,
217 (struct sockaddr *)from, &fromlen);
218 if (bytes_recd < 0)
220 DEBUGF("recvfrom on socket %d failed\n", fd);
221 return -1;
224 DEBUGF("Read %d bytes\n", bytes_recd);
226 return bytes_recd;
230 * udp_read_timed(int fd, char * buf, int len,
231 * struct sockaddr_in * from, int timeout)
233 * This function is called by the application to receive data.
234 * fd - socket handle
235 * buf - data buffer in which the received data will be put
236 * len - size of buf in bytes
237 * from - socket address structure that contains remote ip address and port
238 * from where the data is received
239 * timeout - wait time in seconds
241 * Returns bytes received if succeeded. If there is an error -1 is returned
244 int udp_read_timed(int fd, char * buf, int len,
245 struct sockaddr_in * from, int timeout)
247 int bytes_recd = 0;
248 unsigned int fromlen = 0;
249 fd_set fdvar;
250 int sel_ret;
251 struct timeval tv;
253 DEBUGF("Entered udp_read\n");
255 tv.tv_sec = timeout;
256 tv.tv_usec = 0;
258 FD_ZERO(&fdvar);
259 /* we have to wait for only one descriptor */
260 FD_SET(fd, &fdvar);
261 sel_ret = select(fd + 1, &fdvar, (fd_set *) 0, (fd_set *) 0, &tv);
262 /* if select returns negative value, system error */
263 if (sel_ret < 0)
265 DEBUGF("select call failed; system error\n");
266 return -1;
268 else if (sel_ret == 0)
270 DEBUGF("select call timed out\n");
271 return -1;
274 /* Otherwise Read notification might has come, since we are
275 waiting for only one fd we need not check the bit. Go ahead
276 and read the packet
278 fromlen = sizeof(struct sockaddr_in);
279 bytes_recd = recvfrom(fd, buf, len, 0,
280 (struct sockaddr *)from, &fromlen);
281 if (bytes_recd < 0)
283 DEBUGF("recvfrom on socket %d failed\n", fd);
284 return -1;
287 DEBUGF("Read %d bytes\n", bytes_recd);
289 return bytes_recd;
292 void DEBUGF(char * strFormat, ...)
294 #ifdef U_DEBUG
295 char szTraceMsg[1000];
296 va_list lpArgv;
298 va_start(lpArgv, strFormat);
299 vsprintf(szTraceMsg, strFormat, lpArgv);
300 va_end(lpArgv);
302 fprintf(stdout, "UdpLib: %s", szTraceMsg);
303 #endif