#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).
|
1.2.18