diff options
author | Joe Hershberger <joe.hershberger@ni.com> | 2018-09-26 16:49:01 -0500 |
---|---|---|
committer | Joe Hershberger <joe.hershberger@ni.com> | 2018-10-10 12:29:00 -0500 |
commit | 72ff0042585bedab4364afbd7ecc935e48324ade (patch) | |
tree | 9c4faf29a74ee95a40882b65ea79d79513697797 /drivers/net/sandbox.c | |
parent | 45988dae4cf05f783e40e027c83594a9dc6551cd (diff) | |
download | u-boot-72ff0042585bedab4364afbd7ecc935e48324ade.tar.gz |
test: eth: Add a test for the target being pinged
The target will respond to pings while doing other network handling.
Make sure that the response happens and is correct.
This currently corrupts the ongoing operation of the device if it
happens to be awaiting an ARP reply of its own to whatever serverip it
is attempting to communicate with. In the test, add an expectation that
the user operation (ping, in this case) will fail. A later patch will
address this problem.
Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'drivers/net/sandbox.c')
-rw-r--r-- | drivers/net/sandbox.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c index 81f0764fa6..decce2fa59 100644 --- a/drivers/net/sandbox.c +++ b/drivers/net/sandbox.c @@ -202,6 +202,57 @@ int sandbox_eth_recv_arp_req(struct udevice *dev) } /* + * sandbox_eth_recv_ping_req() + * + * Inject a ping request for this target + * + * returns 0 if injected, -EOVERFLOW if not + */ +int sandbox_eth_recv_ping_req(struct udevice *dev) +{ + struct eth_sandbox_priv *priv = dev_get_priv(dev); + struct ethernet_hdr *eth_recv; + struct ip_udp_hdr *ipr; + struct icmp_hdr *icmpr; + + /* Don't allow the buffer to overrun */ + if (priv->recv_packets >= PKTBUFSRX) + return -EOVERFLOW; + + /* Formulate a fake ping */ + eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; + + memcpy(eth_recv->et_dest, net_ethaddr, ARP_HLEN); + memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); + eth_recv->et_protlen = htons(PROT_IP); + + ipr = (void *)eth_recv + ETHER_HDR_SIZE; + ipr->ip_hl_v = 0x45; + ipr->ip_len = htons(IP_ICMP_HDR_SIZE); + ipr->ip_off = htons(IP_FLAGS_DFRAG); + ipr->ip_p = IPPROTO_ICMP; + ipr->ip_sum = 0; + net_write_ip(&ipr->ip_src, priv->fake_host_ipaddr); + net_write_ip(&ipr->ip_dst, net_ip); + ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE); + + icmpr = (struct icmp_hdr *)&ipr->udp_src; + + icmpr->type = ICMP_ECHO_REQUEST; + icmpr->code = 0; + icmpr->checksum = 0; + icmpr->un.echo.id = 0; + icmpr->un.echo.sequence = htons(1); + icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE); + + priv->recv_packet_length[priv->recv_packets] = + ETHER_HDR_SIZE + IP_ICMP_HDR_SIZE; + ++priv->recv_packets; + + return 0; +} + +/* * sb_default_handler() * * perform typical responses to simple ping |