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