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 }
|
1.2.18