Message ID | 20210410141701.104679-1-lgxue@hotmail.com |
---|---|
State | Superseded |
Delegated to: | Joe Hershberger |
Headers | show |
Series | [v3] cmd: net: Add the "arp" command | expand |
On Sat, Apr 10, 2021 at 5:17 PM <lgxue@hotmail.com> wrote: > > From: Joe Xue <lgxue@hotmail.com> > > The command is to query and show mac address of a specific ipAddress. > > Signed-off-by: Joe Xue <lgxue@hotmail.com> > --- > > cmd/Kconfig | 6 ++++++ > cmd/net.c | 37 +++++++++++++++++++++++++++++++++++++ > doc/usage/arp.rst | 31 +++++++++++++++++++++++++++++++ > include/net.h | 5 +++++ > net/arp.c | 24 ++++++++++++++++++++++++ > net/arp.h | 4 ++++ > net/net.c | 8 ++++++++ > 7 files changed, 115 insertions(+) > create mode 100644 doc/usage/arp.rst > > diff --git a/cmd/Kconfig b/cmd/Kconfig > index 9bf5e863e4..1da4cb67f6 100644 > --- a/cmd/Kconfig > +++ b/cmd/Kconfig > @@ -1587,6 +1587,12 @@ config CMD_PING > help > Send ICMP ECHO_REQUEST to network host > > +config CMD_ARP > + bool "arp" > + help > + Sends ARP_REQUEST to network host and shows the result if there is arp > + response. > + > config CMD_CDP > bool "cdp" > help > diff --git a/cmd/net.c b/cmd/net.c > index beb2877dfd..56703e9641 100644 > --- a/cmd/net.c > +++ b/cmd/net.c > @@ -480,3 +480,40 @@ U_BOOT_CMD( > ); > > #endif /* CONFIG_CMD_LINK_LOCAL */ > + > +#ifdef CONFIG_CMD_ARP > +static int do_arp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) > +{ > + u8 *ethaddr = arp_query_ethaddr; > + > + if (argc < 2) > + return CMD_RET_USAGE; > + > + arp_query_ip = string_to_ip(argv[1]); > + if (arp_query_ip.s_addr == 0) > + return CMD_RET_USAGE; > + > + if ((arp_query_ip.s_addr & net_netmask.s_addr) != > + (net_ip.s_addr & net_netmask.s_addr)) { > + printf("The host %s is not in the same network\n", argv[1]); > + return CMD_RET_SUCCESS; > + } Why do we care about that ? > + > + if (net_loop(ARP) < 0) { > + printf("arp failed; host %s is not alive\n", argv[1]); > + return CMD_RET_FAILURE; > + } > + > + printf("%s\t%02x:%02x:%02x:%02x:%02x:%02x\n", argv[1], ethaddr[0], > + ethaddr[1], ethaddr[2], ethaddr[3], ethaddr[4], ethaddr[5]); > + > + return CMD_RET_SUCCESS; > +} > + > +U_BOOT_CMD( > + arp, 2, 1, do_arp, > + "send ARP ARP_REQUEST to network host", > + "ipAddress" > +); > + > +#endif /* CONFIG_CMD_ARP */ > diff --git a/doc/usage/arp.rst b/doc/usage/arp.rst > new file mode 100644 > index 0000000000..b1f08a2ae9 > --- /dev/null > +++ b/doc/usage/arp.rst > @@ -0,0 +1,31 @@ > +arp command > +=========== > + > +Synopis Typo, Synopsis > +------- > + > +:: > + > + arp ipAddress > + > +Description > +----------- > + > +The arp command is used to send ARP_REQUEST to network host and show the result. > + > +ipAddress > + the host ip address > + > +Example > +------- > + > +:: > + > + => arp 192.168.0.1 > + Using host_ens33 device > + 192.168.0.1 84:94:8c:5f:e1:62 > + > +Return value > +------------ > + > +The return value $? is 0 if the comand running was successful else 1 Typo, command > diff --git a/include/net.h b/include/net.h > index b95d6a6f60..60b4bf610e 100644 > --- a/include/net.h > +++ b/include/net.h > @@ -580,6 +580,11 @@ extern char *net_dns_env_var; /* the env var to put the ip into */ > extern struct in_addr net_ping_ip; /* the ip address to ping */ > #endif > > +#if defined(CONFIG_CMD_ARP) > +extern u8 arp_query_ethaddr[6]; /* the arp query result */ > +extern struct in_addr arp_query_ip; /* the ip address to arp query */ > +#endif > + > #if defined(CONFIG_CMD_CDP) > /* when CDP completes these hold the return values */ > extern ushort cdp_native_vlan; /* CDP returned native VLAN */ > diff --git a/net/arp.c b/net/arp.c > index 1d06ed2572..83c24072d7 100644 > --- a/net/arp.c > +++ b/net/arp.c > @@ -220,11 +220,20 @@ void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) > net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr, > 0, len); > > +#ifdef CONFIG_CMD_ARP > + if (arp_query_ip.s_addr != 0) { > + arp_query_ip.s_addr = 0; > + net_set_state(NETLOOP_SUCCESS); > + } else { > +#endif > /* set the mac address in the waiting packet's header > and transmit it */ > memcpy(((struct ethernet_hdr *)net_tx_packet)->et_dest, > &arp->ar_sha, ARP_HLEN); > net_send_packet(net_tx_packet, arp_wait_tx_packet_size); > +#ifdef CONFIG_CMD_ARP > + } > +#endif > > /* no arp request pending now */ > net_arp_wait_packet_ip.s_addr = 0; > @@ -243,3 +252,18 @@ bool arp_is_waiting(void) > { > return !!net_arp_wait_packet_ip.s_addr; > } > + > +#ifdef CONFIG_CMD_ARP > +u8 arp_query_ethaddr[6]; > +struct in_addr arp_query_ip; > + > +void arp_query(void) > +{ > + arp_wait_packet_ethaddr = arp_query_ethaddr; > + net_arp_wait_packet_ip = arp_query_ip; > + > + arp_wait_timer_start = get_timer(0); > + printf("Using %s device\n", eth_get_name()); > + arp_request(); > +} > +#endif > diff --git a/net/arp.h b/net/arp.h > index 25b3c00d5c..f3e5cb8504 100644 > --- a/net/arp.h > +++ b/net/arp.h > @@ -29,4 +29,8 @@ void arp_raw_request(struct in_addr source_ip, const uchar *targetEther, > int arp_timeout_check(void); > void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len); > > +#ifdef CONFIG_CMD_ARP > +void arp_query(void); > +#endif > + > #endif /* __ARP_H__ */ > diff --git a/net/net.c b/net/net.c > index b58f3062b2..21623562e8 100644 > --- a/net/net.c > +++ b/net/net.c > @@ -492,6 +492,11 @@ restart: > rarp_request(); > break; > #endif > +#if defined(CONFIG_CMD_ARP) > + case ARP: > + arp_query(); > + break; > +#endif > #if defined(CONFIG_CMD_PING) > case PING: > ping_start(); > @@ -1385,6 +1390,9 @@ common: > case CDP: > case DHCP: > case LINKLOCAL: > +#ifdef CONFIG_CMD_ARP > + case ARP: > +#endif > if (memcmp(net_ethaddr, "\0\0\0\0\0\0", 6) == 0) { > int num = eth_get_dev_index(); > > -- > 2.27.0 >
diff --git a/cmd/Kconfig b/cmd/Kconfig index 9bf5e863e4..1da4cb67f6 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1587,6 +1587,12 @@ config CMD_PING help Send ICMP ECHO_REQUEST to network host +config CMD_ARP + bool "arp" + help + Sends ARP_REQUEST to network host and shows the result if there is arp + response. + config CMD_CDP bool "cdp" help diff --git a/cmd/net.c b/cmd/net.c index beb2877dfd..56703e9641 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -480,3 +480,40 @@ U_BOOT_CMD( ); #endif /* CONFIG_CMD_LINK_LOCAL */ + +#ifdef CONFIG_CMD_ARP +static int do_arp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + u8 *ethaddr = arp_query_ethaddr; + + if (argc < 2) + return CMD_RET_USAGE; + + arp_query_ip = string_to_ip(argv[1]); + if (arp_query_ip.s_addr == 0) + return CMD_RET_USAGE; + + if ((arp_query_ip.s_addr & net_netmask.s_addr) != + (net_ip.s_addr & net_netmask.s_addr)) { + printf("The host %s is not in the same network\n", argv[1]); + return CMD_RET_SUCCESS; + } + + if (net_loop(ARP) < 0) { + printf("arp failed; host %s is not alive\n", argv[1]); + return CMD_RET_FAILURE; + } + + printf("%s\t%02x:%02x:%02x:%02x:%02x:%02x\n", argv[1], ethaddr[0], + ethaddr[1], ethaddr[2], ethaddr[3], ethaddr[4], ethaddr[5]); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + arp, 2, 1, do_arp, + "send ARP ARP_REQUEST to network host", + "ipAddress" +); + +#endif /* CONFIG_CMD_ARP */ diff --git a/doc/usage/arp.rst b/doc/usage/arp.rst new file mode 100644 index 0000000000..b1f08a2ae9 --- /dev/null +++ b/doc/usage/arp.rst @@ -0,0 +1,31 @@ +arp command +=========== + +Synopis +------- + +:: + + arp ipAddress + +Description +----------- + +The arp command is used to send ARP_REQUEST to network host and show the result. + +ipAddress + the host ip address + +Example +------- + +:: + + => arp 192.168.0.1 + Using host_ens33 device + 192.168.0.1 84:94:8c:5f:e1:62 + +Return value +------------ + +The return value $? is 0 if the comand running was successful else 1 diff --git a/include/net.h b/include/net.h index b95d6a6f60..60b4bf610e 100644 --- a/include/net.h +++ b/include/net.h @@ -580,6 +580,11 @@ extern char *net_dns_env_var; /* the env var to put the ip into */ extern struct in_addr net_ping_ip; /* the ip address to ping */ #endif +#if defined(CONFIG_CMD_ARP) +extern u8 arp_query_ethaddr[6]; /* the arp query result */ +extern struct in_addr arp_query_ip; /* the ip address to arp query */ +#endif + #if defined(CONFIG_CMD_CDP) /* when CDP completes these hold the return values */ extern ushort cdp_native_vlan; /* CDP returned native VLAN */ diff --git a/net/arp.c b/net/arp.c index 1d06ed2572..83c24072d7 100644 --- a/net/arp.c +++ b/net/arp.c @@ -220,11 +220,20 @@ void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr, 0, len); +#ifdef CONFIG_CMD_ARP + if (arp_query_ip.s_addr != 0) { + arp_query_ip.s_addr = 0; + net_set_state(NETLOOP_SUCCESS); + } else { +#endif /* set the mac address in the waiting packet's header and transmit it */ memcpy(((struct ethernet_hdr *)net_tx_packet)->et_dest, &arp->ar_sha, ARP_HLEN); net_send_packet(net_tx_packet, arp_wait_tx_packet_size); +#ifdef CONFIG_CMD_ARP + } +#endif /* no arp request pending now */ net_arp_wait_packet_ip.s_addr = 0; @@ -243,3 +252,18 @@ bool arp_is_waiting(void) { return !!net_arp_wait_packet_ip.s_addr; } + +#ifdef CONFIG_CMD_ARP +u8 arp_query_ethaddr[6]; +struct in_addr arp_query_ip; + +void arp_query(void) +{ + arp_wait_packet_ethaddr = arp_query_ethaddr; + net_arp_wait_packet_ip = arp_query_ip; + + arp_wait_timer_start = get_timer(0); + printf("Using %s device\n", eth_get_name()); + arp_request(); +} +#endif diff --git a/net/arp.h b/net/arp.h index 25b3c00d5c..f3e5cb8504 100644 --- a/net/arp.h +++ b/net/arp.h @@ -29,4 +29,8 @@ void arp_raw_request(struct in_addr source_ip, const uchar *targetEther, int arp_timeout_check(void); void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len); +#ifdef CONFIG_CMD_ARP +void arp_query(void); +#endif + #endif /* __ARP_H__ */ diff --git a/net/net.c b/net/net.c index b58f3062b2..21623562e8 100644 --- a/net/net.c +++ b/net/net.c @@ -492,6 +492,11 @@ restart: rarp_request(); break; #endif +#if defined(CONFIG_CMD_ARP) + case ARP: + arp_query(); + break; +#endif #if defined(CONFIG_CMD_PING) case PING: ping_start(); @@ -1385,6 +1390,9 @@ common: case CDP: case DHCP: case LINKLOCAL: +#ifdef CONFIG_CMD_ARP + case ARP: +#endif if (memcmp(net_ethaddr, "\0\0\0\0\0\0", 6) == 0) { int num = eth_get_dev_index();