]> rtime.felk.cvut.cz Git - orte.git/blob - orte/liborte/sock.c
New ORTE version 0.3.0 committed
[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   wVersionRequested = MAKEWORD(2, 0);
33   return WSAStartup(wVersionRequested, &wsaData);
34 #endif
35 }
36
37 /*********************************************************************/
38 inline void
39 sock_finish(void) {
40 #if defined(SOCK_WIN)
41   WSACleanup();
42 #endif
43 }
44
45 /*********************************************************************/
46 int
47 sock_init_udp(sock_t *sock) {
48   sock->fd = socket(AF_INET, SOCK_DGRAM, 0);
49   if (sock->fd < 0) return -1;
50   return 0;
51 }
52
53 /*********************************************************************/
54 inline void
55 sock_cleanup(sock_t *sock) {
56 #if defined(SOCK_BSD)
57   close(sock->fd);
58 #elif defined(SOCK_RTLWIP)
59   close_socket_np(sock->fd);
60 #elif defined(SOCK_WIN)
61   closesocket(sock->fd);
62 #endif
63 }
64
65 /*********************************************************************/
66 inline int
67 sock_setsockopt(sock_t *sock,int level,int optname,const char *optval, int optlen) {
68   if (setsockopt(sock->fd, level, optname,(void *)optval, optlen)) {
69     sock_cleanup(sock);
70     return -1;
71   }
72   return 0;
73 }
74
75 /*********************************************************************/
76 inline int
77 sock_getsockopt(sock_t *sock,int level,int optname,char *optval, int *optlen) {
78   if (getsockopt(sock->fd, level, optname,(void *)optval, optlen)) {
79     sock_cleanup(sock);
80     return -1;
81   }
82   return 0;
83 }
84
85 /*********************************************************************/
86 int
87 sock_bind(sock_t *sock,uint16_t port) {
88   struct sockaddr_in name;
89   int size;
90
91   name.sin_family = AF_INET;
92   name.sin_port = htons(port);
93   name.sin_addr.s_addr = htonl(INADDR_ANY);
94   if (bind(sock->fd, 
95           #ifndef CONFIG_ORTE_RTL_ONETD 
96             (struct sockaddr *)
97           #endif
98           &name, sizeof(name)) < 0) {
99     sock_cleanup(sock);
100     return -1;
101   }
102   size = sizeof(name);
103   if (getsockname(sock->fd,
104          #ifndef CONFIG_ORTE_RTL_ONETD 
105            (struct sockaddr *)
106          #endif
107          &name, 
108          #ifndef CONFIG_ORTE_RTL_ONETD 
109            &size
110          #else
111            size 
112          #endif
113          ) < 0) {
114     sock_cleanup(sock);
115     return -1;
116   }
117   sock->port=ntohs(name.sin_port);
118   return 0;
119 }
120
121 /*********************************************************************/
122 inline int
123 sock_recvfrom(sock_t *sock, void *buf, int max_len,struct sockaddr_in *des,int des_len) {
124   return recvfrom(sock->fd, buf, max_len, 0,
125     #ifndef CONFIG_ORTE_RTL_ONETD 
126       (struct sockaddr*)
127     #endif
128     des,&des_len);
129 }
130
131 /*********************************************************************/
132 inline int
133 sock_sendto(sock_t *sock, void *buf, int len,struct sockaddr_in *des,int des_len) {
134   return sendto(sock->fd, buf, len, 0,
135     #ifndef CONFIG_ORTE_RTL_ONETD 
136       (struct sockaddr*)
137     #endif
138     des,des_len);
139 }
140
141 /*********************************************************************/
142 inline int
143 sock_ioctl(sock_t *sock, long cmd, unsigned long *arg) {
144   return ioctl(sock->fd, cmd, arg);
145 }
146
147 /*********************************************************************/
148 int
149 sock_get_local_interfaces(sock_t *sock,ORTEIFProp *IFProp,char *IFCount) {
150 #if defined(SOCK_BSD)
151   struct ifconf           ifc;
152   char                    buf[MAX_INTERFACES*sizeof(struct ifreq)];
153   char                    *ptr;
154
155   ifc.ifc_len = sizeof(buf);
156   ifc.ifc_buf = buf;
157   *IFCount=0;
158   if (ioctl(sock->fd, SIOCGIFCONF, &ifc) < 0) return -1;
159   for (ptr = buf; ptr < (buf + ifc.ifc_len);ptr += sizeof(struct ifreq)) {
160     struct ifreq*     ifr = (struct ifreq*) ptr;
161     struct sockaddr   addr;
162     memcpy(&addr, &ifr->ifr_addr, sizeof(addr));
163     ioctl(sock->fd, SIOCGIFFLAGS, ifr);
164     if ((ifr->ifr_flags & IFF_UP) && !(ifr->ifr_flags & IFF_LOOPBACK)) {
165       (*IFCount)++;
166       IFProp->ifFlags=ifr->ifr_flags;
167       IFProp->ipAddress=ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
168       IFProp++;
169     }
170   }
171   return 0;
172 #elif defined(SOCK_RTLWIP)
173   /* loopback iface is recognized if it has this address */
174   char ip_address [] = "127.0.0.1";
175   struct in_addr loopaddr;
176   int                     i;
177
178   *IFCount=0;
179   if (inet_aton(ip_address, &loopaddr) != 0) return -1;
180   
181   for (i = 0; i < NIC_TABLE_SIZE; i++) {
182     if (nic_table [i].nic_struct != NULL) {
183       if (nic_table[i].ipad.s_addr != loopaddr.s_addr) {
184         (*IFCount)++;
185         IFProp->ifFlags=0; //RT-Linux doesn't flags
186         IFProp->ipAddress=ntohl(nic_table[i].ipad.s_addr);
187         IFProp++;
188       }
189     }
190   }
191   return 0;
192 #elif defined(SOCK_WIN)
193   INTERFACE_INFO      InterfaceList[MAX_INTERFACES];
194   struct sockaddr_in* pAddress;
195   unsigned long       len,i;
196
197   *IFCount=0;
198   if (WSAIoctl(sock->fd,SIO_GET_INTERFACE_LIST,NULL,0,
199                InterfaceList, sizeof(InterfaceList),
200                &len, NULL, NULL)==SOCKET_ERROR) return -1;
201   len=len/sizeof(INTERFACE_INFO);
202   for(i=0;i<len;i++) {
203     long  nFlags;
204     pAddress = (struct sockaddr_in*)&(InterfaceList[i].iiAddress);
205     nFlags = InterfaceList[i].iiFlags;
206     if ((nFlags & IFF_UP) && !(nFlags & IFF_LOOPBACK)) {
207       IFProp->ifFlags=nFlags;
208       IFProp->ipAddress=ntohl(pAddress->sin_addr.s_addr);
209       IFProp++;
210       (*IFCount)++;
211     }
212   }
213   return 0;
214 #endif
215 }
216
217