#include <const.h>
#include <ctype.h>
#include <errno.h>
#include <arch/mem.h>
#include <kernel/clock.h>
#include <kernel/console.h>
#include <kernel/kmalloc.h>
#include <net/arp.h>
#include <net/eth.h>
#include <net/icmp.h>
#include <net/network.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/ip.h>
Go to the source code of this file.
Functions | |||||||||||
uint16_t | ip_checksum (const void *buf, size_t hdr_len) | ||||||||||
Calculate the IP header checksum.
| |||||||||||
void | dump_ip_packet (ip_t *packet) | ||||||||||
Dump an IP packet to the standard output.
| |||||||||||
void | set_host_ip_net (in_addr_t ip, in_addr_t netmask) | ||||||||||
Set the IP and netmask for this host.
| |||||||||||
in_addr_t | get_host_ip () | ||||||||||
Get the IP address of this host.
| |||||||||||
in_addr_t | get_host_netmask () | ||||||||||
Get the netmask of this host.
| |||||||||||
in_addr_t | get_host_bcast () | ||||||||||
Get the broadcast address of the local network.
| |||||||||||
int | inet_aton (const char *cp, in_addr_t *inp) | ||||||||||
Converts an internet IP addres from number-and-dot string notation into binary data network byte order.
| |||||||||||
void | to_ip_layer (ip_t *packet) | ||||||||||
Process an IP packet received from the ethernet layer.
| |||||||||||
int | send_ip_packet (uint32_t ip_to, const void *data, size_t len, uint8_t ttl, uint8_t proto) | ||||||||||
Send an IP packet to the ethernet layer.
| |||||||||||
int | recv_ip_packet (ip_t *buf, size_t len) | ||||||||||
Receive an IP packet.
| |||||||||||
Variables | |||||||||||
in_addr_t | host_ip | ||||||||||
This is the IP address of this host (expressed in network format). | |||||||||||
in_addr_t | host_netmask | ||||||||||
This is the IP netmask of this host (expressed in network format). |
Definition in file ip.c.
|
Dump an IP packet to the standard output.
Definition at line 53 of file ip.c.
00054 { 00055 int i; 00056 uint8_t *data = ((void *)packet + (packet->ip_hdr_len * sizeof(uint32_t))); 00057 00058 // Dump the IP header // 00059 kprintf( "\n\r(ip header)" 00060 "\n\rhdr_len:%u dwords, ip_version:%u, ToS:%#04X, tot_len:%u" 00061 "\n\rid:%#010x, off:%#010x, TTL:%u, proto:%#04X, ip_chk:%#06X" 00062 "\n\rip_src:%u.%u.%u.%u, ip_dst:%u.%u.%u.%u", 00063 packet->ip_hdr_len, packet->ip_version, packet->ip_tos, 00064 ntohs(packet->ip_len), ntohs(packet->ip_id), ntohs(packet->ip_off), 00065 packet->ip_ttl, packet->ip_proto, 00066 ntohs(packet->ip_chk), 00067 00068 IP_A(ntohl(packet->ip_src)), IP_B(ntohl(packet->ip_src)), 00069 IP_C(ntohl(packet->ip_src)), IP_D(ntohl(packet->ip_src)), 00070 00071 IP_A(ntohl(packet->ip_dst)), IP_B(ntohl(packet->ip_dst)), 00072 IP_C(ntohl(packet->ip_dst)), IP_D(ntohl(packet->ip_dst)) 00073 ); 00074 // Dump the IP data section // 00075 kprintf("\n\r(ip data)\n\r"); 00076 for (i=0; i<(ntohs(packet->ip_len) - packet->ip_hdr_len * sizeof(uint32_t)); i++) 00077 if ( isprint(data[i]) ) 00078 kputchar(data[i]); 00079 else 00080 kputchar('.'); 00081 } |
|
Get the broadcast address of the local network.
Definition at line 117 of file ip.c.
00118 { 00119 return( (~host_netmask) | (host_ip & host_netmask) ); 00120 } |
|
Get the IP address of this host.
Definition at line 100 of file ip.c.
00101 {
00102 return( host_ip );
00103 }
|
|
Get the netmask of this host.
Definition at line 108 of file ip.c.
00109 {
00110 return( host_netmask );
00111 }
|
|
Converts an internet IP addres from number-and-dot string notation into binary data network byte order.
Definition at line 131 of file ip.c.
00132 { 00133 static const in_addr_t max[4] = { 0xFFFFFFFF, 0xFFFFFF, 0xFFFF, 0xFF }; 00134 in_addr_t val; 00135 char c; 00136 union iaddr { 00137 uint8_t bytes[4]; 00138 uint32_t word; 00139 } res; 00140 uint8_t *pp = res.bytes; 00141 int digit,base; 00142 00143 res.word = 0; 00144 00145 c = *cp; 00146 for (;;) { 00147 // Collect number up to '.' // 00148 // Values are specified as for C: // 00149 // 0x=hex, 0=octal, isdigit=decimal. // 00150 if (!isdigit(c)) goto ret_0; 00151 val = 0; base = 10; digit = 0; 00152 for (;;) { 00153 if (isdigit(c)) { 00154 val = (val * base) + (c - '0'); 00155 c = *++cp; 00156 digit = 1; 00157 } else { 00158 break; 00159 } 00160 } 00161 if (c == '.') { 00162 // Internet format: // 00163 // a.b.c.d // 00164 // a.b.c (with c treated as 16 bits) // 00165 // a.b (with b treated as 24 bits) // 00166 if (pp > res.bytes + 2 || val > 0xff) { 00167 goto ret_0; 00168 } 00169 *pp++ = val; 00170 c = *++cp; 00171 } else 00172 break; 00173 } 00174 00175 // Check for trailing characters // 00176 if (c != '\0' && (!isascii(c) || !isspace(c))) { 00177 goto ret_0; 00178 } 00179 00180 // Did we get a valid digit? // 00181 if (!digit) { 00182 goto ret_0; 00183 } 00184 00185 // Check whether the last part is in its limits depending on // 00186 // the number of parts in total. // 00187 if (val > max[pp - res.bytes]) { 00188 goto ret_0; 00189 } 00190 00191 if (inp != NULL) { 00192 *inp = res.word | htonl (val); 00193 } 00194 00195 return (1); 00196 ret_0: 00197 return (0); 00198 } |
|
Calculate the IP header checksum.
Definition at line 31 of file ip.c.
00032 { 00033 unsigned long sum = 0; 00034 const uint16_t *ip1; 00035 00036 ip1 = buf; 00037 while (hdr_len > 1) 00038 { 00039 sum += *ip1++; 00040 if (sum & 0x80000000) 00041 sum = (sum & 0xFFFF) + (sum >> 16); 00042 hdr_len -= 2; 00043 } 00044 00045 while (sum >> 16) 00046 sum = (sum & 0xFFFF) + (sum >> 16); 00047 00048 return(~sum); 00049 } |
|
Receive an IP packet.
Definition at line 347 of file ip.c.
00348 { 00349 return( -ENOPROTOOPT ); 00350 } |
|
Send an IP packet to the ethernet layer.
Definition at line 273 of file ip.c.
00274 { 00275 uint8_t eth_to[ETH_ADDR_LEN]; 00276 size_t packet_len = len + sizeof(ip_t); 00277 ip_t *packet; 00278 int tot_len; 00279 00280 if (packet_len > IP_FRAME_LEN) 00281 return(-EMSGSIZE); 00282 00283 packet = kmalloc(packet_len); 00284 if (packet == NULL) 00285 return(-ENOMEM); 00286 00287 // Create the IP header // 00288 packet->ip_version = IP_V4; 00289 packet->ip_hdr_len = sizeof(ip_t) / sizeof(dword); 00290 packet->ip_tos = 0; 00291 packet->ip_len = htons(packet_len); 00292 packet->ip_id = htons(0xDEAD); // :-) // 00293 packet->ip_off = htons(IP_FLAG_DF | 0); 00294 packet->ip_ttl = ttl; 00295 packet->ip_proto = proto; 00296 packet->ip_chk = 0; 00297 packet->ip_dst = ip_to; 00298 packet->ip_src = get_host_ip(); 00299 packet->ip_chk = ip_checksum(packet, sizeof(ip_t)); 00300 00301 // Copy the data into the packet // 00302 memcpy(packet + 1, data, len); 00303 00304 // Translate the IP address into ethernet address // 00305 // using the ARP protocol. // 00306 if ( !arp_ip_to_eth(eth_to, ip_to) ) 00307 { 00308 #ifdef DEBUG 00309 kprintf("\n\rARP fails!"); 00310 #endif 00311 // The ethernet address was not found! // 00312 return(-ENETUNREACH); 00313 } 00314 #ifdef DEBUG 00315 kprintf("\n\rsending eth packet to %02x:%02x:%02x:%02x:%02x:%02x...", 00316 eth_to[0], eth_to[1], eth_to[2], eth_to[3], eth_to[4], eth_to[5] 00317 ); 00318 #endif 00319 00320 // Go to the ethernet layer... // 00321 tot_len = send_eth_packet(eth_to, packet, packet_len, htons(ETH_FRAME_IP)); 00322 00323 #ifdef DEBUG 00324 kprintf("\n\r%u bytes sent from ethernet layer", tot_len); 00325 #endif 00326 00327 // Free the memory of the packet // 00328 kfree(packet); 00329 00330 if ( tot_len < 0 ) 00331 // Something wrong from at the ethernet layer // 00332 return(tot_len); 00333 00334 // Well done! // 00335 return(packet_len); 00336 } |
|
Set the IP and netmask for this host.
Definition at line 91 of file ip.c.
00092 { 00093 host_ip = ip; 00094 host_netmask = netmask; 00095 } |
|
Process an IP packet received from the ethernet layer.
Definition at line 202 of file ip.c.
00203 { 00204 // Calculate the header checksum // 00205 if ( ip_checksum(packet, packet->ip_hdr_len * sizeof(dword)) ) 00206 { 00207 kprintf("\n\rip header checksum error!!!"); 00208 return; 00209 } 00210 00211 //--------------------------------------------------------------// 00212 // Check if we can receive the packet or not // 00213 if ( 00214 (packet->ip_dst!=get_host_ip()) && 00215 (packet->ip_dst!=get_host_bcast()) && 00216 (packet->ip_dst!=INADDR_BROADCAST) 00217 ) 00218 return; 00219 //--------------------------------------------------------------// 00220 00221 // Identify the right protocol // 00222 switch( packet->ip_proto ) 00223 { 00224 case IPPROTO_ICMP: 00225 // ICMP (Internet Control Message Protocol) // 00226 to_icmp_layer(packet); 00227 break; 00228 00229 case IPPROTO_IGMP: 00230 // Internet Group Message Protocol) // 00231 kprintf("\n\rIGMP protocol not yet implemented!"); 00232 dump_ip_packet(packet); 00233 break; 00234 00235 case IPPROTO_TCP: 00236 // TCP (Transmition Control Protocol) // 00237 to_tcp_layer( 00238 ((void *)packet + (packet->ip_hdr_len * sizeof(uint32_t))), 00239 (ntohs(packet->ip_len) - (packet->ip_hdr_len * sizeof(uint32_t))), 00240 packet->ip_src, 00241 packet->ip_dst 00242 ); 00243 // dump_ip_packet(packet); 00244 break; 00245 00246 case IPPROTO_UDP: 00247 // UDP (User Datagram Protocol) // 00248 to_udp_layer( 00249 ((void *)packet + (packet->ip_hdr_len * sizeof(uint32_t))), 00250 packet->ip_src, 00251 packet->ip_dst 00252 ); 00253 break; 00254 00255 default: 00256 kprintf("\n\rUnknown IP protocol!"); 00257 dump_ip_packet(packet); 00258 break; 00259 } 00260 } |
|
This is the IP address of this host (expressed in network format).
|
|
This is the IP netmask of this host (expressed in network format).
|