drivers: net: sandbox: add support for NET_LWIP
Make the sandbox mock ethernet driver (drivers/net/sandbox.c) compatible
with NET_LWIP by not relying on any of the structures or functions
defined in net-legacy.h. This is done by providing local definitions of
the various protocol structures (Ethernet, ARP, IPv4, ICMP). Drop the
stub driver that was introduced specifically for NET_LWIP
(drivers/net/sandbox-lwip.c).
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
(cherry picked from commit 94289e291f)
This commit is contained in:
committed by
Simon Glass
parent
bc8ddf658c
commit
6f9dab5d45
@@ -350,7 +350,7 @@ config ESSEDMA
|
|||||||
|
|
||||||
config ETH_SANDBOX
|
config ETH_SANDBOX
|
||||||
depends on SANDBOX
|
depends on SANDBOX
|
||||||
depends on NET
|
depends on NET || NET_LWIP
|
||||||
default y
|
default y
|
||||||
bool "Sandbox: Mocked Ethernet driver"
|
bool "Sandbox: Mocked Ethernet driver"
|
||||||
help
|
help
|
||||||
@@ -359,17 +359,6 @@ config ETH_SANDBOX
|
|||||||
|
|
||||||
This driver is particularly useful in the test/dm/eth.c tests
|
This driver is particularly useful in the test/dm/eth.c tests
|
||||||
|
|
||||||
config ETH_SANDBOX_LWIP
|
|
||||||
depends on SANDBOX
|
|
||||||
depends on NET_LWIP
|
|
||||||
default y
|
|
||||||
bool "Sandbox: Mocked Ethernet driver (for NET_LWIP)"
|
|
||||||
help
|
|
||||||
This driver is meant as a replacement for ETH_SANDBOX when
|
|
||||||
the network stack is NET_LWIP rather than NET. It currently
|
|
||||||
does nothing, i.e. it drops the sent packets and never receives
|
|
||||||
data.
|
|
||||||
|
|
||||||
config ETH_SANDBOX_RAW
|
config ETH_SANDBOX_RAW
|
||||||
depends on SANDBOX
|
depends on SANDBOX
|
||||||
depends on NET
|
depends on NET
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o
|
|||||||
obj-$(CONFIG_ETH_SANDBOX) += sandbox.o
|
obj-$(CONFIG_ETH_SANDBOX) += sandbox.o
|
||||||
obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw-bus.o
|
obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw-bus.o
|
||||||
obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o
|
obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o
|
||||||
obj-$(CONFIG_ETH_SANDBOX_LWIP) += sandbox-lwip.o
|
|
||||||
obj-$(CONFIG_FEC_MXC) += fec_mxc.o
|
obj-$(CONFIG_FEC_MXC) += fec_mxc.o
|
||||||
obj-$(CONFIG_FMAN_ENET) += fm/
|
obj-$(CONFIG_FMAN_ENET) += fm/
|
||||||
obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o
|
obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2015 National Instruments
|
|
||||||
*
|
|
||||||
* (C) Copyright 2015
|
|
||||||
* Joe Hershberger <joe.hershberger@ni.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <dm.h>
|
|
||||||
#include <log.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <net.h>
|
|
||||||
#include <asm/eth.h>
|
|
||||||
#include <asm/global_data.h>
|
|
||||||
#include <asm/test.h>
|
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
|
||||||
|
|
||||||
static int sb_lwip_eth_start(struct udevice *dev)
|
|
||||||
{
|
|
||||||
debug("eth_sandbox_lwip: Start\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sb_lwip_eth_send(struct udevice *dev, void *packet, int length)
|
|
||||||
{
|
|
||||||
debug("eth_sandbox_lwip: Send packet %d\n", length);
|
|
||||||
|
|
||||||
return -ENOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sb_lwip_eth_recv(struct udevice *dev, int flags, uchar **packetp)
|
|
||||||
{
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sb_lwip_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sb_lwip_eth_stop(struct udevice *dev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sb_lwip_eth_write_hwaddr(struct udevice *dev)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct eth_ops sb_eth_ops = {
|
|
||||||
.start = sb_lwip_eth_start,
|
|
||||||
.send = sb_lwip_eth_send,
|
|
||||||
.recv = sb_lwip_eth_recv,
|
|
||||||
.free_pkt = sb_lwip_eth_free_pkt,
|
|
||||||
.stop = sb_lwip_eth_stop,
|
|
||||||
.write_hwaddr = sb_lwip_eth_write_hwaddr,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int sb_lwip_eth_remove(struct udevice *dev)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sb_lwip_eth_of_to_plat(struct udevice *dev)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct udevice_id sb_eth_ids[] = {
|
|
||||||
{ .compatible = "sandbox,eth" },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(eth_sandbox) = {
|
|
||||||
.name = "eth_lwip_sandbox",
|
|
||||||
.id = UCLASS_ETH,
|
|
||||||
.of_match = sb_eth_ids,
|
|
||||||
.of_to_plat = sb_lwip_eth_of_to_plat,
|
|
||||||
.remove = sb_lwip_eth_remove,
|
|
||||||
.ops = &sb_eth_ops,
|
|
||||||
.priv_auto = 0,
|
|
||||||
.plat_auto = sizeof(struct eth_pdata),
|
|
||||||
};
|
|
||||||
@@ -9,13 +9,84 @@
|
|||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <net.h>
|
|
||||||
#include <asm/eth.h>
|
#include <asm/eth.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
#include <asm/test.h>
|
#include <asm/test.h>
|
||||||
|
#include <asm/types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure definitions for network protocols. Since this file is used for
|
||||||
|
* both NET and NET_LWIP, and given that the two network stacks do have
|
||||||
|
* conflicting types (for instance struct icmp_hdr), it is on purpose that the
|
||||||
|
* structures are defined locally with minimal dependencies -- <asm/types.h> is
|
||||||
|
* included for the bit types and that's it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ETHADDR_LEN 6
|
||||||
|
#define IP4_LEN 4
|
||||||
|
|
||||||
|
struct ethhdr {
|
||||||
|
u8 dst[ETHADDR_LEN];
|
||||||
|
u8 src[ETHADDR_LEN];
|
||||||
|
u16 protlen;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define ETHHDR_SIZE (sizeof(struct ethhdr))
|
||||||
|
|
||||||
|
struct arphdr {
|
||||||
|
u16 htype;
|
||||||
|
u16 ptype;
|
||||||
|
u8 hlen;
|
||||||
|
u8 plen;
|
||||||
|
u16 op;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define ARPHDR_SIZE (sizeof(struct arphdr))
|
||||||
|
|
||||||
|
#define ARP_REQUEST 1
|
||||||
|
#define ARP_REPLY 2
|
||||||
|
|
||||||
|
struct arpdata {
|
||||||
|
u8 sha[ETHADDR_LEN];
|
||||||
|
u32 spa;
|
||||||
|
u8 tha[ETHADDR_LEN];
|
||||||
|
u32 tpa;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define ARPDATA_SIZE (sizeof(struct arpdata))
|
||||||
|
|
||||||
|
struct iphdr {
|
||||||
|
u8 hl_v;
|
||||||
|
u8 tos;
|
||||||
|
u16 len;
|
||||||
|
u16 id;
|
||||||
|
u16 off;
|
||||||
|
u8 ttl;
|
||||||
|
u8 prot;
|
||||||
|
u16 sum;
|
||||||
|
u32 src;
|
||||||
|
u32 dst;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define IPHDR_SIZE (sizeof(struct iphdr))
|
||||||
|
|
||||||
|
struct icmphdr {
|
||||||
|
u8 type;
|
||||||
|
u8 code;
|
||||||
|
u16 checksum;
|
||||||
|
u16 id;
|
||||||
|
u16 sequence;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define ICMPHDR_SIZE (sizeof(struct icmphdr))
|
||||||
|
|
||||||
|
#define ICMP_ECHO_REQUEST 8
|
||||||
|
#define ICMP_ECHO_REPLY 0
|
||||||
|
#define IPPROTO_ICMP 1
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
static const u8 null_ethaddr[6];
|
||||||
static bool skip_timeout;
|
static bool skip_timeout;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -59,17 +130,19 @@ int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet,
|
|||||||
unsigned int len)
|
unsigned int len)
|
||||||
{
|
{
|
||||||
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
||||||
struct ethernet_hdr *eth = packet;
|
struct ethhdr *eth = packet;
|
||||||
struct arp_hdr *arp;
|
struct arphdr *arp;
|
||||||
struct ethernet_hdr *eth_recv;
|
struct arpdata *arpd;
|
||||||
struct arp_hdr *arp_recv;
|
struct ethhdr *eth_recv;
|
||||||
|
struct arphdr *arp_recv;
|
||||||
|
struct arpdata *arp_recvd;
|
||||||
|
|
||||||
if (ntohs(eth->et_protlen) != PROT_ARP)
|
if (ntohs(eth->protlen) != PROT_ARP)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
arp = packet + ETHER_HDR_SIZE;
|
arp = packet + ETHHDR_SIZE;
|
||||||
|
|
||||||
if (ntohs(arp->ar_op) != ARPOP_REQUEST)
|
if (ntohs(arp->op) != ARP_REQUEST)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
/* Don't allow the buffer to overrun */
|
/* Don't allow the buffer to overrun */
|
||||||
@@ -77,27 +150,29 @@ int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* store this as the assumed IP of the fake host */
|
/* store this as the assumed IP of the fake host */
|
||||||
priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa);
|
arpd = (struct arpdata *)(arp + 1);
|
||||||
|
priv->fake_host_ipaddr.s_addr = arpd->tpa;
|
||||||
|
|
||||||
/* Formulate a fake response */
|
/* Formulate a fake response */
|
||||||
eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
|
eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
|
||||||
memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
|
memcpy(eth_recv->dst, eth->src, ETHADDR_LEN);
|
||||||
memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
|
memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN);
|
||||||
eth_recv->et_protlen = htons(PROT_ARP);
|
eth_recv->protlen = htons(PROT_ARP);
|
||||||
|
|
||||||
arp_recv = (void *)eth_recv + ETHER_HDR_SIZE;
|
arp_recv = (void *)eth_recv + ETHHDR_SIZE;
|
||||||
arp_recv->ar_hrd = htons(ARP_ETHER);
|
arp_recv->htype = htons(ARP_ETHER);
|
||||||
arp_recv->ar_pro = htons(PROT_IP);
|
arp_recv->ptype = htons(PROT_IP);
|
||||||
arp_recv->ar_hln = ARP_HLEN;
|
arp_recv->hlen = ETHADDR_LEN;
|
||||||
arp_recv->ar_pln = ARP_PLEN;
|
arp_recv->plen = IP4_LEN;
|
||||||
arp_recv->ar_op = htons(ARPOP_REPLY);
|
arp_recv->op = htons(ARP_REPLY);
|
||||||
memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN);
|
arp_recvd = (struct arpdata *)(arp_recv + 1);
|
||||||
net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
|
memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN);
|
||||||
memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN);
|
arp_recvd->spa = priv->fake_host_ipaddr.s_addr;
|
||||||
net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa);
|
memcpy(&arp_recvd->tha, &arpd->sha, ETHADDR_LEN);
|
||||||
|
arp_recvd->tpa = arpd->spa;
|
||||||
|
|
||||||
priv->recv_packet_length[priv->recv_packets] =
|
priv->recv_packet_length[priv->recv_packets] = ETHHDR_SIZE +
|
||||||
ETHER_HDR_SIZE + ARP_HDR_SIZE;
|
ARPHDR_SIZE + ARPDATA_SIZE;
|
||||||
++priv->recv_packets;
|
++priv->recv_packets;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -114,22 +189,22 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
|
|||||||
unsigned int len)
|
unsigned int len)
|
||||||
{
|
{
|
||||||
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
||||||
struct ethernet_hdr *eth = packet;
|
struct ethhdr *eth = packet;
|
||||||
struct ip_udp_hdr *ip;
|
struct iphdr *ip;
|
||||||
struct icmp_hdr *icmp;
|
struct icmphdr *icmp;
|
||||||
struct ethernet_hdr *eth_recv;
|
struct ethhdr *eth_recv;
|
||||||
struct ip_udp_hdr *ipr;
|
struct iphdr *ipr;
|
||||||
struct icmp_hdr *icmpr;
|
struct icmphdr *icmpr;
|
||||||
|
|
||||||
if (ntohs(eth->et_protlen) != PROT_IP)
|
if (ntohs(eth->protlen) != PROT_IP)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
ip = packet + ETHER_HDR_SIZE;
|
ip = packet + ETHHDR_SIZE;
|
||||||
|
|
||||||
if (ip->ip_p != IPPROTO_ICMP)
|
if (ip->prot != IPPROTO_ICMP)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
icmp = (struct icmp_hdr *)&ip->udp_src;
|
icmp = (struct icmphdr *)(ip + 1);
|
||||||
|
|
||||||
if (icmp->type != ICMP_ECHO_REQUEST)
|
if (icmp->type != ICMP_ECHO_REQUEST)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
@@ -141,19 +216,19 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
|
|||||||
/* reply to the ping */
|
/* reply to the ping */
|
||||||
eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
|
eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
|
||||||
memcpy(eth_recv, packet, len);
|
memcpy(eth_recv, packet, len);
|
||||||
ipr = (void *)eth_recv + ETHER_HDR_SIZE;
|
ipr = (void *)eth_recv + ETHHDR_SIZE;
|
||||||
icmpr = (struct icmp_hdr *)&ipr->udp_src;
|
icmpr = (struct icmphdr *)(ipr + 1);
|
||||||
memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
|
memcpy(eth_recv->dst, eth->src, ETHADDR_LEN);
|
||||||
memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
|
memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN);
|
||||||
ipr->ip_sum = 0;
|
ipr->sum = 0;
|
||||||
ipr->ip_off = 0;
|
ipr->off = 0;
|
||||||
net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src);
|
ipr->dst = ip->src;
|
||||||
net_write_ip((void *)&ipr->ip_src, priv->fake_host_ipaddr);
|
ipr->src = priv->fake_host_ipaddr.s_addr;
|
||||||
ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE);
|
ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE);
|
||||||
|
|
||||||
icmpr->type = ICMP_ECHO_REPLY;
|
icmpr->type = ICMP_ECHO_REPLY;
|
||||||
icmpr->checksum = 0;
|
icmpr->checksum = 0;
|
||||||
icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE);
|
icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE);
|
||||||
|
|
||||||
priv->recv_packet_length[priv->recv_packets] = len;
|
priv->recv_packet_length[priv->recv_packets] = len;
|
||||||
++priv->recv_packets;
|
++priv->recv_packets;
|
||||||
@@ -171,8 +246,9 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet,
|
|||||||
int sandbox_eth_recv_arp_req(struct udevice *dev)
|
int sandbox_eth_recv_arp_req(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
||||||
struct ethernet_hdr *eth_recv;
|
struct ethhdr *eth_recv;
|
||||||
struct arp_hdr *arp_recv;
|
struct arphdr *arp_recv;
|
||||||
|
struct arpdata *arp_recvd;
|
||||||
|
|
||||||
/* Don't allow the buffer to overrun */
|
/* Don't allow the buffer to overrun */
|
||||||
if (priv->recv_packets >= PKTBUFSRX)
|
if (priv->recv_packets >= PKTBUFSRX)
|
||||||
@@ -180,23 +256,24 @@ int sandbox_eth_recv_arp_req(struct udevice *dev)
|
|||||||
|
|
||||||
/* Formulate a fake request */
|
/* Formulate a fake request */
|
||||||
eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
|
eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
|
||||||
memcpy(eth_recv->et_dest, net_bcast_ethaddr, ARP_HLEN);
|
memcpy(eth_recv->dst, net_bcast_ethaddr, ETHADDR_LEN);
|
||||||
memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
|
memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN);
|
||||||
eth_recv->et_protlen = htons(PROT_ARP);
|
eth_recv->protlen = htons(PROT_ARP);
|
||||||
|
|
||||||
arp_recv = (void *)eth_recv + ETHER_HDR_SIZE;
|
arp_recv = (void *)eth_recv + ETHHDR_SIZE;
|
||||||
arp_recv->ar_hrd = htons(ARP_ETHER);
|
arp_recv->htype = htons(ARP_ETHER);
|
||||||
arp_recv->ar_pro = htons(PROT_IP);
|
arp_recv->ptype = htons(PROT_IP);
|
||||||
arp_recv->ar_hln = ARP_HLEN;
|
arp_recv->hlen = ETHADDR_LEN;
|
||||||
arp_recv->ar_pln = ARP_PLEN;
|
arp_recv->plen = IP4_LEN;
|
||||||
arp_recv->ar_op = htons(ARPOP_REQUEST);
|
arp_recv->op = htons(ARP_REQUEST);
|
||||||
memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN);
|
arp_recvd = (struct arpdata *)(arp_recv + 1);
|
||||||
net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
|
memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN);
|
||||||
memcpy(&arp_recv->ar_tha, net_null_ethaddr, ARP_HLEN);
|
arp_recvd->spa = priv->fake_host_ipaddr.s_addr;
|
||||||
net_write_ip(&arp_recv->ar_tpa, net_ip);
|
memcpy(&arp_recvd->tha, null_ethaddr, ETHADDR_LEN);
|
||||||
|
arp_recvd->tpa = net_ip.s_addr;
|
||||||
|
|
||||||
priv->recv_packet_length[priv->recv_packets] =
|
priv->recv_packet_length[priv->recv_packets] =
|
||||||
ETHER_HDR_SIZE + ARP_HDR_SIZE;
|
ETHHDR_SIZE + ARPHDR_SIZE + ARPDATA_SIZE;
|
||||||
++priv->recv_packets;
|
++priv->recv_packets;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -212,9 +289,10 @@ int sandbox_eth_recv_arp_req(struct udevice *dev)
|
|||||||
int sandbox_eth_recv_ping_req(struct udevice *dev)
|
int sandbox_eth_recv_ping_req(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
struct eth_sandbox_priv *priv = dev_get_priv(dev);
|
||||||
struct ethernet_hdr *eth_recv;
|
struct eth_pdata *pdata = dev_get_plat(dev);
|
||||||
struct ip_udp_hdr *ipr;
|
struct ethhdr *eth_recv;
|
||||||
struct icmp_hdr *icmpr;
|
struct iphdr *ipr;
|
||||||
|
struct icmphdr *icmpr;
|
||||||
|
|
||||||
/* Don't allow the buffer to overrun */
|
/* Don't allow the buffer to overrun */
|
||||||
if (priv->recv_packets >= PKTBUFSRX)
|
if (priv->recv_packets >= PKTBUFSRX)
|
||||||
@@ -223,31 +301,31 @@ int sandbox_eth_recv_ping_req(struct udevice *dev)
|
|||||||
/* Formulate a fake ping */
|
/* Formulate a fake ping */
|
||||||
eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
|
eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
|
||||||
|
|
||||||
memcpy(eth_recv->et_dest, net_ethaddr, ARP_HLEN);
|
memcpy(eth_recv->dst, pdata->enetaddr, ETHADDR_LEN);
|
||||||
memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
|
memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN);
|
||||||
eth_recv->et_protlen = htons(PROT_IP);
|
eth_recv->protlen = htons(PROT_IP);
|
||||||
|
|
||||||
ipr = (void *)eth_recv + ETHER_HDR_SIZE;
|
ipr = (void *)eth_recv + ETHHDR_SIZE;
|
||||||
ipr->ip_hl_v = 0x45;
|
ipr->hl_v = 0x45;
|
||||||
ipr->ip_len = htons(IP_ICMP_HDR_SIZE);
|
ipr->len = htons(IPHDR_SIZE + ICMPHDR_SIZE);
|
||||||
ipr->ip_off = htons(IP_FLAGS_DFRAG);
|
ipr->off = htons(IP_FLAGS_DFRAG);
|
||||||
ipr->ip_p = IPPROTO_ICMP;
|
ipr->prot = IPPROTO_ICMP;
|
||||||
ipr->ip_sum = 0;
|
ipr->sum = 0;
|
||||||
net_write_ip(&ipr->ip_src, priv->fake_host_ipaddr);
|
ipr->src = priv->fake_host_ipaddr.s_addr;
|
||||||
net_write_ip(&ipr->ip_dst, net_ip);
|
ipr->dst = net_ip.s_addr;
|
||||||
ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE);
|
ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE);
|
||||||
|
|
||||||
icmpr = (struct icmp_hdr *)&ipr->udp_src;
|
icmpr = (struct icmphdr *)(ipr + 1);
|
||||||
|
|
||||||
icmpr->type = ICMP_ECHO_REQUEST;
|
icmpr->type = ICMP_ECHO_REQUEST;
|
||||||
icmpr->code = 0;
|
icmpr->code = 0;
|
||||||
icmpr->checksum = 0;
|
icmpr->checksum = 0;
|
||||||
icmpr->un.echo.id = 0;
|
icmpr->id = 0;
|
||||||
icmpr->un.echo.sequence = htons(1);
|
icmpr->sequence = htons(1);
|
||||||
icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE);
|
icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE);
|
||||||
|
|
||||||
priv->recv_packet_length[priv->recv_packets] =
|
priv->recv_packet_length[priv->recv_packets] =
|
||||||
ETHER_HDR_SIZE + IP_ICMP_HDR_SIZE;
|
ETHHDR_SIZE + IPHDR_SIZE + ICMPHDR_SIZE;
|
||||||
++priv->recv_packets;
|
++priv->recv_packets;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -398,7 +476,7 @@ static int sb_eth_write_hwaddr(struct udevice *dev)
|
|||||||
|
|
||||||
debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name,
|
debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name,
|
||||||
pdata->enetaddr);
|
pdata->enetaddr);
|
||||||
memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ARP_HLEN);
|
memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ETHADDR_LEN);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user