mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-19 16:38:53 +09:00
![Wolfgang Denk](/assets/img/avatar_default.png)
A number of network related files were imported from the LiMon project; these contain a somewhat unclear license statement: Copyright 1994 - 2000 Neil Russell. (See License) I analyzed the source code of LiMon v1.4.2 which was used for this import. It does not contain any "License" file, but the top level directory contains a file "COPYING", which turns out to be GPL v2 of June 1991. So it is legitimate to conclude that the LiMon derived files are also to be released under GPLv2. Mark them as such. Signed-off-by: Wolfgang Denk <wd@denx.de>
117 lines
2.7 KiB
C
117 lines
2.7 KiB
C
/*
|
|
* Copied from Linux Monitor (LiMon) - Networking.
|
|
*
|
|
* Copyright 1994 - 2000 Neil Russell.
|
|
* (See License)
|
|
* Copyright 2000 Roland Borde
|
|
* Copyright 2000 Paolo Scaffardi
|
|
* Copyright 2000-2002 Wolfgang Denk, wd@denx.de
|
|
* SPDX-License-Identifier: GPL-2.0
|
|
*/
|
|
|
|
#include "ping.h"
|
|
#include "arp.h"
|
|
|
|
static ushort PingSeqNo;
|
|
|
|
/* The ip address to ping */
|
|
IPaddr_t NetPingIP;
|
|
|
|
static void set_icmp_header(uchar *pkt, IPaddr_t dest)
|
|
{
|
|
/*
|
|
* Construct an IP and ICMP header.
|
|
*/
|
|
struct ip_hdr *ip = (struct ip_hdr *)pkt;
|
|
struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE);
|
|
|
|
net_set_ip_header(pkt, dest, NetOurIP);
|
|
|
|
ip->ip_len = htons(IP_ICMP_HDR_SIZE);
|
|
ip->ip_p = IPPROTO_ICMP;
|
|
ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1);
|
|
|
|
icmp->type = ICMP_ECHO_REQUEST;
|
|
icmp->code = 0;
|
|
icmp->checksum = 0;
|
|
icmp->un.echo.id = 0;
|
|
icmp->un.echo.sequence = htons(PingSeqNo++);
|
|
icmp->checksum = ~NetCksum((uchar *)icmp, ICMP_HDR_SIZE >> 1);
|
|
}
|
|
|
|
static int ping_send(void)
|
|
{
|
|
uchar *pkt;
|
|
int eth_hdr_size;
|
|
|
|
/* XXX always send arp request */
|
|
|
|
debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &NetPingIP);
|
|
|
|
NetArpWaitPacketIP = NetPingIP;
|
|
|
|
eth_hdr_size = NetSetEther(NetTxPacket, NetEtherNullAddr, PROT_IP);
|
|
pkt = (uchar *)NetTxPacket + eth_hdr_size;
|
|
|
|
set_icmp_header(pkt, NetPingIP);
|
|
|
|
/* size of the waiting packet */
|
|
NetArpWaitTxPacketSize = eth_hdr_size + IP_ICMP_HDR_SIZE;
|
|
|
|
/* and do the ARP request */
|
|
NetArpWaitTry = 1;
|
|
NetArpWaitTimerStart = get_timer(0);
|
|
ArpRequest();
|
|
return 1; /* waiting */
|
|
}
|
|
|
|
static void ping_timeout(void)
|
|
{
|
|
eth_halt();
|
|
net_set_state(NETLOOP_FAIL); /* we did not get the reply */
|
|
}
|
|
|
|
void ping_start(void)
|
|
{
|
|
printf("Using %s device\n", eth_get_name());
|
|
NetSetTimeout(10000UL, ping_timeout);
|
|
|
|
ping_send();
|
|
}
|
|
|
|
void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
|
|
{
|
|
struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
|
|
IPaddr_t src_ip;
|
|
int eth_hdr_size;
|
|
|
|
switch (icmph->type) {
|
|
case ICMP_ECHO_REPLY:
|
|
src_ip = NetReadIP((void *)&ip->ip_src);
|
|
if (src_ip == NetPingIP)
|
|
net_set_state(NETLOOP_SUCCESS);
|
|
return;
|
|
case ICMP_ECHO_REQUEST:
|
|
eth_hdr_size = net_update_ether(et, et->et_src, PROT_IP);
|
|
|
|
debug_cond(DEBUG_DEV_PKT, "Got ICMP ECHO REQUEST, return "
|
|
"%d bytes\n", eth_hdr_size + len);
|
|
|
|
ip->ip_sum = 0;
|
|
ip->ip_off = 0;
|
|
NetCopyIP((void *)&ip->ip_dst, &ip->ip_src);
|
|
NetCopyIP((void *)&ip->ip_src, &NetOurIP);
|
|
ip->ip_sum = ~NetCksum((uchar *)ip,
|
|
IP_HDR_SIZE >> 1);
|
|
|
|
icmph->type = ICMP_ECHO_REPLY;
|
|
icmph->checksum = 0;
|
|
icmph->checksum = ~NetCksum((uchar *)icmph,
|
|
(len - IP_HDR_SIZE) >> 1);
|
|
NetSendPacket((uchar *)et, eth_hdr_size + len);
|
|
return;
|
|
/* default:
|
|
return;*/
|
|
}
|
|
}
|