| /** @file |
| @brief Network stack private header |
| |
| This is not to be included by the application. |
| */ |
| |
| /* |
| * Copyright (c) 2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <errno.h> |
| #include <zephyr/sys/printk.h> |
| #include <zephyr/net/net_context.h> |
| #include <zephyr/net/net_pkt.h> |
| #include <zephyr/net/icmp.h> |
| |
| #ifdef CONFIG_NET_MGMT_EVENT_INFO |
| |
| #include <zephyr/net/net_event.h> |
| |
| #ifdef CONFIG_NET_L2_WIFI_MGMT |
| /* For struct wifi_scan_result */ |
| #include <zephyr/net/wifi_mgmt.h> |
| #endif /* CONFIG_NET_L2_WIFI_MGMT */ |
| |
| #define DEFAULT_NET_EVENT_INFO_SIZE 32 |
| /* NOTE: Update this union with all *big* event info structs */ |
| union net_mgmt_events { |
| #if defined(CONFIG_NET_DHCPV4) |
| struct net_if_dhcpv4 dhcpv4; |
| #endif /* CONFIG_NET_DHCPV4 */ |
| #if defined(CONFIG_NET_DHCPV6) |
| struct net_if_dhcpv6 dhcpv6; |
| #endif /* CONFIG_NET_DHCPV6 */ |
| #if defined(CONFIG_NET_L2_WIFI_MGMT) |
| union wifi_mgmt_events wifi; |
| #endif /* CONFIG_NET_L2_WIFI_MGMT */ |
| #if defined(CONFIG_NET_IPV6) |
| struct net_event_ipv6_prefix ipv6_prefix; |
| #if defined(CONFIG_NET_IPV6_MLD) |
| struct net_event_ipv6_route ipv6_route; |
| #endif /* CONFIG_NET_IPV6_MLD */ |
| #endif /* CONFIG_NET_IPV6 */ |
| #if defined(CONFIG_NET_HOSTNAME_ENABLE) |
| struct net_event_l4_hostname hostname; |
| #endif /* CONFIG_NET_HOSTNAME_ENABLE */ |
| char default_event[DEFAULT_NET_EVENT_INFO_SIZE]; |
| }; |
| |
| #define NET_EVENT_INFO_MAX_SIZE sizeof(union net_mgmt_events) |
| |
| #endif |
| |
| #include "connection.h" |
| |
| extern void net_if_init(void); |
| extern void net_if_post_init(void); |
| extern void net_if_stats_reset(struct net_if *iface); |
| extern void net_if_stats_reset_all(void); |
| extern void net_process_rx_packet(struct net_pkt *pkt); |
| extern void net_process_tx_packet(struct net_pkt *pkt); |
| |
| extern struct net_if_addr *net_if_ipv4_addr_get_first_by_index(int ifindex); |
| |
| extern int net_icmp_call_ipv4_handlers(struct net_pkt *pkt, |
| struct net_ipv4_hdr *ipv4_hdr, |
| struct net_icmp_hdr *icmp_hdr); |
| extern int net_icmp_call_ipv6_handlers(struct net_pkt *pkt, |
| struct net_ipv6_hdr *ipv6_hdr, |
| struct net_icmp_hdr *icmp_hdr); |
| |
| extern struct net_if *net_ipip_get_virtual_interface(struct net_if *input_iface); |
| |
| #if defined(CONFIG_NET_SOCKETS_SERVICE) |
| extern void socket_service_init(void); |
| #else |
| static inline void socket_service_init(void) { } |
| #endif |
| |
| #if defined(CONFIG_NET_NATIVE) || defined(CONFIG_NET_OFFLOAD) |
| extern void net_context_init(void); |
| extern const char *net_context_state(struct net_context *context); |
| extern bool net_context_is_reuseaddr_set(struct net_context *context); |
| extern bool net_context_is_reuseport_set(struct net_context *context); |
| extern bool net_context_is_v6only_set(struct net_context *context); |
| extern bool net_context_is_recv_pktinfo_set(struct net_context *context); |
| extern bool net_context_is_timestamping_set(struct net_context *context); |
| extern void net_pkt_init(void); |
| int net_context_get_local_addr(struct net_context *context, |
| struct sockaddr *addr, |
| socklen_t *addrlen); |
| #else |
| static inline void net_context_init(void) { } |
| static inline void net_pkt_init(void) { } |
| static inline const char *net_context_state(struct net_context *context) |
| { |
| ARG_UNUSED(context); |
| return NULL; |
| } |
| static inline bool net_context_is_reuseaddr_set(struct net_context *context) |
| { |
| ARG_UNUSED(context); |
| return false; |
| } |
| static inline bool net_context_is_reuseport_set(struct net_context *context) |
| { |
| ARG_UNUSED(context); |
| return false; |
| } |
| static inline bool net_context_is_recv_pktinfo_set(struct net_context *context) |
| { |
| ARG_UNUSED(context); |
| return false; |
| } |
| static inline bool net_context_is_timestamping_set(struct net_context *context) |
| { |
| ARG_UNUSED(context); |
| return false; |
| } |
| |
| static inline int net_context_get_local_addr(struct net_context *context, |
| struct sockaddr *addr, |
| socklen_t *addrlen) |
| { |
| ARG_UNUSED(context); |
| ARG_UNUSED(addr); |
| ARG_UNUSED(addrlen); |
| |
| return -ENOTSUP; |
| } |
| #endif |
| |
| #if defined(CONFIG_DNS_SOCKET_DISPATCHER) |
| extern void dns_dispatcher_init(void); |
| #else |
| static inline void dns_dispatcher_init(void) { } |
| #endif |
| |
| #if defined(CONFIG_MDNS_RESPONDER) |
| extern void mdns_init_responder(void); |
| #else |
| static inline void mdns_init_responder(void) { } |
| #endif /* CONFIG_MDNS_RESPONDER */ |
| |
| #if defined(CONFIG_NET_TEST) |
| extern void loopback_enable_address_swap(bool swap_addresses); |
| #endif /* CONFIG_NET_TEST */ |
| |
| #if defined(CONFIG_NET_NATIVE) |
| enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback); |
| enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback); |
| extern void net_tc_tx_init(void); |
| extern void net_tc_rx_init(void); |
| #else |
| static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt, |
| bool is_loopback) |
| { |
| ARG_UNUSED(pkt); |
| ARG_UNUSED(is_loopback); |
| |
| return NET_CONTINUE; |
| } |
| |
| static inline enum net_verdict net_ipv6_input(struct net_pkt *pkt, |
| bool is_loopback) |
| { |
| ARG_UNUSED(pkt); |
| ARG_UNUSED(is_loopback); |
| |
| return NET_CONTINUE; |
| } |
| |
| static inline void net_tc_tx_init(void) { } |
| static inline void net_tc_rx_init(void) { } |
| #endif |
| extern bool net_tc_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt); |
| extern void net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt); |
| extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt); |
| |
| char *net_sprint_addr(sa_family_t af, const void *addr); |
| |
| #define net_sprint_ipv4_addr(_addr) net_sprint_addr(AF_INET, _addr) |
| |
| #define net_sprint_ipv6_addr(_addr) net_sprint_addr(AF_INET6, _addr) |
| |
| #if defined(CONFIG_COAP) |
| /** |
| * @brief CoAP init function declaration. It belongs here because we don't want |
| * to expose it as a public API -- it should only be called once, and only by |
| * net_core. |
| */ |
| extern void net_coap_init(void); |
| #else |
| static inline void net_coap_init(void) |
| { |
| return; |
| } |
| #endif |
| |
| #if defined(CONFIG_NET_SOCKETS_OBJ_CORE) |
| struct sock_obj_type_raw_stats { |
| uint64_t sent; |
| uint64_t received; |
| }; |
| |
| struct sock_obj { |
| struct net_socket_register *reg; |
| uint64_t create_time; /* in ticks */ |
| k_tid_t creator; |
| int fd; |
| int socket_family; |
| int socket_type; |
| int socket_proto; |
| bool init_done; |
| struct k_obj_core obj_core; |
| struct sock_obj_type_raw_stats stats; |
| }; |
| #endif /* CONFIG_NET_SOCKETS_OBJ_CORE */ |
| |
| #if defined(CONFIG_NET_IPV6_PE) |
| /* This is needed by ipv6_pe.c when privacy extension support is enabled */ |
| void net_if_ipv6_start_dad(struct net_if *iface, |
| struct net_if_addr *ifaddr); |
| #endif |
| |
| #if defined(CONFIG_NET_GPTP) |
| /** |
| * @brief Initialize Precision Time Protocol Layer. |
| */ |
| void net_gptp_init(void); |
| |
| /** |
| * @brief Process a ptp message. |
| * |
| * @param buf Buffer with a valid PTP Ethernet type. |
| * |
| * @return Return the policy for network buffer. |
| */ |
| enum net_verdict net_gptp_recv(struct net_if *iface, struct net_pkt *pkt); |
| #else |
| #define net_gptp_init() |
| #define net_gptp_recv(iface, pkt) NET_DROP |
| #endif /* CONFIG_NET_GPTP */ |
| |
| #if defined(CONFIG_NET_IPV4_FRAGMENT) |
| int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt, |
| uint16_t pkt_len, uint16_t mtu); |
| #endif |
| |
| #if defined(CONFIG_NET_IPV6_FRAGMENT) |
| int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt, |
| uint16_t pkt_len, uint16_t mtu); |
| #endif |
| |
| extern const char *net_verdict2str(enum net_verdict verdict); |
| extern const char *net_proto2str(int family, int proto); |
| extern char *net_byte_to_hex(char *ptr, uint8_t byte, char base, bool pad); |
| extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len, |
| char *buf, int buflen); |
| extern uint16_t calc_chksum(uint16_t sum_in, const uint8_t *data, size_t len); |
| extern uint16_t net_calc_chksum(struct net_pkt *pkt, uint8_t proto); |
| |
| /** |
| * @brief Deliver the incoming packet through the recv_cb of the net_context |
| * to the upper layers |
| * |
| * @param conn Network connection |
| * @param pkt Network packet |
| * @param ip_hdr Pointer to IP header, optional |
| * @param proto_hdr Pointer to transport layer protocol header, optional |
| * @param user_data User data passed as an argument |
| * |
| * @return NET_OK if the packet is consumed through the recv_cb |
| * NET_DROP if the recv_cb isn't set |
| */ |
| enum net_verdict 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); |
| |
| #if defined(CONFIG_NET_IPV4) |
| extern uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt); |
| #endif /* CONFIG_NET_IPV4 */ |
| |
| #if defined(CONFIG_NET_IPV4_IGMP) |
| /** |
| * @brief Initialise the IGMP module for a given interface |
| * |
| * @param iface Interface to init IGMP |
| */ |
| void net_ipv4_igmp_init(struct net_if *iface); |
| #endif /* CONFIG_NET_IPV4_IGMP */ |
| |
| #if defined(CONFIG_NET_IPV4_IGMP) |
| uint16_t net_calc_chksum_igmp(struct net_pkt *pkt); |
| enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt, |
| struct net_ipv4_hdr *ip_hdr); |
| #else |
| #define net_ipv4_igmp_input(...) |
| #define net_calc_chksum_igmp(pkt) 0U |
| #endif /* CONFIG_NET_IPV4_IGMP */ |
| |
| static inline uint16_t net_calc_chksum_icmpv6(struct net_pkt *pkt) |
| { |
| return net_calc_chksum(pkt, IPPROTO_ICMPV6); |
| } |
| |
| static inline uint16_t net_calc_chksum_icmpv4(struct net_pkt *pkt) |
| { |
| return net_calc_chksum(pkt, IPPROTO_ICMP); |
| } |
| |
| static inline uint16_t net_calc_chksum_udp(struct net_pkt *pkt) |
| { |
| uint16_t chksum = net_calc_chksum(pkt, IPPROTO_UDP); |
| |
| return chksum == 0U ? 0xffff : chksum; |
| } |
| |
| static inline uint16_t net_calc_verify_chksum_udp(struct net_pkt *pkt) |
| { |
| return net_calc_chksum(pkt, IPPROTO_UDP); |
| } |
| |
| static inline uint16_t net_calc_chksum_tcp(struct net_pkt *pkt) |
| { |
| return net_calc_chksum(pkt, IPPROTO_TCP); |
| } |
| |
| static inline char *net_sprint_ll_addr(const uint8_t *ll, uint8_t ll_len) |
| { |
| static char buf[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")]; |
| |
| return net_sprint_ll_addr_buf(ll, ll_len, (char *)buf, sizeof(buf)); |
| } |
| |
| static inline void net_hexdump(const char *str, |
| const uint8_t *packet, size_t length) |
| { |
| if (!length) { |
| LOG_DBG("%s zero-length packet", str); |
| return; |
| } |
| |
| LOG_HEXDUMP_DBG(packet, length, str); |
| } |
| |
| |
| /* Hexdump from all fragments */ |
| static inline void net_pkt_hexdump(struct net_pkt *pkt, const char *str) |
| { |
| struct net_buf *buf = pkt->buffer; |
| char pkt_str[sizeof("0x") + sizeof(intptr_t) * 2]; |
| |
| if (str && str[0]) { |
| LOG_DBG("%s", str); |
| } |
| |
| snprintk(pkt_str, sizeof(pkt_str), "%p", pkt); |
| |
| while (buf) { |
| LOG_HEXDUMP_DBG(buf->data, buf->len, pkt_str); |
| buf = buf->frags; |
| } |
| } |
| |
| static inline void net_pkt_print_buffer_info(struct net_pkt *pkt, const char *str) |
| { |
| struct net_buf *buf = pkt->buffer; |
| |
| if (str) { |
| printk("%s", str); |
| } |
| |
| printk("%p[%ld]", pkt, atomic_get(&pkt->atomic_ref)); |
| |
| if (buf) { |
| printk("->"); |
| } |
| |
| while (buf) { |
| printk("%p[%ld/%u (%u/%u)]", buf, atomic_get(&pkt->atomic_ref), |
| buf->len, net_buf_max_len(buf), buf->size); |
| |
| buf = buf->frags; |
| if (buf) { |
| printk("->"); |
| } |
| } |
| |
| printk("\n"); |
| } |