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.smolik@wo.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 /*********************************************************************/
37 #if defined(SOCK_BSD) || defined (SOCK_RTLWIP)
39 #elif defined (SOCK_WIN)
40 WORD wVersionRequested;
42 #ifdef SOCK_WIN_PHARLAP
43 wVersionRequested = MAKEWORD(1, 1);
45 wVersionRequested = MAKEWORD(2, 0);
47 return WSAStartup(wVersionRequested, &wsaData);
51 /*********************************************************************/
59 /*********************************************************************/
61 sock_init_udp(sock_t *sock) {
62 sock->fd = socket(AF_INET, SOCK_DGRAM, 0);
63 if (sock->fd < 0) return -1;
67 /*********************************************************************/
69 sock_cleanup(sock_t *sock) {
72 #elif defined(SOCK_RTLWIP)
73 close_socket_np(sock->fd);
74 #elif defined(SOCK_WIN)
75 closesocket(sock->fd);
79 /*********************************************************************/
81 sock_setsockopt(sock_t *sock,int level,int optname,const char *optval, int optlen) {
82 if (setsockopt(sock->fd, level, optname,(void *)optval, optlen)) {
89 /*********************************************************************/
91 sock_getsockopt(sock_t *sock,int level,int optname,char *optval, int *optlen) {
92 if (getsockopt(sock->fd, level, optname,(void *)optval, (socklen_t *)optlen)) {
99 /*********************************************************************/
101 sock_bind(sock_t *sock,uint16_t port, IPAddress listen) {
102 struct sockaddr_in name;
105 name.sin_family = AF_INET;
106 name.sin_port = htons(port);
107 name.sin_addr.s_addr = htonl(listen);
109 #ifndef CONFIG_ORTE_RTL_ONETD
112 &name, sizeof(name)) < 0) {
117 if (getsockname(sock->fd,
118 #ifndef CONFIG_ORTE_RTL_ONETD
122 #ifndef CONFIG_ORTE_RTL_ONETD
131 sock->port=ntohs(name.sin_port);
135 /*********************************************************************/
137 sock_recvfrom(sock_t *sock, void *buf, int max_len,struct sockaddr_in *des,int des_len) {
138 return recvfrom(sock->fd, buf, max_len, 0,
139 #ifndef CONFIG_ORTE_RTL_ONETD
142 des,(socklen_t *)&des_len);
145 /*********************************************************************/
147 sock_sendto(sock_t *sock, void *buf, int len,struct sockaddr_in *des,int des_len) {
148 return sendto(sock->fd, buf, len, 0,
149 #ifndef CONFIG_ORTE_RTL_ONETD
155 /*********************************************************************/
157 sock_ioctl(sock_t *sock, long cmd, unsigned long *arg) {
158 return ioctl(sock->fd, cmd, arg);
161 /*********************************************************************/
164 #define SOCK_INTF_DEBUG(...) printf( __VA_ARGS__ )
166 #define SOCK_INTF_DEBUG(...) do {;} while(0)
169 #ifdef HAVE_IFADDRS_H
171 #endif /*HAVE_IFADDRS_H*/
174 sock_get_local_interfaces(sock_t *sock,ORTEIFProp *IFProp,char *IFCount) {
175 #if defined(HAVE_IFADDRS_H)
176 struct ifaddrs *ifa = NULL;
177 struct ifaddrs *ifa_it;
179 if (getifaddrs(&ifa)) {
180 SOCK_INTF_DEBUG("getifaddrs() failed\n");
184 for (ifa_it = ifa; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
185 if (ifa_it->ifa_addr == NULL) {
186 SOCK_INTF_DEBUG("interace %s without address ... skipping\n", ifa_it->ifa_name);
189 SOCK_INTF_DEBUG("interace %s SA_%d addr 0x%08lx flags 0x%08lx %s %s ... ",
191 ifa_it->ifa_addr->sa_family,
192 (unsigned long)ntohl(((struct sockaddr_in*)(ifa_it->ifa_addr))->sin_addr.s_addr),
193 (unsigned long)ifa_it->ifa_flags,
194 ifa_it->ifa_flags & IFF_UP? "up":"down",
195 ifa_it->ifa_flags & IFF_LOOPBACK? "loopback":"");
197 if (!(ifa_it->ifa_flags & IFF_UP) || (ifa_it->ifa_flags & IFF_LOOPBACK) ||
198 (ifa_it->ifa_addr->sa_family != AF_INET)) {
199 SOCK_INTF_DEBUG("skipped\n");
202 SOCK_INTF_DEBUG("used\n");
205 IFProp->ifFlags=ifa_it->ifa_flags;
206 IFProp->ipAddress=ntohl(((struct sockaddr_in*)(ifa_it->ifa_addr))->sin_addr.s_addr);
208 if(*IFCount >= MAX_INTERFACES)
214 #elif defined(SOCK_BSD)
215 #define SOCK_SIOCGIFCONF_SA_LEN_UNCONDITIONAL 1 /* seems to be required for RTEMS*/
223 ifc.ifc_len = MAX_INTERFACES*sizeof(struct ifreq);
224 if (ifc.ifc_len < 2 * 1024)
225 ifc.ifc_len = 2 * 1024;
226 ifc.ifc_buf = buf = malloc(ifc.ifc_len);
229 res = ioctl(sock->fd, SIOCGIFCONF, &ifc);
231 SOCK_INTF_DEBUG("ioctl(sock->fd, SIOCGIFCONF) failed\n");
235 SOCK_INTF_DEBUG("ioctl(sock->fd, SIOCGIFCONF) returned %d\n", res);
236 for(i=0; i < ifc.ifc_len; i++)
237 SOCK_INTF_DEBUG(" %02x", buf[i]);
238 SOCK_INTF_DEBUG("\n");
240 SOCK_INTF_DEBUG("sizeof(struct sockaddr) %d, sizeof(struct ifreq) %d ifc.ifc_len %d\n",
241 (int)sizeof(struct sockaddr),
242 (int)sizeof(struct ifreq),
245 for (ptr = buf; ptr < (buf + ifc.ifc_len);) {
246 struct ifreq* ifr = (struct ifreq*) ptr;
247 struct sockaddr addr;
248 size_t addr_len = sizeof(addr);
250 if(buf + ifc.ifc_len - ptr < sizeof(struct ifreq)) {
251 SOCK_INTF_DEBUG("truncated ifreq entry\n");
255 memcpy(&addr, &ifr->ifr_addr, sizeof(addr));
257 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
258 addr_len = addr.sa_len;
259 if ((addr_len > sizeof(addr)) || SOCK_SIOCGIFCONF_SA_LEN_UNCONDITIONAL)
260 ptr = addr_len + (char*)&ifr->ifr_addr;
262 #endif /*HAVE_STRUCT_SOCKADDR_SA_LEN*/
263 ptr += sizeof(struct ifreq);
265 res = ioctl(sock->fd, SIOCGIFFLAGS, ifr);
267 SOCK_INTF_DEBUG("interace %s SA_%d addr 0x%08lx len %d flags 0x%08lx %s %s SIOCGIFFLAGS res %d\n",
270 (unsigned long)ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr),
272 (unsigned long)ifr->ifr_flags,
273 ifr->ifr_flags & IFF_UP? "up":"down",
274 ifr->ifr_flags & IFF_LOOPBACK? "loopback":"",
277 if ((ifr->ifr_flags & IFF_UP) && !(ifr->ifr_flags & IFF_LOOPBACK) &&
278 (addr.sa_family == AF_INET)) {
280 IFProp->ifFlags=ifr->ifr_flags;
281 IFProp->ipAddress=ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
283 if(*IFCount >= MAX_INTERFACES)
289 #elif defined(SOCK_RTLWIP)
290 /* loopback iface is recognized if it has this address */
291 char ip_address [] = "127.0.0.1";
292 struct in_addr loopaddr;
296 if (inet_aton(ip_address, &loopaddr) != 0) return -1;
298 for (i = 0; i < NIC_TABLE_SIZE; i++) {
299 if (nic_table [i].nic_struct != NULL) {
300 if (nic_table[i].ipad.s_addr != loopaddr.s_addr) {
302 IFProp->ifFlags=0; //RT-Linux doesn't flags
303 IFProp->ipAddress=ntohl(nic_table[i].ipad.s_addr);
309 #elif defined(SOCK_WIN_PHARLAP)
314 EK_TCPSLIPSTATUS slip;
320 while (hDev = EtsTCPIterateDeviceList(hDev)) {
321 pCfg = EtsTCPGetDeviceCfg(hDev);
323 if (pCfg->nwIPAddress == 0x0100007F) // 127.0.0.1 localhost
326 status.eth.length = sizeof(EK_TCPETHSTATUS);
327 EtsTCPGetDeviceStatus(hDev, &status);
328 if (status.eth.DevStatus.Flags & ETS_TCP_DEV_ONLINE) {
329 IFProp->ifFlags = IFF_UP;
330 IFProp->ipAddress = ntohl(pCfg->nwIPAddress);
335 #elif defined(SOCK_WIN)
336 INTERFACE_INFO InterfaceList[MAX_INTERFACES];
337 struct sockaddr_in* pAddress;
341 if (WSAIoctl(sock->fd,SIO_GET_INTERFACE_LIST,NULL,0,
342 InterfaceList, sizeof(InterfaceList),
343 &len, NULL, NULL)==SOCKET_ERROR) return -1;
344 len=len/sizeof(INTERFACE_INFO);
347 pAddress = (struct sockaddr_in*)&(InterfaceList[i].iiAddress);
348 nFlags = InterfaceList[i].iiFlags;
349 if ((nFlags & IFF_UP) && !(nFlags & IFF_LOOPBACK)) {
350 IFProp->ifFlags=nFlags;
351 IFProp->ipAddress=ntohl(pAddress->sin_addr.s_addr);