Re: [U-Boot] [RFC PATCH 7/7] net: Add ARP and PING response to sandbox driver

2015-01-28 Thread Simon Glass
Hi Joe,

On 28 January 2015 at 03:36, Joe Hershberger joe.hershber...@gmail.com wrote:
 On Tue, Jan 27, 2015 at 8:34 PM, Simon Glass s...@chromium.org wrote:

 Hi Joe,

 On 27 January 2015 at 16:27, Joe Hershberger joe.hershber...@ni.com
 wrote:
  The sandbox driver will now generate response traffic to exercise the
  ping command even when no network exists.  This allows the basic data
  pathways of the DM to be tested.
 
  Signed-off-by: Joe Hershberger joe.hershber...@ni.com
  ---

 Looks like this can support ping. Very nice.

 I looked at other ways to test the network stack in sandbox, create tests in
 the test/ dir, etc., but this seemed like the best and most straightforward
 way to exercise it without tons of extra code, so I went for this approach.

Well we still need tests in the test/ directory - every uclass should
have tests. In this case the tests could start up a few devices and
try ping. Also the environment variable logic needs tests.


 
   drivers/net/sandbox.c | 75
  +++
   1 file changed, 75 insertions(+)
 
  diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
  index e1ee69b..49413f2 100644
  --- a/drivers/net/sandbox.c
  +++ b/drivers/net/sandbox.c
  @@ -20,6 +20,11 @@ struct eth_sandbox_priv {
  int sd;
   };
 
  +static uchar fake_host_hwaddr[ARP_HLEN] = {0x00, 0x00, 0x66, 0x44,
  0x22, 0x00};
  +static IPaddr_t fake_host_ipaddr;
  +static uchar recv_packet_buffer[PKTSIZE];
  +static int recv_packet_length;

 This could go in the driver's priv area (then we could support
 multiple sandbox devices).

 Good idea.


  +
   int sb_eth_init(struct udevice *dev, bd_t *bis)
   {
  printf(eth_sandbox: Init\n);
  @@ -31,12 +36,82 @@ int sb_eth_send(struct udevice *dev, void *packet,
  int length)
   {
  printf(eth_sandbox: Send packet %d\n, length);
 
  +   struct ethernet_hdr *eth = packet;
  +   if (ntohs(eth-et_protlen) == PROT_ARP) {
  +   struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
  +   if (ntohs(arp-ar_op) == ARPOP_REQUEST) {
  +   /* store this as the assumed IP of the fake host
  */
  +   fake_host_ipaddr = NetReadIP(arp-ar_tpa);
  +   /* Formulate a fake response */
  +   struct ethernet_hdr *eth_recv =
  +   (void *)recv_packet_buffer;
  +   memcpy(eth_recv-et_dest, eth-et_src,
  ARP_HLEN);
  +   memcpy(eth_recv-et_src, fake_host_hwaddr,
  ARP_HLEN);
  +   eth_recv-et_protlen = htons(PROT_ARP);
  +
  +   struct arp_hdr *arp_recv = (void
  *)recv_packet_buffer +
  +   ETHER_HDR_SIZE;
  +   arp_recv-ar_hrd = htons(ARP_ETHER);
  +   arp_recv-ar_pro = htons(PROT_IP);
  +   arp_recv-ar_hln = ARP_HLEN;
  +   arp_recv-ar_pln = ARP_PLEN;
  +   arp_recv-ar_op = htons(ARPOP_REPLY);
  +   memcpy(arp_recv-ar_sha, fake_host_hwaddr,
  ARP_HLEN);
  +   NetWriteIP(arp_recv-ar_spa, fake_host_ipaddr);
  +   memcpy(arp_recv-ar_tha, arp-ar_sha,
  ARP_HLEN);
  +   NetCopyIP(arp_recv-ar_tpa, arp-ar_spa);
  +
  +   recv_packet_length = ETHER_HDR_SIZE +
  ARP_HDR_SIZE;
  +   }
  +   } else if (ntohs(eth-et_protlen) == PROT_IP) {
  +   struct ip_udp_hdr *ip = packet + ETHER_HDR_SIZE;
  +   if (ip-ip_p == IPPROTO_ICMP) {
  +   struct icmp_hdr *icmp = (struct icmp_hdr
  *)ip-udp_src;
  +   if (icmp-type == ICMP_ECHO_REQUEST) {
  +   /* reply to the ping */
  +   memcpy(recv_packet_buffer, packet,
  length);
  +   struct ethernet_hdr *eth_recv =
  +   (void *)recv_packet_buffer;
  +   struct ip_udp_hdr *ipr =
  +   (void *)recv_packet_buffer +
  +   ETHER_HDR_SIZE;
  +   struct icmp_hdr *icmpr =
  +   (struct icmp_hdr
  *)ipr-udp_src;
  +   memcpy(eth_recv-et_dest, eth-et_src,
  +  ARP_HLEN);
  +   memcpy(eth_recv-et_src,
  fake_host_hwaddr,
  +  ARP_HLEN);
  +   ipr-ip_sum = 0;
  +   ipr-ip_off = 0;
  +   NetCopyIP((void *)ipr-ip_dst,
  ip-ip_src);
  +   NetWriteIP((void *)ipr-ip_src,
  +  fake_host_ipaddr);
  +   ipr-ip_sum 

[U-Boot] [RFC PATCH 7/7] net: Add ARP and PING response to sandbox driver

2015-01-27 Thread Joe Hershberger
The sandbox driver will now generate response traffic to exercise the
ping command even when no network exists.  This allows the basic data
pathways of the DM to be tested.

Signed-off-by: Joe Hershberger joe.hershber...@ni.com
---

 drivers/net/sandbox.c | 75 +++
 1 file changed, 75 insertions(+)

diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
index e1ee69b..49413f2 100644
--- a/drivers/net/sandbox.c
+++ b/drivers/net/sandbox.c
@@ -20,6 +20,11 @@ struct eth_sandbox_priv {
int sd;
 };
 
+static uchar fake_host_hwaddr[ARP_HLEN] = {0x00, 0x00, 0x66, 0x44, 0x22, 0x00};
+static IPaddr_t fake_host_ipaddr;
+static uchar recv_packet_buffer[PKTSIZE];
+static int recv_packet_length;
+
 int sb_eth_init(struct udevice *dev, bd_t *bis)
 {
printf(eth_sandbox: Init\n);
@@ -31,12 +36,82 @@ int sb_eth_send(struct udevice *dev, void *packet, int 
length)
 {
printf(eth_sandbox: Send packet %d\n, length);
 
+   struct ethernet_hdr *eth = packet;
+   if (ntohs(eth-et_protlen) == PROT_ARP) {
+   struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+   if (ntohs(arp-ar_op) == ARPOP_REQUEST) {
+   /* store this as the assumed IP of the fake host */
+   fake_host_ipaddr = NetReadIP(arp-ar_tpa);
+   /* Formulate a fake response */
+   struct ethernet_hdr *eth_recv =
+   (void *)recv_packet_buffer;
+   memcpy(eth_recv-et_dest, eth-et_src, ARP_HLEN);
+   memcpy(eth_recv-et_src, fake_host_hwaddr, ARP_HLEN);
+   eth_recv-et_protlen = htons(PROT_ARP);
+
+   struct arp_hdr *arp_recv = (void *)recv_packet_buffer +
+   ETHER_HDR_SIZE;
+   arp_recv-ar_hrd = htons(ARP_ETHER);
+   arp_recv-ar_pro = htons(PROT_IP);
+   arp_recv-ar_hln = ARP_HLEN;
+   arp_recv-ar_pln = ARP_PLEN;
+   arp_recv-ar_op = htons(ARPOP_REPLY);
+   memcpy(arp_recv-ar_sha, fake_host_hwaddr, ARP_HLEN);
+   NetWriteIP(arp_recv-ar_spa, fake_host_ipaddr);
+   memcpy(arp_recv-ar_tha, arp-ar_sha, ARP_HLEN);
+   NetCopyIP(arp_recv-ar_tpa, arp-ar_spa);
+
+   recv_packet_length = ETHER_HDR_SIZE + ARP_HDR_SIZE;
+   }
+   } else if (ntohs(eth-et_protlen) == PROT_IP) {
+   struct ip_udp_hdr *ip = packet + ETHER_HDR_SIZE;
+   if (ip-ip_p == IPPROTO_ICMP) {
+   struct icmp_hdr *icmp = (struct icmp_hdr *)ip-udp_src;
+   if (icmp-type == ICMP_ECHO_REQUEST) {
+   /* reply to the ping */
+   memcpy(recv_packet_buffer, packet, length);
+   struct ethernet_hdr *eth_recv =
+   (void *)recv_packet_buffer;
+   struct ip_udp_hdr *ipr =
+   (void *)recv_packet_buffer +
+   ETHER_HDR_SIZE;
+   struct icmp_hdr *icmpr =
+   (struct icmp_hdr *)ipr-udp_src;
+   memcpy(eth_recv-et_dest, eth-et_src,
+  ARP_HLEN);
+   memcpy(eth_recv-et_src, fake_host_hwaddr,
+  ARP_HLEN);
+   ipr-ip_sum = 0;
+   ipr-ip_off = 0;
+   NetCopyIP((void *)ipr-ip_dst, ip-ip_src);
+   NetWriteIP((void *)ipr-ip_src,
+  fake_host_ipaddr);
+   ipr-ip_sum = ~NetCksum((uchar *)ipr,
+   IP_HDR_SIZE  1);
+
+   icmpr-type = ICMP_ECHO_REPLY;
+   icmpr-checksum = 0;
+   icmpr-checksum = ~NetCksum((uchar *)icmpr,
+   (length - ETHER_HDR_SIZE -
+   IP_HDR_SIZE)  1);
+
+   recv_packet_length = length;
+   }
+   }
+   }
+
return 0;
 #endif
 }
 
 int sb_eth_recv(struct udevice *dev)
 {
+   if (recv_packet_length) {
+   int lcl_recv_packet_length = recv_packet_length;
+   printf(eth_sandbox: received packet %d\n, recv_packet_length);
+   recv_packet_length = 0;
+   NetReceive((void *)recv_packet_buffer, lcl_recv_packet_length);
+   }
return 0;
 }
 
-- 
1.7.11.5

___
U-Boot mailing list

Re: [U-Boot] [RFC PATCH 7/7] net: Add ARP and PING response to sandbox driver

2015-01-27 Thread Simon Glass
Hi Joe,

On 27 January 2015 at 16:27, Joe Hershberger joe.hershber...@ni.com wrote:
 The sandbox driver will now generate response traffic to exercise the
 ping command even when no network exists.  This allows the basic data
 pathways of the DM to be tested.

 Signed-off-by: Joe Hershberger joe.hershber...@ni.com
 ---

Looks like this can support ping. Very nice.


  drivers/net/sandbox.c | 75 
 +++
  1 file changed, 75 insertions(+)

 diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
 index e1ee69b..49413f2 100644
 --- a/drivers/net/sandbox.c
 +++ b/drivers/net/sandbox.c
 @@ -20,6 +20,11 @@ struct eth_sandbox_priv {
 int sd;
  };

 +static uchar fake_host_hwaddr[ARP_HLEN] = {0x00, 0x00, 0x66, 0x44, 0x22, 
 0x00};
 +static IPaddr_t fake_host_ipaddr;
 +static uchar recv_packet_buffer[PKTSIZE];
 +static int recv_packet_length;

This could go in the driver's priv area (then we could support
multiple sandbox devices).

 +
  int sb_eth_init(struct udevice *dev, bd_t *bis)
  {
 printf(eth_sandbox: Init\n);
 @@ -31,12 +36,82 @@ int sb_eth_send(struct udevice *dev, void *packet, int 
 length)
  {
 printf(eth_sandbox: Send packet %d\n, length);

 +   struct ethernet_hdr *eth = packet;
 +   if (ntohs(eth-et_protlen) == PROT_ARP) {
 +   struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
 +   if (ntohs(arp-ar_op) == ARPOP_REQUEST) {
 +   /* store this as the assumed IP of the fake host */
 +   fake_host_ipaddr = NetReadIP(arp-ar_tpa);
 +   /* Formulate a fake response */
 +   struct ethernet_hdr *eth_recv =
 +   (void *)recv_packet_buffer;
 +   memcpy(eth_recv-et_dest, eth-et_src, ARP_HLEN);
 +   memcpy(eth_recv-et_src, fake_host_hwaddr, ARP_HLEN);
 +   eth_recv-et_protlen = htons(PROT_ARP);
 +
 +   struct arp_hdr *arp_recv = (void *)recv_packet_buffer 
 +
 +   ETHER_HDR_SIZE;
 +   arp_recv-ar_hrd = htons(ARP_ETHER);
 +   arp_recv-ar_pro = htons(PROT_IP);
 +   arp_recv-ar_hln = ARP_HLEN;
 +   arp_recv-ar_pln = ARP_PLEN;
 +   arp_recv-ar_op = htons(ARPOP_REPLY);
 +   memcpy(arp_recv-ar_sha, fake_host_hwaddr, ARP_HLEN);
 +   NetWriteIP(arp_recv-ar_spa, fake_host_ipaddr);
 +   memcpy(arp_recv-ar_tha, arp-ar_sha, ARP_HLEN);
 +   NetCopyIP(arp_recv-ar_tpa, arp-ar_spa);
 +
 +   recv_packet_length = ETHER_HDR_SIZE + ARP_HDR_SIZE;
 +   }
 +   } else if (ntohs(eth-et_protlen) == PROT_IP) {
 +   struct ip_udp_hdr *ip = packet + ETHER_HDR_SIZE;
 +   if (ip-ip_p == IPPROTO_ICMP) {
 +   struct icmp_hdr *icmp = (struct icmp_hdr 
 *)ip-udp_src;
 +   if (icmp-type == ICMP_ECHO_REQUEST) {
 +   /* reply to the ping */
 +   memcpy(recv_packet_buffer, packet, length);
 +   struct ethernet_hdr *eth_recv =
 +   (void *)recv_packet_buffer;
 +   struct ip_udp_hdr *ipr =
 +   (void *)recv_packet_buffer +
 +   ETHER_HDR_SIZE;
 +   struct icmp_hdr *icmpr =
 +   (struct icmp_hdr *)ipr-udp_src;
 +   memcpy(eth_recv-et_dest, eth-et_src,
 +  ARP_HLEN);
 +   memcpy(eth_recv-et_src, fake_host_hwaddr,
 +  ARP_HLEN);
 +   ipr-ip_sum = 0;
 +   ipr-ip_off = 0;
 +   NetCopyIP((void *)ipr-ip_dst, ip-ip_src);
 +   NetWriteIP((void *)ipr-ip_src,
 +  fake_host_ipaddr);
 +   ipr-ip_sum = ~NetCksum((uchar *)ipr,
 +   IP_HDR_SIZE  1);
 +
 +   icmpr-type = ICMP_ECHO_REPLY;
 +   icmpr-checksum = 0;
 +   icmpr-checksum = ~NetCksum((uchar *)icmpr,
 +   (length - ETHER_HDR_SIZE -
 +   IP_HDR_SIZE)  1);
 +
 +   recv_packet_length = length;
 +   }
 +   }
 +   }
 +
 return 0;
  #endif
  }

  int sb_eth_recv(struct udevice *dev)
  {
 +   if (recv_packet_length) {
 +   int lcl_recv_packet_length =