]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - net/ping.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copied from Linux Monitor (LiMon) - Networking.
5 * Copyright 1994 - 2000 Neil Russell.
7 * Copyright 2000 Roland Borde
8 * Copyright 2000 Paolo Scaffardi
9 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
17 static ushort ping_seq_number
;
19 /* The ip address to ping */
20 struct in_addr net_ping_ip
;
22 static void set_icmp_header(uchar
*pkt
, struct in_addr dest
)
25 * Construct an IP and ICMP header.
27 struct icmp_hdr
*icmp
= (struct icmp_hdr
*)(pkt
+ IP_HDR_SIZE
);
29 net_set_ip_header(pkt
, dest
, net_ip
, IP_ICMP_HDR_SIZE
, IPPROTO_ICMP
);
31 icmp
->type
= ICMP_ECHO_REQUEST
;
35 icmp
->un
.echo
.sequence
= htons(ping_seq_number
++);
36 icmp
->checksum
= compute_ip_checksum(icmp
, ICMP_HDR_SIZE
);
39 static int ping_send(void)
44 /* XXX always send arp request */
46 debug_cond(DEBUG_DEV_PKT
, "sending ARP for %pI4\n", &net_ping_ip
);
48 net_arp_wait_packet_ip
= net_ping_ip
;
50 eth_hdr_size
= net_set_ether(net_tx_packet
, net_null_ethaddr
, PROT_IP
);
51 pkt
= (uchar
*)net_tx_packet
+ eth_hdr_size
;
53 set_icmp_header(pkt
, net_ping_ip
);
55 /* size of the waiting packet */
56 arp_wait_tx_packet_size
= eth_hdr_size
+ IP_ICMP_HDR_SIZE
;
58 /* and do the ARP request */
60 arp_wait_timer_start
= get_timer(0);
62 return 1; /* waiting */
65 static void ping_timeout_handler(void)
68 net_set_state(NETLOOP_FAIL
); /* we did not get the reply */
73 printf("Using %s device\n", eth_get_name());
74 net_set_timeout_handler(10000UL, ping_timeout_handler
);
79 void ping_receive(struct ethernet_hdr
*et
, struct ip_udp_hdr
*ip
, int len
)
81 struct icmp_hdr
*icmph
= (struct icmp_hdr
*)&ip
->udp_src
;
82 struct in_addr src_ip
;
86 switch (icmph
->type
) {
88 src_ip
= net_read_ip((void *)&ip
->ip_src
);
89 if (src_ip
.s_addr
== net_ping_ip
.s_addr
)
90 net_set_state(NETLOOP_SUCCESS
);
92 case ICMP_ECHO_REQUEST
:
93 if (net_ip
.s_addr
== 0)
96 eth_hdr_size
= net_update_ether(et
, et
->et_src
, PROT_IP
);
98 debug_cond(DEBUG_DEV_PKT
,
99 "Got ICMP ECHO REQUEST, return %d bytes\n",
104 net_copy_ip((void *)&ip
->ip_dst
, &ip
->ip_src
);
105 net_copy_ip((void *)&ip
->ip_src
, &net_ip
);
106 ip
->ip_sum
= compute_ip_checksum(ip
, IP_HDR_SIZE
);
108 icmph
->type
= ICMP_ECHO_REPLY
;
110 icmph
->checksum
= compute_ip_checksum(icmph
, len
- IP_HDR_SIZE
);
112 tx_packet
= net_get_async_tx_pkt_buf();
113 memcpy(tx_packet
, et
, eth_hdr_size
+ len
);
114 net_send_packet(tx_packet
, eth_hdr_size
+ len
);