]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - net/ping6.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2013 Allied Telesis Labs NZ
4 * Chris Packham, <judge.packham@gmail.com>
6 * Copyright (C) 2022 YADRO
7 * Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com>
10 /* Simple ping6 implementation */
19 /* the ipv6 address to ping */
20 struct in6_addr net_ping_ip6
;
23 ip6_make_ping(uchar
*eth_dst_addr
, struct in6_addr
*neigh_addr
, uchar
*pkt
)
30 len
= sizeof(struct echo_msg
);
32 pkt
+= net_set_ether(pkt
, eth_dst_addr
, PROT_IP6
);
33 pkt
+= ip6_add_hdr(pkt
, &net_ip6
, neigh_addr
, PROT_ICMPV6
,
34 IPV6_NDISC_HOPLIMIT
, len
);
37 msg
= (struct echo_msg
*)pkt
;
38 msg
->icmph
.icmp6_type
= IPV6_ICMP_ECHO_REQUEST
;
39 msg
->icmph
.icmp6_code
= 0;
40 msg
->icmph
.icmp6_cksum
= 0;
41 msg
->icmph
.icmp6_identifier
= 0;
42 msg
->icmph
.icmp6_sequence
= htons(seq_no
++);
43 msg
->id
= msg
->icmph
.icmp6_identifier
; /* these seem redundant */
44 msg
->sequence
= msg
->icmph
.icmp6_sequence
;
47 csum_p
= csum_partial((u8
*)msg
, len
, 0);
48 msg
->icmph
.icmp6_cksum
= csum_ipv6_magic(&net_ip6
, neigh_addr
, len
,
61 /* always send neighbor solicit */
63 memcpy(mac
, net_null_ethaddr
, 6);
65 net_nd_sol_packet_ip6
= net_ping_ip6
;
66 net_nd_packet_mac
= mac
;
68 pkt
= net_nd_tx_packet
;
69 pkt
+= ip6_make_ping(mac
, &net_ping_ip6
, pkt
);
71 /* size of the waiting packet */
72 net_nd_tx_packet_size
= (pkt
- net_nd_tx_packet
);
74 /* and do the ARP request */
76 net_nd_timer_start
= get_timer(0);
78 return 1; /* waiting */
81 static void ping6_timeout(void)
84 net_set_state(NETLOOP_FAIL
); /* we did not get the reply */
87 void ping6_start(void)
89 printf("Using %s device\n", eth_get_name());
90 net_set_timeout_handler(10000UL, ping6_timeout
);
95 int ping6_receive(struct ethernet_hdr
*et
, struct ip6_hdr
*ip6
, int len
)
97 struct icmp6hdr
*icmp
=
98 (struct icmp6hdr
*)(((uchar
*)ip6
) + IP6_HDR_SIZE
);
99 struct in6_addr src_ip
;
101 switch (icmp
->icmp6_type
) {
102 case IPV6_ICMP_ECHO_REPLY
:
104 if (memcmp(&net_ping_ip6
, &src_ip
, sizeof(struct in6_addr
)))
106 net_set_state(NETLOOP_SUCCESS
);
108 case IPV6_ICMP_ECHO_REQUEST
:
109 /* ignore for now.... */
110 debug("Got ICMPv6 ECHO REQUEST from %pI6c\n", &ip6
->saddr
);
113 debug("Unexpected ICMPv6 type 0x%x\n", icmp
->icmp6_type
);