1 /** @file
2  * @brief Generic connection related functions
3  */
4 
5 /*
6  * Copyright (c) 2016 Intel Corporation
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 /* TODO: Make core part of networking subsystem less dependent on
12  * UDP, TCP, IPv4 or IPv6. So that we can add new features with
13  * less cross-module changes.
14  */
15 
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(net_conn, CONFIG_NET_CONN_LOG_LEVEL);
18 
19 #include <errno.h>
20 #include <zephyr/sys/util.h>
21 
22 #include <zephyr/net/net_core.h>
23 #include <zephyr/net/net_pkt.h>
24 #include <zephyr/net/udp.h>
25 #include <zephyr/net/ethernet.h>
26 #include <zephyr/net/socketcan.h>
27 
28 #include "net_private.h"
29 #include "icmpv6.h"
30 #include "icmpv4.h"
31 #include "udp_internal.h"
32 #include "tcp_internal.h"
33 #include "connection.h"
34 #include "net_stats.h"
35 
36 /** How long to wait for when cloning multicast packet */
37 #define CLONE_TIMEOUT K_MSEC(100)
38 
39 /** Is this connection used or not */
40 #define NET_CONN_IN_USE			BIT(0)
41 
42 /** Remote address set */
43 #define NET_CONN_REMOTE_ADDR_SET	BIT(1)
44 
45 /** Local address set */
46 #define NET_CONN_LOCAL_ADDR_SET		BIT(2)
47 
48 /** Local port set */
49 #define NET_CONN_REMOTE_PORT_SPEC	BIT(3)
50 
51 /** Remote port set */
52 #define NET_CONN_LOCAL_PORT_SPEC	BIT(4)
53 
54 /** Local address specified */
55 #define NET_CONN_REMOTE_ADDR_SPEC	BIT(5)
56 
57 /** Remote address specified */
58 #define NET_CONN_LOCAL_ADDR_SPEC	BIT(6)
59 
60 #define NET_CONN_RANK(_flags)		(_flags & 0x78)
61 
62 static struct net_conn conns[CONFIG_NET_MAX_CONN];
63 
64 static sys_slist_t conn_unused;
65 static sys_slist_t conn_used;
66 
67 #if (CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG)
68 static inline
conn_register_debug(struct net_conn * conn,uint16_t remote_port,uint16_t local_port)69 void conn_register_debug(struct net_conn *conn,
70 			 uint16_t remote_port, uint16_t local_port)
71 {
72 	char dst[NET_IPV6_ADDR_LEN];
73 	char src[NET_IPV6_ADDR_LEN];
74 
75 	if (conn->flags & NET_CONN_REMOTE_ADDR_SET) {
76 		if (IS_ENABLED(CONFIG_NET_IPV6) &&
77 		    conn->family == AF_INET6) {
78 			snprintk(dst, sizeof(dst), "%s",
79 				 net_sprint_ipv6_addr(&net_sin6(&conn->remote_addr)->sin6_addr));
80 		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
81 			   conn->family == AF_INET) {
82 			snprintk(dst, sizeof(dst), "%s",
83 				 net_sprint_ipv4_addr(&net_sin(&conn->remote_addr)->sin_addr));
84 		} else {
85 			snprintk(dst, sizeof(dst), "%s", "?");
86 		}
87 	} else {
88 		snprintk(dst, sizeof(dst), "%s", "-");
89 	}
90 
91 	if (conn->flags & NET_CONN_LOCAL_ADDR_SET) {
92 		if (IS_ENABLED(CONFIG_NET_IPV6) &&
93 		    conn->family == AF_INET6) {
94 			snprintk(src, sizeof(src), "%s",
95 				 net_sprint_ipv6_addr(&net_sin6(&conn->local_addr)->sin6_addr));
96 		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
97 			   conn->family == AF_INET) {
98 			snprintk(src, sizeof(src), "%s",
99 				 net_sprint_ipv4_addr(&net_sin(&conn->local_addr)->sin_addr));
100 		} else {
101 			snprintk(src, sizeof(src), "%s", "?");
102 		}
103 	} else {
104 		snprintk(src, sizeof(src), "%s", "-");
105 	}
106 
107 	NET_DBG("[%p/%d/%u/0x%02x] remote %s/%u ",
108 		conn, conn->proto, conn->family, conn->flags,
109 		dst, remote_port);
110 	NET_DBG("  local %s/%u cb %p ud %p",
111 		src, local_port, conn->cb, conn->user_data);
112 }
113 #else
114 #define conn_register_debug(...)
115 #endif /* (CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG) */
116 
117 static K_MUTEX_DEFINE(conn_lock);
118 
conn_get_unused(void)119 static struct net_conn *conn_get_unused(void)
120 {
121 	sys_snode_t *node;
122 
123 	k_mutex_lock(&conn_lock, K_FOREVER);
124 
125 	node = sys_slist_peek_head(&conn_unused);
126 	if (!node) {
127 		k_mutex_unlock(&conn_lock);
128 		return NULL;
129 	}
130 
131 	sys_slist_remove(&conn_unused, NULL, node);
132 
133 	k_mutex_unlock(&conn_lock);
134 
135 	return CONTAINER_OF(node, struct net_conn, node);
136 }
137 
conn_set_used(struct net_conn * conn)138 static void conn_set_used(struct net_conn *conn)
139 {
140 	conn->flags |= NET_CONN_IN_USE;
141 
142 	k_mutex_lock(&conn_lock, K_FOREVER);
143 	sys_slist_prepend(&conn_used, &conn->node);
144 	k_mutex_unlock(&conn_lock);
145 }
146 
conn_set_unused(struct net_conn * conn)147 static void conn_set_unused(struct net_conn *conn)
148 {
149 	(void)memset(conn, 0, sizeof(*conn));
150 
151 	k_mutex_lock(&conn_lock, K_FOREVER);
152 	sys_slist_prepend(&conn_unused, &conn->node);
153 	k_mutex_unlock(&conn_lock);
154 }
155 
156 /* Check if we already have identical connection handler installed. */
conn_find_handler(struct net_if * iface,uint16_t proto,uint8_t family,const struct sockaddr * remote_addr,const struct sockaddr * local_addr,uint16_t remote_port,uint16_t local_port,bool reuseport_set)157 static struct net_conn *conn_find_handler(struct net_if *iface,
158 					  uint16_t proto, uint8_t family,
159 					  const struct sockaddr *remote_addr,
160 					  const struct sockaddr *local_addr,
161 					  uint16_t remote_port,
162 					  uint16_t local_port,
163 					  bool reuseport_set)
164 {
165 	struct net_conn *conn;
166 	struct net_conn *tmp;
167 
168 	k_mutex_lock(&conn_lock, K_FOREVER);
169 
170 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&conn_used, conn, tmp, node) {
171 		if (conn->proto != proto) {
172 			continue;
173 		}
174 
175 		if (conn->family != family) {
176 			continue;
177 		}
178 
179 		if (local_addr) {
180 			if (!(conn->flags & NET_CONN_LOCAL_ADDR_SET)) {
181 				continue;
182 			}
183 
184 			if (IS_ENABLED(CONFIG_NET_IPV6) &&
185 			    local_addr->sa_family == AF_INET6 &&
186 			    local_addr->sa_family ==
187 			    conn->local_addr.sa_family) {
188 				if (!net_ipv6_addr_cmp(
189 					    &net_sin6(local_addr)->sin6_addr,
190 					    &net_sin6(&conn->local_addr)->
191 								sin6_addr)) {
192 					continue;
193 				}
194 			} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
195 				   local_addr->sa_family == AF_INET &&
196 				   local_addr->sa_family ==
197 				   conn->local_addr.sa_family) {
198 				if (!net_ipv4_addr_cmp(
199 					    &net_sin(local_addr)->sin_addr,
200 					    &net_sin(&conn->local_addr)->
201 								sin_addr)) {
202 					continue;
203 				}
204 			} else {
205 				continue;
206 			}
207 		} else if (conn->flags & NET_CONN_LOCAL_ADDR_SET) {
208 			continue;
209 		}
210 
211 		if (net_sin(&conn->local_addr)->sin_port !=
212 		    htons(local_port)) {
213 			continue;
214 		}
215 
216 		if (remote_addr) {
217 			if (!(conn->flags & NET_CONN_REMOTE_ADDR_SET)) {
218 				continue;
219 			}
220 
221 			if (IS_ENABLED(CONFIG_NET_IPV6) &&
222 			    remote_addr->sa_family == AF_INET6 &&
223 			    remote_addr->sa_family ==
224 			    conn->remote_addr.sa_family) {
225 				if (!net_ipv6_addr_cmp(
226 					    &net_sin6(remote_addr)->sin6_addr,
227 					    &net_sin6(&conn->remote_addr)->
228 								sin6_addr)) {
229 					continue;
230 				}
231 			} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
232 				   remote_addr->sa_family == AF_INET &&
233 				   remote_addr->sa_family ==
234 				   conn->remote_addr.sa_family) {
235 				if (!net_ipv4_addr_cmp(
236 					    &net_sin(remote_addr)->sin_addr,
237 					    &net_sin(&conn->remote_addr)->
238 								sin_addr)) {
239 					continue;
240 				}
241 			} else {
242 				continue;
243 			}
244 		} else if (conn->flags & NET_CONN_REMOTE_ADDR_SET) {
245 			continue;
246 		} else if (reuseport_set && conn->context != NULL &&
247 			   net_context_is_reuseport_set(conn->context)) {
248 			continue;
249 		}
250 
251 		if (net_sin(&conn->remote_addr)->sin_port !=
252 		    htons(remote_port)) {
253 			continue;
254 		}
255 
256 		if (conn->context != NULL && iface != NULL &&
257 		    net_context_is_bound_to_iface(conn->context)) {
258 			if (iface != net_context_get_iface(conn->context)) {
259 				continue;
260 			}
261 		}
262 
263 		k_mutex_unlock(&conn_lock);
264 		return conn;
265 	}
266 
267 	k_mutex_unlock(&conn_lock);
268 	return NULL;
269 }
270 
net_conn_change_callback(struct net_conn * conn,net_conn_cb_t cb,void * user_data)271 static void net_conn_change_callback(struct net_conn *conn,
272 				     net_conn_cb_t cb, void *user_data)
273 {
274 	NET_DBG("[%zu] connection handler %p changed callback",
275 		conn - conns, conn);
276 
277 	conn->cb = cb;
278 	conn->user_data = user_data;
279 }
280 
net_conn_change_remote(struct net_conn * conn,const struct sockaddr * remote_addr,uint16_t remote_port)281 static int net_conn_change_remote(struct net_conn *conn,
282 				  const struct sockaddr *remote_addr,
283 				  uint16_t remote_port)
284 {
285 	NET_DBG("[%zu] connection handler %p changed remote",
286 		conn - conns, conn);
287 
288 	if (remote_addr) {
289 		if (IS_ENABLED(CONFIG_NET_IPV6) &&
290 		    remote_addr->sa_family == AF_INET6) {
291 			memcpy(&conn->remote_addr, remote_addr,
292 			       sizeof(struct sockaddr_in6));
293 
294 			if (!net_ipv6_is_addr_unspecified(
295 				    &net_sin6(remote_addr)->
296 				    sin6_addr)) {
297 				conn->flags |= NET_CONN_REMOTE_ADDR_SPEC;
298 			}
299 		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
300 			   remote_addr->sa_family == AF_INET) {
301 			memcpy(&conn->remote_addr, remote_addr,
302 			       sizeof(struct sockaddr_in));
303 
304 			if (net_sin(remote_addr)->sin_addr.s_addr) {
305 				conn->flags |= NET_CONN_REMOTE_ADDR_SPEC;
306 			}
307 		} else {
308 			NET_ERR("Remote address family not set");
309 			return -EINVAL;
310 		}
311 
312 		conn->flags |= NET_CONN_REMOTE_ADDR_SET;
313 	} else {
314 		conn->flags &= ~NET_CONN_REMOTE_ADDR_SPEC;
315 		conn->flags &= ~NET_CONN_REMOTE_ADDR_SET;
316 	}
317 
318 	if (remote_port) {
319 		conn->flags |= NET_CONN_REMOTE_PORT_SPEC;
320 		net_sin(&conn->remote_addr)->sin_port = htons(remote_port);
321 	} else {
322 		conn->flags &= ~NET_CONN_REMOTE_PORT_SPEC;
323 	}
324 
325 	return 0;
326 }
327 
net_conn_register(uint16_t proto,uint8_t family,const struct sockaddr * remote_addr,const struct sockaddr * local_addr,uint16_t remote_port,uint16_t local_port,struct net_context * context,net_conn_cb_t cb,void * user_data,struct net_conn_handle ** handle)328 int net_conn_register(uint16_t proto, uint8_t family,
329 		      const struct sockaddr *remote_addr,
330 		      const struct sockaddr *local_addr,
331 		      uint16_t remote_port,
332 		      uint16_t local_port,
333 		      struct net_context *context,
334 		      net_conn_cb_t cb,
335 		      void *user_data,
336 		      struct net_conn_handle **handle)
337 {
338 	struct net_conn *conn;
339 	uint8_t flags = 0U;
340 	int ret;
341 
342 	conn = conn_find_handler(context != NULL ? net_context_get_iface(context) : NULL,
343 				 proto, family, remote_addr, local_addr,
344 				 remote_port, local_port,
345 				 context != NULL ?
346 					net_context_is_reuseport_set(context) :
347 					false);
348 	if (conn) {
349 		NET_ERR("Identical connection handler %p already found.", conn);
350 		return -EADDRINUSE;
351 	}
352 
353 	conn = conn_get_unused();
354 	if (!conn) {
355 		NET_ERR("Not enough connection contexts. "
356 			"Consider increasing CONFIG_NET_MAX_CONN.");
357 		return -ENOENT;
358 	}
359 
360 	if (local_addr) {
361 		if (IS_ENABLED(CONFIG_NET_IPV6) &&
362 		    local_addr->sa_family == AF_INET6) {
363 			memcpy(&conn->local_addr, local_addr,
364 			       sizeof(struct sockaddr_in6));
365 
366 			if (!net_ipv6_is_addr_unspecified(
367 				    &net_sin6(local_addr)->
368 				    sin6_addr)) {
369 				flags |= NET_CONN_LOCAL_ADDR_SPEC;
370 			}
371 		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
372 			   local_addr->sa_family == AF_INET) {
373 			memcpy(&conn->local_addr, local_addr,
374 			       sizeof(struct sockaddr_in));
375 
376 			if (net_sin(local_addr)->sin_addr.s_addr) {
377 				flags |= NET_CONN_LOCAL_ADDR_SPEC;
378 			}
379 		} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
380 			   local_addr->sa_family == AF_CAN) {
381 			memcpy(&conn->local_addr, local_addr,
382 			       sizeof(struct sockaddr_can));
383 		} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
384 			   local_addr->sa_family == AF_PACKET) {
385 			memcpy(&conn->local_addr, local_addr,
386 			       sizeof(struct sockaddr_ll));
387 		} else {
388 			NET_ERR("Local address family not set");
389 			goto error;
390 		}
391 
392 		flags |= NET_CONN_LOCAL_ADDR_SET;
393 	}
394 
395 	if (remote_addr && local_addr) {
396 		if (remote_addr->sa_family != local_addr->sa_family) {
397 			NET_ERR("Address families different");
398 			goto error;
399 		}
400 	}
401 
402 	if (local_port) {
403 		flags |= NET_CONN_LOCAL_PORT_SPEC;
404 		net_sin(&conn->local_addr)->sin_port = htons(local_port);
405 	}
406 
407 	net_conn_change_callback(conn, cb, user_data);
408 
409 	conn->flags = flags;
410 	conn->proto = proto;
411 	conn->family = family;
412 	conn->context = context;
413 
414 	/*
415 	 * Since the net_conn_change_remote() updates the flags in connection,
416 	 * must to be called after set the flags to connection.
417 	 */
418 	ret = net_conn_change_remote(conn, remote_addr, remote_port);
419 	if (ret) {
420 		goto error;
421 	}
422 
423 	if (handle) {
424 		*handle = (struct net_conn_handle *)conn;
425 	}
426 
427 	conn_set_used(conn);
428 
429 	conn->v6only = net_context_is_v6only_set(context);
430 
431 	conn_register_debug(conn, remote_port, local_port);
432 
433 	return 0;
434 error:
435 	conn_set_unused(conn);
436 	return -EINVAL;
437 }
438 
net_conn_unregister(struct net_conn_handle * handle)439 int net_conn_unregister(struct net_conn_handle *handle)
440 {
441 	struct net_conn *conn = (struct net_conn *)handle;
442 
443 	if (conn < &conns[0] || conn > &conns[CONFIG_NET_MAX_CONN]) {
444 		return -EINVAL;
445 	}
446 
447 	if (!(conn->flags & NET_CONN_IN_USE)) {
448 		return -ENOENT;
449 	}
450 
451 	NET_DBG("Connection handler %p removed", conn);
452 
453 	k_mutex_lock(&conn_lock, K_FOREVER);
454 	sys_slist_find_and_remove(&conn_used, &conn->node);
455 	k_mutex_unlock(&conn_lock);
456 
457 	conn_set_unused(conn);
458 
459 	return 0;
460 }
461 
net_conn_update(struct net_conn_handle * handle,net_conn_cb_t cb,void * user_data,const struct sockaddr * remote_addr,uint16_t remote_port)462 int net_conn_update(struct net_conn_handle *handle,
463 		    net_conn_cb_t cb,
464 		    void *user_data,
465 		    const struct sockaddr *remote_addr,
466 		    uint16_t remote_port)
467 {
468 	struct net_conn *conn = (struct net_conn *)handle;
469 	int ret;
470 
471 	if (conn < &conns[0] || conn > &conns[CONFIG_NET_MAX_CONN]) {
472 		return -EINVAL;
473 	}
474 
475 	if (!(conn->flags & NET_CONN_IN_USE)) {
476 		return -ENOENT;
477 	}
478 
479 	net_conn_change_callback(conn, cb, user_data);
480 
481 	ret = net_conn_change_remote(conn, remote_addr, remote_port);
482 
483 	return ret;
484 }
485 
conn_addr_cmp(struct net_pkt * pkt,union net_ip_header * ip_hdr,struct sockaddr * addr,bool is_remote)486 static bool conn_addr_cmp(struct net_pkt *pkt,
487 			  union net_ip_header *ip_hdr,
488 			  struct sockaddr *addr,
489 			  bool is_remote)
490 {
491 	if (addr->sa_family != net_pkt_family(pkt)) {
492 		return false;
493 	}
494 
495 	if (IS_ENABLED(CONFIG_NET_IPV6) &&
496 	    net_pkt_family(pkt) == AF_INET6 &&
497 	    addr->sa_family == AF_INET6) {
498 		uint8_t *addr6;
499 
500 		if (is_remote) {
501 			addr6 = ip_hdr->ipv6->src;
502 		} else {
503 			addr6 = ip_hdr->ipv6->dst;
504 		}
505 
506 		if (!net_ipv6_is_addr_unspecified(
507 			    &net_sin6(addr)->sin6_addr)) {
508 			if (!net_ipv6_addr_cmp_raw((uint8_t *)&net_sin6(addr)->sin6_addr,
509 						   addr6)) {
510 				return false;
511 			}
512 		}
513 
514 		return true;
515 	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
516 		   net_pkt_family(pkt) == AF_INET &&
517 		   addr->sa_family == AF_INET) {
518 		uint8_t *addr4;
519 
520 		if (is_remote) {
521 			addr4 = ip_hdr->ipv4->src;
522 		} else {
523 			addr4 = ip_hdr->ipv4->dst;
524 		}
525 
526 		if (net_sin(addr)->sin_addr.s_addr) {
527 			if (!net_ipv4_addr_cmp_raw((uint8_t *)&net_sin(addr)->sin_addr,
528 						   addr4)) {
529 				return false;
530 			}
531 		}
532 	}
533 
534 	return true;
535 }
536 
conn_send_icmp_error(struct net_pkt * pkt)537 static inline void conn_send_icmp_error(struct net_pkt *pkt)
538 {
539 	if (IS_ENABLED(CONFIG_NET_DISABLE_ICMP_DESTINATION_UNREACHABLE)) {
540 		return;
541 	}
542 
543 	if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
544 		net_icmpv6_send_error(pkt, NET_ICMPV6_DST_UNREACH,
545 				      NET_ICMPV6_DST_UNREACH_NO_PORT, 0);
546 
547 	} else if (IS_ENABLED(CONFIG_NET_IPV4)) {
548 		net_icmpv4_send_error(pkt, NET_ICMPV4_DST_UNREACH,
549 				      NET_ICMPV4_DST_UNREACH_NO_PORT);
550 	}
551 }
552 
conn_are_endpoints_valid(struct net_pkt * pkt,uint8_t family,union net_ip_header * ip_hdr,uint16_t src_port,uint16_t dst_port)553 static bool conn_are_endpoints_valid(struct net_pkt *pkt, uint8_t family,
554 				     union net_ip_header *ip_hdr,
555 				     uint16_t src_port, uint16_t dst_port)
556 {
557 	bool is_my_src_addr;
558 	bool is_same_src_and_dst_addr;
559 
560 	if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
561 		is_my_src_addr = net_ipv4_is_my_addr(
562 			(struct in_addr *)ip_hdr->ipv4->src);
563 		is_same_src_and_dst_addr = net_ipv4_addr_cmp_raw(
564 			ip_hdr->ipv4->src, ip_hdr->ipv4->dst);
565 	} else if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
566 		is_my_src_addr = net_ipv6_is_my_addr(
567 			(struct in6_addr *)ip_hdr->ipv6->src);
568 		is_same_src_and_dst_addr = net_ipv6_addr_cmp_raw(
569 			ip_hdr->ipv6->src, ip_hdr->ipv6->dst);
570 	} else {
571 		return true;
572 	}
573 
574 	bool is_same_src_and_dst_port = src_port == dst_port;
575 	bool are_invalid_endpoints =
576 		(is_same_src_and_dst_addr || is_my_src_addr) && is_same_src_and_dst_port;
577 
578 	return !are_invalid_endpoints;
579 }
580 
conn_raw_socket(struct net_pkt * pkt,struct net_conn * conn,uint8_t proto)581 static enum net_verdict conn_raw_socket(struct net_pkt *pkt,
582 					struct net_conn *conn, uint8_t proto)
583 {
584 	enum net_sock_type type = net_context_get_type(conn->context);
585 
586 	if (proto == ETH_P_ALL) {
587 		if ((type == SOCK_DGRAM && !net_pkt_is_l2_processed(pkt)) ||
588 		    (type == SOCK_RAW && net_pkt_is_l2_processed(pkt))) {
589 			return NET_CONTINUE;
590 		}
591 	}
592 
593 	/*
594 	 * After l2 processed only deliver protocol matched pkt,
595 	 * unless the connection protocol is all packets
596 	 */
597 	if (type == SOCK_DGRAM && net_pkt_is_l2_processed(pkt) &&
598 	    conn->proto != ETH_P_ALL &&
599 	    conn->proto != net_pkt_ll_proto_type(pkt)) {
600 		return NET_CONTINUE;
601 	}
602 
603 	if (!(conn->flags & NET_CONN_LOCAL_ADDR_SET)) {
604 		return NET_CONTINUE;
605 	}
606 
607 	struct net_if *pkt_iface = net_pkt_iface(pkt);
608 	struct sockaddr_ll *local;
609 	struct net_pkt *raw_pkt;
610 
611 	local = (struct sockaddr_ll *)&conn->local_addr;
612 
613 	if (local->sll_ifindex != net_if_get_by_iface(pkt_iface)) {
614 		return NET_CONTINUE;
615 	}
616 
617 	NET_DBG("[%p] raw match found cb %p ud %p", conn, conn->cb,
618 		conn->user_data);
619 
620 	raw_pkt = net_pkt_clone(pkt, CLONE_TIMEOUT);
621 	if (!raw_pkt) {
622 		net_stats_update_per_proto_drop(pkt_iface, proto);
623 		NET_WARN("pkt cloning failed, pkt %p dropped", pkt);
624 		return NET_DROP;
625 	}
626 
627 	if (conn->cb(conn, raw_pkt, NULL, NULL, conn->user_data) == NET_DROP) {
628 		net_stats_update_per_proto_drop(pkt_iface, proto);
629 		net_pkt_unref(raw_pkt);
630 	} else {
631 		net_stats_update_per_proto_recv(pkt_iface, proto);
632 	}
633 
634 	return NET_OK;
635 }
636 
net_conn_input(struct net_pkt * pkt,union net_ip_header * ip_hdr,uint8_t proto,union net_proto_header * proto_hdr)637 enum net_verdict net_conn_input(struct net_pkt *pkt,
638 				union net_ip_header *ip_hdr,
639 				uint8_t proto,
640 				union net_proto_header *proto_hdr)
641 {
642 	struct net_if *pkt_iface = net_pkt_iface(pkt);
643 	uint8_t pkt_family = net_pkt_family(pkt);
644 	uint16_t src_port = 0U, dst_port = 0U;
645 
646 	if (!net_pkt_filter_local_in_recv_ok(pkt)) {
647 		/* drop the packet */
648 		return NET_DROP;
649 	}
650 
651 	if (IS_ENABLED(CONFIG_NET_IP) && (pkt_family == AF_INET || pkt_family == AF_INET6)) {
652 		if (IS_ENABLED(CONFIG_NET_UDP) && proto == IPPROTO_UDP) {
653 			src_port = proto_hdr->udp->src_port;
654 			dst_port = proto_hdr->udp->dst_port;
655 		} else if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP) {
656 			if (proto_hdr->tcp == NULL) {
657 				return NET_DROP;
658 			}
659 			src_port = proto_hdr->tcp->src_port;
660 			dst_port = proto_hdr->tcp->dst_port;
661 		}
662 		if (!conn_are_endpoints_valid(pkt, pkt_family, ip_hdr, src_port, dst_port)) {
663 			NET_DBG("Dropping invalid src/dst end-points packet");
664 			return NET_DROP;
665 		}
666 	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && pkt_family == AF_PACKET) {
667 		if (proto != ETH_P_ALL && proto != IPPROTO_RAW) {
668 			return NET_DROP;
669 		}
670 	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && pkt_family == AF_CAN) {
671 		if (proto != CAN_RAW) {
672 			return NET_DROP;
673 		}
674 	} else {
675 		NET_DBG("No suitable protocol handler configured");
676 		return NET_DROP;
677 	}
678 
679 	NET_DBG("Check %s listener for pkt %p src port %u dst port %u"
680 		" family %d", net_proto2str(net_pkt_family(pkt), proto), pkt,
681 		ntohs(src_port), ntohs(dst_port), net_pkt_family(pkt));
682 
683 
684 	struct net_conn *best_match = NULL;
685 	int16_t best_rank = -1;
686 	bool is_mcast_pkt = false;
687 	bool mcast_pkt_delivered = false;
688 	bool is_bcast_pkt = false;
689 	bool raw_pkt_delivered = false;
690 	bool raw_pkt_continue = false;
691 	struct net_conn *conn;
692 	net_conn_cb_t cb = NULL;
693 	void *user_data = NULL;
694 
695 	if (IS_ENABLED(CONFIG_NET_IP)) {
696 		/* If we receive a packet with multicast destination address, we might
697 		 * need to deliver the packet to multiple recipients.
698 		 */
699 		if (IS_ENABLED(CONFIG_NET_IPV4) && pkt_family == AF_INET) {
700 			if (net_ipv4_is_addr_mcast((struct in_addr *)ip_hdr->ipv4->dst)) {
701 				is_mcast_pkt = true;
702 			} else if (net_if_ipv4_is_addr_bcast(pkt_iface,
703 							     (struct in_addr *)ip_hdr->ipv4->dst)) {
704 				is_bcast_pkt = true;
705 			}
706 		} else if (IS_ENABLED(CONFIG_NET_IPV6) && pkt_family == AF_INET6) {
707 			is_mcast_pkt = net_ipv6_is_addr_mcast((struct in6_addr *)ip_hdr->ipv6->dst);
708 		}
709 	}
710 
711 	k_mutex_lock(&conn_lock, K_FOREVER);
712 
713 	SYS_SLIST_FOR_EACH_CONTAINER(&conn_used, conn, node) {
714 		/* Is the candidate connection matching the packet's interface? */
715 		if (conn->context != NULL &&
716 		    net_context_is_bound_to_iface(conn->context) &&
717 		    net_pkt_iface(pkt) != net_context_get_iface(conn->context)) {
718 			continue; /* wrong interface */
719 		}
720 
721 		/* Is the candidate connection matching the packet's protocol family? */
722 		if (conn->family != AF_UNSPEC &&
723 		    conn->family != pkt_family) {
724 			if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET)) {
725 				/* If there are other listening connections than
726 				 * AF_PACKET, the packet shall be also passed back to
727 				 * net_conn_input() in upper layer processing in order to
728 				 * re-check if there is any listening socket interested
729 				 * in this packet.
730 				 */
731 				if (conn->family != AF_PACKET) {
732 					raw_pkt_continue = true;
733 				}
734 			}
735 
736 			if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) {
737 				if (!(conn->family == AF_INET6 && pkt_family == AF_INET &&
738 				      !conn->v6only)) {
739 					continue;
740 				}
741 			} else {
742 				continue; /* wrong protocol family */
743 			}
744 
745 			/* We might have a match for v4-to-v6 mapping, check more */
746 		}
747 
748 		/* Is the candidate connection matching the packet's protocol within the family? */
749 		if (conn->proto != proto) {
750 			/* For packet socket data, the proto is set to ETH_P_ALL
751 			 * or IPPROTO_RAW but the listener might have a specific
752 			 * protocol set. This is ok and let the packet pass this
753 			 * check in this case.
754 			 */
755 			if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && pkt_family == AF_PACKET) {
756 				if (proto != ETH_P_ALL && proto != IPPROTO_RAW) {
757 					continue; /* wrong protocol */
758 				}
759 			} else {
760 				continue; /* wrong protocol */
761 			}
762 		}
763 
764 		/* Apply protocol-specific matching criteria... */
765 		uint8_t conn_family = conn->family;
766 
767 		if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && conn_family == AF_PACKET) {
768 			/* This code shall be only executed when one enters
769 			 * the net_conn_input() from net_packet_socket() which
770 			 * targets AF_PACKET sockets.
771 			 *
772 			 * All AF_PACKET connections will receive the packet if
773 			 * their socket type and - in case of IPPROTO - protocol
774 			 * also matches.
775 			 */
776 			if (proto == ETH_P_ALL) {
777 				/* We shall continue with ETH_P_ALL to IPPROTO_RAW: */
778 				raw_pkt_continue = true;
779 			}
780 
781 			/* With IPPROTO_RAW deliver only if protocol match: */
782 			if ((proto == ETH_P_ALL && conn->proto != IPPROTO_RAW) ||
783 			    conn->proto == proto) {
784 				enum net_verdict ret = conn_raw_socket(pkt, conn, proto);
785 
786 				if (ret == NET_DROP) {
787 					k_mutex_unlock(&conn_lock);
788 					goto drop;
789 				} else if (ret == NET_OK) {
790 					raw_pkt_delivered = true;
791 				}
792 
793 				continue; /* packet was consumed */
794 			}
795 		} else if ((IS_ENABLED(CONFIG_NET_UDP) || IS_ENABLED(CONFIG_NET_TCP)) &&
796 			   (conn_family == AF_INET || conn_family == AF_INET6 ||
797 			    conn_family == AF_UNSPEC)) {
798 			/* Is the candidate connection matching the packet's TCP/UDP
799 			 * address and port?
800 			 */
801 			if (net_sin(&conn->remote_addr)->sin_port &&
802 			    net_sin(&conn->remote_addr)->sin_port != src_port) {
803 				continue; /* wrong remote port */
804 			}
805 
806 			if (net_sin(&conn->local_addr)->sin_port &&
807 			    net_sin(&conn->local_addr)->sin_port != dst_port) {
808 				continue; /* wrong local port */
809 			}
810 
811 			if ((conn->flags & NET_CONN_REMOTE_ADDR_SET) &&
812 			    !conn_addr_cmp(pkt, ip_hdr, &conn->remote_addr, true)) {
813 				continue; /* wrong remote address */
814 			}
815 
816 			if ((conn->flags & NET_CONN_LOCAL_ADDR_SET) &&
817 			    !conn_addr_cmp(pkt, ip_hdr, &conn->local_addr, false)) {
818 
819 				/* Check if we could do a v4-mapping-to-v6 and the IPv6 socket
820 				 * has no IPV6_V6ONLY option set and if the local IPV6 address
821 				 * is unspecified, then we could accept a connection from IPv4
822 				 * address by mapping it to IPv6 address.
823 				 */
824 				if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) {
825 					if (!(conn->family == AF_INET6 && pkt_family == AF_INET &&
826 					      !conn->v6only &&
827 					      net_ipv6_is_addr_unspecified(
828 						      &net_sin6(&conn->local_addr)->sin6_addr))) {
829 						continue; /* wrong local address */
830 					}
831 				} else {
832 					continue; /* wrong local address */
833 				}
834 
835 				/* We might have a match for v4-to-v6 mapping,
836 				 * continue with rank checking.
837 				 */
838 			}
839 
840 			if (best_rank < NET_CONN_RANK(conn->flags)) {
841 				struct net_pkt *mcast_pkt;
842 
843 				if (!is_mcast_pkt) {
844 					best_rank = NET_CONN_RANK(conn->flags);
845 					best_match = conn;
846 
847 					continue; /* found a match - but maybe not yet the best */
848 				}
849 
850 				/* If we have a multicast packet, and we found
851 				 * a match, then deliver the packet immediately
852 				 * to the handler. As there might be several
853 				 * sockets interested about these, we need to
854 				 * clone the received pkt.
855 				 */
856 
857 				NET_DBG("[%p] mcast match found cb %p ud %p", conn, conn->cb,
858 					conn->user_data);
859 
860 				mcast_pkt = net_pkt_clone(pkt, CLONE_TIMEOUT);
861 				if (!mcast_pkt) {
862 					k_mutex_unlock(&conn_lock);
863 					goto drop;
864 				}
865 
866 				if (conn->cb(conn, mcast_pkt, ip_hdr, proto_hdr, conn->user_data) ==
867 				    NET_DROP) {
868 					net_stats_update_per_proto_drop(pkt_iface, proto);
869 					net_pkt_unref(mcast_pkt);
870 				} else {
871 					net_stats_update_per_proto_recv(pkt_iface, proto);
872 				}
873 
874 				mcast_pkt_delivered = true;
875 			}
876 		} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && conn_family == AF_CAN) {
877 			best_match = conn;
878 		}
879 	} /* loop end */
880 
881 	if (best_match) {
882 		cb = best_match->cb;
883 		user_data = best_match->user_data;
884 	}
885 
886 	k_mutex_unlock(&conn_lock);
887 
888 	if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && pkt_family == AF_PACKET) {
889 		if (raw_pkt_continue) {
890 			/* When there is open connection different than
891 			 * AF_PACKET this packet shall be also handled in
892 			 * the upper net stack layers.
893 			 */
894 			return NET_CONTINUE;
895 		}
896 		if (raw_pkt_delivered) {
897 			/* As one or more raw socket packets
898 			 * have already been delivered in the loop above,
899 			 * we shall not call the callback again here.
900 			 */
901 			net_pkt_unref(pkt);
902 			return NET_OK;
903 		}
904 	}
905 
906 	if (IS_ENABLED(CONFIG_NET_IP) && is_mcast_pkt && mcast_pkt_delivered) {
907 		/* As one or more multicast packets
908 		 * have already been delivered in the loop above,
909 		 * we shall not call the callback again here.
910 		 */
911 		net_pkt_unref(pkt);
912 		return NET_OK;
913 	}
914 
915 	if (cb) {
916 		NET_DBG("[%p] match found cb %p ud %p rank 0x%02x", best_match, cb,
917 			user_data, NET_CONN_RANK(best_match->flags));
918 
919 		if (cb(best_match, pkt, ip_hdr, proto_hdr, user_data)
920 				== NET_DROP) {
921 			goto drop;
922 		}
923 
924 		net_stats_update_per_proto_recv(pkt_iface, proto);
925 
926 		return NET_OK;
927 	}
928 
929 	NET_DBG("No match found.");
930 
931 	if (IS_ENABLED(CONFIG_NET_IP) && (pkt_family == AF_INET || pkt_family == AF_INET6) &&
932 	    !(is_mcast_pkt || is_bcast_pkt)) {
933 		if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP &&
934 		    IS_ENABLED(CONFIG_NET_TCP_REJECT_CONN_WITH_RST)) {
935 			net_tcp_reply_rst(pkt);
936 			net_stats_update_tcp_seg_connrst(pkt_iface);
937 		} else {
938 			conn_send_icmp_error(pkt);
939 		}
940 	}
941 
942 drop:
943 	net_stats_update_per_proto_drop(pkt_iface, proto);
944 
945 	return NET_DROP;
946 }
947 
net_conn_foreach(net_conn_foreach_cb_t cb,void * user_data)948 void net_conn_foreach(net_conn_foreach_cb_t cb, void *user_data)
949 {
950 	struct net_conn *conn;
951 
952 	k_mutex_lock(&conn_lock, K_FOREVER);
953 
954 	SYS_SLIST_FOR_EACH_CONTAINER(&conn_used, conn, node) {
955 		cb(conn, user_data);
956 	}
957 
958 	k_mutex_unlock(&conn_lock);
959 }
960 
net_conn_init(void)961 void net_conn_init(void)
962 {
963 	int i;
964 
965 	sys_slist_init(&conn_unused);
966 	sys_slist_init(&conn_used);
967 
968 	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
969 		sys_slist_prepend(&conn_unused, &conns[i].node);
970 	}
971 }
972