From 0e84bbb300ee9b66dbbe8870a3a2b3c7ecb84527 Mon Sep 17 00:00:00 2001 From: gaohedong Date: Tue, 20 May 2025 00:44:52 +0800 Subject: [PATCH] net/ethernet: ARP can be configured on interface ARP can be configured on interface Signed-off-by: gaohedong --- include/netutils/netlib.h | 2 + netutils/netlib/netlib_setifstatus.c | 114 ++++++++++++++++++++++++++- nshlib/nsh_netcmds.c | 37 +++++++++ 3 files changed, 149 insertions(+), 4 deletions(-) diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h index 469bd046104..074637dc337 100644 --- a/include/netutils/netlib.h +++ b/include/netutils/netlib.h @@ -477,6 +477,8 @@ void netlib_server(uint16_t portno, pthread_startroutine_t handler, int netlib_getifstatus(FAR const char *ifname, FAR uint8_t *flags); int netlib_ifup(FAR const char *ifname); int netlib_ifdown(FAR const char *ifname); +int netlib_ifarp(const char *ifname); +int netlib_ifnoarp(const char *ifname); /* DNS server addressing */ diff --git a/netutils/netlib/netlib_setifstatus.c b/netutils/netlib/netlib_setifstatus.c index 8a3f58db111..d2f56dd8bcd 100644 --- a/netutils/netlib/netlib_setifstatus.c +++ b/netutils/netlib/netlib_setifstatus.c @@ -74,12 +74,16 @@ int netlib_ifup(const char *ifname) /* Put the driver name into the request */ strlcpy(req.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req); + if (ret >= 0) + { + /* Perform the ioctl to ifup flag */ - /* Perform the ioctl to ifup flag */ + IFF_SET_UP(req.ifr_flags); - req.ifr_flags |= IFF_UP; + ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + } - ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); close(sockfd); } } @@ -108,6 +112,53 @@ int netlib_ifdown(const char *ifname) { /* Get a socket (only so that we get access to the INET subsystem) */ + int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); + if (sockfd >= 0) + { + struct ifreq req; + memset(&req, 0, sizeof(struct ifreq)); + + /* Put the driver name into the request */ + + strlcpy(req.ifr_name, ifname, IFNAMSIZ); + ret = ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req); + if (ret >= 0) + { + /* Perform the ioctl to ifdown flag */ + + IFF_CLR_UP(req.ifr_flags); + + ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + } + + close(sockfd); + } + } + + return ret; +} + +/**************************************************************************** + * Name: netlib_ifarp + * + * Description: + * Enable ARP learning capability on the interface + * + * Parameters: + * ifname The name of the interface to use + * + * Return: + * 0 on success; -1 on failure + * + ****************************************************************************/ + +int netlib_ifarp(const char *ifname) +{ + int ret = ERROR; + if (ifname) + { + /* Get a socket (only so that we get access to the INET subsystem) */ + int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); if (sockfd >= 0) { @@ -120,7 +171,62 @@ int netlib_ifdown(const char *ifname) /* Perform the ioctl to ifup flag */ - ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + ret = ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req); + if (ret >= 0) + { + IFF_CLR_NOARP(req.ifr_flags); + + ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + } + + close(sockfd); + } + } + + return ret; +} + +/**************************************************************************** + * Name: netlib_ifnoarp + * + * Description: + * Disable ARP learning capability on the interface + * + * Parameters: + * ifname The name of the interface to use + * + * Return: + * 0 on success; -1 on failure + * + ****************************************************************************/ + +int netlib_ifnoarp(const char *ifname) +{ + int ret = ERROR; + if (ifname) + { + /* Get a socket (only so that we get access to the INET subsystem) */ + + int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); + if (sockfd >= 0) + { + struct ifreq req; + memset(&req, 0, sizeof(struct ifreq)); + + /* Put the driver name into the request */ + + strlcpy(req.ifr_name, ifname, IFNAMSIZ); + + /* Perform the ioctl to ifup flag */ + + ret = ioctl(sockfd, SIOCGIFFLAGS, (unsigned long)&req); + if (ret >= 0) + { + IFF_SET_NOARP(req.ifr_flags); + + ret = ioctl(sockfd, SIOCSIFFLAGS, (unsigned long)&req); + } + close(sockfd); } } diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c index 791e1c922e3..1b2c8efd7f6 100644 --- a/nshlib/nsh_netcmds.c +++ b/nshlib/nsh_netcmds.c @@ -142,6 +142,15 @@ struct tftpc_args_s }; #endif +#ifdef CONFIG_NET_ARP +typedef enum +{ + ARP_DEFAULT, /* Did not set arp configure in the command */ + ARP_ENABLE, /* Clean the NOARP flag for the interface to enable the arp learning function */ + ARP_DISABLE /* Set the NOARP flag for the interface to disable the arp learning function */ +} arp_cfg_e; +#endif + typedef int (*nsh_netdev_callback_t)(FAR struct nsh_vtbl_s *vtbl, FAR char *devname); @@ -575,6 +584,9 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) #endif bool missingarg = true; bool badarg = false; +#ifdef CONFIG_NET_ARP + arp_cfg_e arpflag = ARP_DEFAULT; +#endif #ifdef HAVE_HWADDR mac_addr_t macaddr; #endif @@ -742,6 +754,20 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) badarg = true; } } +#ifdef CONFIG_NET_ARP + else if (!strcmp(tmp, "arp")) + { + /* Enable arp function on interface */ + + arpflag = ARP_ENABLE; + } + else if (!strcmp(tmp, "-arp")) + { + /* Disable arp function on interface */ + + arpflag = ARP_DISABLE; + } +#endif else if (hostip == NULL && i <= 4) { /* Let first non-option be host ip, to support inet/inet6 @@ -1044,6 +1070,17 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) } #endif +#ifdef CONFIG_NET_ARP + if (arpflag == ARP_ENABLE) + { + netlib_ifarp(ifname); + } + else if (arpflag == ARP_DISABLE) + { + netlib_ifnoarp(ifname); + } +#endif + #if !defined(CONFIG_NET_IPv4) && !defined(CONFIG_NET_IPv6) UNUSED(hostip); UNUSED(mask);