]> rtime.felk.cvut.cz Git - orte.git/blob - orte/liborte/sock.c
upgrade to new version 0.3.1
[orte.git] / orte / liborte / sock.c
1 /*
2  *  $Id: sock.c,v 0.0.0.1               2003/08/21 
3  *
4  *  DEBUG:  section 6                   Socket 
5  *  AUTHOR: Petr Smolik                 petr.smolik@wo.cz
6  *
7  *  ORTE - OCERA Real-Time Ethernet     http://www.ocera.org/
8  *  --------------------------------------------------------------------
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  */ 
21
22 #include "orte_all.h"
23
24 /*********************************************************************/
25 int
26 sock_start(void) {
27 #if defined(SOCK_BSD) || defined (SOCK_RTLWIP)
28   return 0;
29 #elif defined (SOCK_WIN)
30   WORD wVersionRequested;
31   WSADATA wsaData;
32   #ifdef SOCK_WIN_PHARLAP
33     wVersionRequested = MAKEWORD(1, 1);
34   #else
35     wVersionRequested = MAKEWORD(2, 0);
36   #endif
37   return WSAStartup(wVersionRequested, &wsaData);
38 #endif
39 }
40
41 /*********************************************************************/
42 inline void
43 sock_finish(void) {
44 #if defined(SOCK_WIN)
45   WSACleanup();
46 #endif
47 }
48
49 /*********************************************************************/
50 int
51 sock_init_udp(sock_t *sock) {
52   sock->fd = socket(AF_INET, SOCK_DGRAM, 0);
53   if (sock->fd < 0) return -1;
54   return 0;
55 }
56
57 /*********************************************************************/
58 inline void
59 sock_cleanup(sock_t *sock) {
60 #if defined(SOCK_BSD)
61   close(sock->fd);
62 #elif defined(SOCK_RTLWIP)
63   close_socket_np(sock->fd);
64 #elif defined(SOCK_WIN)
65   closesocket(sock->fd);
66 #endif
67 }
68
69 /*********************************************************************/
70 inline int
71 sock_setsockopt(sock_t *sock,int level,int optname,const char *optval, int optlen) {
72   if (setsockopt(sock->fd, level, optname,(void *)optval, optlen)) {
73     sock_cleanup(sock);
74     return -1;
75   }
76   return 0;
77 }
78
79 /*********************************************************************/
80 inline int
81 sock_getsockopt(sock_t *sock,int level,int optname,char *optval, int *optlen) {
82   if (getsockopt(sock->fd, level, optname,(void *)optval, optlen)) {
83     sock_cleanup(sock);
84     return -1;
85   }
86   return 0;
87 }
88
89 /*********************************************************************/
90 int
91 sock_bind(sock_t *sock,uint16_t port) {
92   struct sockaddr_in name;
93   int size;
94
95   name.sin_family = AF_INET;
96   name.sin_port = htons(port);
97   name.sin_addr.s_addr = htonl(INADDR_ANY);
98   if (bind(sock->fd, 
99           #ifndef CONFIG_ORTE_RTL_ONETD 
100             (struct sockaddr *)
101           #endif
102           &name, sizeof(name)) < 0) {
103     sock_cleanup(sock);
104     return -1;
105   }
106   size = sizeof(name);
107   if (getsockname(sock->fd,
108          #ifndef CONFIG_ORTE_RTL_ONETD 
109            (struct sockaddr *)
110          #endif
111          &name, 
112          #ifndef CONFIG_ORTE_RTL_ONETD 
113            &size
114          #else
115            size 
116          #endif
117          ) < 0) {
118     sock_cleanup(sock);
119     return -1;
120   }
121   sock->port=ntohs(name.sin_port);
122   return 0;
123 }
124
125 /*********************************************************************/
126 inline int
127 sock_recvfrom(sock_t *sock, void *buf, int max_len,struct sockaddr_in *des,int des_len) {
128   return recvfrom(sock->fd, buf, max_len, 0,
129     #ifndef CONFIG_ORTE_RTL_ONETD 
130       (struct sockaddr*)
131     #endif
132     des,&des_len);
133 }
134
135 /*********************************************************************/
136 inline int
137 sock_sendto(sock_t *sock, void *buf, int len,struct sockaddr_in *des,int des_len) {
138   return sendto(sock->fd, buf, len, 0,
139     #ifndef CONFIG_ORTE_RTL_ONETD 
140       (struct sockaddr*)
141     #endif
142     des,des_len);
143 }
144
145 /*********************************************************************/
146 inline int
147 sock_ioctl(sock_t *sock, long cmd, unsigned long *arg) {
148   return ioctl(sock->fd, cmd, arg);
149 }
150
151 /*********************************************************************/
152 int
153 sock_get_local_interfaces(sock_t *sock,ORTEIFProp *IFProp,char *IFCount) {
154 #if defined(SOCK_BSD)
155   struct ifconf           ifc;
156   char                    buf[MAX_INTERFACES*sizeof(struct ifreq)];
157   char                    *ptr;
158
159   ifc.ifc_len = sizeof(buf);
160   ifc.ifc_buf = buf;
161   *IFCount=0;
162   if (ioctl(sock->fd, SIOCGIFCONF, &ifc) < 0) return -1;
163   for (ptr = buf; ptr < (buf + ifc.ifc_len);ptr += sizeof(struct ifreq)) {
164     struct ifreq*     ifr = (struct ifreq*) ptr;
165     struct sockaddr   addr;
166     memcpy(&addr, &ifr->ifr_addr, sizeof(addr));
167     ioctl(sock->fd, SIOCGIFFLAGS, ifr);
168     if ((ifr->ifr_flags & IFF_UP) && !(ifr->ifr_flags & IFF_LOOPBACK)) {
169       (*IFCount)++;
170       IFProp->ifFlags=ifr->ifr_flags;
171       IFProp->ipAddress=ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
172       IFProp++;
173     }
174   }
175   return 0;
176 #elif defined(SOCK_RTLWIP)
177   /* loopback iface is recognized if it has this address */
178   char ip_address [] = "127.0.0.1";
179   struct in_addr loopaddr;
180   int i;
181
182   *IFCount=0;
183   if (inet_aton(ip_address, &loopaddr) != 0) return -1;
184   
185   for (i = 0; i < NIC_TABLE_SIZE; i++) {
186     if (nic_table [i].nic_struct != NULL) {
187       if (nic_table[i].ipad.s_addr != loopaddr.s_addr) {
188         (*IFCount)++;
189         IFProp->ifFlags=0; //RT-Linux doesn't flags
190         IFProp->ipAddress=ntohl(nic_table[i].ipad.s_addr);
191         IFProp++;
192       }
193     }
194   }
195   return 0;
196 #elif defined(SOCK_WIN_PHARLAP)
197   DEVHANDLE hDev;
198   EK_TCPIPCFG *pCfg;
199   union {
200     EK_TCPETHSTATUS eth;
201     EK_TCPSLIPSTATUS slip;
202     EK_TCPPPPSTATUS ppp;
203   } status;
204   *IFCount = 0;
205   hDev = NULL;
206
207   while (hDev = EtsTCPIterateDeviceList(hDev)) {
208     pCfg = EtsTCPGetDeviceCfg(hDev);
209
210     if (pCfg->nwIPAddress == 0x0100007F) // 127.0.0.1 localhost
211       continue;
212
213     status.eth.length = sizeof(EK_TCPETHSTATUS);
214     EtsTCPGetDeviceStatus(hDev, &status);
215     if (status.eth.DevStatus.Flags & ETS_TCP_DEV_ONLINE) {
216       IFProp->ifFlags = IFF_UP;
217       IFProp->ipAddress = ntohl(pCfg->nwIPAddress);
218       (*IFCount)++;
219     }
220   }
221   return 0;
222 #elif defined(SOCK_WIN)
223   INTERFACE_INFO      InterfaceList[MAX_INTERFACES];
224   struct sockaddr_in* pAddress;
225   unsigned long       len,i;
226
227   *IFCount=0;
228   if (WSAIoctl(sock->fd,SIO_GET_INTERFACE_LIST,NULL,0,
229                InterfaceList, sizeof(InterfaceList),
230                &len, NULL, NULL)==SOCKET_ERROR) return -1;
231   len=len/sizeof(INTERFACE_INFO);
232   for(i=0;i<len;i++) {
233     long  nFlags;
234     pAddress = (struct sockaddr_in*)&(InterfaceList[i].iiAddress);
235     nFlags = InterfaceList[i].iiFlags;
236     if ((nFlags & IFF_UP) && !(nFlags & IFF_LOOPBACK)) {
237       IFProp->ifFlags=nFlags;
238       IFProp->ipAddress=ntohl(pAddress->sin_addr.s_addr);
239       IFProp++;
240       (*IFCount)++;
241     }
242   }
243   return 0;
244 #endif
245 }
246
247