1 /*
2 * Copyright (c) 2019 Intel Corporation
3 * Copyright (c) 2021 Nordic Semiconductor
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <stdbool.h>
9 #include <zephyr/posix/fcntl.h>
10
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(net_sock_packet, CONFIG_NET_SOCKETS_LOG_LEVEL);
13
14 #include <zephyr/kernel.h>
15 #include <zephyr/drivers/entropy.h>
16 #include <zephyr/sys/util.h>
17 #include <zephyr/net/net_context.h>
18 #include <zephyr/net/net_pkt.h>
19 #include <zephyr/net/socket.h>
20 #include <zephyr/net/ethernet.h>
21 #include <zephyr/internal/syscall_handler.h>
22 #include <zephyr/sys/fdtable.h>
23
24 #include "../../ip/net_stats.h"
25
26 #include "sockets_internal.h"
27
28 extern const struct socket_op_vtable sock_fd_op_vtable;
29
30 static const struct socket_op_vtable packet_sock_fd_op_vtable;
31
k_fifo_wait_non_empty(struct k_fifo * fifo,k_timeout_t timeout)32 static inline int k_fifo_wait_non_empty(struct k_fifo *fifo,
33 k_timeout_t timeout)
34 {
35 struct k_poll_event events[] = {
36 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
37 K_POLL_MODE_NOTIFY_ONLY, fifo),
38 };
39
40 return k_poll(events, ARRAY_SIZE(events), timeout);
41 }
42
zpacket_socket(int family,int type,int proto)43 static int zpacket_socket(int family, int type, int proto)
44 {
45 struct net_context *ctx;
46 int fd;
47 int ret;
48
49 fd = zvfs_reserve_fd();
50 if (fd < 0) {
51 return -1;
52 }
53
54 if (proto == 0) {
55 if (type == SOCK_RAW) {
56 proto = IPPROTO_RAW;
57 }
58 } else {
59 /* For example in Linux, the protocol parameter can be given
60 * as htons(ETH_P_ALL) to receive all the network packets.
61 * So convert the proto field back to host byte order so that
62 * we do not need to change the protocol field handling in
63 * other part of the network stack.
64 */
65 proto = ntohs(proto);
66 }
67
68 ret = net_context_get(family, type, proto, &ctx);
69 if (ret < 0) {
70 zvfs_free_fd(fd);
71 errno = -ret;
72 return -1;
73 }
74
75 /* Initialize user_data, all other calls will preserve it */
76 ctx->user_data = NULL;
77
78 /* recv_q and accept_q are in union */
79 k_fifo_init(&ctx->recv_q);
80 zvfs_finalize_typed_fd(fd, ctx, (const struct fd_op_vtable *)&packet_sock_fd_op_vtable,
81 ZVFS_MODE_IFSOCK);
82
83 return fd;
84 }
85
zpacket_received_cb(struct net_context * ctx,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,int status,void * user_data)86 static void zpacket_received_cb(struct net_context *ctx,
87 struct net_pkt *pkt,
88 union net_ip_header *ip_hdr,
89 union net_proto_header *proto_hdr,
90 int status,
91 void *user_data)
92 {
93 NET_DBG("ctx=%p, pkt=%p, st=%d, user_data=%p", ctx, pkt, status,
94 user_data);
95
96 /* if pkt is NULL, EOF */
97 if (!pkt) {
98 struct net_pkt *last_pkt = k_fifo_peek_tail(&ctx->recv_q);
99
100 if (!last_pkt) {
101 /* If there're no packets in the queue, recv() may
102 * be blocked waiting on it to become non-empty,
103 * so cancel that wait.
104 */
105 sock_set_eof(ctx);
106 k_fifo_cancel_wait(&ctx->recv_q);
107 NET_DBG("Marked socket %p as peer-closed", ctx);
108 } else {
109 net_pkt_set_eof(last_pkt, true);
110 NET_DBG("Set EOF flag on pkt %p", ctx);
111 }
112
113 return;
114 }
115
116 /* Normal packet */
117 net_pkt_set_eof(pkt, false);
118
119 k_fifo_put(&ctx->recv_q, pkt);
120 }
121
zpacket_bind_ctx(struct net_context * ctx,const struct sockaddr * addr,socklen_t addrlen)122 static int zpacket_bind_ctx(struct net_context *ctx,
123 const struct sockaddr *addr,
124 socklen_t addrlen)
125 {
126 int ret = 0;
127
128 ret = net_context_bind(ctx, addr, addrlen);
129 if (ret < 0) {
130 errno = -ret;
131 return -1;
132 }
133
134 /* For packet socket, we expect to receive packets after call
135 * to bind().
136 */
137 ret = net_context_recv(ctx, zpacket_received_cb, K_NO_WAIT,
138 ctx->user_data);
139 if (ret < 0) {
140 errno = -ret;
141 return -1;
142 }
143
144 return 0;
145 }
146
zpacket_set_eth_pkttype(struct net_if * iface,struct sockaddr_ll * addr,struct net_linkaddr * lladdr)147 static void zpacket_set_eth_pkttype(struct net_if *iface,
148 struct sockaddr_ll *addr,
149 struct net_linkaddr *lladdr)
150 {
151 if (lladdr == NULL || lladdr->addr == NULL) {
152 return;
153 }
154
155 if (net_eth_is_addr_broadcast((struct net_eth_addr *)lladdr->addr)) {
156 addr->sll_pkttype = PACKET_BROADCAST;
157 } else if (net_eth_is_addr_multicast(
158 (struct net_eth_addr *)lladdr->addr)) {
159 addr->sll_pkttype = PACKET_MULTICAST;
160 } else if (!net_linkaddr_cmp(net_if_get_link_addr(iface), lladdr)) {
161 addr->sll_pkttype = PACKET_HOST;
162 } else {
163 addr->sll_pkttype = PACKET_OTHERHOST;
164 }
165 }
166
zpacket_set_source_addr(struct net_context * ctx,struct net_pkt * pkt,struct sockaddr * src_addr,socklen_t * addrlen)167 static void zpacket_set_source_addr(struct net_context *ctx,
168 struct net_pkt *pkt,
169 struct sockaddr *src_addr,
170 socklen_t *addrlen)
171 {
172 struct sockaddr_ll addr = {0};
173 struct net_if *iface = net_context_get_iface(ctx);
174
175 if (iface == NULL) {
176 return;
177 }
178
179 addr.sll_family = AF_PACKET;
180 addr.sll_ifindex = net_if_get_by_iface(iface);
181
182 if (net_pkt_is_l2_processed(pkt)) {
183 /* L2 has already processed the packet - can copy information
184 * directly from the net_pkt structure
185 */
186 addr.sll_halen = pkt->lladdr_src.len;
187 memcpy(addr.sll_addr, pkt->lladdr_src.addr,
188 MIN(sizeof(addr.sll_addr), pkt->lladdr_src.len));
189
190 addr.sll_protocol = net_pkt_ll_proto_type(pkt);
191
192 if (net_if_get_link_addr(iface)->type == NET_LINK_ETHERNET) {
193 addr.sll_hatype = ARPHRD_ETHER;
194 zpacket_set_eth_pkttype(iface, &addr,
195 net_pkt_lladdr_dst(pkt));
196 }
197 } else if (net_if_get_link_addr(iface)->type == NET_LINK_ETHERNET) {
198 /* Need to extract information from the L2 header. Only
199 * Ethernet L2 supported currently.
200 */
201 struct net_eth_hdr *hdr;
202 struct net_linkaddr dst_addr;
203 struct net_pkt_cursor cur;
204
205 net_pkt_cursor_backup(pkt, &cur);
206 net_pkt_cursor_init(pkt);
207
208 hdr = NET_ETH_HDR(pkt);
209 if (hdr == NULL ||
210 pkt->buffer->len < sizeof(struct net_eth_hdr)) {
211 net_pkt_cursor_restore(pkt, &cur);
212 return;
213 }
214
215 addr.sll_halen = sizeof(struct net_eth_addr);
216 memcpy(addr.sll_addr, hdr->src.addr,
217 sizeof(struct net_eth_addr));
218
219 addr.sll_protocol = ntohs(hdr->type);
220 addr.sll_hatype = ARPHRD_ETHER;
221
222 dst_addr.addr = hdr->dst.addr;
223 dst_addr.len = sizeof(struct net_eth_addr);
224 dst_addr.type = NET_LINK_ETHERNET;
225
226 zpacket_set_eth_pkttype(iface, &addr, &dst_addr);
227 net_pkt_cursor_restore(pkt, &cur);
228 }
229
230 /* Copy the result sockaddr_ll structure into provided buffer. If the
231 * buffer is smaller than the structure size, it will be truncated.
232 */
233 memcpy(src_addr, &addr, MIN(sizeof(struct sockaddr_ll), *addrlen));
234 *addrlen = sizeof(struct sockaddr_ll);
235 }
236
zpacket_sendto_ctx(struct net_context * ctx,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)237 ssize_t zpacket_sendto_ctx(struct net_context *ctx, const void *buf, size_t len,
238 int flags, const struct sockaddr *dest_addr,
239 socklen_t addrlen)
240 {
241 k_timeout_t timeout = K_FOREVER;
242 int status;
243
244 if (!dest_addr) {
245 errno = EDESTADDRREQ;
246 return -1;
247 }
248
249 if ((flags & ZSOCK_MSG_DONTWAIT) || sock_is_nonblock(ctx)) {
250 timeout = K_NO_WAIT;
251 } else {
252 net_context_get_option(ctx, NET_OPT_SNDTIMEO, &timeout, NULL);
253 }
254
255 /* Register the callback before sending in order to receive the response
256 * from the peer.
257 */
258
259 status = net_context_recv(ctx, zpacket_received_cb, K_NO_WAIT,
260 ctx->user_data);
261 if (status < 0) {
262 errno = -status;
263 return -1;
264 }
265
266 status = net_context_sendto(ctx, buf, len, dest_addr, addrlen,
267 NULL, timeout, ctx->user_data);
268 if (status < 0) {
269 errno = -status;
270 return -1;
271 }
272
273 return status;
274 }
275
zpacket_sendmsg_ctx(struct net_context * ctx,const struct msghdr * msg,int flags)276 ssize_t zpacket_sendmsg_ctx(struct net_context *ctx, const struct msghdr *msg,
277 int flags)
278 {
279 k_timeout_t timeout = K_FOREVER;
280 int status;
281
282 if ((flags & ZSOCK_MSG_DONTWAIT) || sock_is_nonblock(ctx)) {
283 timeout = K_NO_WAIT;
284 } else {
285 net_context_get_option(ctx, NET_OPT_SNDTIMEO, &timeout, NULL);
286 }
287
288 status = net_context_sendmsg(ctx, msg, flags, NULL, timeout, NULL);
289 if (status < 0) {
290 errno = -status;
291 return -1;
292 }
293
294 return status;
295 }
296
zpacket_recvfrom_ctx(struct net_context * ctx,void * buf,size_t max_len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)297 ssize_t zpacket_recvfrom_ctx(struct net_context *ctx, void *buf, size_t max_len,
298 int flags, struct sockaddr *src_addr,
299 socklen_t *addrlen)
300 {
301 size_t recv_len = 0;
302 k_timeout_t timeout = K_FOREVER;
303 struct net_pkt *pkt;
304
305 if ((flags & ZSOCK_MSG_DONTWAIT) || sock_is_nonblock(ctx)) {
306 timeout = K_NO_WAIT;
307 } else {
308 net_context_get_option(ctx, NET_OPT_RCVTIMEO, &timeout, NULL);
309 }
310
311 if (flags & ZSOCK_MSG_PEEK) {
312 int res;
313
314 res = k_fifo_wait_non_empty(&ctx->recv_q, timeout);
315 /* EAGAIN when timeout expired, EINTR when cancelled */
316 if (res && res != -EAGAIN && res != -EINTR) {
317 errno = -res;
318 return -1;
319 }
320
321 pkt = k_fifo_peek_head(&ctx->recv_q);
322 } else {
323 pkt = k_fifo_get(&ctx->recv_q, timeout);
324 }
325
326 if (!pkt) {
327 errno = EAGAIN;
328 return -1;
329 }
330
331 /* We do not handle any headers here,
332 * just pass the whole packet to caller.
333 */
334 recv_len = net_pkt_get_len(pkt);
335 if (recv_len > max_len) {
336 recv_len = max_len;
337 }
338
339 if (net_pkt_read(pkt, buf, recv_len)) {
340 errno = ENOBUFS;
341 return -1;
342 }
343
344 if (src_addr && addrlen) {
345 zpacket_set_source_addr(ctx, pkt, src_addr, addrlen);
346 }
347
348 if ((IS_ENABLED(CONFIG_NET_PKT_RXTIME_STATS) ||
349 IS_ENABLED(CONFIG_TRACING_NET_CORE)) &&
350 !(flags & ZSOCK_MSG_PEEK)) {
351 net_socket_update_tc_rx_time(pkt, k_cycle_get_32());
352 }
353
354 if (!(flags & ZSOCK_MSG_PEEK)) {
355 net_pkt_unref(pkt);
356 } else {
357 net_pkt_cursor_init(pkt);
358 }
359
360 return recv_len;
361 }
362
zpacket_getsockopt_ctx(struct net_context * ctx,int level,int optname,void * optval,socklen_t * optlen)363 int zpacket_getsockopt_ctx(struct net_context *ctx, int level, int optname,
364 void *optval, socklen_t *optlen)
365 {
366 if (!optval || !optlen) {
367 errno = EINVAL;
368 return -1;
369 }
370
371 return sock_fd_op_vtable.getsockopt(ctx, level, optname,
372 optval, optlen);
373 }
374
zpacket_setsockopt_ctx(struct net_context * ctx,int level,int optname,const void * optval,socklen_t optlen)375 int zpacket_setsockopt_ctx(struct net_context *ctx, int level, int optname,
376 const void *optval, socklen_t optlen)
377 {
378 return sock_fd_op_vtable.setsockopt(ctx, level, optname,
379 optval, optlen);
380 }
381
packet_sock_read_vmeth(void * obj,void * buffer,size_t count)382 static ssize_t packet_sock_read_vmeth(void *obj, void *buffer, size_t count)
383 {
384 return zpacket_recvfrom_ctx(obj, buffer, count, 0, NULL, 0);
385 }
386
packet_sock_write_vmeth(void * obj,const void * buffer,size_t count)387 static ssize_t packet_sock_write_vmeth(void *obj, const void *buffer,
388 size_t count)
389 {
390 return zpacket_sendto_ctx(obj, buffer, count, 0, NULL, 0);
391 }
392
packet_sock_ioctl_vmeth(void * obj,unsigned int request,va_list args)393 static int packet_sock_ioctl_vmeth(void *obj, unsigned int request,
394 va_list args)
395 {
396 return sock_fd_op_vtable.fd_vtable.ioctl(obj, request, args);
397 }
398
399 /*
400 * TODO: A packet socket can be bound to a network device using SO_BINDTODEVICE.
401 */
packet_sock_bind_vmeth(void * obj,const struct sockaddr * addr,socklen_t addrlen)402 static int packet_sock_bind_vmeth(void *obj, const struct sockaddr *addr,
403 socklen_t addrlen)
404 {
405 return zpacket_bind_ctx(obj, addr, addrlen);
406 }
407
408 /* The connect() function is no longer necessary. */
packet_sock_connect_vmeth(void * obj,const struct sockaddr * addr,socklen_t addrlen)409 static int packet_sock_connect_vmeth(void *obj, const struct sockaddr *addr,
410 socklen_t addrlen)
411 {
412 return -EOPNOTSUPP;
413 }
414
415 /*
416 * The listen() and accept() functions are without any functionality,
417 * since the client-Server-Semantic is no longer present.
418 * When we use packet sockets we are sending unconnected packets.
419 */
packet_sock_listen_vmeth(void * obj,int backlog)420 static int packet_sock_listen_vmeth(void *obj, int backlog)
421 {
422 return -EOPNOTSUPP;
423 }
424
packet_sock_accept_vmeth(void * obj,struct sockaddr * addr,socklen_t * addrlen)425 static int packet_sock_accept_vmeth(void *obj, struct sockaddr *addr,
426 socklen_t *addrlen)
427 {
428 return -EOPNOTSUPP;
429 }
430
packet_sock_sendto_vmeth(void * obj,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)431 static ssize_t packet_sock_sendto_vmeth(void *obj, const void *buf, size_t len,
432 int flags,
433 const struct sockaddr *dest_addr,
434 socklen_t addrlen)
435 {
436 return zpacket_sendto_ctx(obj, buf, len, flags, dest_addr, addrlen);
437 }
438
packet_sock_sendmsg_vmeth(void * obj,const struct msghdr * msg,int flags)439 static ssize_t packet_sock_sendmsg_vmeth(void *obj, const struct msghdr *msg,
440 int flags)
441 {
442 return zpacket_sendmsg_ctx(obj, msg, flags);
443 }
444
packet_sock_recvfrom_vmeth(void * obj,void * buf,size_t max_len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)445 static ssize_t packet_sock_recvfrom_vmeth(void *obj, void *buf, size_t max_len,
446 int flags, struct sockaddr *src_addr,
447 socklen_t *addrlen)
448 {
449 return zpacket_recvfrom_ctx(obj, buf, max_len, flags,
450 src_addr, addrlen);
451 }
452
packet_sock_getsockopt_vmeth(void * obj,int level,int optname,void * optval,socklen_t * optlen)453 static int packet_sock_getsockopt_vmeth(void *obj, int level, int optname,
454 void *optval, socklen_t *optlen)
455 {
456 return zpacket_getsockopt_ctx(obj, level, optname, optval, optlen);
457 }
458
packet_sock_setsockopt_vmeth(void * obj,int level,int optname,const void * optval,socklen_t optlen)459 static int packet_sock_setsockopt_vmeth(void *obj, int level, int optname,
460 const void *optval, socklen_t optlen)
461 {
462 return zpacket_setsockopt_ctx(obj, level, optname, optval, optlen);
463 }
464
packet_sock_close2_vmeth(void * obj,int fd)465 static int packet_sock_close2_vmeth(void *obj, int fd)
466 {
467 return zsock_close_ctx(obj, fd);
468 }
469
470 static const struct socket_op_vtable packet_sock_fd_op_vtable = {
471 .fd_vtable = {
472 .read = packet_sock_read_vmeth,
473 .write = packet_sock_write_vmeth,
474 .close2 = packet_sock_close2_vmeth,
475 .ioctl = packet_sock_ioctl_vmeth,
476 },
477 .bind = packet_sock_bind_vmeth,
478 .connect = packet_sock_connect_vmeth,
479 .listen = packet_sock_listen_vmeth,
480 .accept = packet_sock_accept_vmeth,
481 .sendto = packet_sock_sendto_vmeth,
482 .sendmsg = packet_sock_sendmsg_vmeth,
483 .recvfrom = packet_sock_recvfrom_vmeth,
484 .getsockopt = packet_sock_getsockopt_vmeth,
485 .setsockopt = packet_sock_setsockopt_vmeth,
486 };
487
packet_is_supported(int family,int type,int proto)488 static bool packet_is_supported(int family, int type, int proto)
489 {
490 switch (type) {
491 case SOCK_RAW:
492 proto = ntohs(proto);
493 return proto == ETH_P_ALL
494 || proto == ETH_P_ECAT
495 || proto == ETH_P_IEEE802154
496 || proto == IPPROTO_RAW;
497
498 case SOCK_DGRAM:
499 return proto > 0;
500
501 default:
502 return false;
503 }
504 }
505
506 NET_SOCKET_REGISTER(af_packet, NET_SOCKET_DEFAULT_PRIO, AF_PACKET,
507 packet_is_supported, zpacket_socket);
508