390 lines
10 KiB
C
390 lines
10 KiB
C
/** @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 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_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);
|
|
#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");
|
|
}
|