Data Structures | |||||||||||
struct | ip | ||||||||||
The IP packet structure. More... | |||||||||||
Defines | |||||||||||
#define | IP_ADDRESS(a, b, c, d) ((a) | (b) << 8 | (c) << 16 | (d) << 24) | ||||||||||
Create an IP address in the binary network format from the notation "a.b.c.d". | |||||||||||
#define | IP_A(ip) ((uint8_t) ((ip) >> 24)) | ||||||||||
Get the 1st most significant byte of a host-format IP address. | |||||||||||
#define | IP_B(ip) ((uint8_t) ((ip) >> 16)) | ||||||||||
Get the 2nd most significant byte of a host-format IP address. | |||||||||||
#define | IP_C(ip) ((uint8_t) ((ip) >> 8)) | ||||||||||
Get the 3rd most significant byte of a host-format IP address. | |||||||||||
#define | IP_D(ip) ((uint8_t) ((ip) >> 0)) | ||||||||||
Get the less significant byte of a host-format IP address. | |||||||||||
#define | INADDR_LOOPBACK IP_ADDRESS(127, 0, 0, 1) | ||||||||||
Loopback IP address. | |||||||||||
#define | INADDR_ANY IP_ADDRESS(0, 0, 0, 0) | ||||||||||
Null IP address. | |||||||||||
#define | INADDR_BROADCAST IP_ADDRESS(255, 255, 255, 255) | ||||||||||
Broadcast IP address. | |||||||||||
Typedefs | |||||||||||
typedef uint32_t | in_addr_t | ||||||||||
IP address type (in binary network format). | |||||||||||
typedef ip | ip_t | ||||||||||
The IP packet structure. | |||||||||||
Functions | |||||||||||
uint16_t | ip_checksum (const void *buf, size_t hdr_len) | ||||||||||
Calculate the IP header checksum.
| |||||||||||
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.
| |||||||||||
void | to_ip_layer (ip_t *packet) | ||||||||||
Process an IP packet received from the ethernet layer.
| |||||||||||
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.
| |||||||||||
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.
|
|
Null IP address.
|
|
Broadcast IP address.
|
|
Loopback IP address.
|
|
Get the 1st most significant byte of a host-format IP address.
|
|
Create an IP address in the binary network format from the notation "a.b.c.d".
|
|
Get the 2nd most significant byte of a host-format IP address.
|
|
Get the 3rd most significant byte of a host-format IP address.
|
|
Get the less significant byte of a host-format IP address.
|
|
IP address type (in binary network format).
|
|
The IP packet structure.
|
|
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 } |
|
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 } |