On Mon, Nov 9, 2015 at 1:38 AM, Chris Packham <judge.pack...@gmail.com> wrote: > Signed-off-by: Chris Packham <judge.pack...@gmail.com> > > --- > > Changes in v2: > - split ping6 support into it's own patch > > common/Kconfig | 6 +++ > common/cmd_net.c | 28 ++++++++++++++ > include/net.h | 4 +- > net/net6.c | 7 ++++ > net/ping6.c | 111 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 154 insertions(+), 2 deletions(-) > create mode 100644 net/ping6.c > > diff --git a/common/Kconfig b/common/Kconfig > index 0388a6c..b1effc6 100644 > --- a/common/Kconfig > +++ b/common/Kconfig > @@ -431,6 +431,12 @@ config CMD_PING > help > Send ICMP ECHO_REQUEST to network host > > +config CMD_PING6 > + bool "ping6" > + depends on CMD_NET6 > + help > + Send ICMPv6 ECHO_REQUEST to network host > + > config CMD_CDP > bool "cdp" > help > diff --git a/common/cmd_net.c b/common/cmd_net.c > index b2f3c7b..271f91d 100644 > --- a/common/cmd_net.c > +++ b/common/cmd_net.c > @@ -11,6 +11,7 @@ > #include <common.h> > #include <command.h> > #include <net.h> > +#include <net6.h> > > static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []); > > @@ -284,6 +285,33 @@ U_BOOT_CMD( > ); > #endif > > +#ifdef CONFIG_CMD_PING6 > +int do_ping6(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > +{ > + if (argc < 2) > + return -1; > + > + if (string_to_ip6(argv[1], &net_ping_ip6) != 0) > + return CMD_RET_USAGE; > + > + if (net_loop(PING6) < 0) { > + printf("ping6 failed; host %pI6c is not alive\n", > + &net_ping_ip6); > + return 1; > + } > + > + printf("host %pI6c is alive\n", &net_ping_ip6); > + > + return 0; > +} > + > +U_BOOT_CMD( > + ping6, 2, 1, do_ping6, > + "send ICMPv6 ECHO_REQUEST to network host", > + "pingAddress" > +); > +#endif /* CONFIG_CMD_PING6 */ > + > #if defined(CONFIG_CMD_CDP) > > static void cdp_update_env(void) > diff --git a/include/net.h b/include/net.h > index 8b7c878..6a9832c 100644 > --- a/include/net.h > +++ b/include/net.h > @@ -524,8 +524,8 @@ extern ushort net_native_vlan; /* > Our Native VLAN */ > extern int net_restart_wrap; /* Tried all network devices > */ > > enum proto_t { > - BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP, > - TFTPSRV, TFTPPUT, LINKLOCAL > + BOOTP, RARP, ARP, TFTPGET, DHCP, PING, PING6, DNS, NFS, CDP, NETCONS, > + SNTP, TFTPSRV, TFTPPUT, LINKLOCAL > }; > > extern char net_boot_file_name[1024];/* Boot File name */ > diff --git a/net/net6.c b/net/net6.c > index 955a089..8f0c721 100644 > --- a/net/net6.c > +++ b/net/net6.c > @@ -370,6 +370,13 @@ void net_ip6_handler(struct ethernet_hdr *et, struct > ip6_hdr *ip6, int len) > return; > > switch (icmp->icmp6_type) { > +#ifdef CONFIG_CMD_PING6 > + case IPV6_ICMP_ECHO_REQUEST: > + case IPV6_ICMP_ECHO_REPLY: > + ping6_receive(et, ip6, len); > + break; > +#endif /* CONFIG_CMD_PING6 */ > + > case IPV6_NDISC_NEIGHBOUR_SOLICITATION: > case IPV6_NDISC_NEIGHBOUR_ADVERTISEMENT: > ndisc_receive(et, ip6, len); > diff --git a/net/ping6.c b/net/ping6.c > new file mode 100644 > index 0000000..34796c6 > --- /dev/null > +++ b/net/ping6.c > @@ -0,0 +1,111 @@ > +/* > + * net/ping6.c > + * > + * (C) Copyright 2013 Allied Telesis Labs NZ > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > +#define DEBUG > +#include <common.h> > +#include <net.h> > +#include <net6.h> > +#include "ndisc.h" > + > +static ushort seq_no; > + > +/* the ipv6 address to ping */ > +struct in6_addr net_ping_ip6; > + > +int
+ static int > +ip6_make_ping(uchar *eth_dst_addr, struct in6_addr *neigh_addr, uchar *pkt) > +{ > + struct echo_msg *msg; > + __u16 len; > + uchar *pkt_old = pkt; > + > + len = sizeof(struct echo_msg); > + > + pkt += net_set_ether(pkt, eth_dst_addr, PROT_IP6); > + pkt += ip6_add_hdr(pkt, &net_ip6, neigh_addr, IPPROTO_ICMPV6, > + IPV6_NDISC_HOPLIMIT, len); > + > + /* ICMPv6 - Echo */ > + msg = (struct echo_msg *)pkt; > + msg->icmph.icmp6_type = IPV6_ICMP_ECHO_REQUEST; > + msg->icmph.icmp6_code = 0; > + msg->icmph.icmp6_cksum = 0; > + msg->icmph.icmp6_identifier = 0; > + msg->icmph.icmp6_sequence = htons(seq_no++); > + msg->id = msg->icmph.icmp6_identifier; /* these seem redundant */ > + msg->sequence = msg->icmph.icmp6_sequence; > + > + /* checksum */ > + msg->icmph.icmp6_cksum = csum_ipv6_magic(&net_ip6, neigh_addr, len, > + IPPROTO_ICMPV6, > + csum_partial((__u8 *)msg, > len, 0)); > + > + pkt += len; > + > + return pkt - pkt_old; > +} > + > +int ping6_send(void) +static int ping6_send(void) > +{ > + uchar *pkt; > + static uchar mac[6]; > + > + /* always send neighbor solicit */ > + > + memcpy(mac, net_null_ethaddr, 6); > + > + net_nd_sol_packet_ip6 = net_ping_ip6; > + net_nd_packet_mac = mac; > + > + pkt = net_nd_tx_packet; > + pkt += ip6_make_ping(mac, &net_ping_ip6, pkt); > + > + /* size of the waiting packet */ > + net_nd_tx_packet_size = (pkt - net_nd_tx_packet); > + > + /* and do the ARP request */ > + net_nd_try = 1; > + net_nd_timer_start = get_timer(0); > + ndisc_request(); > + return 1; /* waiting */ > +} > + > +static void ping6_timeout(void) > +{ > + eth_halt(); > + net_set_state(NETLOOP_FAIL); /* we did not get the reply */ > +} > + > +void ping6_start(void) > +{ > + printf("Using %s device\n", eth_get_name()); > + net_set_timeout_handler(10000UL, ping6_timeout); > + > + ping6_send(); > +} > + > +void ping6_receive(struct ethernet_hdr *et, struct ip6_hdr *ip6, int len) > +{ > + struct icmp6hdr *icmp = > + (struct icmp6hdr *)(((uchar *)ip6) + IP6_HDR_SIZE); > + struct in6_addr src_ip; > + > + switch (icmp->icmp6_type) { > + case IPV6_ICMP_ECHO_REPLY: > + src_ip = ip6->saddr; > + if (memcmp(&net_ping_ip6, &src_ip, sizeof(struct in6_addr)) > != 0) > + return; > + net_set_state(NETLOOP_SUCCESS); > + break; > + case IPV6_ICMP_ECHO_REQUEST: > + debug("Got ICMPv6 ECHO REQUEST from %pI6c\n", &ip6->saddr); > + /* ignore for now.... */ > + break; > + default: > + debug("Unexpected ICMPv6 type 0x%x\n", icmp->icmp6_type); > + } > +} > -- > 2.5.3 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot