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 void net_process_rx_packet(struct net_pkt *pkt);
63 extern void net_process_tx_packet(struct net_pkt *pkt);
64 
65 extern int net_icmp_call_ipv4_handlers(struct net_pkt *pkt,
66 				       struct net_ipv4_hdr *ipv4_hdr,
67 				       struct net_icmp_hdr *icmp_hdr);
68 extern int net_icmp_call_ipv6_handlers(struct net_pkt *pkt,
69 				       struct net_ipv6_hdr *ipv6_hdr,
70 				       struct net_icmp_hdr *icmp_hdr);
71 
72 extern struct net_if *net_ipip_get_virtual_interface(struct net_if *input_iface);
73 
74 #if defined(CONFIG_NET_SOCKETS_SERVICE)
75 extern void socket_service_init(void);
76 #else
socket_service_init(void)77 static inline void socket_service_init(void) { }
78 #endif
79 
80 #if defined(CONFIG_NET_NATIVE) || defined(CONFIG_NET_OFFLOAD)
81 extern void net_context_init(void);
82 extern const char *net_context_state(struct net_context *context);
83 extern bool net_context_is_reuseaddr_set(struct net_context *context);
84 extern bool net_context_is_reuseport_set(struct net_context *context);
85 extern bool net_context_is_v6only_set(struct net_context *context);
86 extern bool net_context_is_recv_pktinfo_set(struct net_context *context);
87 extern void net_pkt_init(void);
88 extern void net_tc_tx_init(void);
89 extern void net_tc_rx_init(void);
90 int net_context_get_local_addr(struct net_context *context,
91 			       struct sockaddr *addr,
92 			       socklen_t *addrlen);
93 #else
net_context_init(void)94 static inline void net_context_init(void) { }
net_pkt_init(void)95 static inline void net_pkt_init(void) { }
net_tc_tx_init(void)96 static inline void net_tc_tx_init(void) { }
net_tc_rx_init(void)97 static inline void net_tc_rx_init(void) { }
net_context_state(struct net_context * context)98 static inline const char *net_context_state(struct net_context *context)
99 {
100 	ARG_UNUSED(context);
101 	return NULL;
102 }
net_context_is_reuseaddr_set(struct net_context * context)103 static inline bool net_context_is_reuseaddr_set(struct net_context *context)
104 {
105 	ARG_UNUSED(context);
106 	return false;
107 }
net_context_is_reuseport_set(struct net_context * context)108 static inline bool net_context_is_reuseport_set(struct net_context *context)
109 {
110 	ARG_UNUSED(context);
111 	return false;
112 }
net_context_is_recv_pktinfo_set(struct net_context * context)113 static inline bool net_context_is_recv_pktinfo_set(struct net_context *context)
114 {
115 	ARG_UNUSED(context);
116 	return false;
117 }
118 
net_context_get_local_addr(struct net_context * context,struct sockaddr * addr,socklen_t * addrlen)119 static inline int net_context_get_local_addr(struct net_context *context,
120 					     struct sockaddr *addr,
121 					     socklen_t *addrlen)
122 {
123 	ARG_UNUSED(context);
124 	ARG_UNUSED(addr);
125 	ARG_UNUSED(addrlen);
126 
127 	return -ENOTSUP;
128 }
129 #endif
130 
131 #if defined(CONFIG_DNS_SOCKET_DISPATCHER)
132 extern void dns_dispatcher_init(void);
133 #else
dns_dispatcher_init(void)134 static inline void dns_dispatcher_init(void) { }
135 #endif
136 
137 #if defined(CONFIG_MDNS_RESPONDER)
138 extern void mdns_init_responder(void);
139 #else
mdns_init_responder(void)140 static inline void mdns_init_responder(void) { }
141 #endif /* CONFIG_MDNS_RESPONDER */
142 
143 #if defined(CONFIG_NET_NATIVE)
144 enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback);
145 enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback);
146 #else
net_ipv4_input(struct net_pkt * pkt,bool is_loopback)147 static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt,
148 					      bool is_loopback)
149 {
150 	ARG_UNUSED(pkt);
151 	ARG_UNUSED(is_loopback);
152 
153 	return NET_CONTINUE;
154 }
155 
net_ipv6_input(struct net_pkt * pkt,bool is_loopback)156 static inline enum net_verdict net_ipv6_input(struct net_pkt *pkt,
157 					      bool is_loopback)
158 {
159 	ARG_UNUSED(pkt);
160 	ARG_UNUSED(is_loopback);
161 
162 	return NET_CONTINUE;
163 }
164 #endif
165 extern bool net_tc_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt);
166 extern void net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt);
167 extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt);
168 
169 char *net_sprint_addr(sa_family_t af, const void *addr);
170 
171 #define net_sprint_ipv4_addr(_addr) net_sprint_addr(AF_INET, _addr)
172 
173 #define net_sprint_ipv6_addr(_addr) net_sprint_addr(AF_INET6, _addr)
174 
175 #if defined(CONFIG_COAP)
176 /**
177  * @brief CoAP init function declaration. It belongs here because we don't want
178  * to expose it as a public API -- it should only be called once, and only by
179  * net_core.
180  */
181 extern void net_coap_init(void);
182 #else
net_coap_init(void)183 static inline void net_coap_init(void)
184 {
185 	return;
186 }
187 #endif
188 
189 #if defined(CONFIG_NET_SOCKETS_OBJ_CORE)
190 struct sock_obj_type_raw_stats {
191 	uint64_t sent;
192 	uint64_t received;
193 };
194 
195 struct sock_obj {
196 	struct net_socket_register *reg;
197 	uint64_t create_time; /* in ticks */
198 	k_tid_t creator;
199 	int fd;
200 	int socket_family;
201 	int socket_type;
202 	int socket_proto;
203 	bool init_done;
204 	struct k_obj_core obj_core;
205 	struct sock_obj_type_raw_stats stats;
206 };
207 #endif /* CONFIG_NET_SOCKETS_OBJ_CORE */
208 
209 #if defined(CONFIG_NET_IPV6_PE)
210 /* This is needed by ipv6_pe.c when privacy extension support is enabled */
211 void net_if_ipv6_start_dad(struct net_if *iface,
212 			   struct net_if_addr *ifaddr);
213 #endif
214 
215 #if defined(CONFIG_NET_GPTP)
216 /**
217  * @brief Initialize Precision Time Protocol Layer.
218  */
219 void net_gptp_init(void);
220 
221 /**
222  * @brief Process a ptp message.
223  *
224  * @param buf Buffer with a valid PTP Ethernet type.
225  *
226  * @return Return the policy for network buffer.
227  */
228 enum net_verdict net_gptp_recv(struct net_if *iface, struct net_pkt *pkt);
229 #else
230 #define net_gptp_init()
231 #define net_gptp_recv(iface, pkt) NET_DROP
232 #endif /* CONFIG_NET_GPTP */
233 
234 #if defined(CONFIG_NET_IPV4_FRAGMENT)
235 int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
236 				 uint16_t pkt_len, uint16_t mtu);
237 #endif
238 
239 #if defined(CONFIG_NET_IPV6_FRAGMENT)
240 int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
241 				 uint16_t pkt_len);
242 #endif
243 
244 extern const char *net_verdict2str(enum net_verdict verdict);
245 extern const char *net_proto2str(int family, int proto);
246 extern char *net_byte_to_hex(char *ptr, uint8_t byte, char base, bool pad);
247 extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len,
248 				    char *buf, int buflen);
249 extern uint16_t calc_chksum(uint16_t sum_in, const uint8_t *data, size_t len);
250 extern uint16_t net_calc_chksum(struct net_pkt *pkt, uint8_t proto);
251 
252 /**
253  * @brief Deliver the incoming packet through the recv_cb of the net_context
254  *        to the upper layers
255  *
256  * @param conn		Network connection
257  * @param pkt		Network packet
258  * @param ip_hdr	Pointer to IP header, optional
259  * @param proto_hdr	Pointer to transport layer protocol header, optional
260  * @param user_data	User data passed as an argument
261  *
262  * @return NET_OK	if the packet is consumed through the recv_cb
263  *         NET_DROP	if the recv_cb isn't set
264  */
265 enum net_verdict net_context_packet_received(struct net_conn *conn,
266 					     struct net_pkt *pkt,
267 					     union net_ip_header *ip_hdr,
268 					     union net_proto_header *proto_hdr,
269 					     void *user_data);
270 
271 #if defined(CONFIG_NET_IPV4)
272 extern uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt);
273 #endif /* CONFIG_NET_IPV4 */
274 
275 #if defined(CONFIG_NET_IPV4_IGMP)
276 /**
277  * @brief Initialise the IGMP module for a given interface
278  *
279  * @param iface		Interface to init IGMP
280  */
281 void net_ipv4_igmp_init(struct net_if *iface);
282 #endif /* CONFIG_NET_IPV4_IGMP */
283 
284 #if defined(CONFIG_NET_IPV4_IGMP)
285 uint16_t net_calc_chksum_igmp(struct net_pkt *pkt);
286 enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt,
287 				     struct net_ipv4_hdr *ip_hdr);
288 #else
289 #define net_ipv4_igmp_input(...)
290 #define net_calc_chksum_igmp(pkt) 0U
291 #endif /* CONFIG_NET_IPV4_IGMP */
292 
net_calc_chksum_icmpv6(struct net_pkt * pkt)293 static inline uint16_t net_calc_chksum_icmpv6(struct net_pkt *pkt)
294 {
295 	return net_calc_chksum(pkt, IPPROTO_ICMPV6);
296 }
297 
net_calc_chksum_icmpv4(struct net_pkt * pkt)298 static inline uint16_t net_calc_chksum_icmpv4(struct net_pkt *pkt)
299 {
300 	return net_calc_chksum(pkt, IPPROTO_ICMP);
301 }
302 
net_calc_chksum_udp(struct net_pkt * pkt)303 static inline uint16_t net_calc_chksum_udp(struct net_pkt *pkt)
304 {
305 	uint16_t chksum = net_calc_chksum(pkt, IPPROTO_UDP);
306 
307 	return chksum == 0U ? 0xffff : chksum;
308 }
309 
net_calc_verify_chksum_udp(struct net_pkt * pkt)310 static inline uint16_t net_calc_verify_chksum_udp(struct net_pkt *pkt)
311 {
312 	return net_calc_chksum(pkt, IPPROTO_UDP);
313 }
314 
net_calc_chksum_tcp(struct net_pkt * pkt)315 static inline uint16_t net_calc_chksum_tcp(struct net_pkt *pkt)
316 {
317 	return net_calc_chksum(pkt, IPPROTO_TCP);
318 }
319 
net_sprint_ll_addr(const uint8_t * ll,uint8_t ll_len)320 static inline char *net_sprint_ll_addr(const uint8_t *ll, uint8_t ll_len)
321 {
322 	static char buf[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
323 
324 	return net_sprint_ll_addr_buf(ll, ll_len, (char *)buf, sizeof(buf));
325 }
326 
net_hexdump(const char * str,const uint8_t * packet,size_t length)327 static inline void net_hexdump(const char *str,
328 			       const uint8_t *packet, size_t length)
329 {
330 	if (!length) {
331 		LOG_DBG("%s zero-length packet", str);
332 		return;
333 	}
334 
335 	LOG_HEXDUMP_DBG(packet, length, str);
336 }
337 
338 
339 /* Hexdump from all fragments */
net_pkt_hexdump(struct net_pkt * pkt,const char * str)340 static inline void net_pkt_hexdump(struct net_pkt *pkt, const char *str)
341 {
342 	struct net_buf *buf = pkt->buffer;
343 	char pkt_str[sizeof("0x") + sizeof(intptr_t) * 2];
344 
345 	if (str && str[0]) {
346 		LOG_DBG("%s", str);
347 	}
348 
349 	snprintk(pkt_str, sizeof(pkt_str), "%p", pkt);
350 
351 	while (buf) {
352 		LOG_HEXDUMP_DBG(buf->data, buf->len, pkt_str);
353 		buf = buf->frags;
354 	}
355 }
356 
net_pkt_print_buffer_info(struct net_pkt * pkt,const char * str)357 static inline void net_pkt_print_buffer_info(struct net_pkt *pkt, const char *str)
358 {
359 	struct net_buf *buf = pkt->buffer;
360 
361 	if (str) {
362 		printk("%s", str);
363 	}
364 
365 	printk("%p[%ld]", pkt, atomic_get(&pkt->atomic_ref));
366 
367 	if (buf) {
368 		printk("->");
369 	}
370 
371 	while (buf) {
372 		printk("%p[%ld/%u (%u/%u)]", buf, atomic_get(&pkt->atomic_ref),
373 		       buf->len, net_buf_max_len(buf), buf->size);
374 
375 		buf = buf->frags;
376 		if (buf) {
377 			printk("->");
378 		}
379 	}
380 
381 	printk("\n");
382 }
383