1 /** @file
2  @brief Network stack private header
3 
4  This is not to be included by the application.
5  */
6 
7 /*
8  * Copyright (c) 2016 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #include <errno.h>
14 #include <zephyr/sys/printk.h>
15 #include <zephyr/net/net_context.h>
16 #include <zephyr/net/net_pkt.h>
17 #include <zephyr/net/icmp.h>
18 
19 #ifdef CONFIG_NET_MGMT_EVENT_INFO
20 
21 #include <zephyr/net/net_event.h>
22 
23 #ifdef CONFIG_NET_L2_WIFI_MGMT
24 /* For struct wifi_scan_result */
25 #include <zephyr/net/wifi_mgmt.h>
26 #endif /* CONFIG_NET_L2_WIFI_MGMT */
27 
28 #define DEFAULT_NET_EVENT_INFO_SIZE 32
29 /* NOTE: Update this union with all *big* event info structs */
30 union net_mgmt_events {
31 #if defined(CONFIG_NET_DHCPV4)
32 	struct net_if_dhcpv4 dhcpv4;
33 #endif /* CONFIG_NET_DHCPV4 */
34 #if defined(CONFIG_NET_DHCPV6)
35 	struct net_if_dhcpv6 dhcpv6;
36 #endif /* CONFIG_NET_DHCPV6 */
37 #if defined(CONFIG_NET_L2_WIFI_MGMT)
38 	union wifi_mgmt_events wifi;
39 #endif /* CONFIG_NET_L2_WIFI_MGMT */
40 #if defined(CONFIG_NET_IPV6)
41 	struct net_event_ipv6_prefix ipv6_prefix;
42 #if defined(CONFIG_NET_IPV6_MLD)
43 	struct net_event_ipv6_route ipv6_route;
44 #endif /* CONFIG_NET_IPV6_MLD */
45 #endif /* CONFIG_NET_IPV6 */
46 #if defined(CONFIG_NET_HOSTNAME_ENABLE)
47 	struct net_event_l4_hostname hostname;
48 #endif /* CONFIG_NET_HOSTNAME_ENABLE */
49 	char default_event[DEFAULT_NET_EVENT_INFO_SIZE];
50 };
51 
52 #define NET_EVENT_INFO_MAX_SIZE sizeof(union net_mgmt_events)
53 
54 #endif
55 
56 #include "connection.h"
57 
58 extern void net_if_init(void);
59 extern void net_if_post_init(void);
60 extern void net_if_stats_reset(struct net_if *iface);
61 extern void net_if_stats_reset_all(void);
62 extern const char *net_if_oper_state2str(enum net_if_oper_state state);
63 extern void net_process_rx_packet(struct net_pkt *pkt);
64 extern void net_process_tx_packet(struct net_pkt *pkt);
65 
66 extern struct net_if_addr *net_if_ipv4_addr_get_first_by_index(int ifindex);
67 
68 extern int net_icmp_call_ipv4_handlers(struct net_pkt *pkt,
69 				       struct net_ipv4_hdr *ipv4_hdr,
70 				       struct net_icmp_hdr *icmp_hdr);
71 extern int net_icmp_call_ipv6_handlers(struct net_pkt *pkt,
72 				       struct net_ipv6_hdr *ipv6_hdr,
73 				       struct net_icmp_hdr *icmp_hdr);
74 
75 extern struct net_if *net_ipip_get_virtual_interface(struct net_if *input_iface);
76 
77 #if defined(CONFIG_NET_STATISTICS_VIA_PROMETHEUS)
78 extern void net_stats_prometheus_init(struct net_if *iface);
79 #else
net_stats_prometheus_init(struct net_if * iface)80 static inline void net_stats_prometheus_init(struct net_if *iface)
81 {
82 	ARG_UNUSED(iface);
83 }
84 #endif /* CONFIG_NET_STATISTICS_VIA_PROMETHEUS */
85 
86 #if defined(CONFIG_NET_SOCKETS_SERVICE)
87 extern void socket_service_init(void);
88 #else
socket_service_init(void)89 static inline void socket_service_init(void) { }
90 #endif
91 
92 #if defined(CONFIG_NET_NATIVE) || defined(CONFIG_NET_OFFLOAD)
93 extern void net_context_init(void);
94 extern const char *net_context_state(struct net_context *context);
95 extern bool net_context_is_reuseaddr_set(struct net_context *context);
96 extern bool net_context_is_reuseport_set(struct net_context *context);
97 extern bool net_context_is_v6only_set(struct net_context *context);
98 extern bool net_context_is_recv_pktinfo_set(struct net_context *context);
99 extern bool net_context_is_recv_hoplimit_set(struct net_context *context);
100 extern bool net_context_is_timestamping_set(struct net_context *context);
101 extern void net_pkt_init(void);
102 int net_context_get_local_addr(struct net_context *context,
103 			       struct sockaddr *addr,
104 			       socklen_t *addrlen);
105 #else
net_context_init(void)106 static inline void net_context_init(void) { }
net_pkt_init(void)107 static inline void net_pkt_init(void) { }
net_context_state(struct net_context * context)108 static inline const char *net_context_state(struct net_context *context)
109 {
110 	ARG_UNUSED(context);
111 	return NULL;
112 }
net_context_is_reuseaddr_set(struct net_context * context)113 static inline bool net_context_is_reuseaddr_set(struct net_context *context)
114 {
115 	ARG_UNUSED(context);
116 	return false;
117 }
net_context_is_reuseport_set(struct net_context * context)118 static inline bool net_context_is_reuseport_set(struct net_context *context)
119 {
120 	ARG_UNUSED(context);
121 	return false;
122 }
net_context_is_recv_pktinfo_set(struct net_context * context)123 static inline bool net_context_is_recv_pktinfo_set(struct net_context *context)
124 {
125 	ARG_UNUSED(context);
126 	return false;
127 }
net_context_is_recv_hoplimit_set(struct net_context * context)128 static inline bool net_context_is_recv_hoplimit_set(struct net_context *context)
129 {
130 	ARG_UNUSED(context);
131 	return false;
132 }
net_context_is_timestamping_set(struct net_context * context)133 static inline bool net_context_is_timestamping_set(struct net_context *context)
134 {
135 	ARG_UNUSED(context);
136 	return false;
137 }
138 
net_context_get_local_addr(struct net_context * context,struct sockaddr * addr,socklen_t * addrlen)139 static inline int net_context_get_local_addr(struct net_context *context,
140 					     struct sockaddr *addr,
141 					     socklen_t *addrlen)
142 {
143 	ARG_UNUSED(context);
144 	ARG_UNUSED(addr);
145 	ARG_UNUSED(addrlen);
146 
147 	return -ENOTSUP;
148 }
149 #endif
150 
151 #if defined(CONFIG_DNS_SOCKET_DISPATCHER)
152 extern void dns_dispatcher_init(void);
153 #else
dns_dispatcher_init(void)154 static inline void dns_dispatcher_init(void) { }
155 #endif
156 
157 #if defined(CONFIG_MDNS_RESPONDER)
158 extern void mdns_init_responder(void);
159 #else
mdns_init_responder(void)160 static inline void mdns_init_responder(void) { }
161 #endif /* CONFIG_MDNS_RESPONDER */
162 
163 #if defined(CONFIG_DNS_RESOLVER)
164 #include <zephyr/net/dns_resolve.h>
165 extern int dns_resolve_name_internal(struct dns_resolve_context *ctx,
166 				     const char *query,
167 				     enum dns_query_type type,
168 				     uint16_t *dns_id,
169 				     dns_resolve_cb_t cb,
170 				     void *user_data,
171 				     int32_t timeout,
172 				     bool use_cache);
173 #include <zephyr/net/socket_service.h>
174 extern int dns_resolve_init_with_svc(struct dns_resolve_context *ctx,
175 				     const char *servers[],
176 				     const struct sockaddr *servers_sa[],
177 				     const struct net_socket_service_desc *svc,
178 				     uint16_t port, int interfaces[]);
179 #endif /* CONFIG_DNS_RESOLVER */
180 
181 #if defined(CONFIG_NET_TEST)
182 extern void loopback_enable_address_swap(bool swap_addresses);
183 #endif /* CONFIG_NET_TEST */
184 
185 #if defined(CONFIG_NET_NATIVE)
186 enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback);
187 enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback);
188 extern void net_tc_tx_init(void);
189 extern void net_tc_rx_init(void);
190 #else
net_ipv4_input(struct net_pkt * pkt,bool is_loopback)191 static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt,
192 					      bool is_loopback)
193 {
194 	ARG_UNUSED(pkt);
195 	ARG_UNUSED(is_loopback);
196 
197 	return NET_CONTINUE;
198 }
199 
net_ipv6_input(struct net_pkt * pkt,bool is_loopback)200 static inline enum net_verdict net_ipv6_input(struct net_pkt *pkt,
201 					      bool is_loopback)
202 {
203 	ARG_UNUSED(pkt);
204 	ARG_UNUSED(is_loopback);
205 
206 	return NET_CONTINUE;
207 }
208 
net_tc_tx_init(void)209 static inline void net_tc_tx_init(void) { }
net_tc_rx_init(void)210 static inline void net_tc_rx_init(void) { }
211 #endif
212 enum net_verdict net_tc_try_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt,
213 					       k_timeout_t timeout);
214 extern enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt);
215 extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt);
216 
217 char *net_sprint_addr(sa_family_t af, const void *addr);
218 
219 #define net_sprint_ipv4_addr(_addr) net_sprint_addr(AF_INET, _addr)
220 
221 #define net_sprint_ipv6_addr(_addr) net_sprint_addr(AF_INET6, _addr)
222 
223 #if defined(CONFIG_COAP)
224 /**
225  * @brief CoAP init function declaration. It belongs here because we don't want
226  * to expose it as a public API -- it should only be called once, and only by
227  * net_core.
228  */
229 extern void net_coap_init(void);
230 #else
net_coap_init(void)231 static inline void net_coap_init(void)
232 {
233 	return;
234 }
235 #endif
236 
237 #if defined(CONFIG_NET_SOCKETS_OBJ_CORE)
238 struct sock_obj_type_raw_stats {
239 	uint64_t sent;
240 	uint64_t received;
241 };
242 
243 struct sock_obj {
244 	struct net_socket_register *reg;
245 	uint64_t create_time; /* in ticks */
246 	k_tid_t creator;
247 	int fd;
248 	int socket_family;
249 	int socket_type;
250 	int socket_proto;
251 	bool init_done;
252 	struct k_obj_core obj_core;
253 	struct sock_obj_type_raw_stats stats;
254 };
255 #endif /* CONFIG_NET_SOCKETS_OBJ_CORE */
256 
257 #if defined(CONFIG_NET_IPV6_PE)
258 /* This is needed by ipv6_pe.c when privacy extension support is enabled */
259 void net_if_ipv6_start_dad(struct net_if *iface,
260 			   struct net_if_addr *ifaddr);
261 #endif
262 
263 #if defined(CONFIG_NET_GPTP)
264 /**
265  * @brief Initialize Precision Time Protocol Layer.
266  */
267 void net_gptp_init(void);
268 #else
269 #define net_gptp_init()
270 #endif /* CONFIG_NET_GPTP */
271 
272 #if defined(CONFIG_NET_IPV4_FRAGMENT)
273 int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
274 				 uint16_t pkt_len, uint16_t mtu);
275 #endif
276 
277 #if defined(CONFIG_NET_IPV6_FRAGMENT)
278 int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
279 				 uint16_t pkt_len, uint16_t mtu);
280 #endif
281 
282 extern const char *net_verdict2str(enum net_verdict verdict);
283 extern const char *net_proto2str(int family, int proto);
284 extern char *net_byte_to_hex(char *ptr, uint8_t byte, char base, bool pad);
285 extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len,
286 				    char *buf, int buflen);
287 extern uint16_t calc_chksum(uint16_t sum_in, const uint8_t *data, size_t len);
288 extern uint16_t net_calc_chksum(struct net_pkt *pkt, uint8_t proto);
289 
290 /**
291  * @brief Deliver the incoming packet through the recv_cb of the net_context
292  *        to the upper layers
293  *
294  * @param conn		Network connection
295  * @param pkt		Network packet
296  * @param ip_hdr	Pointer to IP header, optional
297  * @param proto_hdr	Pointer to transport layer protocol header, optional
298  * @param user_data	User data passed as an argument
299  *
300  * @return NET_OK	if the packet is consumed through the recv_cb
301  *         NET_DROP	if the recv_cb isn't set
302  */
303 enum net_verdict net_context_packet_received(struct net_conn *conn,
304 					     struct net_pkt *pkt,
305 					     union net_ip_header *ip_hdr,
306 					     union net_proto_header *proto_hdr,
307 					     void *user_data);
308 
309 #if defined(CONFIG_NET_IPV4)
310 uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt);
311 #else
312 #define net_calc_chksum_ipv4(...) 0U
313 #endif /* CONFIG_NET_IPV4 */
314 
315 #if defined(CONFIG_NET_IPV4_IGMP)
316 /**
317  * @brief Initialise the IGMP module for a given interface
318  *
319  * @param iface		Interface to init IGMP
320  */
321 void net_ipv4_igmp_init(struct net_if *iface);
322 #endif /* CONFIG_NET_IPV4_IGMP */
323 
324 #if defined(CONFIG_NET_IPV4_IGMP)
325 uint16_t net_calc_chksum_igmp(struct net_pkt *pkt);
326 enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt,
327 				     struct net_ipv4_hdr *ip_hdr);
328 #else
329 #define net_ipv4_igmp_input(...)
330 #define net_calc_chksum_igmp(pkt) 0U
331 #endif /* CONFIG_NET_IPV4_IGMP */
332 
net_calc_chksum_icmpv6(struct net_pkt * pkt)333 static inline uint16_t net_calc_chksum_icmpv6(struct net_pkt *pkt)
334 {
335 	return net_calc_chksum(pkt, IPPROTO_ICMPV6);
336 }
337 
net_calc_chksum_icmpv4(struct net_pkt * pkt)338 static inline uint16_t net_calc_chksum_icmpv4(struct net_pkt *pkt)
339 {
340 	return net_calc_chksum(pkt, IPPROTO_ICMP);
341 }
342 
net_calc_chksum_udp(struct net_pkt * pkt)343 static inline uint16_t net_calc_chksum_udp(struct net_pkt *pkt)
344 {
345 	uint16_t chksum = net_calc_chksum(pkt, IPPROTO_UDP);
346 
347 	return chksum == 0U ? 0xffff : chksum;
348 }
349 
net_calc_verify_chksum_udp(struct net_pkt * pkt)350 static inline uint16_t net_calc_verify_chksum_udp(struct net_pkt *pkt)
351 {
352 	return net_calc_chksum(pkt, IPPROTO_UDP);
353 }
354 
net_calc_chksum_tcp(struct net_pkt * pkt)355 static inline uint16_t net_calc_chksum_tcp(struct net_pkt *pkt)
356 {
357 	return net_calc_chksum(pkt, IPPROTO_TCP);
358 }
359 
net_sprint_ll_addr(const uint8_t * ll,uint8_t ll_len)360 static inline char *net_sprint_ll_addr(const uint8_t *ll, uint8_t ll_len)
361 {
362 	static char buf[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
363 
364 	return net_sprint_ll_addr_buf(ll, ll_len, (char *)buf, sizeof(buf));
365 }
366 
net_hexdump(const char * str,const uint8_t * packet,size_t length)367 static inline void net_hexdump(const char *str,
368 			       const uint8_t *packet, size_t length)
369 {
370 	if (!length) {
371 		LOG_DBG("%s zero-length packet", str);
372 		return;
373 	}
374 
375 	LOG_HEXDUMP_DBG(packet, length, str);
376 }
377 
378 
379 /* Hexdump from all fragments */
net_pkt_hexdump(struct net_pkt * pkt,const char * str)380 static inline void net_pkt_hexdump(struct net_pkt *pkt, const char *str)
381 {
382 	struct net_buf *buf = pkt->buffer;
383 	char pkt_str[sizeof("0x") + sizeof(intptr_t) * 2];
384 
385 	if (str && str[0]) {
386 		LOG_DBG("%s", str);
387 	}
388 
389 	snprintk(pkt_str, sizeof(pkt_str), "%p", pkt);
390 
391 	while (buf) {
392 		LOG_HEXDUMP_DBG(buf->data, buf->len, pkt_str);
393 		buf = buf->frags;
394 	}
395 }
396 
net_pkt_print_buffer_info(struct net_pkt * pkt,const char * str)397 static inline void net_pkt_print_buffer_info(struct net_pkt *pkt, const char *str)
398 {
399 	struct net_buf *buf = pkt->buffer;
400 
401 	if (str) {
402 		printk("%s", str);
403 	}
404 
405 	printk("%p[%ld]", pkt, atomic_get(&pkt->atomic_ref));
406 
407 	if (buf) {
408 		printk("->");
409 	}
410 
411 	while (buf) {
412 		printk("%p[%ld/%u (%u/%u)]", buf, atomic_get(&pkt->atomic_ref),
413 		       buf->len, net_buf_max_len(buf), buf->size);
414 
415 		buf = buf->frags;
416 		if (buf) {
417 			printk("->");
418 		}
419 	}
420 
421 	printk("\n");
422 }
423