2 * Copied from Linux Monitor (LiMon) - Networking.
4 * Copyright 1994 - 2000 Neil Russell.
6 * Copyright 2000 Roland Borde
7 * Copyright 2000 Paolo Scaffardi
8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
14 static ushort PingSeqNo
;
16 /* The ip address to ping */
19 static void set_icmp_header(uchar
*pkt
, IPaddr_t dest
)
22 * Construct an IP and ICMP header.
24 struct ip_hdr
*ip
= (struct ip_hdr
*)pkt
;
25 struct icmp_hdr
*icmp
= (struct icmp_hdr
*)(pkt
+ IP_HDR_SIZE
);
27 net_set_ip_header(pkt
, dest
, NetOurIP
);
29 ip
->ip_len
= htons(IP_ICMP_HDR_SIZE
);
30 ip
->ip_p
= IPPROTO_ICMP
;
31 ip
->ip_sum
= ~NetCksum((uchar
*)ip
, IP_HDR_SIZE
>> 1);
33 icmp
->type
= ICMP_ECHO_REQUEST
;
37 icmp
->un
.echo
.sequence
= htons(PingSeqNo
++);
38 icmp
->checksum
= ~NetCksum((uchar
*)icmp
, ICMP_HDR_SIZE
>> 1);
41 static int ping_send(void)
46 /* XXX always send arp request */
48 debug_cond(DEBUG_DEV_PKT
, "sending ARP for %pI4\n", &NetPingIP
);
50 NetArpWaitPacketIP
= NetPingIP
;
52 eth_hdr_size
= NetSetEther(NetTxPacket
, NetEtherNullAddr
, PROT_IP
);
53 pkt
= (uchar
*)NetTxPacket
+ eth_hdr_size
;
55 set_icmp_header(pkt
, NetPingIP
);
57 /* size of the waiting packet */
58 NetArpWaitTxPacketSize
= eth_hdr_size
+ IP_ICMP_HDR_SIZE
;
60 /* and do the ARP request */
62 NetArpWaitTimerStart
= get_timer(0);
64 return 1; /* waiting */
67 static void ping_timeout(void)
70 net_set_state(NETLOOP_FAIL
); /* we did not get the reply */
75 printf("Using %s device\n", eth_get_name());
76 NetSetTimeout(10000UL, ping_timeout
);
81 void ping_receive(struct ethernet_hdr
*et
, struct ip_udp_hdr
*ip
, int len
)
83 struct icmp_hdr
*icmph
= (struct icmp_hdr
*)&ip
->udp_src
;
87 switch (icmph
->type
) {
89 src_ip
= NetReadIP((void *)&ip
->ip_src
);
90 if (src_ip
== NetPingIP
)
91 net_set_state(NETLOOP_SUCCESS
);
93 case ICMP_ECHO_REQUEST
:
94 eth_hdr_size
= net_update_ether(et
, et
->et_src
, PROT_IP
);
96 debug_cond(DEBUG_DEV_PKT
, "Got ICMP ECHO REQUEST, return "
97 "%d bytes\n", eth_hdr_size
+ len
);
101 NetCopyIP((void *)&ip
->ip_dst
, &ip
->ip_src
);
102 NetCopyIP((void *)&ip
->ip_src
, &NetOurIP
);
103 ip
->ip_sum
= ~NetCksum((uchar
*)ip
,
106 icmph
->type
= ICMP_ECHO_REPLY
;
108 icmph
->checksum
= ~NetCksum((uchar
*)icmph
,
109 (len
- IP_HDR_SIZE
) >> 1);
110 NetSendPacket((uchar
*)et
, eth_hdr_size
+ len
);