8 #include <sys/socket.h>
10 #include <netinet/tcp.h>
12 #include <net/gen/in.h>
13 #include <net/gen/tcp.h>
14 #include <net/gen/tcp_io.h>
15 #include <net/gen/udp.h>
16 #include <net/gen/udp_io.h>
20 static int _tcp_setsockopt(int sock
, int level
, int option_name
,
21 const void *option_value
, socklen_t option_len
);
23 static int _udp_setsockopt(int sock
, int level
, int option_name
,
24 const void *option_value
, socklen_t option_len
);
26 static int _uds_setsockopt(int sock
, int level
, int option_name
,
27 const void *option_value
, socklen_t option_len
);
29 int setsockopt(int sock
, int level
, int option_name
,
30 const void *option_value
, socklen_t option_len
)
35 struct sockaddr_un uds_addr
;
37 r
= ioctl(sock
, NWIOGTCPOPT
, &tcpopt
);
38 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
42 /* Bad file descriptor */
45 return _tcp_setsockopt(sock
, level
, option_name
,
46 option_value
, option_len
);
49 r
= ioctl(sock
, NWIOGUDPOPT
, &udpopt
);
50 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
54 /* Bad file descriptor */
57 return _udp_setsockopt(sock
, level
, option_name
,
58 option_value
, option_len
);
61 r
= ioctl(sock
, NWIOGUDSADDR
, &uds_addr
);
62 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
66 /* Bad file descriptor */
69 return _uds_setsockopt(sock
, level
, option_name
,
70 option_value
, option_len
);
75 fprintf(stderr
, "setsockopt: not implemented for fd %d\n", sock
);
81 static int _tcp_setsockopt(int sock
, int level
, int option_name
,
82 const void *option_value
, socklen_t option_len
)
86 if (level
== SOL_SOCKET
&& option_name
== SO_REUSEADDR
)
88 if (option_len
!= sizeof(i
))
93 i
= *(const int *)option_value
;
96 /* At the moment there is no way to turn off
104 if (level
== SOL_SOCKET
&& option_name
== SO_KEEPALIVE
)
106 if (option_len
!= sizeof(i
))
111 i
= *(const int *)option_value
;
114 /* At the moment there is no way to turn off
122 if (level
== SOL_SOCKET
&& option_name
== SO_RCVBUF
)
124 if (option_len
!= sizeof(i
))
129 i
= *(const int *)option_value
;
132 /* The receive buffer is limited to 32K at the moment.
137 /* There is no way to reduce the receive buffer, do we have to
138 * let this call fail for smaller buffers?
142 if (level
== SOL_SOCKET
&& option_name
== SO_SNDBUF
)
144 if (option_len
!= sizeof(i
))
149 i
= *(const int *)option_value
;
152 /* The send buffer is limited to 32K at the moment.
157 /* There is no way to reduce the send buffer, do we have to
158 * let this call fail for smaller buffers?
162 if (level
== IPPROTO_TCP
&& option_name
== TCP_NODELAY
)
164 if (option_len
!= sizeof(i
))
169 i
= *(const int *)option_value
;
172 /* At the moment there is no way to turn on
181 fprintf(stderr
, "_tcp_setsocketopt: level %d, name %d\n",
189 static int _udp_setsockopt(int sock
, int level
, int option_name
,
190 const void *option_value
, socklen_t option_len
)
193 fprintf(stderr
, "_udp_setsocketopt: level %d, name %d\n",
202 static int _uds_setsockopt(int sock
, int level
, int option_name
,
203 const void *option_value
, socklen_t option_len
)
208 if (level
== SOL_SOCKET
&& option_name
== SO_RCVBUF
)
210 if (option_len
!= sizeof(size
))
215 size
= *(const size_t *)option_value
;
216 return ioctl(sock
, NWIOSUDSRCVBUF
, &size
);
219 if (level
== SOL_SOCKET
&& option_name
== SO_SNDBUF
)
221 if (option_len
!= sizeof(size
))
226 size
= *(const size_t *)option_value
;
227 return ioctl(sock
, NWIOSUDSSNDBUF
, &size
);
230 if (level
== SOL_SOCKET
&& option_name
== SO_REUSEADDR
)
232 if (option_len
!= sizeof(i
))
237 i
= *(const int *)option_value
;
240 /* At the moment there is no way to turn off
249 if (level
== SOL_SOCKET
&& option_name
== SO_PASSCRED
)
251 if (option_len
!= sizeof(i
))
256 i
= *(const int *)option_value
;
259 /* credentials can always be received. */
267 fprintf(stderr
, "_uds_setsocketopt: level %d, name %d\n",