Add missing includes
[contiki-2.x.git] / apps / shell / shell-ping.c
blobf2f15adc4eaec338434bedfa5ade030a06e19c6f
1 /*
2 * Copyright (c) 2004, Adam Dunkels.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * This file is part of the Contiki operating system.
31 * Author: Adam Dunkels <adam@sics.se>
33 * $Id: shell-ping.c,v 1.5 2010/10/19 18:29:03 adamdunkels Exp $
36 #include <string.h>
37 #include <stddef.h>
39 #include "contiki.h"
40 #include "shell.h"
41 #include "contiki-net.h"
43 /*---------------------------------------------------------------------------*/
44 PROCESS(shell_ping_process, "ping");
45 SHELL_COMMAND(ping_command,
46 "ping",
47 "ping <host>: ping an IP host",
48 &shell_ping_process);
49 /*---------------------------------------------------------------------------*/
51 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
52 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
53 #define PING_DATALEN 16
55 #define ICMP_ECHO_REPLY 0
56 #define ICMP_ECHO 8
58 #define ICMP6_ECHO_REPLY 129
59 #define ICMP6_ECHO 128
61 static uip_ipaddr_t remoteaddr;
62 static unsigned char running;
63 /*---------------------------------------------------------------------------*/
64 static void
65 send_ping(uip_ipaddr_t *dest_addr)
66 #if UIP_CONF_IPV6
68 static uint16_t count;
69 UIP_IP_BUF->vtc = 0x60;
70 UIP_IP_BUF->tcflow = 1;
71 UIP_IP_BUF->flow = 0;
72 UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
73 UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
74 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest_addr);
75 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
77 UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST;
78 UIP_ICMP_BUF->icode = 0;
79 /* set identifier and sequence number to 0 */
80 memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
81 /* put one byte of data */
82 memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN,
83 count, PING_DATALEN);
84 count++;
86 uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN +
87 UIP_IPH_LEN + PING_DATALEN;
88 UIP_IP_BUF->len[0] = (u8_t)((uip_len - 40) >> 8);
89 UIP_IP_BUF->len[1] = (u8_t)((uip_len - 40) & 0x00ff);
91 UIP_ICMP_BUF->icmpchksum = 0;
92 UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
94 tcpip_ipv6_output();
96 #else /* UIP_CONF_IPV6 */
98 static uint16_t ipid = 0;
99 static uint16_t seqno = 0;
101 UIP_IP_BUF->vhl = 0x45;
102 UIP_IP_BUF->tos = 0;
103 UIP_IP_BUF->ipoffset[0] = UIP_IP_BUF->ipoffset[1] = 0;
104 ++ipid;
105 UIP_IP_BUF->ipid[0] = ipid >> 8;
106 UIP_IP_BUF->ipid[1] = ipid & 0xff;
107 UIP_IP_BUF->proto = UIP_PROTO_ICMP;
108 UIP_IP_BUF->ttl = UIP_TTL;
110 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest_addr);
111 uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &uip_hostaddr);
113 UIP_ICMP_BUF->type = ICMP_ECHO;
114 UIP_ICMP_BUF->icode = 0;
115 UIP_ICMP_BUF->id = 0xadad;
116 UIP_ICMP_BUF->seqno = uip_htons(seqno++);
118 uip_len = UIP_ICMPH_LEN + UIP_IPH_LEN + PING_DATALEN;
119 UIP_IP_BUF->len[0] = (u8_t)((uip_len) >> 8);
120 UIP_IP_BUF->len[1] = (u8_t)((uip_len) & 0x00ff);
122 UIP_ICMP_BUF->icmpchksum = 0;
123 UIP_ICMP_BUF->icmpchksum = ~uip_chksum((u16_t *)&(UIP_ICMP_BUF->type),
124 UIP_ICMPH_LEN + PING_DATALEN);
126 /* Calculate IP checksum. */
127 UIP_IP_BUF->ipchksum = 0;
128 UIP_IP_BUF->ipchksum = ~(uip_ipchksum());
130 tcpip_output();
132 #endif /* UIP_CONF_IPV6 */
133 /*---------------------------------------------------------------------------*/
134 PROCESS_THREAD(shell_ping_process, ev, data)
136 struct shell_input *input;
138 PROCESS_BEGIN();
140 if(data == NULL) {
141 shell_output_str(&ping_command,
142 "ping <server>: server as address", "");
143 PROCESS_EXIT();
145 uiplib_ipaddrconv(data, &remoteaddr);
147 send_ping(&remoteaddr);
149 running = 1;
151 while(running) {
152 static struct etimer e;
155 etimer_set(&e, CLOCK_SECOND * 10);
157 PROCESS_WAIT_EVENT();
159 if(etimer_expired(&e)) {
160 PROCESS_EXIT();
163 if(ev == shell_event_input) {
164 input = data;
165 if(input->len1 + input->len2 == 0) {
166 PROCESS_EXIT();
168 #if 0
169 } else if(ev == resolv_event_found) {
170 /* Either found a hostname, or not. */
171 if((char *)data != NULL &&
172 resolv_lookup((char *)data) != NULL) {
173 uip_ipaddr_copy(serveraddr, ipaddr);
174 telnet_connect(&s, server, serveraddr, nick);
175 } else {
176 shell_output_str(&ping_command, "Host not found.", "");
178 #endif /* 0 */
182 PROCESS_END();
184 /*---------------------------------------------------------------------------*/
185 void
186 shell_ping_init(void)
188 shell_register_command(&ping_command);
190 /*---------------------------------------------------------------------------*/