14
#include <sys/socket.h>
16
#include <netinet/in.h>
19
#include <net/inetdevice.h>
24
#include <mem/misc/pool.h>
26
#include <net/l3/route.h>
27
#include <net/l3/ipv4/ip.h>
29
#include <net/socket/inet_sock.h>
30
#include <framework/mod/options.h>
32
#define MODOPS_AMOUNT_INET_SOCK OPTION_GET(NUMBER, amount_inet_sock)
34
static const struct sock_family_ops inet_stream_ops;
35
static const struct sock_family_ops inet_dgram_ops;
36
static const struct sock_family_ops inet_raw_ops;
38
static const struct net_family_type inet_types[] = {
39
{ SOCK_STREAM, &inet_stream_ops },
40
{ SOCK_DGRAM, &inet_dgram_ops },
41
{ SOCK_RAW, &inet_raw_ops }
44
EMBOX_NET_FAMILY(AF_INET, inet_types, ip_out_ops);
46
static int inet_init(struct sock *sk) {
47
struct inet_sock *in_sk;
51
in_sk = to_inet_sock(sk);
54
memset(&in_sk->src_in, 0, sizeof in_sk->src_in);
55
memset(&in_sk->dst_in, 0, sizeof in_sk->dst_in);
56
in_sk->src_in.sin_family = in_sk->dst_in.sin_family = AF_INET;
58
in_sk->sk.src_addr = (const struct sockaddr *)&in_sk->src_in;
59
in_sk->sk.dst_addr = (const struct sockaddr *)&in_sk->dst_in;
60
in_sk->sk.addr_len = sizeof(struct sockaddr_in);
61
memset(&in_sk->opt, 0, sizeof in_sk->opt);
66
static int inet_close(struct sock *sk) {
69
assert(sk->p_ops != NULL);
70
if (sk->p_ops->close == NULL) {
75
return sk->p_ops->close(sk);
78
static void __inet_bind(struct inet_sock *in_sk,
79
const struct sockaddr_in *addr_in) {
80
assert(in_sk != NULL);
81
assert(addr_in != NULL);
82
assert(addr_in->sin_family == AF_INET);
83
memcpy(&in_sk->src_in, addr_in, sizeof *addr_in);
86
static int inet_addr_tester(const struct sockaddr *lhs_sa,
87
const struct sockaddr *rhs_sa) {
88
static const struct in_addr inaddr_any = {
89
{ .s_addr = htonl(INADDR_ANY) }
91
const struct sockaddr_in *lhs_in, *rhs_in;
93
assert(lhs_sa != NULL);
94
assert(rhs_sa != NULL);
96
lhs_in = (const struct sockaddr_in *)lhs_sa;
97
rhs_in = (const struct sockaddr_in *)rhs_sa;
99
assert(lhs_in->sin_family == AF_INET);
100
return (lhs_in->sin_family == rhs_in->sin_family)
101
&& ((0 == memcmp(&lhs_in->sin_addr, &rhs_in->sin_addr,
102
sizeof lhs_in->sin_addr))
103
|| (0 == memcmp(&lhs_in->sin_addr, &inaddr_any,
104
sizeof lhs_in->sin_addr))
105
|| (0 == memcmp(&rhs_in->sin_addr, &inaddr_any,
106
sizeof rhs_in->sin_addr)))
107
&& (lhs_in->sin_port == rhs_in->sin_port);
109
#if defined(NET_NAMESPACE_ENABLED) && (NET_NAMESPACE_ENABLED == 1)
110
int sock_addr_is_busy_net_ns(const struct sock_proto_ops *p_ops,
111
sock_addr_tester_ft tester, const struct sockaddr *addr,
112
socklen_t addrlen, struct sock *src_sk) {
113
const struct sock *sk;
115
assert(p_ops != NULL);
116
assert(tester != NULL);
118
sock_foreach(sk, p_ops) {
119
if (!cmp_net_ns(src_sk->net_ns, sk->net_ns)) {
122
if ((sk->addr_len == addrlen)
123
&& tester(addr, sk->src_addr)) {
132
static int inet_bind(struct sock *sk, const struct sockaddr *addr,
134
struct sockaddr_in addr_in;
139
if (addrlen != sizeof addr_in) {
143
memcpy(&addr_in, addr, sizeof addr_in);
145
if (addr_in.sin_family != AF_INET) {
146
return -EAFNOSUPPORT;
148
#if defined(NET_NAMESPACE_ENABLED) && (NET_NAMESPACE_ENABLED == 1)
149
else if ((addr_in.sin_addr.s_addr != htonl(INADDR_ANY)) &&
150
!ip_is_local_net_ns(addr_in.sin_addr.s_addr,
151
IP_LOCAL_BROADCAST | IP_LOCAL_MULTICAST,
153
return -EADDRNOTAVAIL;
156
else if ((addr_in.sin_addr.s_addr != htonl(INADDR_ANY)) &&
157
!ip_is_local(addr_in.sin_addr.s_addr, IP_LOCAL_BROADCAST | IP_LOCAL_MULTICAST)) {
158
return -EADDRNOTAVAIL;
162
if (addr_in.sin_port == 0) {
166
if (!sock_addr_alloc_port(sk->p_ops, &addr_in.sin_port,
167
inet_addr_tester, (const struct sockaddr *)&addr_in,
172
#if defined(NET_NAMESPACE_ENABLED) && (NET_NAMESPACE_ENABLED == 1)
173
else if (sock_addr_is_busy_net_ns(sk->p_ops, inet_addr_tester, (struct sockaddr *)&addr_in,
179
else if (sock_addr_is_busy(sk->p_ops, inet_addr_tester, (struct sockaddr *)&addr_in,
185
__inet_bind(to_inet_sock(sk), &addr_in);
190
static int inet_bind_local(struct sock *sk) {
191
struct sockaddr_in addr_in;
195
memset(&addr_in, 0, sizeof addr_in);
197
addr_in.sin_family = AF_INET;
198
addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
200
if (!sock_addr_alloc_port(sk->p_ops, &addr_in.sin_port,
201
inet_addr_tester, (const struct sockaddr *)&addr_in,
206
__inet_bind(to_inet_sock(sk), &addr_in);
211
static int __inet_connect(struct inet_sock *in_sk,
212
const struct sockaddr_in *addr_in) {
216
assert(in_sk != NULL);
217
assert(addr_in != NULL);
218
assert(addr_in->sin_family == AF_INET);
220
#if defined(NET_NAMESPACE_ENABLED) && (NET_NAMESPACE_ENABLED == 1)
221
ret = rt_fib_source_ip_net_ns(addr_in->sin_addr.s_addr, NULL, &src_ip,
222
((struct sock *)in_sk)->net_ns);
224
ret = rt_fib_source_ip(addr_in->sin_addr.s_addr, NULL, &src_ip);
231
if ((in_sk->src_in.sin_addr.s_addr != htonl(INADDR_ANY))
232
&& (in_sk->src_in.sin_addr.s_addr != src_ip)) {
236
in_sk->src_in.sin_addr.s_addr = src_ip;
238
memcpy(&in_sk->dst_in, addr_in, sizeof *addr_in);
243
static int inet_stream_connect(struct sock *sk,
244
const struct sockaddr *addr, socklen_t addrlen,
247
const struct sockaddr_in *addr_in;
252
if (addrlen != sizeof *addr_in) {
256
addr_in = (const struct sockaddr_in *)addr;
257
if (addr_in->sin_family != AF_INET) {
261
ret = __inet_connect(to_inet_sock(sk), addr_in);
266
assert(sk->p_ops != NULL);
267
if (sk->p_ops->connect == NULL) {
271
return sk->p_ops->connect(sk, addr, addrlen, flags);
274
static int inet_nonstream_connect(struct sock *sk,
275
const struct sockaddr *addr, socklen_t addrlen,
278
const struct sockaddr_in *addr_in;
283
if (addrlen != sizeof *addr_in) {
287
addr_in = (const struct sockaddr_in *)addr;
288
if (addr_in->sin_family != AF_INET) {
292
ret = __inet_connect(to_inet_sock(sk), addr_in);
297
assert(sk->p_ops != NULL);
298
if (sk->p_ops->connect == NULL) {
302
return sk->p_ops->connect(sk, addr, addrlen, flags);
305
static int inet_listen(struct sock *sk, int backlog) {
307
assert(backlog >= 0);
309
assert(sk->p_ops != NULL);
310
if (sk->p_ops->listen == NULL) {
314
return sk->p_ops->listen(sk, backlog);
317
static int inet_accept(struct sock *sk, struct sockaddr *addr,
318
socklen_t *addrlen, int flags, struct sock **out_sk) {
320
struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
324
assert(addr || !addrlen);
325
assert(!addr || addrlen);
327
if (addrlen != NULL && *addrlen < sizeof *addr_in) {
331
assert(sk->p_ops != NULL);
332
if (sk->p_ops->accept == NULL) {
336
ret = sk->p_ops->accept(sk, addr, addrlen, flags, out_sk);
341
if (addr_in != NULL) {
342
memcpy(addr_in, &to_inet_sock(*out_sk)->dst_in, sizeof *addr_in);
343
assert(addr_in->sin_family == AF_INET);
344
*addrlen = sizeof *addr_in;
350
static int inet_sendmsg(struct sock *sk, struct msghdr *msg,
352
const struct sockaddr_in *addr_in;
357
addr_in = (const struct sockaddr_in *)msg->msg_name;
358
if ((addr_in != NULL) &&
359
((msg->msg_namelen != sizeof *addr_in)
360
|| (addr_in->sin_family != AF_INET))) {
364
assert(sk->p_ops != NULL);
365
if (sk->p_ops->sendmsg == NULL) {
369
return sk->p_ops->sendmsg(sk, msg, flags);
372
static int inet_recvmsg(struct sock *sk, struct msghdr *msg,
374
struct sockaddr_in *addr_in;
379
assert(sk->p_ops != NULL);
380
if (sk->p_ops->recvmsg == NULL) {
384
if (msg->msg_name != NULL) {
385
if (msg->msg_namelen < sizeof *addr_in) {
388
addr_in = (struct sockaddr_in *)msg->msg_name;
389
memcpy(addr_in, &to_inet_sock(sk)->dst_in, sizeof *addr_in);
390
assert(addr_in->sin_family == AF_INET);
391
msg->msg_namelen = sizeof *addr_in;
394
return sk->p_ops->recvmsg(sk, msg, flags);
397
static int inet_getsockname(struct sock *sk,
398
struct sockaddr *addr, socklen_t *addrlen) {
399
struct sockaddr_in *addr_in;
405
if (*addrlen < sizeof *addr_in) {
409
addr_in = (struct sockaddr_in *)addr;
410
memcpy(addr_in, &to_inet_sock(sk)->src_in, sizeof *addr_in);
412
assert((addr_in->sin_family == AF_UNSPEC)
413
|| (addr_in->sin_family == AF_INET));
415
addr_in->sin_family = AF_INET;
417
*addrlen = sizeof *addr_in;
422
static int inet_getpeername(struct sock *sk,
423
struct sockaddr *addr, socklen_t *addrlen) {
424
struct sockaddr_in *addr_in;
430
if (*addrlen < sizeof *addr_in) {
434
addr_in = (struct sockaddr_in *)addr;
435
memcpy(addr_in, &to_inet_sock(sk)->dst_in, sizeof *addr_in);
437
assert((addr_in->sin_family == AF_UNSPEC)
438
|| (addr_in->sin_family == AF_INET));
440
addr_in->sin_family = AF_INET;
442
*addrlen = sizeof *addr_in;
447
static int inet_getsockopt(struct sock *sk, int level,
448
int optname, void *optval, socklen_t *optlen) {
452
assert(*optlen >= 0);
454
if (level != IPPROTO_IP) {
455
assert(sk->p_ops != NULL);
456
if (sk->p_ops->getsockopt == NULL) {
459
return sk->p_ops->getsockopt(sk, level, optname, optval,
471
static int inet_setsockopt(struct sock *sk, int level,
472
int optname, const void *optval, socklen_t optlen) {
473
struct inet_sock *inet;
480
inet = to_inet_sock(sk);
482
if (level != IPPROTO_IP) {
483
assert(sk->p_ops != NULL);
484
if (sk->p_ops->setsockopt == NULL) {
487
return sk->p_ops->setsockopt(sk, level, optname, optval,
493
if (optlen <= 0 || optlen > sizeof(int)) {
496
memcpy(&val, optval, optlen);
502
if (sk->opt.so_type != SOCK_RAW) {
505
inet->opt.hdrincl = val ? 1 : 0;
516
static int inet_shutdown(struct sock *sk, int how) {
518
assert(sk->p_ops != NULL);
520
if (sk->p_ops->shutdown == NULL) {
524
return sk->p_ops->shutdown(sk, how);
527
POOL_DEF(inet_sock_pool, struct inet_sock, MODOPS_AMOUNT_INET_SOCK);
529
static const struct sock_family_ops inet_stream_ops = {
533
.bind_local = inet_bind_local,
534
.connect = inet_stream_connect,
535
.listen = inet_listen,
536
.accept = inet_accept,
537
.sendmsg = inet_sendmsg,
538
.recvmsg = inet_recvmsg,
539
.getsockname = inet_getsockname,
540
.getpeername = inet_getpeername,
541
.getsockopt = inet_getsockopt,
542
.setsockopt = inet_setsockopt,
543
.shutdown = inet_shutdown,
544
.sock_pool = &inet_sock_pool
547
static const struct sock_family_ops inet_dgram_ops = {
551
.bind_local = inet_bind_local,
552
.connect = inet_nonstream_connect,
553
.listen = inet_listen,
554
.accept = inet_accept,
555
.sendmsg = inet_sendmsg,
556
.recvmsg = inet_recvmsg,
557
.getsockname = inet_getsockname,
558
.getpeername = inet_getpeername,
559
.getsockopt = inet_getsockopt,
560
.setsockopt = inet_setsockopt,
561
.shutdown = inet_shutdown,
562
.sock_pool = &inet_sock_pool
565
static const struct sock_family_ops inet_raw_ops = {
569
.bind_local = inet_bind_local,
570
.connect = inet_nonstream_connect,
571
.listen = inet_listen,
572
.accept = inet_accept,
573
.sendmsg = inet_sendmsg,
574
.recvmsg = inet_recvmsg,
575
.getsockname = inet_getsockname,
576
.getpeername = inet_getpeername,
577
.getsockopt = inet_getsockopt,
578
.setsockopt = inet_setsockopt,
579
.shutdown = inet_shutdown,
580
.sock_pool = &inet_sock_pool