2 * $Id: sock.c,v 0.0.0.1 2003/08/21
4 * DEBUG: section 6 Socket
6 * -------------------------------------------------------------------
8 * Open Real-Time Ethernet
10 * Copyright (C) 2001-2006
11 * Department of Control Engineering FEE CTU Prague, Czech Republic
12 * http://dce.felk.cvut.cz
13 * http://www.ocera.org
15 * Author: Petr Smolik petr@smoliku.cz
17 * Project Responsible: Zdenek Hanzalek
18 * --------------------------------------------------------------------
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
34 /*********************************************************************/
38 #if defined(SOCK_BSD) || defined (SOCK_RTLWIP)
40 #elif defined (SOCK_WIN)
41 WORD wVersionRequested;
43 #ifdef SOCK_WIN_PHARLAP
44 wVersionRequested = MAKEWORD(1, 1);
46 wVersionRequested = MAKEWORD(2, 0);
48 return WSAStartup(wVersionRequested, &wsaData);
52 /*********************************************************************/
61 /*********************************************************************/
63 sock_init_udp(sock_t *sock)
65 sock->fd = socket(AF_INET, SOCK_DGRAM, 0);
71 /*********************************************************************/
73 sock_cleanup(sock_t *sock)
77 #elif defined(SOCK_RTLWIP)
78 close_socket_np(sock->fd);
79 #elif defined(SOCK_WIN)
80 closesocket(sock->fd);
84 /*********************************************************************/
86 sock_setsockopt(sock_t *sock, int level, int optname, const char *optval, int optlen)
88 if (setsockopt(sock->fd, level, optname, (void *)optval, optlen)) {
95 /*********************************************************************/
97 sock_getsockopt(sock_t *sock, int level, int optname, char *optval, int *optlen)
99 if (getsockopt(sock->fd, level, optname, (void *)optval, (socklen_t *)optlen)) {
106 /*********************************************************************/
108 sock_bind(sock_t *sock, uint16_t port, IPAddress listen)
110 struct sockaddr_in name;
113 name.sin_family = AF_INET;
114 name.sin_port = htons(port);
115 name.sin_addr.s_addr = htonl(listen);
117 #ifndef CONFIG_ORTE_RTL_ONETD
120 &name, sizeof(name)) < 0) {
125 if (getsockname(sock->fd,
126 #ifndef CONFIG_ORTE_RTL_ONETD
130 #ifndef CONFIG_ORTE_RTL_ONETD
139 sock->port = ntohs(name.sin_port);
143 /*********************************************************************/
145 sock_recvfrom(sock_t *sock, void *buf, int max_len, struct sockaddr_in *des, int des_len)
147 return recvfrom(sock->fd, buf, max_len, 0,
148 #ifndef CONFIG_ORTE_RTL_ONETD
151 des, (socklen_t *)&des_len);
154 /*********************************************************************/
156 sock_sendto(sock_t *sock, void *buf, int len, struct sockaddr_in *des, int des_len)
158 return sendto(sock->fd, buf, len, 0,
159 #ifndef CONFIG_ORTE_RTL_ONETD
165 /*********************************************************************/
167 sock_ioctl(sock_t *sock, long cmd, unsigned long *arg)
169 return ioctl(sock->fd, cmd, arg);
172 /*********************************************************************/
175 #define SOCK_INTF_DEBUG(...) printf(__VA_ARGS__)
177 #define SOCK_INTF_DEBUG(...) do {; } while (0)
180 #ifdef HAVE_IFADDRS_H
182 #endif /*HAVE_IFADDRS_H*/
185 sock_get_local_interfaces(sock_t *sock, ORTEIFProp *IFProp, char *IFCount)
187 #if defined(HAVE_IFADDRS_H)
188 struct ifaddrs *ifa = NULL;
189 struct ifaddrs *ifa_it;
191 if (getifaddrs(&ifa)) {
192 SOCK_INTF_DEBUG("getifaddrs() failed\n");
196 for (ifa_it = ifa; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
197 if (ifa_it->ifa_addr == NULL) {
198 SOCK_INTF_DEBUG("interace %s without address ... skipping\n", ifa_it->ifa_name);
201 SOCK_INTF_DEBUG("interace %s SA_%d addr 0x%08lx flags 0x%08lx %s %s ... ",
203 ifa_it->ifa_addr->sa_family,
204 (unsigned long)ntohl(((struct sockaddr_in *)(ifa_it->ifa_addr))->sin_addr.s_addr),
205 (unsigned long)ifa_it->ifa_flags,
206 ifa_it->ifa_flags & IFF_UP ? "up" : "down",
207 ifa_it->ifa_flags & IFF_LOOPBACK ? "loopback" : "");
209 if (!(ifa_it->ifa_flags & IFF_UP) || (ifa_it->ifa_flags & IFF_LOOPBACK) ||
210 (ifa_it->ifa_addr->sa_family != AF_INET)) {
211 SOCK_INTF_DEBUG("skipped\n");
214 SOCK_INTF_DEBUG("used\n");
217 IFProp->ifFlags = ifa_it->ifa_flags;
218 IFProp->ipAddress = ntohl(((struct sockaddr_in *)(ifa_it->ifa_addr))->sin_addr.s_addr);
220 if (*IFCount >= MAX_INTERFACES)
226 #elif defined(SOCK_BSD)
227 #define SOCK_SIOCGIFCONF_SA_LEN_UNCONDITIONAL 1 /* seems to be required for RTEMS*/
235 ifc.ifc_len = MAX_INTERFACES*sizeof(struct ifreq);
236 if (ifc.ifc_len < 2 * 1024)
237 ifc.ifc_len = 2 * 1024;
238 ifc.ifc_buf = buf = malloc(ifc.ifc_len);
241 res = ioctl(sock->fd, SIOCGIFCONF, &ifc);
243 SOCK_INTF_DEBUG("ioctl(sock->fd, SIOCGIFCONF) failed\n");
247 SOCK_INTF_DEBUG("ioctl(sock->fd, SIOCGIFCONF) returned %d\n", res);
248 for (i = 0; i < ifc.ifc_len; i++)
249 SOCK_INTF_DEBUG(" %02x", buf[i]);
250 SOCK_INTF_DEBUG("\n");
252 SOCK_INTF_DEBUG("sizeof(struct sockaddr) %d, sizeof(struct ifreq) %d ifc.ifc_len %d\n",
253 (int)sizeof(struct sockaddr),
254 (int)sizeof(struct ifreq),
257 for (ptr = buf; ptr < (buf + ifc.ifc_len); ) {
258 struct ifreq *ifr = (struct ifreq *)ptr;
259 struct sockaddr addr;
260 size_t addr_len = sizeof(addr);
262 if (buf + ifc.ifc_len - ptr < sizeof(struct ifreq)) {
263 SOCK_INTF_DEBUG("truncated ifreq entry\n");
267 memcpy(&addr, &ifr->ifr_addr, sizeof(addr));
269 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
270 addr_len = addr.sa_len;
271 if ((addr_len > sizeof(addr)) || SOCK_SIOCGIFCONF_SA_LEN_UNCONDITIONAL)
272 ptr = addr_len + (char *)&ifr->ifr_addr;
274 #endif /*HAVE_STRUCT_SOCKADDR_SA_LEN*/
275 ptr += sizeof(struct ifreq);
277 res = ioctl(sock->fd, SIOCGIFFLAGS, ifr);
279 SOCK_INTF_DEBUG("interace %s SA_%d addr 0x%08lx len %d flags 0x%08lx %s %s SIOCGIFFLAGS res %d\n",
282 (unsigned long)ntohl(((struct sockaddr_in *)&addr)->sin_addr.s_addr),
284 (unsigned long)ifr->ifr_flags,
285 ifr->ifr_flags & IFF_UP ? "up" : "down",
286 ifr->ifr_flags & IFF_LOOPBACK ? "loopback" : "",
289 if ((ifr->ifr_flags & IFF_UP) && !(ifr->ifr_flags & IFF_LOOPBACK) &&
290 (addr.sa_family == AF_INET)) {
292 IFProp->ifFlags = ifr->ifr_flags;
293 IFProp->ipAddress = ntohl(((struct sockaddr_in *)&addr)->sin_addr.s_addr);
295 if (*IFCount >= MAX_INTERFACES)
301 #elif defined(SOCK_RTLWIP)
302 /* loopback iface is recognized if it has this address */
303 char ip_address[] = "127.0.0.1";
304 struct in_addr loopaddr;
308 if (inet_aton(ip_address, &loopaddr) != 0)
311 for (i = 0; i < NIC_TABLE_SIZE; i++) {
312 if (nic_table[i].nic_struct != NULL) {
313 if (nic_table[i].ipad.s_addr != loopaddr.s_addr) {
315 IFProp->ifFlags = 0; //RT-Linux doesn't flags
316 IFProp->ipAddress = ntohl(nic_table[i].ipad.s_addr);
322 #elif defined(SOCK_WIN_PHARLAP)
327 EK_TCPSLIPSTATUS slip;
333 while (hDev = EtsTCPIterateDeviceList(hDev)) {
334 pCfg = EtsTCPGetDeviceCfg(hDev);
336 if (pCfg->nwIPAddress == 0x0100007F) // 127.0.0.1 localhost
339 status.eth.length = sizeof(EK_TCPETHSTATUS);
340 EtsTCPGetDeviceStatus(hDev, &status);
341 if (status.eth.DevStatus.Flags & ETS_TCP_DEV_ONLINE) {
342 IFProp->ifFlags = IFF_UP;
343 IFProp->ipAddress = ntohl(pCfg->nwIPAddress);
348 #elif defined(SOCK_WIN)
349 INTERFACE_INFO InterfaceList[MAX_INTERFACES];
350 struct sockaddr_in *pAddress;
351 unsigned long len, i;
354 if (WSAIoctl(sock->fd, SIO_GET_INTERFACE_LIST, NULL, 0,
355 InterfaceList, sizeof(InterfaceList),
356 &len, NULL, NULL) == SOCKET_ERROR)
358 len = len/sizeof(INTERFACE_INFO);
359 for (i = 0; i < len; i++) {
361 pAddress = (struct sockaddr_in *)&(InterfaceList[i].iiAddress);
362 nFlags = InterfaceList[i].iiFlags;
363 if ((nFlags & IFF_UP) && !(nFlags & IFF_LOOPBACK)) {
364 IFProp->ifFlags = nFlags;
365 IFProp->ipAddress = ntohl(pAddress->sin_addr.s_addr);
371 #endif /* if defined(HAVE_IFADDRS_H) */