6 __weak_alias(socket
, __socket30
)
15 #include <sys/socket.h>
17 #include <sys/ioctl.h>
18 #include <sys/ioc_net.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>
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
);
46 __socket(int domain
, int type
, int protocol
)
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
)
62 r
= __socket(domain
, type
, protocol
);
63 if (r
!= -1 || (errno
!= EAFNOSUPPORT
&& errno
!= ENOSYS
))
66 sock_type
= type
& ~SOCK_FLAGS_MASK
;
69 fprintf(stderr
, "socket: domain %d, type %d, protocol %d\n",
70 domain
, type
, protocol
);
73 if (domain
== AF_UNIX
)
74 return _uds_socket(type
, protocol
);
76 if (domain
== AF_INET
) {
79 return _tcp_socket(type
, protocol
);
81 return _udp_socket(type
, protocol
);
83 return _raw_socket(type
, protocol
);
95 _socket_flags(int type
, int *result
)
97 /* Process socket flags */
98 if (type
& SOCK_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
)
113 if (protocol
!= 0 && protocol
!= IPPROTO_TCP
)
116 fprintf(stderr
, "socket(tcp): bad protocol %d\n", protocol
);
118 errno
= EPROTONOSUPPORT
;
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
)
135 fprintf(stderr
, "socket(udp): bad protocol %d\n", protocol
);
137 errno
= EPROTONOSUPPORT
;
140 _socket_flags(type
, &flags
);
141 fd
= open(UDP_DEVICE
, flags
);
145 /* Bind is implict for UDP sockets? */
146 sin
.sin_family
= AF_INET
;
147 sin
.sin_addr
.s_addr
= INADDR_ANY
;
149 r
= bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
));
160 static int _raw_socket(int type
, int protocol
)
162 int fd
, flags
= O_RDWR
;
166 if (protocol
!= IPPROTO_ICMP
&& protocol
!= IPPROTO_UDP
&& protocol
!= 0)
169 fprintf(stderr
, "socket(icmp): bad protocol %d\n", protocol
);
171 errno
= EPROTONOSUPPORT
;
174 _socket_flags(type
, &flags
);
175 fd
= open(IP_DEVICE
, flags
);
179 memset(&ipopt
, 0, sizeof(ipopt
));
181 ipopt
.nwio_flags
= NWIO_COPY
;
184 ipopt
.nwio_flags
|= NWIO_PROTOSPEC
;
185 ipopt
.nwio_proto
= protocol
;
188 result
= ioctl (fd
, NWIOSIPOPT
, &ipopt
);
194 result
= ioctl (fd
, NWIOGIPOPT
, &ipopt
);
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
) {
218 fprintf(stderr
, "socket(uds): bad protocol %d\n", protocol
);
220 errno
= EPROTONOSUPPORT
;
224 _socket_flags(type
, &flags
);
225 fd
= open(UDS_DEVICE
, flags
);
230 /* set the type for the socket via ioctl (SOCK_DGRAM,
231 * SOCK_STREAM, SOCK_SEQPACKET, etc)
233 r
= ioctl(fd
, NWIOSUDSTYPE
, &sock_type
);
237 /* if that failed rollback socket creation */
241 /* return the error thrown by the call to ioctl */