Add basic support for mini2440 board to barebox.
[barebox-mini2440.git] / net / ping.c
blob440e229ba084c9d709afc50364e7add13c501f36
1 #include <common.h>
2 #include <command.h>
3 #include <clock.h>
4 #include <net.h>
5 #include <errno.h>
6 #include <linux/err.h>
8 static uint16_t ping_sequence_number;
10 static IPaddr_t net_ping_ip; /* the ip address to ping */
12 #define PING_STATE_INIT 0
13 #define PING_STATE_SUCCESS 1
15 static int ping_state;
17 static struct net_connection *ping_con;
19 static int ping_send(void)
21 unsigned char *payload;
22 struct icmphdr *icmp;
23 uint64_t ts;
25 icmp = ping_con->icmp;
27 icmp->type = ICMP_ECHO_REQUEST;
28 icmp->code = 0;
29 icmp->checksum = 0;
30 icmp->un.echo.id = 0;
31 icmp->un.echo.sequence = htons(ping_sequence_number);
33 ping_sequence_number++;
35 payload = (char *)(icmp + 1);
36 ts = get_time_ns();
37 memcpy(payload, &ts, sizeof(ts));
38 payload[8] = 0xab;
39 payload[9] = 0xcd;
40 return net_icmp_send(ping_con, 9);
43 void ping_handler(char *pkt, unsigned len)
45 IPaddr_t tmp;
46 struct iphdr *ip = net_eth_to_iphdr(pkt);
48 tmp = net_read_ip((void *)&ip->saddr);
49 if (tmp != net_ping_ip)
50 return;
52 ping_state = PING_STATE_SUCCESS;
55 int do_ping(struct command *cmdtp, int argc, char *argv[])
57 int ret;
58 uint64_t ping_start = 0;
60 if (argc < 2)
61 return COMMAND_ERROR_USAGE;
63 net_ping_ip = resolv(argv[1]);
64 if (!net_ping_ip) {
65 printf("unknown host %s\n", argv[1]);
66 return 1;
69 ping_con = net_icmp_new(net_ping_ip, ping_handler);
70 if (IS_ERR(ping_con)) {
71 ret = PTR_ERR(ping_con);
72 goto out;
75 ping_start = get_time_ns();
76 ret = ping_send();
77 if (ret)
78 goto out_unreg;
80 ping_state = PING_STATE_INIT;
81 ping_sequence_number = 0;
83 while (ping_state == PING_STATE_INIT) {
84 if (ctrlc()) {
85 ret = -EINTR;
86 break;
89 net_poll();
91 if (is_timeout(ping_start, 10 * SECOND)) {
92 ping_start = get_time_ns();
93 ret = ping_send();
94 if (ret)
95 goto out_unreg;
99 if (!ret)
100 printf("host %s is alive\n", argv[1]);
102 out_unreg:
103 net_unregister(ping_con);
104 out:
105 if (ret)
106 printf("ping failed: %s\n", strerror(-ret));
107 return ping_state == PING_STATE_SUCCESS ? 0 : 1;
110 BAREBOX_CMD_START(ping)
111 .cmd = do_ping,
112 .usage = "ping <destination>",
113 BAREBOX_CMD_END