Data Structures | |||||||||
struct | icmp | ||||||||
ICMP packet structure. More... | |||||||||
struct | icmp_ping | ||||||||
ICMP::PING packet structure. More... | |||||||||
Defines | |||||||||
#define | ICMP_ECHOREPLY 0 | ||||||||
Echo Reply. | |||||||||
#define | ICMP_DEST_UNREACH 3 | ||||||||
Destination Unreachable. | |||||||||
#define | ICMP_SOURCE_QUENCH 4 | ||||||||
Source Quench. | |||||||||
#define | ICMP_REDIRECT 5 | ||||||||
Redirect (change route). | |||||||||
#define | ICMP_ECHO 8 | ||||||||
Echo Request. | |||||||||
#define | ICMP_TIME_EXCEEDED 11 | ||||||||
Time Exceeded. | |||||||||
#define | ICMP_PARAMETERPROB 12 | ||||||||
Parameter Problem. | |||||||||
#define | ICMP_TIMESTAMP 13 | ||||||||
Timestamp Request. | |||||||||
#define | ICMP_TIMESTAMPREPLY 14 | ||||||||
Timestamp Reply. | |||||||||
#define | ICMP_INFO_REQUEST 15 | ||||||||
Information Request. | |||||||||
#define | ICMP_INFO_REPLY 16 | ||||||||
Information Reply. | |||||||||
#define | ICMP_ADDRESS 17 | ||||||||
Address Mask Request. | |||||||||
#define | ICMP_ADDRESSREPLY 18 | ||||||||
Address Mask Reply. | |||||||||
#define | ICMP_NET_UNREACH 0 | ||||||||
Network Unreachable. | |||||||||
#define | ICMP_HOST_UNREACH 1 | ||||||||
Host Unreachable. | |||||||||
#define | ICMP_PROT_UNREACH 2 | ||||||||
Protocol Unreachable. | |||||||||
#define | ICMP_PORT_UNREACH 3 | ||||||||
Port Unreachable. | |||||||||
#define | ICMP_FRAG_NEEDED 4 | ||||||||
Fragmentation Needed/DF set. | |||||||||
#define | ICMP_SR_FAILED 5 | ||||||||
Source Route failed. | |||||||||
#define | ICMP_NET_UNKNOWN 6 | ||||||||
Network Unknown. | |||||||||
#define | ICMP_HOST_UNKNOWN 7 | ||||||||
Host Unknown. | |||||||||
#define | ICMP_HOST_ISOLATED 8 | ||||||||
Host isolated. | |||||||||
#define | ICMP_NET_ANO 9 | ||||||||
#define | ICMP_HOST_ANO 10 | ||||||||
#define | ICMP_NET_UNR_TOS 11 | ||||||||
#define | ICMP_HOST_UNR_TOS 12 | ||||||||
#define | ICMP_PKT_FILTERED 13 | ||||||||
Packet Filtered. | |||||||||
#define | ICMP_PREC_VIOLATION 14 | ||||||||
Precedence Violation. | |||||||||
#define | ICMP_PREC_CUTOFF 15 | ||||||||
Precedence Cut Off. | |||||||||
#define | ICMP_REDIR_NET 0 | ||||||||
Redirect Net. | |||||||||
#define | ICMP_REDIR_HOST 1 | ||||||||
Redirect Host. | |||||||||
#define | ICMP_REDIR_NETTOS 2 | ||||||||
Redirect Net for TOS. | |||||||||
#define | ICMP_REDIR_HOSTTOS 3 | ||||||||
Redirect Host for TOS. | |||||||||
#define | ICMP_EXC_TTL 0 | ||||||||
TTL cound exceeded. | |||||||||
#define | ICMP_EXC_FRAGTIME 1 | ||||||||
Fragment Reass Time exceeeded. | |||||||||
Typedefs | |||||||||
typedef icmp | icmp_t | ||||||||
ICMP packet structure. | |||||||||
typedef icmp_ping | icmp_ping_t | ||||||||
ICMP::PING packet structure. | |||||||||
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.
| |||||||||
void | ping (char *ip_dot) | ||||||||
Send a ping to a destination host
|
|
Address Mask Request.
|
|
Address Mask Reply.
|
|
Destination Unreachable.
|
|
Echo Request.
|
|
Echo Reply.
|
|
Fragment Reass Time exceeeded.
|
|
TTL cound exceeded.
|
|
Fragmentation Needed/DF set.
|
|
|
|
Host isolated.
|
|
Host Unknown.
|
|
|
|
Host Unreachable.
|
|
Information Reply.
|
|
Information Request.
|
|
|
|
Network Unknown.
|
|
|
|
Network Unreachable.
|
|
Parameter Problem.
|
|
Packet Filtered.
|
|
Port Unreachable.
|
|
Precedence Cut Off.
|
|
Precedence Violation.
|
|
Protocol Unreachable.
|
|
Redirect Host.
|
|
Redirect Host for TOS.
|
|
Redirect Net.
|
|
Redirect Net for TOS.
|
|
Redirect (change route).
|
|
Source Quench.
|
|
Source Route failed.
|
|
Time Exceeded.
|
|
Timestamp Request.
|
|
Timestamp Reply.
|
|
ICMP::PING packet structure.
|
|
ICMP packet structure.
|
|
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 } |
|
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 } |