This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6fd74f817db99325e618dfec96240f8c058b5744 Author: Zhe Weng <[email protected]> AuthorDate: Wed Jan 15 16:59:22 2025 +0800 net/pkt: Support filtering protocol in AF_PACKET Ref: https://man7.org/linux/man-pages/man7/packet.7.html 1. For `socket(AF_PACKET, int socket_type, int protocol)`: When `protocol` is set to `htons(ETH_P_ALL)`, then all protocols are received. If `protocol` is set to zero, no packets are received. 2. For `bind`: `bind` can optionally be called with a nonzero `sll_protocol` to start receiving packets for the protocols specified. Signed-off-by: Zhe Weng <[email protected]> --- Documentation/components/net/pkt.rst | 1 + include/netinet/if_ether.h | 7 ++++--- include/nuttx/net/net.h | 2 +- net/pkt/pkt.h | 1 + net/pkt/pkt_conn.c | 11 ++++++++++- net/pkt/pkt_sockif.c | 13 ++++++++++--- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/Documentation/components/net/pkt.rst b/Documentation/components/net/pkt.rst index 28eb044293f..9df38f43c35 100644 --- a/Documentation/components/net/pkt.rst +++ b/Documentation/components/net/pkt.rst @@ -29,6 +29,7 @@ Usage addr.sll_family = AF_PACKET; addr.sll_ifindex = if_nametoindex("eth0"); + addr.sll_protocol = htons(ETH_P_ALL); bind(sd, (FAR struct sockaddr *)&addr, sizeof(addr)); /* Bind to device */ recv(sd, buffer, sizeof(buffer), 0); /* read(sd, buffer, sizeof(buffer)); */ diff --git a/include/netinet/if_ether.h b/include/netinet/if_ether.h index de71b9c7936..01da882ab35 100644 --- a/include/netinet/if_ether.h +++ b/include/netinet/if_ether.h @@ -46,9 +46,10 @@ #define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */ #define ETH_MAX_MTU 0xFFFFU /* 65535, same as IP_MAX_MTU */ -#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ -#define ETH_P_IP ETHERTYPE_IP -#define ETH_P_ARP ETHERTYPE_ARP +#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ +#define ETH_P_IP ETHERTYPE_IP +#define ETH_P_IPV6 ETHERTYPE_IPV6 +#define ETH_P_ARP ETHERTYPE_ARP /**************************************************************************** * Public Type Definitions diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 28beb668658..af2af577b3e 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -247,7 +247,7 @@ struct socket { uint8_t s_domain; /* IP domain */ uint8_t s_type; /* Protocol type */ - uint8_t s_proto; /* Socket Protocol */ + uint16_t s_proto; /* Socket Protocol */ FAR void *s_conn; /* Connection inherits from struct socket_conn_s */ /* Socket interface */ diff --git a/net/pkt/pkt.h b/net/pkt/pkt.h index 83ce4d287b8..ab866c21336 100644 --- a/net/pkt/pkt.h +++ b/net/pkt/pkt.h @@ -74,6 +74,7 @@ struct pkt_conn_s uint8_t ifindex; uint8_t crefs; /* Reference counts on this instance */ + uint16_t type; /* The Ethernet type of the packet */ /* Read-ahead buffering. * diff --git a/net/pkt/pkt_conn.c b/net/pkt/pkt_conn.c index 91ea5bb09e9..9387cd961f5 100644 --- a/net/pkt/pkt_conn.c +++ b/net/pkt/pkt_conn.c @@ -32,6 +32,7 @@ #include <debug.h> #include <arch/irq.h> +#include <netinet/if_ether.h> #include <nuttx/kmalloc.h> #include <nuttx/mutex.h> @@ -161,10 +162,18 @@ FAR struct pkt_conn_s *pkt_active(FAR struct net_driver_s *dev) { FAR struct pkt_conn_s *conn = (FAR struct pkt_conn_s *)g_active_pkt_connections.head; + uint16_t ethertype = 0; + + if (dev->d_lltype == NET_LL_ETHERNET || dev->d_lltype == NET_LL_IEEE80211) + { + FAR struct eth_hdr_s *ethhdr = NETLLBUF; + ethertype = ethhdr->type; + } while (conn) { - if (dev->d_ifindex == conn->ifindex) + if (dev->d_ifindex == conn->ifindex && + (conn->type == HTONS(ETH_P_ALL) || conn->type == ethertype)) { /* Matching connection found.. return a reference to it */ diff --git a/net/pkt/pkt_sockif.c b/net/pkt/pkt_sockif.c index b8fe6b369eb..be401da804f 100644 --- a/net/pkt/pkt_sockif.c +++ b/net/pkt/pkt_sockif.c @@ -113,6 +113,10 @@ static int pkt_sockif_alloc(FAR struct socket *psock) DEBUGASSERT(conn->crefs == 0); conn->crefs = 1; + /* Save the protocol in the connection structure */ + + conn->type = psock->s_proto; + /* Save the pre-allocated connection in the socket structure */ psock->s_conn = conn; @@ -225,8 +229,6 @@ static void pkt_addref(FAR struct socket *psock) static int pkt_bind(FAR struct socket *psock, FAR const struct sockaddr *addr, socklen_t addrlen) { - int ifindex; - /* Verify that a valid address has been provided */ if (addr->sa_family != AF_PACKET || addrlen < sizeof(struct sockaddr_ll)) @@ -245,7 +247,8 @@ static int pkt_bind(FAR struct socket *psock, /* Look at the addr and identify the network interface */ - ifindex = ((FAR struct sockaddr_ll *)addr)->sll_ifindex; + int ifindex = ((FAR struct sockaddr_ll *)addr)->sll_ifindex; + int protocol = ((FAR struct sockaddr_ll *)addr)->sll_protocol; /* Check if we have that interface */ @@ -258,6 +261,10 @@ static int pkt_bind(FAR struct socket *psock, /* Put ifindex into connection */ conn->ifindex = ifindex; + if (protocol != 0) + { + conn->type = protocol; + } return OK; }
