#include <const.h>
#include <errno.h>
#include <stdlib.h>
#include <arch/i386.h>
#include <arch/mem.h>
#include <kernel/clock.h>
#include <kernel/console.h>
#include <kernel/kmalloc.h>
#include <net/ip.h>
#include <net/network.h>
#include <net/icmp.h>
Go to the source code of this file.
Functions | |||||||||
| void | to_icmp_layer (ip_t *packet) | ||||||||
Process an ICMP packet received from the IP layer.
| |||||||||
| int | send_icmp_packet (in_addr_t ip_to, uint8_t message, uint8_t *data, size_t len) | ||||||||
Send an ICMP packet.
| |||||||||
| int | recv_icmp_packet (icmp_t *buf, size_t len) | ||||||||
Receive an ICMP packet.
| |||||||||
| void | ping (char *ip_dot) | ||||||||
Send a ping to a destination host
| |||||||||
Definition in file icmp.c.
|
|
Send a ping to a destination host
Definition at line 205 of file icmp.c.
00206 {
00207 struct
00208 {
00209 uint16_t ping_id;
00210 uint16_t ping_seq;
00211 uint8_t data[128 - sizeof(ip_t) + sizeof(icmp_ping_t)];
00212 } packet;
00213 int tot_sent, i;
00214 in_addr_t ip, host_ip = ntohl( get_host_ip() );
00215
00216 // Translate the IP address from numbers-and-dot notation into //
00217 // binary network order byte number. //
00218 if ( !inet_aton(ip_dot, &ip) )
00219 {
00220 kprintf("\n\rUsage: ping <IP address>\n\r");
00221 return;
00222 }
00223
00224 // Fill the packet //
00225 for (i = 0; i < _countof(packet.data); i++)
00226 packet.data[i] = 'a' + i % 26;
00227
00228 // Fill the header of the ping //
00229 packet.ping_id = 3636;
00230 packet.ping_seq = 0;
00231
00232 kprintf("\n\rPING: %u(%u) bytes %u.%u.%u.%u from %u.%u.%u.%u",
00233
00234 sizeof(packet)-sizeof(icmp_ping_t),
00235 sizeof(packet),
00236
00237 IP_A(ntohl(ip)), IP_B(ntohl(ip)), IP_C(ntohl(ip)), IP_D(ntohl(ip)),
00238 IP_A(host_ip), IP_B(host_ip), IP_C(host_ip), IP_D(host_ip)
00239 );
00240
00241 tot_sent = send_icmp_packet(
00242 ip,
00243 ICMP_ECHO,
00244 (uint8_t *)&packet,
00245 sizeof(packet)
00246 );
00247 if ( tot_sent < 0 )
00248 {
00249 switch( tot_sent )
00250 {
00251 case (-ENETUNREACH):
00252 kprintf("\n\rHost unreachable!");
00253 break;
00254
00255 kprintf("\n\rCannot send data to ip layer!");
00256 break;
00257 }
00258 kprintf("\n\r");
00259 return;
00260 }
00261 // Wait 500ms for the answer //
00262 delay(500);
00263 // Well done! //
00264 kprintf("\n\r");
00265 }
|
|
||||||||||||
|
Receive an ICMP packet.
Definition at line 197 of file icmp.c.
00198 {
00199 return( -ENOPROTOOPT );
00200 }
|
|
||||||||||||||||||||
|
Send an ICMP packet.
Definition at line 149 of file icmp.c.
00150 {
00151 icmp_t *packet;
00152 int tot_len;
00153
00154 packet = kmalloc(len + sizeof(icmp_t));
00155 if (packet == NULL)
00156 // Out of memory! //
00157 return(-ENOMEM);
00158
00159 // Create the ICMP header //
00160 packet->icmp_type = message;
00161 packet->icmp_code = 0;
00162 packet->icmp_chk = 0;
00163
00164 // Copy the data into the packet //
00165 memcpy(packet + 1, data, len);
00166 len += sizeof(icmp_t);
00167
00168 // Calculate the checksum of the ICMP message //
00169 packet->icmp_chk = ip_checksum(packet, len);
00170
00171 // Send the IP packet //
00172 tot_len = send_ip_packet(ip_to, packet, len, IP_DEFAULT_TTL, IPPROTO_ICMP);
00173
00174 #ifdef DEBUG
00175 kprintf("\n\r%u bytes sent from ip layer", tot_len);
00176 #endif
00177
00178 // Free the memory of the packet //
00179 kfree(packet);
00180
00181 if ( tot_len < 0 )
00182 // Something wrong from at the IP layer //
00183 return(tot_len);
00184
00185 return(len);
00186 }
|
|
|
Process an ICMP packet received from the IP layer.
Definition at line 26 of file icmp.c.
00027 {
00028 int size = ntohs(packet->ip_len) - (packet->ip_hdr_len)*sizeof(uint32_t);
00029 icmp_t *icmp_packet = (icmp_t *)((void *)packet + (packet->ip_hdr_len)*sizeof(uint32_t));
00030 #if 0
00031 kprintf( "\n\ricmp_type:%02X, icmp_code:%02X, icmp_chk:%04X"
00032 "\n\rping_id:%04X, ping_seq:%u"
00033 "\n\rping %u bytes",
00034 icmp_packet->icmp_type,
00035 icmp_packet->icmp_code,
00036 icmp_packet->icmp_chk,
00037 ((icmp_ping_t *)icmp_packet)->ping_id,
00038 ((icmp_ping_t *)icmp_packet)->ping_seq,
00039 size-sizeof(icmp_ping_t)
00040 );
00041 kprintf( "\n\rlocal checksum = %04X", ip_checksum(icmp_packet, size) );
00042 #endif
00043 // Calculate the header checksum //
00044 if ( ip_checksum(icmp_packet, size) )
00045 {
00046 kprintf("\n\ricmp: header checksum error!!!");
00047 return;
00048 }
00049 // Identify the message type //
00050 switch( icmp_packet->icmp_type )
00051 {
00052 case ICMP_ECHO:
00053 // Print the echo request to stdout //
00054 #ifdef ICMP_DEBUG
00055 kprintf( "\n\recho request %u(%u) bytes "
00056 "%u.%u.%u.%u > %u.%u.%u.%u id=%u seq=%u ttl=%u",
00057 size,
00058 size - sizeof(icmp_ping_t),
00059
00060 IP_A(ntohl(packet->ip_src)), IP_B(ntohl(packet->ip_src)),
00061 IP_C(ntohl(packet->ip_src)), IP_D(ntohl(packet->ip_src)),
00062
00063 IP_A(ntohl(packet->ip_dst)), IP_B(ntohl(packet->ip_dst)),
00064 IP_C(ntohl(packet->ip_dst)), IP_D(ntohl(packet->ip_dst)),
00065
00066 ((icmp_ping_t *)icmp_packet)->ping_id,
00067 ((icmp_ping_t *)icmp_packet)->ping_seq,
00068 packet->ip_ttl
00069 );
00070 #endif
00071 // Check if we must send the echo reply message //
00072 if (
00073 (packet->ip_dst==get_host_ip()) ||
00074 (packet->ip_dst==get_host_bcast()) ||
00075 (packet->ip_dst==INADDR_BROADCAST)
00076 )
00077 {
00078 #ifdef ICMP_DEBUG
00079 // Notify that we're sending the reply //
00080 kprintf( "\n\recho reply %u(%u) bytes "
00081 "%u.%u.%u.%u > %u.%u.%u.%u id=%u seq=%u ttl=%u",
00082 size,
00083 size - sizeof(icmp_ping_t),
00084
00085 IP_A(ntohl(get_host_ip())), IP_B(ntohl(get_host_ip())),
00086 IP_C(ntohl(get_host_ip())), IP_D(ntohl(get_host_ip())),
00087
00088 IP_A(ntohl(packet->ip_src)), IP_B(ntohl(packet->ip_src)),
00089 IP_C(ntohl(packet->ip_src)), IP_D(ntohl(packet->ip_src)),
00090
00091 ((icmp_ping_t *)icmp_packet)->ping_id,
00092 ((icmp_ping_t *)icmp_packet)->ping_seq,
00093 IP_DEFAULT_TTL
00094 );
00095 #endif
00096 // Send the echo reply //
00097 send_icmp_packet(
00098 packet->ip_src,
00099 ICMP_ECHOREPLY,
00100 (void *)icmp_packet + sizeof(icmp_t),
00101 size-sizeof(icmp_t)
00102 );
00103 }
00104 break;
00105
00106 case ICMP_ECHOREPLY:
00107 // Show the echo reply message //
00108 kprintf("\n\recho reply %u.%u.%u.%u > %u.%u.%u.%u id=%u seq=%u ttl=%u",
00109
00110 IP_A(ntohl(packet->ip_src)), IP_B(ntohl(packet->ip_src)),
00111 IP_C(ntohl(packet->ip_src)), IP_D(ntohl(packet->ip_src)),
00112
00113 IP_A(ntohl(packet->ip_dst)), IP_B(ntohl(packet->ip_dst)),
00114 IP_C(ntohl(packet->ip_dst)), IP_D(ntohl(packet->ip_dst)),
00115
00116 ((icmp_ping_t *)icmp_packet)->ping_id,
00117 ((icmp_ping_t *)icmp_packet)->ping_seq,
00118 packet->ip_ttl
00119 );
00120 // TODO: //
00121 // Insert the message into the icmp recv buffer //
00122 break;
00123
00124 default:
00125 kprintf("\n\ricmp: ??? %u.%u.%u.%u > %u.%u.%u.%u id=%u seq=%u ttl=%u",
00126
00127 IP_A(ntohl(packet->ip_src)), IP_B(ntohl(packet->ip_src)),
00128 IP_C(ntohl(packet->ip_src)), IP_D(ntohl(packet->ip_src)),
00129
00130 IP_A(ntohl(packet->ip_dst)), IP_B(ntohl(packet->ip_dst)),
00131 IP_C(ntohl(packet->ip_dst)), IP_D(ntohl(packet->ip_dst)),
00132
00133 ((icmp_ping_t *)icmp_packet)->ping_id,
00134 ((icmp_ping_t *)icmp_packet)->ping_seq,
00135 packet->ip_ttl
00136 );
00137 break;
00138 }
00139 }
|
1.2.18