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