1 /** @file
2  * @brief Network context API
3  *
4  * An API for applications to define a network connection.
5  */
6 
7 /*
8  * Copyright (c) 2016 Intel Corporation
9  * Copyright (c) 2021 Nordic Semiconductor
10  *
11  * SPDX-License-Identifier: Apache-2.0
12  */
13 
14 #include <logging/log.h>
15 LOG_MODULE_REGISTER(net_ctx, CONFIG_NET_CONTEXT_LOG_LEVEL);
16 
17 #include <kernel.h>
18 #include <random/rand32.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <stdbool.h>
22 
23 #include <net/net_pkt.h>
24 #include <net/net_ip.h>
25 #include <net/socket.h>
26 #include <net/net_context.h>
27 #include <net/net_offload.h>
28 #include <net/ethernet.h>
29 #include <net/socket_can.h>
30 
31 #include "connection.h"
32 #include "net_private.h"
33 
34 #include "ipv6.h"
35 #include "ipv4.h"
36 #include "udp_internal.h"
37 #include "tcp_internal.h"
38 #include "net_stats.h"
39 
40 #if IS_ENABLED(CONFIG_NET_TCP2)
41 #include "tcp2.h"
42 #endif
43 
44 #ifndef EPFNOSUPPORT
45 /* Some old versions of newlib haven't got this defined in errno.h,
46  * Just use EPROTONOSUPPORT in this case
47  */
48 #define EPFNOSUPPORT EPROTONOSUPPORT
49 #endif
50 
51 #define PKT_WAIT_TIME K_SECONDS(1)
52 
53 #define NET_MAX_CONTEXT CONFIG_NET_MAX_CONTEXTS
54 
55 static struct net_context contexts[NET_MAX_CONTEXT];
56 
57 /* We need to lock the contexts array as these APIs are typically called
58  * from applications which are usually run in task context.
59  */
60 static struct k_sem contexts_lock;
61 
62 #if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
check_used_port(enum net_ip_protocol ip_proto,uint16_t local_port,const struct sockaddr * local_addr)63 static int check_used_port(enum net_ip_protocol ip_proto,
64 			   uint16_t local_port,
65 			   const struct sockaddr *local_addr)
66 
67 {
68 	int i;
69 
70 	for (i = 0; i < NET_MAX_CONTEXT; i++) {
71 		if (!net_context_is_used(&contexts[i])) {
72 			continue;
73 		}
74 
75 		if (!(net_context_get_ip_proto(&contexts[i]) == ip_proto &&
76 		      net_sin((struct sockaddr *)&
77 			      contexts[i].local)->sin_port == local_port)) {
78 			continue;
79 		}
80 
81 		if (IS_ENABLED(CONFIG_NET_IPV6) &&
82 		    local_addr->sa_family == AF_INET6) {
83 			if (net_sin6_ptr(&contexts[i].local)->sin6_addr == NULL) {
84 				continue;
85 			}
86 
87 			if (net_ipv6_addr_cmp(
88 				    net_sin6_ptr(&contexts[i].local)->
89 							     sin6_addr,
90 				    &((struct sockaddr_in6 *)
91 				      local_addr)->sin6_addr)) {
92 				return -EEXIST;
93 			}
94 		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
95 			   local_addr->sa_family == AF_INET) {
96 			if (net_sin_ptr(&contexts[i].local)->sin_addr == NULL) {
97 				continue;
98 			}
99 
100 			if (net_ipv4_addr_cmp(
101 				    net_sin_ptr(&contexts[i].local)->
102 							      sin_addr,
103 				    &((struct sockaddr_in *)
104 				      local_addr)->sin_addr)) {
105 				return -EEXIST;
106 			}
107 		}
108 	}
109 
110 	return 0;
111 }
112 
find_available_port(struct net_context * context,const struct sockaddr * addr)113 static uint16_t find_available_port(struct net_context *context,
114 				    const struct sockaddr *addr)
115 {
116 	uint16_t local_port;
117 
118 	do {
119 		local_port = sys_rand32_get() | 0x8000;
120 		if (local_port <= 1023U) {
121 			/* 0 - 1023 ports are reserved */
122 			continue;
123 		}
124 	} while (check_used_port(net_context_get_ip_proto(context),
125 				 htons(local_port), addr) == -EEXIST);
126 
127 	return htons(local_port);
128 }
129 #else
130 #define check_used_port(...) 0
131 #define find_available_port(...) 0
132 #endif
133 
net_context_port_in_use(enum net_ip_protocol ip_proto,uint16_t local_port,const struct sockaddr * local_addr)134 bool net_context_port_in_use(enum net_ip_protocol ip_proto,
135 			   uint16_t local_port,
136 			   const struct sockaddr *local_addr)
137 {
138 	return check_used_port(ip_proto, htons(local_port), local_addr) != 0;
139 }
140 
net_context_get(sa_family_t family,enum net_sock_type type,uint16_t ip_proto,struct net_context ** context)141 int net_context_get(sa_family_t family,
142 		    enum net_sock_type type,
143 		    uint16_t ip_proto,
144 		    struct net_context **context)
145 {
146 	int i, ret = -ENOENT;
147 
148 	if (IS_ENABLED(CONFIG_NET_CONTEXT_CHECK)) {
149 		if (!IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
150 			NET_DBG("IPv4 disabled");
151 			return -EPFNOSUPPORT;
152 		}
153 
154 		if (!IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
155 			NET_DBG("IPv6 disabled");
156 			return -EPFNOSUPPORT;
157 		}
158 
159 		if (!IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
160 			NET_DBG("AF_CAN disabled");
161 			return -EPFNOSUPPORT;
162 		}
163 
164 		if (type == SOCK_RAW) {
165 			if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
166 			    IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
167 				if (family != AF_PACKET && family != AF_CAN) {
168 					NET_DBG("Invalid family");
169 					return -EINVAL;
170 				}
171 			} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
172 				   !IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
173 				if (family != AF_PACKET) {
174 					NET_DBG("Invalid family");
175 					return -EINVAL;
176 				}
177 			} else if (!IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
178 				   IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
179 				if (family != AF_CAN) {
180 					NET_DBG("Invalid family");
181 					return -EINVAL;
182 				}
183 			}
184 		} else {
185 			if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
186 			    family == AF_PACKET && type == SOCK_DGRAM &&
187 			    ip_proto > 0) {
188 				goto check_context;
189 			} else if (family == AF_PACKET || family == AF_CAN) {
190 				NET_DBG("Invalid family");
191 				return -EPROTOTYPE;
192 			}
193 		}
194 
195 		if (!IS_ENABLED(CONFIG_NET_UDP)) {
196 			if (type == SOCK_DGRAM) {
197 				NET_DBG("Datagram context disabled");
198 				return -EPROTOTYPE;
199 			}
200 
201 			if (ip_proto == IPPROTO_UDP) {
202 				NET_DBG("UDP disabled");
203 				return -EPROTONOSUPPORT;
204 			}
205 		}
206 
207 		if (!IS_ENABLED(CONFIG_NET_TCP)) {
208 			if (type == SOCK_STREAM) {
209 				NET_DBG("Stream context disabled");
210 				return -EPROTOTYPE;
211 			}
212 
213 			if (ip_proto == IPPROTO_TCP) {
214 				NET_DBG("TCP disabled");
215 				return -EPROTONOSUPPORT;
216 			}
217 		}
218 
219 		if (family != AF_INET && family != AF_INET6 &&
220 		    family != AF_PACKET && family != AF_CAN) {
221 			NET_DBG("Unknown address family %d", family);
222 			return -EAFNOSUPPORT;
223 		}
224 
225 		if (type != SOCK_DGRAM && type != SOCK_STREAM &&
226 		    type != SOCK_RAW) {
227 			NET_DBG("Unknown context type");
228 			return -EPROTOTYPE;
229 		}
230 
231 		if (type != SOCK_RAW && ip_proto != IPPROTO_UDP &&
232 		    ip_proto != IPPROTO_TCP) {
233 			NET_DBG("Unknown IP protocol %d", ip_proto);
234 			return -EPROTONOSUPPORT;
235 		}
236 
237 		if ((type == SOCK_STREAM && ip_proto == IPPROTO_UDP) ||
238 		    (type == SOCK_DGRAM && ip_proto == IPPROTO_TCP)) {
239 			NET_DBG("Context type and protocol mismatch,"
240 				" type %d proto %d", type, ip_proto);
241 			return -EOPNOTSUPP;
242 		}
243 
244 	check_context:
245 		if (!context) {
246 			NET_DBG("Invalid context");
247 			return -EINVAL;
248 		}
249 	}
250 
251 	k_sem_take(&contexts_lock, K_FOREVER);
252 
253 	for (i = 0; i < NET_MAX_CONTEXT; i++) {
254 		if (net_context_is_used(&contexts[i])) {
255 			continue;
256 		}
257 
258 		memset(&contexts[i], 0, sizeof(contexts[i]));
259 	/* FIXME - Figure out a way to get the correct network interface
260 	 * as it is not known at this point yet.
261 	 */
262 		if (!net_if_is_ip_offloaded(net_if_get_default())
263 			&& ip_proto == IPPROTO_TCP) {
264 			if (net_tcp_get(&contexts[i]) < 0) {
265 				break;
266 			}
267 		}
268 
269 		contexts[i].iface = -1;
270 		contexts[i].flags = 0U;
271 		atomic_set(&contexts[i].refcount, 1);
272 
273 		net_context_set_family(&contexts[i], family);
274 		net_context_set_type(&contexts[i], type);
275 		net_context_set_ip_proto(&contexts[i], ip_proto);
276 
277 #if defined(CONFIG_NET_CONTEXT_RCVTIMEO)
278 		contexts[i].options.rcvtimeo = K_FOREVER;
279 #endif
280 #if defined(CONFIG_NET_CONTEXT_SNDTIMEO)
281 		contexts[i].options.sndtimeo = K_FOREVER;
282 #endif
283 
284 		if (IS_ENABLED(CONFIG_NET_IPV6) ||
285 		    IS_ENABLED(CONFIG_NET_IPV4)) {
286 			(void)memset(&contexts[i].remote, 0,
287 				     sizeof(struct sockaddr));
288 			(void)memset(&contexts[i].local, 0,
289 				     sizeof(struct sockaddr_ptr));
290 		}
291 
292 		if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
293 			struct sockaddr_in6 *addr6 = (struct sockaddr_in6
294 						      *)&contexts[i].local;
295 			addr6->sin6_port = find_available_port(&contexts[i],
296 						    (struct sockaddr *)addr6);
297 
298 			if (!addr6->sin6_port) {
299 				ret = -EADDRINUSE;
300 				break;
301 			}
302 		}
303 
304 		if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
305 			struct sockaddr_in *addr = (struct sockaddr_in
306 						      *)&contexts[i].local;
307 			addr->sin_port = find_available_port(&contexts[i],
308 						    (struct sockaddr *)addr);
309 
310 			if (!addr->sin_port) {
311 				ret = -EADDRINUSE;
312 				break;
313 			}
314 		}
315 
316 #if defined(CONFIG_NET_CONTEXT_SYNC_RECV)
317 		k_sem_init(&contexts[i].recv_data_wait, 1, K_SEM_MAX_LIMIT);
318 #endif /* CONFIG_NET_CONTEXT_SYNC_RECV */
319 
320 		k_mutex_init(&contexts[i].lock);
321 
322 		contexts[i].flags |= NET_CONTEXT_IN_USE;
323 		*context = &contexts[i];
324 
325 		ret = 0;
326 		break;
327 	}
328 
329 	k_sem_give(&contexts_lock);
330 
331 	/* FIXME - Figure out a way to get the correct network interface
332 	 * as it is not known at this point yet.
333 	 */
334 	if (!ret && IS_ENABLED(CONFIG_NET_OFFLOAD) &&
335 	    net_if_is_ip_offloaded(net_if_get_default())) {
336 		ret = net_offload_get(net_if_get_default(),
337 				      family,
338 				      type,
339 				      ip_proto,
340 				      context);
341 		if (ret < 0) {
342 			(*context)->flags &= ~NET_CONTEXT_IN_USE;
343 			*context = NULL;
344 		}
345 
346 		return ret;
347 	}
348 
349 	return ret;
350 }
351 
net_context_ref(struct net_context * context)352 int net_context_ref(struct net_context *context)
353 {
354 	int old_rc = atomic_inc(&context->refcount);
355 
356 	return old_rc + 1;
357 }
358 
net_context_unref(struct net_context * context)359 int net_context_unref(struct net_context *context)
360 {
361 	int old_rc = atomic_dec(&context->refcount);
362 
363 	if (old_rc != 1) {
364 		return old_rc - 1;
365 	}
366 
367 	k_mutex_lock(&context->lock, K_FOREVER);
368 
369 	net_tcp_unref(context);
370 
371 	if (context->conn_handler) {
372 		if (IS_ENABLED(CONFIG_NET_TCP) || IS_ENABLED(CONFIG_NET_UDP) ||
373 		    IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
374 			net_conn_unregister(context->conn_handler);
375 		}
376 
377 		context->conn_handler = NULL;
378 	}
379 
380 	net_context_set_state(context, NET_CONTEXT_UNCONNECTED);
381 
382 	context->flags &= ~NET_CONTEXT_IN_USE;
383 
384 	NET_DBG("Context %p released", context);
385 
386 	k_mutex_unlock(&context->lock);
387 
388 	return 0;
389 }
390 
net_context_put(struct net_context * context)391 int net_context_put(struct net_context *context)
392 {
393 	int ret = 0;
394 
395 	NET_ASSERT(context);
396 
397 	if (!PART_OF_ARRAY(contexts, context)) {
398 		return -EINVAL;
399 	}
400 
401 	k_mutex_lock(&context->lock, K_FOREVER);
402 
403 	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
404 	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
405 		context->flags &= ~NET_CONTEXT_IN_USE;
406 		ret = net_offload_put(net_context_get_iface(context), context);
407 		goto unlock;
408 	}
409 
410 	context->connect_cb = NULL;
411 	context->recv_cb = NULL;
412 	context->send_cb = NULL;
413 
414 	/* net_tcp_put() will handle decrementing refcount on stack's behalf */
415 	net_tcp_put(context);
416 
417 	/* Decrement refcount on user app's behalf */
418 	net_context_unref(context);
419 
420 unlock:
421 	k_mutex_unlock(&context->lock);
422 
423 	return ret;
424 }
425 
426 /* If local address is not bound, bind it to INADDR_ANY and random port. */
bind_default(struct net_context * context)427 static int bind_default(struct net_context *context)
428 {
429 	sa_family_t family = net_context_get_family(context);
430 
431 	if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
432 		struct sockaddr_in6 addr6;
433 
434 		if (net_sin6_ptr(&context->local)->sin6_addr) {
435 			return 0;
436 		}
437 
438 		addr6.sin6_family = AF_INET6;
439 		memcpy(&addr6.sin6_addr, net_ipv6_unspecified_address(),
440 		       sizeof(addr6.sin6_addr));
441 		addr6.sin6_port =
442 			find_available_port(context,
443 					    (struct sockaddr *)&addr6);
444 
445 		return net_context_bind(context, (struct sockaddr *)&addr6,
446 					sizeof(addr6));
447 	}
448 
449 	if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
450 		struct sockaddr_in addr4;
451 
452 		if (net_sin_ptr(&context->local)->sin_addr) {
453 			return 0;
454 		}
455 
456 		addr4.sin_family = AF_INET;
457 		addr4.sin_addr.s_addr = INADDR_ANY;
458 		addr4.sin_port =
459 			find_available_port(context,
460 					    (struct sockaddr *)&addr4);
461 
462 		return net_context_bind(context, (struct sockaddr *)&addr4,
463 					sizeof(addr4));
464 	}
465 
466 	if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && family == AF_PACKET) {
467 		struct sockaddr_ll ll_addr;
468 
469 		if (net_sll_ptr(&context->local)->sll_addr) {
470 			return 0;
471 		}
472 
473 		ll_addr.sll_family = AF_PACKET;
474 		ll_addr.sll_protocol = htons(ETH_P_ALL);
475 		ll_addr.sll_ifindex = net_if_get_by_iface(net_if_get_default());
476 
477 		return net_context_bind(context, (struct sockaddr *)&ll_addr,
478 					sizeof(ll_addr));
479 	}
480 
481 	if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
482 		struct sockaddr_can can_addr;
483 
484 		if (context->iface >= 0) {
485 			return 0;
486 		} else {
487 #if defined(CONFIG_NET_L2_CANBUS_RAW)
488 			struct net_if *iface;
489 
490 			iface = net_if_get_first_by_type(
491 						&NET_L2_GET_NAME(CANBUS_RAW));
492 			if (!iface) {
493 				return -ENOENT;
494 			}
495 
496 			can_addr.can_ifindex = net_if_get_by_iface(iface);
497 			context->iface = can_addr.can_ifindex;
498 #else
499 			return -ENOENT;
500 #endif
501 		}
502 
503 		can_addr.can_family = AF_CAN;
504 
505 		return net_context_bind(context, (struct sockaddr *)&can_addr,
506 					sizeof(can_addr));
507 	}
508 
509 	return -EINVAL;
510 }
511 
net_context_bind(struct net_context * context,const struct sockaddr * addr,socklen_t addrlen)512 int net_context_bind(struct net_context *context, const struct sockaddr *addr,
513 		     socklen_t addrlen)
514 {
515 	int ret;
516 
517 	NET_ASSERT(addr);
518 	NET_ASSERT(PART_OF_ARRAY(contexts, context));
519 
520 	/* If we already have connection handler, then it effectively
521 	 * means that it's already bound to an interface/port, and we
522 	 * don't support rebinding connection to new address/port in
523 	 * the code below.
524 	 * TODO: Support rebinding.
525 	 */
526 	if (context->conn_handler) {
527 		return -EISCONN;
528 	}
529 
530 	if (IS_ENABLED(CONFIG_NET_IPV6) && addr->sa_family == AF_INET6) {
531 		struct net_if *iface = NULL;
532 		struct in6_addr *ptr;
533 		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
534 
535 		if (addrlen < sizeof(struct sockaddr_in6)) {
536 			return -EINVAL;
537 		}
538 
539 		if (net_context_is_bound_to_iface(context)) {
540 			iface = net_context_get_iface(context);
541 		}
542 
543 		if (net_ipv6_is_addr_mcast(&addr6->sin6_addr)) {
544 			struct net_if_mcast_addr *maddr;
545 
546 			maddr = net_if_ipv6_maddr_lookup(&addr6->sin6_addr,
547 							 &iface);
548 			if (!maddr) {
549 				return -ENOENT;
550 			}
551 
552 			ptr = &maddr->address.in6_addr;
553 
554 		} else if (net_ipv6_is_addr_unspecified(&addr6->sin6_addr)) {
555 			if (iface == NULL) {
556 				iface = net_if_ipv6_select_src_iface(
557 					&net_sin6(&context->remote)->sin6_addr);
558 			}
559 
560 			ptr = (struct in6_addr *)net_ipv6_unspecified_address();
561 		} else {
562 			struct net_if_addr *ifaddr;
563 
564 			ifaddr = net_if_ipv6_addr_lookup(
565 					&addr6->sin6_addr,
566 					iface == NULL ? &iface : NULL);
567 			if (!ifaddr) {
568 				return -ENOENT;
569 			}
570 
571 			ptr = &ifaddr->address.in6_addr;
572 		}
573 
574 		if (!iface) {
575 			NET_ERR("Cannot bind to %s",
576 				log_strdup(net_sprint_ipv6_addr(
577 						   &addr6->sin6_addr)));
578 
579 			return -EADDRNOTAVAIL;
580 		}
581 
582 		if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
583 		    net_if_is_ip_offloaded(iface)) {
584 			net_context_set_iface(context, iface);
585 
586 			return net_offload_bind(iface,
587 						context,
588 						addr,
589 						addrlen);
590 		}
591 
592 		k_mutex_lock(&context->lock, K_FOREVER);
593 
594 		ret = 0;
595 
596 		net_context_set_iface(context, iface);
597 
598 		net_sin6_ptr(&context->local)->sin6_family = AF_INET6;
599 		net_sin6_ptr(&context->local)->sin6_addr = ptr;
600 		if (addr6->sin6_port) {
601 			ret = check_used_port(AF_INET6, addr6->sin6_port,
602 					      addr);
603 			if (!ret) {
604 				net_sin6_ptr(&context->local)->sin6_port =
605 					addr6->sin6_port;
606 			} else {
607 				NET_ERR("Port %d is in use!",
608 					ntohs(addr6->sin6_port));
609 				goto unlock_ipv6;
610 			}
611 		} else {
612 			addr6->sin6_port =
613 				net_sin6_ptr(&context->local)->sin6_port;
614 		}
615 
616 		NET_DBG("Context %p binding to %s [%s]:%d iface %d (%p)",
617 			context,
618 			net_proto2str(AF_INET6,
619 				      net_context_get_ip_proto(context)),
620 			log_strdup(net_sprint_ipv6_addr(ptr)),
621 			ntohs(addr6->sin6_port),
622 			net_if_get_by_iface(iface), iface);
623 
624 	unlock_ipv6:
625 		k_mutex_unlock(&context->lock);
626 
627 		return ret;
628 	}
629 
630 	if (IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET) {
631 		struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
632 		struct net_if *iface = NULL;
633 		struct net_if_addr *ifaddr;
634 		struct in_addr *ptr;
635 
636 		if (addrlen < sizeof(struct sockaddr_in)) {
637 			return -EINVAL;
638 		}
639 
640 		if (net_context_is_bound_to_iface(context)) {
641 			iface = net_context_get_iface(context);
642 		}
643 
644 		if (net_ipv4_is_addr_mcast(&addr4->sin_addr)) {
645 			struct net_if_mcast_addr *maddr;
646 
647 			maddr = net_if_ipv4_maddr_lookup(&addr4->sin_addr,
648 							 &iface);
649 			if (!maddr) {
650 				return -ENOENT;
651 			}
652 
653 			ptr = &maddr->address.in_addr;
654 
655 		} else if (addr4->sin_addr.s_addr == INADDR_ANY) {
656 			if (iface == NULL) {
657 				iface = net_if_ipv4_select_src_iface(
658 					&net_sin(&context->remote)->sin_addr);
659 			}
660 
661 			ptr = (struct in_addr *)net_ipv4_unspecified_address();
662 		} else {
663 			ifaddr = net_if_ipv4_addr_lookup(
664 					&addr4->sin_addr,
665 					iface == NULL ? &iface : NULL);
666 			if (!ifaddr) {
667 				return -ENOENT;
668 			}
669 
670 			ptr = &ifaddr->address.in_addr;
671 		}
672 
673 		if (!iface) {
674 			NET_ERR("Cannot bind to %s",
675 				log_strdup(net_sprint_ipv4_addr(
676 						   &addr4->sin_addr)));
677 
678 			return -EADDRNOTAVAIL;
679 		}
680 
681 		if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
682 		    net_if_is_ip_offloaded(iface)) {
683 			net_context_set_iface(context, iface);
684 
685 			return net_offload_bind(iface,
686 						context,
687 						addr,
688 						addrlen);
689 		}
690 
691 		k_mutex_lock(&context->lock, K_FOREVER);
692 
693 		ret = 0;
694 
695 		net_context_set_iface(context, iface);
696 
697 		net_sin_ptr(&context->local)->sin_family = AF_INET;
698 		net_sin_ptr(&context->local)->sin_addr = ptr;
699 		if (addr4->sin_port) {
700 			ret = check_used_port(AF_INET, addr4->sin_port,
701 					      addr);
702 			if (!ret) {
703 				net_sin_ptr(&context->local)->sin_port =
704 					addr4->sin_port;
705 			} else {
706 				NET_ERR("Port %d is in use!",
707 					ntohs(addr4->sin_port));
708 				goto unlock_ipv4;
709 			}
710 		} else {
711 			addr4->sin_port =
712 				net_sin_ptr(&context->local)->sin_port;
713 		}
714 
715 		NET_DBG("Context %p binding to %s %s:%d iface %d (%p)",
716 			context,
717 			net_proto2str(AF_INET,
718 				      net_context_get_ip_proto(context)),
719 			log_strdup(net_sprint_ipv4_addr(ptr)),
720 			ntohs(addr4->sin_port),
721 			net_if_get_by_iface(iface), iface);
722 
723 	unlock_ipv4:
724 		k_mutex_unlock(&context->lock);
725 
726 		return ret;
727 	}
728 
729 	if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
730 	    addr->sa_family == AF_PACKET) {
731 		struct sockaddr_ll *ll_addr = (struct sockaddr_ll *)addr;
732 		struct net_if *iface = NULL;
733 
734 		if (addrlen < sizeof(struct sockaddr_ll)) {
735 			return -EINVAL;
736 		}
737 
738 		if (ll_addr->sll_ifindex < 0) {
739 			return -EINVAL;
740 		}
741 
742 		iface = net_if_get_by_index(ll_addr->sll_ifindex);
743 		if (!iface) {
744 			NET_ERR("Cannot bind to interface index %d",
745 				ll_addr->sll_ifindex);
746 			return -EADDRNOTAVAIL;
747 		}
748 
749 		if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
750 		    net_if_is_ip_offloaded(iface)) {
751 			net_context_set_iface(context, iface);
752 
753 			return net_offload_bind(iface,
754 						context,
755 						addr,
756 						addrlen);
757 		}
758 
759 		k_mutex_lock(&context->lock, K_FOREVER);
760 
761 		net_context_set_iface(context, iface);
762 
763 		net_sll_ptr(&context->local)->sll_family = AF_PACKET;
764 		net_sll_ptr(&context->local)->sll_ifindex =
765 			ll_addr->sll_ifindex;
766 		net_sll_ptr(&context->local)->sll_protocol =
767 			ll_addr->sll_protocol;
768 		net_sll_ptr(&context->local)->sll_addr =
769 			net_if_get_link_addr(iface)->addr;
770 		net_sll_ptr(&context->local)->sll_halen =
771 			net_if_get_link_addr(iface)->len;
772 
773 		NET_DBG("Context %p bind to type 0x%04x iface[%d] %p addr %s",
774 			context, htons(net_context_get_ip_proto(context)),
775 			ll_addr->sll_ifindex, iface,
776 			log_strdup(net_sprint_ll_addr(
777 				net_sll_ptr(&context->local)->sll_addr,
778 				net_sll_ptr(&context->local)->sll_halen)));
779 
780 		k_mutex_unlock(&context->lock);
781 
782 		return 0;
783 	}
784 
785 	if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && addr->sa_family == AF_CAN) {
786 		struct sockaddr_can *can_addr = (struct sockaddr_can *)addr;
787 		struct net_if *iface = NULL;
788 
789 		if (addrlen < sizeof(struct sockaddr_can)) {
790 			return -EINVAL;
791 		}
792 
793 		if (can_addr->can_ifindex < 0) {
794 			return -EINVAL;
795 		}
796 
797 		iface = net_if_get_by_index(can_addr->can_ifindex);
798 		if (!iface) {
799 			NET_ERR("Cannot bind to interface index %d",
800 				can_addr->can_ifindex);
801 			return -EADDRNOTAVAIL;
802 		}
803 
804 		if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
805 		    net_if_is_ip_offloaded(iface)) {
806 			net_context_set_iface(context, iface);
807 
808 			return net_offload_bind(iface,
809 						context,
810 						addr,
811 						addrlen);
812 		}
813 
814 		k_mutex_lock(&context->lock, K_FOREVER);
815 
816 		net_context_set_iface(context, iface);
817 		net_context_set_family(context, AF_CAN);
818 
819 		net_can_ptr(&context->local)->can_family = AF_CAN;
820 		net_can_ptr(&context->local)->can_ifindex =
821 			can_addr->can_ifindex;
822 
823 		NET_DBG("Context %p binding to %d iface[%d] %p",
824 			context, net_context_get_ip_proto(context),
825 			can_addr->can_ifindex, iface);
826 
827 		k_mutex_unlock(&context->lock);
828 
829 		return 0;
830 	}
831 
832 	return -EINVAL;
833 }
834 
find_context(void * conn_handler)835 static inline struct net_context *find_context(void *conn_handler)
836 {
837 	int i;
838 
839 	for (i = 0; i < NET_MAX_CONTEXT; i++) {
840 		if (!net_context_is_used(&contexts[i])) {
841 			continue;
842 		}
843 
844 		if (contexts[i].conn_handler == conn_handler) {
845 			return &contexts[i];
846 		}
847 	}
848 
849 	return NULL;
850 }
851 
net_context_listen(struct net_context * context,int backlog)852 int net_context_listen(struct net_context *context, int backlog)
853 {
854 	ARG_UNUSED(backlog);
855 
856 	NET_ASSERT(PART_OF_ARRAY(contexts, context));
857 
858 	if (!net_context_is_used(context)) {
859 		return -EBADF;
860 	}
861 
862 	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
863 	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
864 		return net_offload_listen(net_context_get_iface(context),
865 					  context, backlog);
866 	}
867 
868 	k_mutex_lock(&context->lock, K_FOREVER);
869 
870 	if (net_tcp_listen(context) >= 0) {
871 		k_mutex_unlock(&context->lock);
872 		return 0;
873 	}
874 
875 	k_mutex_unlock(&context->lock);
876 
877 	return -EOPNOTSUPP;
878 }
879 
880 #if defined(CONFIG_NET_IPV4)
net_context_create_ipv4_new(struct net_context * context,struct net_pkt * pkt,const struct in_addr * src,const struct in_addr * dst)881 int net_context_create_ipv4_new(struct net_context *context,
882 				struct net_pkt *pkt,
883 				const struct in_addr *src,
884 				const struct in_addr *dst)
885 {
886 	if (!src) {
887 		NET_ASSERT(((
888 			struct sockaddr_in_ptr *)&context->local)->sin_addr);
889 
890 		src = ((struct sockaddr_in_ptr *)&context->local)->sin_addr;
891 	}
892 
893 	if (net_ipv4_is_addr_unspecified(src)
894 	    || net_ipv4_is_addr_mcast(src)) {
895 		src = net_if_ipv4_select_src_addr(net_pkt_iface(pkt),
896 						  (struct in_addr *)dst);
897 		/* If src address is still unspecified, do not create pkt */
898 		if (net_ipv4_is_addr_unspecified(src)) {
899 			NET_DBG("DROP: src addr is unspecified");
900 			return -EINVAL;
901 		}
902 	}
903 
904 	net_pkt_set_ipv4_ttl(pkt, net_context_get_ipv4_ttl(context));
905 
906 	return net_ipv4_create(pkt, src, dst);
907 }
908 #endif /* CONFIG_NET_IPV4 */
909 
910 #if defined(CONFIG_NET_IPV6)
net_context_create_ipv6_new(struct net_context * context,struct net_pkt * pkt,const struct in6_addr * src,const struct in6_addr * dst)911 int net_context_create_ipv6_new(struct net_context *context,
912 				struct net_pkt *pkt,
913 				const struct in6_addr *src,
914 				const struct in6_addr *dst)
915 {
916 	if (!src) {
917 		NET_ASSERT(((
918 			struct sockaddr_in6_ptr *)&context->local)->sin6_addr);
919 
920 		src = ((struct sockaddr_in6_ptr *)&context->local)->sin6_addr;
921 	}
922 
923 	if (net_ipv6_is_addr_unspecified(src)
924 	    || net_ipv6_is_addr_mcast(src)) {
925 		src = net_if_ipv6_select_src_addr(net_pkt_iface(pkt),
926 						  (struct in6_addr *)dst);
927 	}
928 
929 	net_pkt_set_ipv6_hop_limit(pkt,
930 				   net_context_get_ipv6_hop_limit(context));
931 
932 	return net_ipv6_create(pkt, src, dst);
933 }
934 #endif /* CONFIG_NET_IPV6 */
935 
net_context_connect(struct net_context * context,const struct sockaddr * addr,socklen_t addrlen,net_context_connect_cb_t cb,k_timeout_t timeout,void * user_data)936 int net_context_connect(struct net_context *context,
937 			const struct sockaddr *addr,
938 			socklen_t addrlen,
939 			net_context_connect_cb_t cb,
940 			k_timeout_t timeout,
941 			void *user_data)
942 {
943 	struct sockaddr *laddr = NULL;
944 	struct sockaddr local_addr __unused;
945 	uint16_t lport, rport;
946 	int ret;
947 
948 	NET_ASSERT(addr);
949 	NET_ASSERT(PART_OF_ARRAY(contexts, context));
950 
951 	k_mutex_lock(&context->lock, K_FOREVER);
952 
953 	if (!net_context_is_used(context)) {
954 		ret = -EBADF;
955 		goto unlock;
956 	}
957 
958 	if (addr->sa_family != net_context_get_family(context)) {
959 		NET_ASSERT(addr->sa_family == net_context_get_family(context),
960 			   "Family mismatch %d should be %d",
961 			   addr->sa_family,
962 			   net_context_get_family(context));
963 		ret = -EINVAL;
964 		goto unlock;
965 	}
966 
967 	if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
968 	    addr->sa_family == AF_PACKET) {
969 		ret = -EOPNOTSUPP;
970 		goto unlock;
971 	}
972 
973 	if (net_context_get_state(context) == NET_CONTEXT_LISTENING) {
974 		ret = -EOPNOTSUPP;
975 		goto unlock;
976 	}
977 
978 	if (IS_ENABLED(CONFIG_NET_IPV6) &&
979 	    net_context_get_family(context) == AF_INET6) {
980 		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)
981 							&context->remote;
982 
983 		if (addrlen < sizeof(struct sockaddr_in6)) {
984 			ret = -EINVAL;
985 			goto unlock;
986 		}
987 
988 		if (net_context_get_ip_proto(context) == IPPROTO_TCP &&
989 		    net_ipv6_is_addr_mcast(&addr6->sin6_addr)) {
990 			ret = -EADDRNOTAVAIL;
991 			goto unlock;
992 		}
993 
994 		memcpy(&addr6->sin6_addr, &net_sin6(addr)->sin6_addr,
995 		       sizeof(struct in6_addr));
996 
997 		addr6->sin6_port = net_sin6(addr)->sin6_port;
998 		addr6->sin6_family = AF_INET6;
999 
1000 		if (!net_ipv6_is_addr_unspecified(&addr6->sin6_addr)) {
1001 			context->flags |= NET_CONTEXT_REMOTE_ADDR_SET;
1002 		} else {
1003 			context->flags &= ~NET_CONTEXT_REMOTE_ADDR_SET;
1004 		}
1005 
1006 		rport = addr6->sin6_port;
1007 
1008 		/* The binding must be done after we have set the remote
1009 		 * address but before checking the local address. Otherwise
1010 		 * the laddr might not be set properly which would then cause
1011 		 * issues when doing net_tcp_connect(). This issue was seen
1012 		 * with socket tests and when connecting to loopback interface.
1013 		 */
1014 		ret = bind_default(context);
1015 		if (ret) {
1016 			goto unlock;
1017 		}
1018 
1019 		net_sin6_ptr(&context->local)->sin6_family = AF_INET6;
1020 		net_sin6(&local_addr)->sin6_family = AF_INET6;
1021 		net_sin6(&local_addr)->sin6_port = lport =
1022 			net_sin6((struct sockaddr *)&context->local)->sin6_port;
1023 
1024 		if (net_sin6_ptr(&context->local)->sin6_addr) {
1025 			net_ipaddr_copy(&net_sin6(&local_addr)->sin6_addr,
1026 				     net_sin6_ptr(&context->local)->sin6_addr);
1027 
1028 			laddr = &local_addr;
1029 		}
1030 	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
1031 		   net_context_get_family(context) == AF_INET) {
1032 		struct sockaddr_in *addr4 = (struct sockaddr_in *)
1033 							&context->remote;
1034 
1035 		if (addrlen < sizeof(struct sockaddr_in)) {
1036 			ret = -EINVAL;
1037 			goto unlock;
1038 		}
1039 
1040 		/* FIXME - Add multicast and broadcast address check */
1041 
1042 		addr4 = (struct sockaddr_in *)&context->remote;
1043 
1044 		memcpy(&addr4->sin_addr, &net_sin(addr)->sin_addr,
1045 		       sizeof(struct in_addr));
1046 
1047 		addr4->sin_port = net_sin(addr)->sin_port;
1048 		addr4->sin_family = AF_INET;
1049 
1050 		if (addr4->sin_addr.s_addr) {
1051 			context->flags |= NET_CONTEXT_REMOTE_ADDR_SET;
1052 		} else {
1053 			context->flags &= ~NET_CONTEXT_REMOTE_ADDR_SET;
1054 		}
1055 
1056 		rport = addr4->sin_port;
1057 
1058 		ret = bind_default(context);
1059 		if (ret) {
1060 			goto unlock;
1061 		}
1062 
1063 		net_sin_ptr(&context->local)->sin_family = AF_INET;
1064 		net_sin(&local_addr)->sin_family = AF_INET;
1065 		net_sin(&local_addr)->sin_port = lport =
1066 			net_sin((struct sockaddr *)&context->local)->sin_port;
1067 
1068 		if (net_sin_ptr(&context->local)->sin_addr) {
1069 			net_ipaddr_copy(&net_sin(&local_addr)->sin_addr,
1070 				       net_sin_ptr(&context->local)->sin_addr);
1071 
1072 			laddr = &local_addr;
1073 		}
1074 	} else {
1075 		ret = -EINVAL; /* Not IPv4 or IPv6 */
1076 		goto unlock;
1077 	}
1078 
1079 	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
1080 	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
1081 		ret = net_offload_connect(
1082 			net_context_get_iface(context),
1083 			context,
1084 			addr,
1085 			addrlen,
1086 			cb,
1087 			timeout,
1088 			user_data);
1089 		goto unlock;
1090 	}
1091 
1092 	if (IS_ENABLED(CONFIG_NET_UDP) &&
1093 	    net_context_get_type(context) == SOCK_DGRAM) {
1094 		if (cb) {
1095 			cb(context, 0, user_data);
1096 		}
1097 
1098 		ret = 0;
1099 	} else if (IS_ENABLED(CONFIG_NET_TCP) &&
1100 		   net_context_get_type(context) == SOCK_STREAM) {
1101 		ret = net_tcp_connect(context, addr, laddr, rport, lport,
1102 				      timeout, cb, user_data);
1103 	} else {
1104 		ret = -ENOTSUP;
1105 	}
1106 
1107 unlock:
1108 	k_mutex_unlock(&context->lock);
1109 
1110 	return ret;
1111 }
1112 
net_context_accept(struct net_context * context,net_tcp_accept_cb_t cb,k_timeout_t timeout,void * user_data)1113 int net_context_accept(struct net_context *context,
1114 		       net_tcp_accept_cb_t cb,
1115 		       k_timeout_t timeout,
1116 		       void *user_data)
1117 {
1118 	int ret = 0;
1119 
1120 	NET_ASSERT(PART_OF_ARRAY(contexts, context));
1121 
1122 	if (!net_context_is_used(context)) {
1123 		return -EBADF;
1124 	}
1125 
1126 	k_mutex_lock(&context->lock, K_FOREVER);
1127 
1128 	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
1129 	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
1130 		ret = net_offload_accept(
1131 			net_context_get_iface(context),
1132 			context,
1133 			cb,
1134 			timeout,
1135 			user_data);
1136 		goto unlock;
1137 	}
1138 
1139 	if ((net_context_get_state(context) != NET_CONTEXT_LISTENING) &&
1140 	    (net_context_get_type(context) != SOCK_STREAM)) {
1141 		NET_DBG("Invalid socket, state %d type %d",
1142 			net_context_get_state(context),
1143 			net_context_get_type(context));
1144 		ret = -EINVAL;
1145 		goto unlock;
1146 	}
1147 
1148 	if (net_context_get_ip_proto(context) == IPPROTO_TCP) {
1149 		ret = net_tcp_accept(context, cb, user_data);
1150 		goto unlock;
1151 	}
1152 
1153 unlock:
1154 	k_mutex_unlock(&context->lock);
1155 
1156 	return ret;
1157 }
1158 
1159 
get_context_priority(struct net_context * context,void * value,size_t * len)1160 static int get_context_priority(struct net_context *context,
1161 				void *value, size_t *len)
1162 {
1163 #if defined(CONFIG_NET_CONTEXT_PRIORITY)
1164 	*((uint8_t *)value) = context->options.priority;
1165 
1166 	if (len) {
1167 		*len = sizeof(uint8_t);
1168 	}
1169 
1170 	return 0;
1171 #else
1172 	return -ENOTSUP;
1173 #endif
1174 }
1175 
get_context_proxy(struct net_context * context,void * value,size_t * len)1176 static int get_context_proxy(struct net_context *context,
1177 			     void *value, size_t *len)
1178 {
1179 #if defined(CONFIG_SOCKS)
1180 	struct sockaddr *addr = (struct sockaddr *)value;
1181 
1182 	if (!value || !len) {
1183 		return -EINVAL;
1184 	}
1185 
1186 	if (*len < context->options.proxy.addrlen) {
1187 		return -EINVAL;
1188 	}
1189 
1190 	*len = MIN(context->options.proxy.addrlen, *len);
1191 
1192 	memcpy(addr, &context->options.proxy.addr, *len);
1193 
1194 	return 0;
1195 #else
1196 	return -ENOTSUP;
1197 #endif
1198 }
1199 
get_context_txtime(struct net_context * context,void * value,size_t * len)1200 static int get_context_txtime(struct net_context *context,
1201 			      void *value, size_t *len)
1202 {
1203 #if defined(CONFIG_NET_CONTEXT_TXTIME)
1204 	*((bool *)value) = context->options.txtime;
1205 
1206 	if (len) {
1207 		*len = sizeof(bool);
1208 	}
1209 
1210 	return 0;
1211 #else
1212 	return -ENOTSUP;
1213 #endif
1214 }
1215 
get_context_rcvtimeo(struct net_context * context,void * value,size_t * len)1216 static int get_context_rcvtimeo(struct net_context *context,
1217 				void *value, size_t *len)
1218 {
1219 #if defined(CONFIG_NET_CONTEXT_RCVTIMEO)
1220 	*((k_timeout_t *)value) = context->options.rcvtimeo;
1221 
1222 	if (len) {
1223 		*len = sizeof(k_timeout_t);
1224 	}
1225 
1226 	return 0;
1227 #else
1228 	return -ENOTSUP;
1229 #endif
1230 }
1231 
get_context_sndtimeo(struct net_context * context,void * value,size_t * len)1232 static int get_context_sndtimeo(struct net_context *context,
1233 				void *value, size_t *len)
1234 {
1235 #if defined(CONFIG_NET_CONTEXT_SNDTIMEO)
1236 	*((k_timeout_t *)value) = context->options.sndtimeo;
1237 
1238 	if (len) {
1239 		*len = sizeof(k_timeout_t);
1240 	}
1241 
1242 	return 0;
1243 #else
1244 	return -ENOTSUP;
1245 #endif
1246 }
1247 
1248 /* If buf is not NULL, then use it. Otherwise read the data to be written
1249  * to net_pkt from msghdr.
1250  */
context_write_data(struct net_pkt * pkt,const void * buf,int buf_len,const struct msghdr * msghdr)1251 static int context_write_data(struct net_pkt *pkt, const void *buf,
1252 			      int buf_len, const struct msghdr *msghdr)
1253 {
1254 	int ret = 0;
1255 
1256 	if (msghdr) {
1257 		int i;
1258 
1259 		for (i = 0; i < msghdr->msg_iovlen; i++) {
1260 			int len = MIN(msghdr->msg_iov[i].iov_len, buf_len);
1261 
1262 			ret = net_pkt_write(pkt, msghdr->msg_iov[i].iov_base,
1263 					    len);
1264 			if (ret < 0) {
1265 				break;
1266 			}
1267 
1268 			buf_len -= len;
1269 			if (buf_len == 0) {
1270 				break;
1271 			}
1272 		}
1273 	} else {
1274 		ret = net_pkt_write(pkt, buf, buf_len);
1275 	}
1276 
1277 	return ret;
1278 }
1279 
context_setup_udp_packet(struct net_context * context,struct net_pkt * pkt,const void * buf,size_t len,const struct msghdr * msg,const struct sockaddr * dst_addr,socklen_t addrlen)1280 static int context_setup_udp_packet(struct net_context *context,
1281 				    struct net_pkt *pkt,
1282 				    const void *buf,
1283 				    size_t len,
1284 				    const struct msghdr *msg,
1285 				    const struct sockaddr *dst_addr,
1286 				    socklen_t addrlen)
1287 {
1288 	int ret = -EINVAL;
1289 	uint16_t dst_port = 0U;
1290 
1291 	if (IS_ENABLED(CONFIG_NET_IPV6) &&
1292 	    net_context_get_family(context) == AF_INET6) {
1293 		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)dst_addr;
1294 
1295 		dst_port = addr6->sin6_port;
1296 
1297 		ret = net_context_create_ipv6_new(context, pkt,
1298 						  NULL, &addr6->sin6_addr);
1299 	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
1300 		   net_context_get_family(context) == AF_INET) {
1301 		struct sockaddr_in *addr4 = (struct sockaddr_in *)dst_addr;
1302 
1303 		dst_port = addr4->sin_port;
1304 
1305 		ret = net_context_create_ipv4_new(context, pkt,
1306 						  NULL, &addr4->sin_addr);
1307 	}
1308 
1309 	if (ret < 0) {
1310 		return ret;
1311 	}
1312 
1313 	ret = bind_default(context);
1314 	if (ret) {
1315 		return ret;
1316 	}
1317 
1318 	ret = net_udp_create(pkt,
1319 			     net_sin((struct sockaddr *)
1320 				     &context->local)->sin_port,
1321 			     dst_port);
1322 	if (ret) {
1323 		return ret;
1324 	}
1325 
1326 	ret = context_write_data(pkt, buf, len, msg);
1327 	if (ret) {
1328 		return ret;
1329 	}
1330 
1331 	return 0;
1332 }
1333 
context_finalize_packet(struct net_context * context,struct net_pkt * pkt)1334 static void context_finalize_packet(struct net_context *context,
1335 				    struct net_pkt *pkt)
1336 {
1337 	/* This function is meant to be temporary: once all moved to new
1338 	 * API, it will be up to net_send_data() to finalize the packet.
1339 	 */
1340 
1341 	net_pkt_cursor_init(pkt);
1342 
1343 	if (IS_ENABLED(CONFIG_NET_IPV6) &&
1344 	    net_context_get_family(context) == AF_INET6) {
1345 		net_ipv6_finalize(pkt, net_context_get_ip_proto(context));
1346 	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
1347 		   net_context_get_family(context) == AF_INET) {
1348 		net_ipv4_finalize(pkt, net_context_get_ip_proto(context));
1349 	}
1350 }
1351 
context_alloc_pkt(struct net_context * context,size_t len,k_timeout_t timeout)1352 static struct net_pkt *context_alloc_pkt(struct net_context *context,
1353 					 size_t len, k_timeout_t timeout)
1354 {
1355 	struct net_pkt *pkt;
1356 
1357 #if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL)
1358 	if (context->tx_slab) {
1359 		pkt = net_pkt_alloc_from_slab(context->tx_slab(), timeout);
1360 		if (!pkt) {
1361 			return NULL;
1362 		}
1363 
1364 		net_pkt_set_iface(pkt, net_context_get_iface(context));
1365 		net_pkt_set_family(pkt, net_context_get_family(context));
1366 		net_pkt_set_context(pkt, context);
1367 
1368 		if (net_pkt_alloc_buffer(pkt, len,
1369 					 net_context_get_ip_proto(context),
1370 					 timeout)) {
1371 			net_pkt_unref(pkt);
1372 			return NULL;
1373 		}
1374 
1375 		return pkt;
1376 	}
1377 #endif
1378 	pkt = net_pkt_alloc_with_buffer(net_context_get_iface(context), len,
1379 					net_context_get_family(context),
1380 					net_context_get_ip_proto(context),
1381 					timeout);
1382 	if (pkt) {
1383 		net_pkt_set_context(pkt, context);
1384 	}
1385 
1386 	return pkt;
1387 }
1388 
set_pkt_txtime(struct net_pkt * pkt,const struct msghdr * msghdr)1389 static void set_pkt_txtime(struct net_pkt *pkt, const struct msghdr *msghdr)
1390 {
1391 	struct cmsghdr *cmsg;
1392 
1393 	for (cmsg = CMSG_FIRSTHDR(msghdr); cmsg != NULL;
1394 	     cmsg = CMSG_NXTHDR(msghdr, cmsg)) {
1395 		if (cmsg->cmsg_len == CMSG_LEN(sizeof(uint64_t)) &&
1396 		    cmsg->cmsg_level == SOL_SOCKET &&
1397 		    cmsg->cmsg_type == SCM_TXTIME) {
1398 			uint64_t txtime = *(uint64_t *)CMSG_DATA(cmsg);
1399 
1400 			net_pkt_set_txtime(pkt, txtime);
1401 			break;
1402 		}
1403 	}
1404 }
1405 
context_sendto(struct net_context * context,const void * buf,size_t len,const struct sockaddr * dst_addr,socklen_t addrlen,net_context_send_cb_t cb,k_timeout_t timeout,void * user_data,bool sendto)1406 static int context_sendto(struct net_context *context,
1407 			  const void *buf,
1408 			  size_t len,
1409 			  const struct sockaddr *dst_addr,
1410 			  socklen_t addrlen,
1411 			  net_context_send_cb_t cb,
1412 			  k_timeout_t timeout,
1413 			  void *user_data,
1414 			  bool sendto)
1415 {
1416 	const struct msghdr *msghdr = NULL;
1417 	struct net_if *iface;
1418 	struct net_pkt *pkt;
1419 	size_t tmp_len;
1420 	int ret;
1421 
1422 	NET_ASSERT(PART_OF_ARRAY(contexts, context));
1423 
1424 	if (!net_context_is_used(context)) {
1425 		return -EBADF;
1426 	}
1427 
1428 	if (sendto && addrlen == 0 && dst_addr == NULL && buf != NULL) {
1429 		/* User wants to call sendmsg */
1430 		msghdr = buf;
1431 	}
1432 
1433 	if (!msghdr && !dst_addr) {
1434 		return -EDESTADDRREQ;
1435 	}
1436 
1437 	if (IS_ENABLED(CONFIG_NET_IPV6) &&
1438 	    net_context_get_family(context) == AF_INET6) {
1439 		const struct sockaddr_in6 *addr6 =
1440 			(const struct sockaddr_in6 *)dst_addr;
1441 
1442 		if (msghdr) {
1443 			addr6 = msghdr->msg_name;
1444 			addrlen = msghdr->msg_namelen;
1445 
1446 			if (!addr6) {
1447 				addr6 = net_sin6(&context->remote);
1448 				addrlen = sizeof(struct sockaddr_in6);
1449 			}
1450 
1451 			/* For sendmsg(), the dst_addr is NULL so set it here.
1452 			 */
1453 			dst_addr = (const struct sockaddr *)addr6;
1454 		}
1455 
1456 		if (addrlen < sizeof(struct sockaddr_in6)) {
1457 			return -EINVAL;
1458 		}
1459 
1460 		if (net_ipv6_is_addr_unspecified(&addr6->sin6_addr)) {
1461 			return -EDESTADDRREQ;
1462 		}
1463 
1464 		/* If application has not yet set the destination address
1465 		 * i.e., by not calling connect(), then set the interface
1466 		 * here so that the packet gets sent to the correct network
1467 		 * interface. This issue can be seen if there are multiple
1468 		 * network interfaces and we are trying to send data to
1469 		 * second or later network interface.
1470 		 */
1471 		if (net_ipv6_is_addr_unspecified(
1472 				&net_sin6(&context->remote)->sin6_addr) &&
1473 		    !net_context_is_bound_to_iface(context)) {
1474 			iface = net_if_ipv6_select_src_iface(&addr6->sin6_addr);
1475 			net_context_set_iface(context, iface);
1476 		}
1477 
1478 	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
1479 		   net_context_get_family(context) == AF_INET) {
1480 		const struct sockaddr_in *addr4 =
1481 			(const struct sockaddr_in *)dst_addr;
1482 
1483 		if (msghdr) {
1484 			addr4 = msghdr->msg_name;
1485 			addrlen = msghdr->msg_namelen;
1486 
1487 			if (!addr4) {
1488 				addr4 = net_sin(&context->remote);
1489 				addrlen = sizeof(struct sockaddr_in);
1490 			}
1491 
1492 			/* For sendmsg(), the dst_addr is NULL so set it here.
1493 			 */
1494 			dst_addr = (const struct sockaddr *)addr4;
1495 		}
1496 
1497 		if (addrlen < sizeof(struct sockaddr_in)) {
1498 			return -EINVAL;
1499 		}
1500 
1501 		if (!addr4->sin_addr.s_addr) {
1502 			return -EDESTADDRREQ;
1503 		}
1504 
1505 		/* If application has not yet set the destination address
1506 		 * i.e., by not calling connect(), then set the interface
1507 		 * here so that the packet gets sent to the correct network
1508 		 * interface. This issue can be seen if there are multiple
1509 		 * network interfaces and we are trying to send data to
1510 		 * second or later network interface.
1511 		 */
1512 		if (net_sin(&context->remote)->sin_addr.s_addr == 0U &&
1513 		    !net_context_is_bound_to_iface(context)) {
1514 			iface = net_if_ipv4_select_src_iface(&addr4->sin_addr);
1515 			net_context_set_iface(context, iface);
1516 		}
1517 
1518 	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
1519 		   net_context_get_family(context) == AF_PACKET) {
1520 		struct sockaddr_ll *ll_addr = (struct sockaddr_ll *)dst_addr;
1521 
1522 		if (msghdr) {
1523 			ll_addr = msghdr->msg_name;
1524 			addrlen = msghdr->msg_namelen;
1525 
1526 			if (!ll_addr) {
1527 				ll_addr = (struct sockaddr_ll *)
1528 							(&context->remote);
1529 				addrlen = sizeof(struct sockaddr_ll);
1530 			}
1531 
1532 			/* For sendmsg(), the dst_addr is NULL so set it here.
1533 			 */
1534 			dst_addr = (const struct sockaddr *)ll_addr;
1535 		}
1536 
1537 		if (addrlen < sizeof(struct sockaddr_ll)) {
1538 			return -EINVAL;
1539 		}
1540 
1541 		if (ll_addr->sll_ifindex < 0) {
1542 			return -EDESTADDRREQ;
1543 		}
1544 
1545 		iface = net_if_get_by_index(ll_addr->sll_ifindex);
1546 		if (!iface) {
1547 			NET_ERR("Cannot bind to interface index %d",
1548 				ll_addr->sll_ifindex);
1549 			return -EDESTADDRREQ;
1550 		}
1551 
1552 		if (net_context_get_type(context) == SOCK_DGRAM) {
1553 			context->flags |= NET_CONTEXT_REMOTE_ADDR_SET;
1554 
1555 			/* The user must set the protocol in send call */
1556 
1557 			/* For sendmsg() call, we might have set ll_addr to
1558 			 * point to remote addr.
1559 			 */
1560 			if ((void *)&context->remote != (void *)ll_addr) {
1561 				memcpy((struct sockaddr_ll *)&context->remote,
1562 				       ll_addr, sizeof(struct sockaddr_ll));
1563 			}
1564 		}
1565 
1566 	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
1567 		   net_context_get_family(context) == AF_CAN) {
1568 		struct sockaddr_can *can_addr = (struct sockaddr_can *)dst_addr;
1569 
1570 		if (msghdr) {
1571 			can_addr = msghdr->msg_name;
1572 			addrlen = msghdr->msg_namelen;
1573 
1574 			if (!can_addr) {
1575 				can_addr = (struct sockaddr_can *)
1576 							(&context->remote);
1577 				addrlen = sizeof(struct sockaddr_can);
1578 			}
1579 
1580 			/* For sendmsg(), the dst_addr is NULL so set it here.
1581 			 */
1582 			dst_addr = (const struct sockaddr *)can_addr;
1583 		}
1584 
1585 		if (addrlen < sizeof(struct sockaddr_can)) {
1586 			return -EINVAL;
1587 		}
1588 
1589 		if (can_addr->can_ifindex < 0) {
1590 			/* The index should have been set in bind */
1591 			can_addr->can_ifindex =
1592 				net_can_ptr(&context->local)->can_ifindex;
1593 		}
1594 
1595 		if (can_addr->can_ifindex < 0) {
1596 			return -EDESTADDRREQ;
1597 		}
1598 
1599 		iface = net_if_get_by_index(can_addr->can_ifindex);
1600 		if (!iface) {
1601 			NET_ERR("Cannot bind to interface index %d",
1602 				can_addr->can_ifindex);
1603 			return -EDESTADDRREQ;
1604 		}
1605 	} else {
1606 		NET_DBG("Invalid protocol family %d",
1607 			net_context_get_family(context));
1608 		return -EINVAL;
1609 	}
1610 
1611 	if (msghdr && len == 0) {
1612 		int i;
1613 
1614 		for (i = 0; i < msghdr->msg_iovlen; i++) {
1615 			len += msghdr->msg_iov[i].iov_len;
1616 		}
1617 	}
1618 
1619 	iface = net_context_get_iface(context);
1620 	if (iface && !net_if_is_up(iface)) {
1621 		return -ENETDOWN;
1622 	}
1623 
1624 	pkt = context_alloc_pkt(context, len, PKT_WAIT_TIME);
1625 	if (!pkt) {
1626 		return -ENOBUFS;
1627 	}
1628 
1629 	tmp_len = net_pkt_available_payload_buffer(
1630 				pkt, net_context_get_ip_proto(context));
1631 	if (tmp_len < len) {
1632 		len = tmp_len;
1633 	}
1634 
1635 	context->send_cb = cb;
1636 	context->user_data = user_data;
1637 
1638 	if (IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) {
1639 		uint8_t priority;
1640 
1641 		get_context_priority(context, &priority, NULL);
1642 		net_pkt_set_priority(pkt, priority);
1643 	}
1644 
1645 	/* If there is ancillary data in msghdr, then we need to add that
1646 	 * to net_pkt as there is no other way to store it.
1647 	 */
1648 	if (msghdr && msghdr->msg_control && msghdr->msg_controllen) {
1649 		if (IS_ENABLED(CONFIG_NET_CONTEXT_TXTIME)) {
1650 			bool is_txtime;
1651 
1652 			get_context_txtime(context, &is_txtime, NULL);
1653 			if (is_txtime) {
1654 				set_pkt_txtime(pkt, msghdr);
1655 			}
1656 		}
1657 	}
1658 
1659 	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
1660 	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
1661 		ret = context_write_data(pkt, buf, len, msghdr);
1662 		if (ret < 0) {
1663 			goto fail;
1664 		}
1665 
1666 		net_pkt_cursor_init(pkt);
1667 
1668 		if (sendto) {
1669 			ret = net_offload_sendto(net_context_get_iface(context),
1670 						 pkt, dst_addr, addrlen, cb,
1671 						 timeout, user_data);
1672 		} else {
1673 			ret = net_offload_send(net_context_get_iface(context),
1674 					       pkt, cb, timeout, user_data);
1675 		}
1676 	} else if (IS_ENABLED(CONFIG_NET_UDP) &&
1677 	    net_context_get_ip_proto(context) == IPPROTO_UDP) {
1678 		ret = context_setup_udp_packet(context, pkt, buf, len, msghdr,
1679 					       dst_addr, addrlen);
1680 		if (ret < 0) {
1681 			goto fail;
1682 		}
1683 
1684 		context_finalize_packet(context, pkt);
1685 
1686 		ret = net_send_data(pkt);
1687 	} else if (IS_ENABLED(CONFIG_NET_TCP) &&
1688 		   net_context_get_ip_proto(context) == IPPROTO_TCP) {
1689 
1690 		ret = context_write_data(pkt, buf, len, msghdr);
1691 		if (ret < 0) {
1692 			goto fail;
1693 		}
1694 
1695 		net_pkt_cursor_init(pkt);
1696 		ret = net_tcp_queue_data(context, pkt);
1697 		if (ret < 0) {
1698 			goto fail;
1699 		}
1700 
1701 		ret = net_tcp_send_data(context, cb, user_data);
1702 	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
1703 		   net_context_get_family(context) == AF_PACKET) {
1704 		ret = context_write_data(pkt, buf, len, msghdr);
1705 		if (ret < 0) {
1706 			goto fail;
1707 		}
1708 
1709 		net_pkt_cursor_init(pkt);
1710 
1711 		if (net_context_get_ip_proto(context) == IPPROTO_RAW) {
1712 			/* Pass to L2: */
1713 			ret = net_send_data(pkt);
1714 		} else {
1715 			net_if_queue_tx(net_pkt_iface(pkt), pkt);
1716 		}
1717 	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
1718 		   net_context_get_family(context) == AF_CAN &&
1719 		   net_context_get_ip_proto(context) == CAN_RAW) {
1720 		ret = context_write_data(pkt, buf, len, msghdr);
1721 		if (ret < 0) {
1722 			goto fail;
1723 		}
1724 
1725 		net_pkt_cursor_init(pkt);
1726 
1727 		ret = net_send_data(pkt);
1728 	} else {
1729 		NET_DBG("Unknown protocol while sending packet: %d",
1730 		net_context_get_ip_proto(context));
1731 		ret = -EPROTONOSUPPORT;
1732 	}
1733 
1734 	if (ret < 0) {
1735 		goto fail;
1736 	}
1737 
1738 	return len;
1739 fail:
1740 	net_pkt_unref(pkt);
1741 
1742 	return ret;
1743 }
1744 
net_context_send(struct net_context * context,const void * buf,size_t len,net_context_send_cb_t cb,k_timeout_t timeout,void * user_data)1745 int net_context_send(struct net_context *context,
1746 		     const void *buf,
1747 		     size_t len,
1748 		     net_context_send_cb_t cb,
1749 		     k_timeout_t timeout,
1750 		     void *user_data)
1751 {
1752 	socklen_t addrlen;
1753 	int ret = 0;
1754 
1755 	k_mutex_lock(&context->lock, K_FOREVER);
1756 
1757 	if (!(context->flags & NET_CONTEXT_REMOTE_ADDR_SET) ||
1758 	    !net_sin(&context->remote)->sin_port) {
1759 		ret = -EDESTADDRREQ;
1760 		goto unlock;
1761 	}
1762 
1763 	if (IS_ENABLED(CONFIG_NET_IPV6) &&
1764 	    net_context_get_family(context) == AF_INET6) {
1765 		addrlen = sizeof(struct sockaddr_in6);
1766 	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
1767 		   net_context_get_family(context) == AF_INET) {
1768 		addrlen = sizeof(struct sockaddr_in);
1769 	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
1770 		   net_context_get_family(context) == AF_PACKET) {
1771 		ret = -EOPNOTSUPP;
1772 		goto unlock;
1773 	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
1774 		   net_context_get_family(context) == AF_CAN) {
1775 		addrlen = sizeof(struct sockaddr_can);
1776 	} else {
1777 		addrlen = 0;
1778 	}
1779 
1780 	ret = context_sendto(context, buf, len, &context->remote,
1781 			     addrlen, cb, timeout, user_data, false);
1782 unlock:
1783 	k_mutex_unlock(&context->lock);
1784 
1785 	return ret;
1786 }
1787 
net_context_sendmsg(struct net_context * context,const struct msghdr * msghdr,int flags,net_context_send_cb_t cb,k_timeout_t timeout,void * user_data)1788 int net_context_sendmsg(struct net_context *context,
1789 			const struct msghdr *msghdr,
1790 			int flags,
1791 			net_context_send_cb_t cb,
1792 			k_timeout_t timeout,
1793 			void *user_data)
1794 {
1795 	int ret;
1796 
1797 	k_mutex_lock(&context->lock, K_FOREVER);
1798 
1799 	ret = context_sendto(context, msghdr, 0, NULL, 0,
1800 			     cb, timeout, user_data, true);
1801 
1802 	k_mutex_unlock(&context->lock);
1803 
1804 	return ret;
1805 }
1806 
net_context_sendto(struct net_context * context,const void * buf,size_t len,const struct sockaddr * dst_addr,socklen_t addrlen,net_context_send_cb_t cb,k_timeout_t timeout,void * user_data)1807 int net_context_sendto(struct net_context *context,
1808 		       const void *buf,
1809 		       size_t len,
1810 		       const struct sockaddr *dst_addr,
1811 		       socklen_t addrlen,
1812 		       net_context_send_cb_t cb,
1813 		       k_timeout_t timeout,
1814 		       void *user_data)
1815 {
1816 	int ret;
1817 
1818 	k_mutex_lock(&context->lock, K_FOREVER);
1819 
1820 	ret = context_sendto(context, buf, len, dst_addr, addrlen,
1821 			     cb, timeout, user_data, true);
1822 
1823 	k_mutex_unlock(&context->lock);
1824 
1825 	return ret;
1826 }
1827 
net_context_packet_received(struct net_conn * conn,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,void * user_data)1828 enum net_verdict net_context_packet_received(struct net_conn *conn,
1829 					     struct net_pkt *pkt,
1830 					     union net_ip_header *ip_hdr,
1831 					     union net_proto_header *proto_hdr,
1832 					     void *user_data)
1833 {
1834 	struct net_context *context = find_context(conn);
1835 	enum net_verdict verdict = NET_DROP;
1836 
1837 	NET_ASSERT(context);
1838 	NET_ASSERT(net_pkt_iface(pkt));
1839 
1840 	k_mutex_lock(&context->lock, K_FOREVER);
1841 
1842 	net_context_set_iface(context, net_pkt_iface(pkt));
1843 	net_pkt_set_context(pkt, context);
1844 
1845 	/* If there is no callback registered, then we can only drop
1846 	 * the packet.
1847 	 */
1848 	if (!context->recv_cb) {
1849 		goto unlock;
1850 	}
1851 
1852 	if (net_context_get_ip_proto(context) == IPPROTO_TCP) {
1853 		net_stats_update_tcp_recv(net_pkt_iface(pkt),
1854 					  net_pkt_remaining_data(pkt));
1855 	}
1856 
1857 #if defined(CONFIG_NET_CONTEXT_SYNC_RECV)
1858 	k_sem_give(&context->recv_data_wait);
1859 #endif /* CONFIG_NET_CONTEXT_SYNC_RECV */
1860 
1861 	k_mutex_unlock(&context->lock);
1862 
1863 	context->recv_cb(context, pkt, ip_hdr, proto_hdr, 0, user_data);
1864 
1865 	verdict = NET_OK;
1866 
1867 	return verdict;
1868 
1869 unlock:
1870 	k_mutex_unlock(&context->lock);
1871 
1872 	return verdict;
1873 }
1874 
1875 #if defined(CONFIG_NET_UDP)
recv_udp(struct net_context * context,net_context_recv_cb_t cb,k_timeout_t timeout,void * user_data)1876 static int recv_udp(struct net_context *context,
1877 		    net_context_recv_cb_t cb,
1878 		    k_timeout_t timeout,
1879 		    void *user_data)
1880 {
1881 	struct sockaddr local_addr = {
1882 		.sa_family = net_context_get_family(context),
1883 	};
1884 	struct sockaddr *laddr = NULL;
1885 	uint16_t lport = 0U;
1886 	int ret;
1887 
1888 	ARG_UNUSED(timeout);
1889 
1890 	if (context->conn_handler) {
1891 		net_conn_unregister(context->conn_handler);
1892 		context->conn_handler = NULL;
1893 	}
1894 
1895 	ret = bind_default(context);
1896 	if (ret) {
1897 		return ret;
1898 	}
1899 
1900 	if (IS_ENABLED(CONFIG_NET_IPV6) &&
1901 	    net_context_get_family(context) == AF_INET6) {
1902 		if (net_sin6_ptr(&context->local)->sin6_addr) {
1903 			net_ipaddr_copy(&net_sin6(&local_addr)->sin6_addr,
1904 				     net_sin6_ptr(&context->local)->sin6_addr);
1905 
1906 			laddr = &local_addr;
1907 		}
1908 
1909 		net_sin6(&local_addr)->sin6_port =
1910 			net_sin6((struct sockaddr *)&context->local)->sin6_port;
1911 		lport = net_sin6((struct sockaddr *)&context->local)->sin6_port;
1912 	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
1913 		   net_context_get_family(context) == AF_INET) {
1914 		if (net_sin_ptr(&context->local)->sin_addr) {
1915 			net_ipaddr_copy(&net_sin(&local_addr)->sin_addr,
1916 				      net_sin_ptr(&context->local)->sin_addr);
1917 
1918 			laddr = &local_addr;
1919 		}
1920 
1921 		lport = net_sin((struct sockaddr *)&context->local)->sin_port;
1922 	}
1923 
1924 	context->recv_cb = cb;
1925 
1926 	ret = net_conn_register(net_context_get_ip_proto(context),
1927 				net_context_get_family(context),
1928 				context->flags & NET_CONTEXT_REMOTE_ADDR_SET ?
1929 							&context->remote : NULL,
1930 				laddr,
1931 				ntohs(net_sin(&context->remote)->sin_port),
1932 				ntohs(lport),
1933 				context,
1934 				net_context_packet_received,
1935 				user_data,
1936 				&context->conn_handler);
1937 
1938 	return ret;
1939 }
1940 #else
1941 #define recv_udp(...) 0
1942 #endif /* CONFIG_NET_UDP */
1943 
net_context_raw_packet_received(struct net_conn * conn,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,void * user_data)1944 static enum net_verdict net_context_raw_packet_received(
1945 					struct net_conn *conn,
1946 					struct net_pkt *pkt,
1947 					union net_ip_header *ip_hdr,
1948 					union net_proto_header *proto_hdr,
1949 					void *user_data)
1950 {
1951 	struct net_context *context = find_context(conn);
1952 
1953 	NET_ASSERT(context);
1954 	NET_ASSERT(net_pkt_iface(pkt));
1955 
1956 	/* If there is no callback registered, then we can only drop
1957 	 * the packet.
1958 	 */
1959 
1960 	if (!context->recv_cb) {
1961 		return NET_DROP;
1962 	}
1963 
1964 	net_context_set_iface(context, net_pkt_iface(pkt));
1965 	net_pkt_set_context(pkt, context);
1966 
1967 	context->recv_cb(context, pkt, ip_hdr, proto_hdr, 0, user_data);
1968 
1969 #if defined(CONFIG_NET_CONTEXT_SYNC_RECV)
1970 	k_sem_give(&context->recv_data_wait);
1971 #endif /* CONFIG_NET_CONTEXT_SYNC_RECV */
1972 
1973 	return NET_OK;
1974 }
1975 
recv_raw(struct net_context * context,net_context_recv_cb_t cb,k_timeout_t timeout,struct sockaddr * local_addr,void * user_data)1976 static int recv_raw(struct net_context *context,
1977 		    net_context_recv_cb_t cb,
1978 		    k_timeout_t timeout,
1979 		    struct sockaddr *local_addr,
1980 		    void *user_data)
1981 {
1982 	int ret;
1983 
1984 	ARG_UNUSED(timeout);
1985 
1986 	context->recv_cb = cb;
1987 
1988 	if (context->conn_handler) {
1989 		net_conn_unregister(context->conn_handler);
1990 		context->conn_handler = NULL;
1991 	}
1992 
1993 	ret = bind_default(context);
1994 	if (ret) {
1995 		return ret;
1996 	}
1997 
1998 	ret = net_conn_register(net_context_get_ip_proto(context),
1999 				net_context_get_family(context),
2000 				NULL, local_addr, 0, 0,
2001 				context,
2002 				net_context_raw_packet_received,
2003 				user_data,
2004 				&context->conn_handler);
2005 
2006 	return ret;
2007 }
2008 
net_context_recv(struct net_context * context,net_context_recv_cb_t cb,k_timeout_t timeout,void * user_data)2009 int net_context_recv(struct net_context *context,
2010 		     net_context_recv_cb_t cb,
2011 		     k_timeout_t timeout,
2012 		     void *user_data)
2013 {
2014 	int ret;
2015 	NET_ASSERT(context);
2016 
2017 	if (!net_context_is_used(context)) {
2018 		return -EBADF;
2019 	}
2020 
2021 	k_mutex_lock(&context->lock, K_FOREVER);
2022 
2023 	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
2024 	    net_if_is_ip_offloaded(net_context_get_iface(context))) {
2025 		ret = net_offload_recv(
2026 			net_context_get_iface(context),
2027 			context, cb, timeout, user_data);
2028 		goto unlock;
2029 	}
2030 
2031 	if (IS_ENABLED(CONFIG_NET_UDP) &&
2032 	    net_context_get_ip_proto(context) == IPPROTO_UDP) {
2033 		ret = recv_udp(context, cb, timeout, user_data);
2034 	} else if (IS_ENABLED(CONFIG_NET_TCP) &&
2035 		   net_context_get_ip_proto(context) == IPPROTO_TCP) {
2036 		ret = net_tcp_recv(context, cb, user_data);
2037 	} else {
2038 		if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
2039 		    net_context_get_family(context) == AF_PACKET) {
2040 			struct sockaddr_ll addr;
2041 
2042 			addr.sll_family = AF_PACKET;
2043 			addr.sll_ifindex =
2044 				net_sll_ptr(&context->local)->sll_ifindex;
2045 			addr.sll_protocol =
2046 				net_sll_ptr(&context->local)->sll_protocol;
2047 			addr.sll_halen =
2048 				net_sll_ptr(&context->local)->sll_halen;
2049 
2050 			memcpy(addr.sll_addr,
2051 			       net_sll_ptr(&context->local)->sll_addr,
2052 			       MIN(addr.sll_halen, sizeof(addr.sll_addr)));
2053 
2054 			ret = recv_raw(context, cb, timeout,
2055 				       (struct sockaddr *)&addr, user_data);
2056 		} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
2057 			   net_context_get_family(context) == AF_CAN) {
2058 			struct sockaddr_can local_addr = {
2059 				.can_family = AF_CAN,
2060 			};
2061 
2062 			ret = recv_raw(context, cb, timeout,
2063 				       (struct sockaddr *)&local_addr,
2064 				       user_data);
2065 			if (ret == -EALREADY) {
2066 				/* This is perfectly normal for CAN sockets.
2067 				 * The SocketCAN will dispatch the packet to
2068 				 * correct net_context listener.
2069 				 */
2070 				ret = 0;
2071 			}
2072 		} else {
2073 			ret = -EPROTOTYPE;
2074 		}
2075 	}
2076 
2077 	if (ret < 0) {
2078 		goto unlock;
2079 	}
2080 
2081 #if defined(CONFIG_NET_CONTEXT_SYNC_RECV)
2082 	if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
2083 		int ret;
2084 
2085 		/* Make sure we have the lock, then the
2086 		 * net_context_packet_received() callback will release the
2087 		 * semaphore when data has been received.
2088 		 */
2089 		k_sem_reset(&context->recv_data_wait);
2090 
2091 		k_mutex_unlock(&context->lock);
2092 
2093 		ret = k_sem_take(&context->recv_data_wait, timeout);
2094 
2095 		k_mutex_lock(&context->lock, K_FOREVER);
2096 
2097 		if (ret == -EAGAIN) {
2098 			ret = -ETIMEDOUT;
2099 			goto unlock;
2100 		}
2101 	}
2102 #endif /* CONFIG_NET_CONTEXT_SYNC_RECV */
2103 
2104 unlock:
2105 	k_mutex_unlock(&context->lock);
2106 
2107 	return ret;
2108 }
2109 
net_context_update_recv_wnd(struct net_context * context,int32_t delta)2110 int net_context_update_recv_wnd(struct net_context *context,
2111 				int32_t delta)
2112 {
2113 	int ret;
2114 
2115 	if (IS_ENABLED(CONFIG_NET_OFFLOAD) &&
2116 		net_if_is_ip_offloaded(net_context_get_iface(context))) {
2117 		return 0;
2118 	}
2119 
2120 	k_mutex_lock(&context->lock, K_FOREVER);
2121 
2122 	ret = net_tcp_update_recv_wnd(context, delta);
2123 
2124 	k_mutex_unlock(&context->lock);
2125 
2126 	return ret;
2127 }
2128 
set_context_priority(struct net_context * context,const void * value,size_t len)2129 static int set_context_priority(struct net_context *context,
2130 				const void *value, size_t len)
2131 {
2132 #if defined(CONFIG_NET_CONTEXT_PRIORITY)
2133 	if (len > sizeof(uint8_t)) {
2134 		return -EINVAL;
2135 	}
2136 
2137 	context->options.priority = *((uint8_t *)value);
2138 
2139 	return 0;
2140 #else
2141 	return -ENOTSUP;
2142 #endif
2143 }
2144 
set_context_txtime(struct net_context * context,const void * value,size_t len)2145 static int set_context_txtime(struct net_context *context,
2146 			      const void *value, size_t len)
2147 {
2148 #if defined(CONFIG_NET_CONTEXT_TXTIME)
2149 	if (len > sizeof(bool)) {
2150 		return -EINVAL;
2151 	}
2152 
2153 	context->options.txtime = *((bool *)value);
2154 
2155 	return 0;
2156 #else
2157 	return -ENOTSUP;
2158 #endif
2159 }
2160 
set_context_proxy(struct net_context * context,const void * value,size_t len)2161 static int set_context_proxy(struct net_context *context,
2162 			     const void *value, size_t len)
2163 {
2164 #if defined(CONFIG_SOCKS)
2165 	struct sockaddr *addr = (struct sockaddr *)value;
2166 
2167 	if (len > NET_SOCKADDR_MAX_SIZE) {
2168 		return -EINVAL;
2169 	}
2170 
2171 	if (addr->sa_family != net_context_get_family(context)) {
2172 		return -EINVAL;
2173 	}
2174 
2175 	context->options.proxy.addrlen = len;
2176 	memcpy(&context->options.proxy.addr, addr, len);
2177 
2178 	return 0;
2179 #else
2180 	return -ENOTSUP;
2181 #endif
2182 }
2183 
set_context_rcvtimeo(struct net_context * context,const void * value,size_t len)2184 static int set_context_rcvtimeo(struct net_context *context,
2185 				const void *value, size_t len)
2186 {
2187 #if defined(CONFIG_NET_CONTEXT_RCVTIMEO)
2188 	if (len != sizeof(k_timeout_t)) {
2189 		return -EINVAL;
2190 	}
2191 
2192 	context->options.rcvtimeo = *((k_timeout_t *)value);
2193 
2194 	return 0;
2195 #else
2196 	return -ENOTSUP;
2197 #endif
2198 }
2199 
set_context_sndtimeo(struct net_context * context,const void * value,size_t len)2200 static int set_context_sndtimeo(struct net_context *context,
2201 				const void *value, size_t len)
2202 {
2203 #if defined(CONFIG_NET_CONTEXT_SNDTIMEO)
2204 	if (len != sizeof(k_timeout_t)) {
2205 		return -EINVAL;
2206 	}
2207 
2208 	context->options.sndtimeo = *((k_timeout_t *)value);
2209 
2210 	return 0;
2211 #else
2212 	return -ENOTSUP;
2213 #endif
2214 }
2215 
net_context_set_option(struct net_context * context,enum net_context_option option,const void * value,size_t len)2216 int net_context_set_option(struct net_context *context,
2217 			   enum net_context_option option,
2218 			   const void *value, size_t len)
2219 {
2220 	int ret = 0;
2221 
2222 	NET_ASSERT(context);
2223 
2224 	if (!PART_OF_ARRAY(contexts, context)) {
2225 		return -EINVAL;
2226 	}
2227 
2228 	k_mutex_lock(&context->lock, K_FOREVER);
2229 
2230 	switch (option) {
2231 	case NET_OPT_PRIORITY:
2232 		ret = set_context_priority(context, value, len);
2233 		break;
2234 	case NET_OPT_TXTIME:
2235 		ret = set_context_txtime(context, value, len);
2236 		break;
2237 	case NET_OPT_SOCKS5:
2238 		ret = set_context_proxy(context, value, len);
2239 		break;
2240 	case NET_OPT_RCVTIMEO:
2241 		ret = set_context_rcvtimeo(context, value, len);
2242 		break;
2243 	case NET_OPT_SNDTIMEO:
2244 		ret = set_context_sndtimeo(context, value, len);
2245 		break;
2246 	}
2247 
2248 	k_mutex_unlock(&context->lock);
2249 
2250 	return ret;
2251 }
2252 
net_context_get_option(struct net_context * context,enum net_context_option option,void * value,size_t * len)2253 int net_context_get_option(struct net_context *context,
2254 			    enum net_context_option option,
2255 			    void *value, size_t *len)
2256 {
2257 	int ret = 0;
2258 
2259 	NET_ASSERT(context);
2260 
2261 	if (!PART_OF_ARRAY(contexts, context)) {
2262 		return -EINVAL;
2263 	}
2264 
2265 	k_mutex_lock(&context->lock, K_FOREVER);
2266 
2267 	switch (option) {
2268 	case NET_OPT_PRIORITY:
2269 		ret = get_context_priority(context, value, len);
2270 		break;
2271 	case NET_OPT_TXTIME:
2272 		ret = get_context_txtime(context, value, len);
2273 		break;
2274 	case NET_OPT_SOCKS5:
2275 		ret = get_context_proxy(context, value, len);
2276 		break;
2277 	case NET_OPT_RCVTIMEO:
2278 		ret = get_context_rcvtimeo(context, value, len);
2279 		break;
2280 	case NET_OPT_SNDTIMEO:
2281 		ret = get_context_sndtimeo(context, value, len);
2282 		break;
2283 	}
2284 
2285 	k_mutex_unlock(&context->lock);
2286 
2287 	return ret;
2288 }
2289 
net_context_foreach(net_context_cb_t cb,void * user_data)2290 void net_context_foreach(net_context_cb_t cb, void *user_data)
2291 {
2292 	int i;
2293 
2294 	k_sem_take(&contexts_lock, K_FOREVER);
2295 
2296 	for (i = 0; i < NET_MAX_CONTEXT; i++) {
2297 		if (!net_context_is_used(&contexts[i])) {
2298 			continue;
2299 		}
2300 
2301 		k_mutex_lock(&contexts[i].lock, K_FOREVER);
2302 
2303 		cb(&contexts[i], user_data);
2304 
2305 		k_mutex_unlock(&contexts[i].lock);
2306 	}
2307 
2308 	k_sem_give(&contexts_lock);
2309 }
2310 
net_context_state(struct net_context * context)2311 const char *net_context_state(struct net_context *context)
2312 {
2313 	switch (net_context_get_state(context)) {
2314 	case NET_CONTEXT_IDLE:
2315 		return "IDLE";
2316 	case NET_CONTEXT_CONNECTING:
2317 		return "CONNECTING";
2318 	case NET_CONTEXT_CONNECTED:
2319 		return "CONNECTED";
2320 	case NET_CONTEXT_LISTENING:
2321 		return "LISTENING";
2322 	}
2323 
2324 	return NULL;
2325 }
2326 
net_context_init(void)2327 void net_context_init(void)
2328 {
2329 	k_sem_init(&contexts_lock, 1, K_SEM_MAX_LIMIT);
2330 }
2331