etc/services - sync with NetBSD-8
[minix.git] / minix / lib / libc / sys / socket.c
blobce2352a2bec7a09a2a7c39839b74db75a49d69e6
1 #include <sys/cdefs.h>
2 #include "namespace.h"
3 #include <lib.h>
5 #ifdef __weak_alias
6 __weak_alias(socket, __socket30)
7 #endif
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <signal.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <sys/socket.h>
17 #include <sys/ioctl.h>
18 #include <sys/ioc_net.h>
19 #include <net/hton.h>
20 #include <net/gen/in.h>
21 #include <net/gen/ether.h>
22 #include <net/gen/eth_hdr.h>
23 #include <net/gen/eth_io.h>
24 #include <net/gen/ip_hdr.h>
25 #include <net/gen/ip_io.h>
26 #include <net/gen/udp.h>
27 #include <net/gen/udp_hdr.h>
28 #include <net/gen/udp_io.h>
29 #include <net/gen/dhcp.h>
31 #include <net/netlib.h>
32 #include <netinet/in.h>
34 #define DEBUG 0
36 static int _tcp_socket(int type, int protocol);
37 static int _udp_socket(int type, int protocol);
38 static int _uds_socket(int type, int protocol);
39 static int _raw_socket(int type, int protocol);
40 static void _socket_flags(int type, int *result);
43 * Create a socket.
45 static int
46 __socket(int domain, int type, int protocol)
48 message m;
50 memset(&m, 0, sizeof(m));
51 m.m_lc_vfs_socket.domain = domain;
52 m.m_lc_vfs_socket.type = type;
53 m.m_lc_vfs_socket.protocol = protocol;
55 return _syscall(VFS_PROC_NR, VFS_SOCKET, &m);
58 int socket(int domain, int type, int protocol)
60 int r, sock_type;
62 r = __socket(domain, type, protocol);
63 if (r != -1 || (errno != EAFNOSUPPORT && errno != ENOSYS))
64 return r;
66 sock_type = type & ~SOCK_FLAGS_MASK;
68 #if DEBUG
69 fprintf(stderr, "socket: domain %d, type %d, protocol %d\n",
70 domain, type, protocol);
71 #endif
73 if (domain == AF_UNIX)
74 return _uds_socket(type, protocol);
76 if (domain == AF_INET) {
77 switch (sock_type) {
78 case SOCK_STREAM:
79 return _tcp_socket(type, protocol);
80 case SOCK_DGRAM:
81 return _udp_socket(type, protocol);
82 case SOCK_RAW:
83 return _raw_socket(type, protocol);
84 default:
85 errno = EPROTOTYPE;
86 return -1;
90 errno = EAFNOSUPPORT;
91 return -1;
94 static void
95 _socket_flags(int type, int *result)
97 /* Process socket flags */
98 if (type & SOCK_CLOEXEC) {
99 *result |= O_CLOEXEC;
101 if (type & SOCK_NONBLOCK) {
102 *result |= O_NONBLOCK;
104 if (type & SOCK_NOSIGPIPE) {
105 *result |= O_NOSIGPIPE;
109 static int _tcp_socket(int type, int protocol)
111 int flags = O_RDWR;
113 if (protocol != 0 && protocol != IPPROTO_TCP)
115 #if DEBUG
116 fprintf(stderr, "socket(tcp): bad protocol %d\n", protocol);
117 #endif
118 errno= EPROTONOSUPPORT;
119 return -1;
122 _socket_flags(type, &flags);
124 return open(TCP_DEVICE, flags);
127 static int _udp_socket(int type, int protocol)
129 int r, fd, t_errno, flags = O_RDWR;
130 struct sockaddr_in sin;
132 if (protocol != 0 && protocol != IPPROTO_UDP)
134 #if DEBUG
135 fprintf(stderr, "socket(udp): bad protocol %d\n", protocol);
136 #endif
137 errno= EPROTONOSUPPORT;
138 return -1;
140 _socket_flags(type, &flags);
141 fd= open(UDP_DEVICE, flags);
142 if (fd == -1)
143 return fd;
145 /* Bind is implict for UDP sockets? */
146 sin.sin_family= AF_INET;
147 sin.sin_addr.s_addr= INADDR_ANY;
148 sin.sin_port= 0;
149 r= bind(fd, (struct sockaddr *)&sin, sizeof(sin));
150 if (r != 0)
152 t_errno= errno;
153 close(fd);
154 errno= t_errno;
155 return -1;
157 return fd;
160 static int _raw_socket(int type, int protocol)
162 int fd, flags = O_RDWR;
163 nwio_ipopt_t ipopt;
164 int result;
166 if (protocol != IPPROTO_ICMP && protocol != IPPROTO_UDP && protocol != 0)
168 #if DEBUG
169 fprintf(stderr, "socket(icmp): bad protocol %d\n", protocol);
170 #endif
171 errno= EPROTONOSUPPORT;
172 return -1;
174 _socket_flags(type, &flags);
175 fd= open(IP_DEVICE, flags);
176 if (fd == -1)
177 return fd;
179 memset(&ipopt, 0, sizeof(ipopt));
181 ipopt.nwio_flags= NWIO_COPY;
183 if(protocol) {
184 ipopt.nwio_flags |= NWIO_PROTOSPEC;
185 ipopt.nwio_proto = protocol;
188 result = ioctl (fd, NWIOSIPOPT, &ipopt);
189 if (result<0) {
190 close(fd);
191 return -1;
194 result = ioctl (fd, NWIOGIPOPT, &ipopt);
195 if (result<0) {
196 close(fd);
197 return -1;
200 return fd;
203 static int _uds_socket(int type, int protocol)
205 int fd, r, flags = O_RDWR, sock_type;
207 sock_type = type & ~SOCK_FLAGS_MASK;
208 if (sock_type != SOCK_STREAM &&
209 sock_type != SOCK_DGRAM &&
210 sock_type != SOCK_SEQPACKET) {
211 errno = EPROTOTYPE;
212 return -1;
215 if (protocol != 0)
217 #if DEBUG
218 fprintf(stderr, "socket(uds): bad protocol %d\n", protocol);
219 #endif
220 errno= EPROTONOSUPPORT;
221 return -1;
224 _socket_flags(type, &flags);
225 fd= open(UDS_DEVICE, flags);
226 if (fd == -1) {
227 return fd;
230 /* set the type for the socket via ioctl (SOCK_DGRAM,
231 * SOCK_STREAM, SOCK_SEQPACKET, etc)
233 r= ioctl(fd, NWIOSUDSTYPE, &sock_type);
234 if (r == -1) {
235 int ioctl_errno;
237 /* if that failed rollback socket creation */
238 ioctl_errno= errno;
239 close(fd);
241 /* return the error thrown by the call to ioctl */
242 errno= ioctl_errno;
243 return -1;
246 return fd;