2 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
27 * This file is part of the lwIP TCP/IP stack.
29 * Author: Adam Dunkels <adam@sics.se>
34 /*-----------------------------------------------------------------------------------*/
37 * This is the code for the IP layer.
40 /*-----------------------------------------------------------------------------------*/
42 #include "lwip/debug.h"
47 #include "lwip/ip_frag.h"
48 #include "lwip/inet.h"
49 #include "lwip/netif.h"
50 #include "lwip/icmp.h"
54 #include "lwip/stats.h"
56 #include "arch/perf.h"
58 #include "lwip/snmp.h"
60 #include "lwip/dhcp.h"
61 #endif /* LWIP_DHCP */
63 /*-----------------------------------------------------------------------------------*/
66 * Initializes the IP layer.
68 /*-----------------------------------------------------------------------------------*/
73 /*-----------------------------------------------------------------------------------*/
76 * An experimental feature that will be changed in future versions. Do
77 * not depend on it yet...
79 /*-----------------------------------------------------------------------------------*/
82 ip_lookup(void *header, struct netif *inp)
89 if(IPH_V(iphdr) != 4) {
93 /* Immediately accept/decline packets that are fragments or has
95 #if IP_REASSEMBLY == 0
96 /* if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
99 #endif /* IP_REASSEMBLY == 0 */
102 if(IPH_HL(iphdr) != 5) {
105 #endif /* IP_OPTIONS == 0 */
107 switch(IPH_PROTO(iphdr)) {
110 return udp_lookup(iphdr, inp);
111 #endif /* LWIP_UDP */
115 #endif /* LWIP_TCP */
122 #endif /* LWIP_DEBUG */
123 /*-----------------------------------------------------------------------------------*/
126 * Finds the appropriate network interface for a given IP address. It
127 * searches the list of network interfaces linearly. A match is found
128 * if the masked IP address of the network interface equals the masked
129 * IP address given to the function.
131 /*-----------------------------------------------------------------------------------*/
133 ip_route(struct ip_addr *dest)
137 /* iterate through netifs */
138 for(netif = netif_list; netif != NULL; netif = netif->next) {
139 /* network mask matches? */
140 if(ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
141 /* return netif on which to forward IP packet */
145 /* no matching netif found, use default netif */
146 return netif_default;
149 /*-----------------------------------------------------------------------------------*/
152 * Forwards an IP packet. It finds an appropriate route for the
153 * packet, decrements the TTL value of the packet, adjusts the
154 * checksum and outputs the packet on the appropriate interface.
156 /*-----------------------------------------------------------------------------------*/
158 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
163 /* Find network interface where to forward this IP packet to. */
164 netif = ip_route((struct ip_addr *)&(iphdr->dest));
166 DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",
168 snmp_inc_ipnoroutes();
171 /* Do not forward packets onto the same network interface on which
174 DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
175 snmp_inc_ipnoroutes();
180 IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
181 /* send ICMP if TTL == 0 */
182 if(IPH_TTL(iphdr) == 0) {
183 /* Don't send ICMP messages in response to ICMP messages */
184 if(IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
185 icmp_time_exceeded(p, ICMP_TE_TTL);
186 snmp_inc_icmpouttimeexcds();
191 /* Incrementally update the IP checksum. */
192 if(IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
193 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
195 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
198 DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",
203 ++lwip_stats.ip.xmit;
204 #endif /* IP_STATS */
205 snmp_inc_ipforwdatagrams();
207 PERF_STOP("ip_forward");
208 /* transmit pbuf on chosen interface */
209 netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
211 #endif /* IP_FORWARD */
212 /*-----------------------------------------------------------------------------------*/
215 * This function is called by the network interface device driver when
216 * an IP packet is received. The function does the basic checks of the
217 * IP header such as packet size being at least larger than the header
218 * size etc. If the packet was not destined for us, the packet is
219 * forwarded (using ip_forward). The IP checksum is always checked.
221 * Finally, the packet is sent to the upper layer protocol input function.
223 /*-----------------------------------------------------------------------------------*/
225 ip_input(struct pbuf *p, struct netif *inp) {
226 static struct ip_hdr *iphdr;
227 static struct netif *netif;
228 static u16_t iphdrlen;
231 ++lwip_stats.ip.recv;
232 #endif /* IP_STATS */
233 snmp_inc_ipinreceives();
235 /* identify the IP header */
237 if(IPH_V(iphdr) != 4) {
238 DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number %d\n", IPH_V(iphdr)));
241 #endif /* IP_DEBUG */
245 ++lwip_stats.ip.drop;
246 #endif /* IP_STATS */
247 snmp_inc_ipunknownprotos();
250 /* obtain IP header length in number of 32-bit words */
251 iphdrlen = IPH_HL(iphdr);
252 /* calculate IP header length in bytes */
255 /* header length exceeds first pbuf length? */
256 if(iphdrlen > p->len) {
257 DEBUGF(IP_DEBUG, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
259 /* free (drop) packet pbufs */
262 ++lwip_stats.ip.lenerr;
263 ++lwip_stats.ip.drop;
264 #endif /* IP_STATS */
265 snmp_inc_ipindiscards();
269 /* verify checksum */
270 if(inet_chksum(iphdr, iphdrlen) != 0) {
272 DEBUGF(IP_DEBUG, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
275 #endif /* IP_DEBUG */
278 ++lwip_stats.ip.chkerr;
279 ++lwip_stats.ip.drop;
280 #endif /* IP_STATS */
281 snmp_inc_ipindiscards();
285 /* Trim pbuf. This should have been done at the netif layer,
286 but we'll do it anyway just to be sure that its done. */
287 pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
289 /* is this packet for us? */
290 for(netif = netif_list; netif != NULL; netif = netif->next) {
292 DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",
293 iphdr->dest.addr, netif->ip_addr.addr,
294 iphdr->dest.addr & netif->netmask.addr,
295 netif->ip_addr.addr & netif->netmask.addr,
296 iphdr->dest.addr & ~(netif->netmask.addr)));
298 /* interface configured? */
299 if(!ip_addr_isany(&(netif->ip_addr)))
301 /* unicast to this interface address? */
302 if(ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
303 /* or broadcast matching this interface network address? */
304 (ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) &&
305 ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
306 /* or restricted broadcast? */
307 ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
308 DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
309 netif->name[0], netif->name[1]));
310 /* break out of for loop */
316 /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
317 using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
318 According to RFC 1542 section 3.1.1, referred by RFC 2131). */
320 /* remote port is DHCP server? */
321 if(IPH_PROTO(iphdr) == IP_PROTO_UDP) {
322 DEBUGF(IP_DEBUG, ("ip_input: UDP packet to DHCP client port %u\n",
323 ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
324 if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
325 DEBUGF(IP_DEBUG, ("ip_input: DHCP packet accepted.\n"));
330 #endif /* LWIP_DHCP */
331 /* packet not for us? */
333 /* packet not for us, route or discard */
334 DEBUGF(IP_DEBUG, ("ip_input: packet not for us.\n"));
336 /* non-broadcast packet? */
337 if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) {
338 /* try to forward IP packet on (other) interfaces */
339 ip_forward(p, iphdr, inp);
342 #endif /* IP_FORWARD */
344 snmp_inc_ipindiscards();
351 if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
352 DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
359 #else /* IP_REASSEMBLY */
360 if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
362 DEBUGF(IP_DEBUG, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
363 ntohs(IPH_OFFSET(iphdr))));
365 ++lwip_stats.ip.opterr;
366 ++lwip_stats.ip.drop;
367 #endif /* IP_STATS */
368 snmp_inc_ipunknownprotos();
371 #endif /* IP_REASSEMBLY */
374 if(iphdrlen > IP_HLEN) {
375 DEBUGF(IP_DEBUG, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
378 ++lwip_stats.ip.opterr;
379 ++lwip_stats.ip.drop;
380 #endif /* IP_STATS */
381 snmp_inc_ipunknownprotos();
384 #endif /* IP_OPTIONS == 0 */
386 /* send to upper layers */
388 DEBUGF(IP_DEBUG, ("ip_input: \n"));
390 DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
391 #endif /* IP_DEBUG */
393 switch(IPH_PROTO(iphdr)) {
396 snmp_inc_ipindelivers();
399 #endif /* LWIP_UDP */
402 snmp_inc_ipindelivers();
405 #endif /* LWIP_TCP */
407 snmp_inc_ipindelivers();
411 /* send ICMP destination protocol unreachable unless is was a broadcast */
412 if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) &&
413 !ip_addr_ismulticast(&(iphdr->dest))) {
415 icmp_dest_unreach(p, ICMP_DUR_PROTO);
419 DEBUGF(IP_DEBUG, ("Unsupported transportation protocol %d\n", IPH_PROTO(iphdr)));
422 ++lwip_stats.ip.proterr;
423 ++lwip_stats.ip.drop;
424 #endif /* IP_STATS */
425 snmp_inc_ipunknownprotos();
431 /*-----------------------------------------------------------------------------------*/
434 * Sends an IP packet on a network interface. This function constructs
435 * the IP header and calculates the IP header checksum. If the source
436 * IP address is NULL, the IP address of the outgoing network
437 * interface is filled in as source address.
439 /*-----------------------------------------------------------------------------------*/
441 ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
443 u8_t proto, struct netif *netif)
445 static struct ip_hdr *iphdr;
446 static u16_t ip_id = 0;
448 snmp_inc_ipoutrequests();
450 if(dest != IP_HDRINCL) {
451 if(pbuf_header(p, IP_HLEN)) {
452 DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
456 #endif /* IP_STATS */
457 snmp_inc_ipoutdiscards();
463 IPH_TTL_SET(iphdr, ttl);
464 IPH_PROTO_SET(iphdr, proto);
466 ip_addr_set(&(iphdr->dest), dest);
468 IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
469 IPH_LEN_SET(iphdr, htons(p->tot_len));
470 IPH_OFFSET_SET(iphdr, htons(IP_DF));
471 IPH_ID_SET(iphdr, htons(ip_id));
474 if(ip_addr_isany(src)) {
475 ip_addr_set(&(iphdr->src), &(netif->ip_addr));
477 ip_addr_set(&(iphdr->src), src);
480 IPH_CHKSUM_SET(iphdr, 0);
481 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
484 dest = &(iphdr->dest);
488 /* don't fragment if interface has mtu set to 0 [loopif] */
489 if (netif->mtu && (p->tot_len > netif->mtu))
490 return ip_frag(p,netif,dest);
494 lwip_stats.ip.xmit++;
495 #endif /* IP_STATS */
496 DEBUGF(IP_DEBUG, ("ip_output_if: %c%c ", netif->name[0], netif->name[1]));
499 #endif /* IP_DEBUG */
501 DEBUGF(IP_DEBUG, ("netif->output()"));
503 return netif->output(netif, p, dest);
505 /*-----------------------------------------------------------------------------------*/
508 * Simple interface to ip_output_if. It finds the outgoing network
509 * interface and calls upon ip_output_if to do the actual work.
511 /*-----------------------------------------------------------------------------------*/
513 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
514 u8_t ttl, u8_t proto)
518 if((netif = ip_route(dest)) == NULL) {
519 DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%lx\n", dest->addr));
522 ++lwip_stats.ip.rterr;
523 #endif /* IP_STATS */
524 snmp_inc_ipoutdiscards();
528 return ip_output_if(p, src, dest, ttl, proto, netif);
530 /*-----------------------------------------------------------------------------------*/
533 ip_debug_print(struct pbuf *p)
535 struct ip_hdr *iphdr = p->payload;
538 payload = (u8_t *)iphdr + IP_HLEN;
540 DEBUGF(IP_DEBUG, ("IP header:\n"));
541 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
542 DEBUGF(IP_DEBUG, ("|%2d |%2d | %2u | %4u | (v, hl, tos, len)\n",
546 ntohs(IPH_LEN(iphdr))));
547 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
548 DEBUGF(IP_DEBUG, ("| %5u |%u%u%u| %4u | (id, flags, offset)\n",
549 ntohs(IPH_ID(iphdr)),
550 ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
551 ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
552 ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
553 ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
554 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
555 DEBUGF(IP_DEBUG, ("| %2u | %2u | 0x%04x | (ttl, proto, chksum)\n",
558 ntohs(IPH_CHKSUM(iphdr))));
559 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
560 DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (src)\n",
561 ntohl(iphdr->src.addr) >> 24 & 0xff,
562 ntohl(iphdr->src.addr) >> 16 & 0xff,
563 ntohl(iphdr->src.addr) >> 8 & 0xff,
564 ntohl(iphdr->src.addr) & 0xff));
565 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
566 DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (dest)\n",
567 ntohl(iphdr->dest.addr) >> 24 & 0xff,
568 ntohl(iphdr->dest.addr) >> 16 & 0xff,
569 ntohl(iphdr->dest.addr) >> 8 & 0xff,
570 ntohl(iphdr->dest.addr) & 0xff));
571 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
573 #endif /* IP_DEBUG */
574 /*-----------------------------------------------------------------------------------*/