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 /*-----------------------------------------------------------------------------------*/
48 #include "lwip/ip_frag.h"
49 #include "lwip/inet.h"
50 #include "lwip/netif.h"
51 #include "lwip/icmp.h"
55 #include "lwip/stats.h"
57 #include "arch/perf.h"
59 #include "lwip/snmp.h"
61 # include "lwip/dhcp.h"
62 #endif /* LWIP_DHCP */
64 /*-----------------------------------------------------------------------------------*/
67 * Initializes the IP layer.
69 /*-----------------------------------------------------------------------------------*/
74 /*-----------------------------------------------------------------------------------*/
77 * An experimental feature that will be changed in future versions. Do
78 * not depend on it yet...
80 /*-----------------------------------------------------------------------------------*/
83 ip_lookup(void *header, struct netif *inp)
90 if(IPH_V(iphdr) != 4) {
94 /* Immediately accept/decline packets that are fragments or has
96 #if IP_REASSEMBLY == 0
97 /* if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
100 #endif /* IP_REASSEMBLY == 0 */
103 if(IPH_HL(iphdr) != 5) {
106 #endif /* IP_OPTIONS == 0 */
108 switch(IPH_PROTO(iphdr)) {
111 return udp_lookup(iphdr, inp);
112 #endif /* LWIP_UDP */
116 #endif /* LWIP_TCP */
123 #endif /* LWIP_DEBUG */
124 /*-----------------------------------------------------------------------------------*/
127 * Finds the appropriate network interface for a given IP address. It
128 * searches the list of network interfaces linearly. A match is found
129 * if the masked IP address of the network interface equals the masked
130 * IP address given to the function.
132 /*-----------------------------------------------------------------------------------*/
134 ip_route(struct ip_addr *dest)
138 /* iterate through netifs */
139 for(netif = netif_list; netif != NULL; netif = netif->next) {
140 /* network mask matches? */
141 if(ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
142 /* return netif on which to forward IP packet */
146 /* no matching netif found, use default netif */
147 return netif_default;
150 /*-----------------------------------------------------------------------------------*/
153 * Forwards an IP packet. It finds an appropriate route for the
154 * packet, decrements the TTL value of the packet, adjusts the
155 * checksum and outputs the packet on the appropriate interface.
157 /*-----------------------------------------------------------------------------------*/
159 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
164 /* Find network interface where to forward this IP packet to. */
165 netif = ip_route((struct ip_addr *)&(iphdr->dest));
167 DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",
169 snmp_inc_ipnoroutes();
172 /* Do not forward packets onto the same network interface on which
175 DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
176 snmp_inc_ipnoroutes();
181 IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
182 /* send ICMP if TTL == 0 */
183 if(IPH_TTL(iphdr) == 0) {
184 /* Don't send ICMP messages in response to ICMP messages */
185 if(IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
186 icmp_time_exceeded(p, ICMP_TE_TTL);
187 snmp_inc_icmpouttimeexcds();
192 /* Incrementally update the IP checksum. */
193 if(IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
194 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
196 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
199 DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",
204 ++lwip_stats.ip.xmit;
205 #endif /* IP_STATS */
206 snmp_inc_ipforwdatagrams();
208 PERF_STOP("ip_forward");
209 /* transmit pbuf on chosen interface */
210 netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
212 #endif /* IP_FORWARD */
213 /*-----------------------------------------------------------------------------------*/
216 * This function is called by the network interface device driver when
217 * an IP packet is received. The function does the basic checks of the
218 * IP header such as packet size being at least larger than the header
219 * size etc. If the packet was not destined for us, the packet is
220 * forwarded (using ip_forward). The IP checksum is always checked.
222 * Finally, the packet is sent to the upper layer protocol input function.
224 /*-----------------------------------------------------------------------------------*/
226 ip_input(struct pbuf *p, struct netif *inp) {
227 static struct ip_hdr *iphdr;
228 static struct netif *netif;
229 static u16_t iphdrlen;
232 ++lwip_stats.ip.recv;
233 #endif /* IP_STATS */
234 snmp_inc_ipinreceives();
236 /* identify the IP header */
238 if(IPH_V(iphdr) != 4) {
239 DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %d\n", IPH_V(iphdr)));
242 #endif /* IP_DEBUG */
246 ++lwip_stats.ip.drop;
247 #endif /* IP_STATS */
248 snmp_inc_ipunknownprotos();
251 /* obtain IP header length in number of 32-bit words */
252 iphdrlen = IPH_HL(iphdr);
253 /* calculate IP header length in bytes */
256 /* header length exceeds first pbuf length? */
257 if(iphdrlen > p->len) {
258 DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
260 /* free (drop) packet pbufs */
263 ++lwip_stats.ip.lenerr;
264 ++lwip_stats.ip.drop;
265 #endif /* IP_STATS */
266 snmp_inc_ipindiscards();
270 /* verify checksum */
271 if(inet_chksum(iphdr, iphdrlen) != 0) {
273 DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
276 #endif /* IP_DEBUG */
279 ++lwip_stats.ip.chkerr;
280 ++lwip_stats.ip.drop;
281 #endif /* IP_STATS */
282 snmp_inc_ipindiscards();
286 /* Trim pbuf. This should have been done at the netif layer,
287 but we'll do it anyway just to be sure that its done. */
288 pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
290 /* is this packet for us? */
291 for(netif = netif_list; netif != NULL; netif = netif->next) {
293 DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",
294 iphdr->dest.addr, netif->ip_addr.addr,
295 iphdr->dest.addr & netif->netmask.addr,
296 netif->ip_addr.addr & netif->netmask.addr,
297 iphdr->dest.addr & ~(netif->netmask.addr)));
299 /* interface configured? */
300 if(!ip_addr_isany(&(netif->ip_addr)))
302 /* unicast to this interface address? */
303 if(ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
304 /* or broadcast matching this interface network address? */
305 (ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) &&
306 ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
307 /* or restricted broadcast? */
308 ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
309 DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
310 netif->name[0], netif->name[1]));
311 /* break out of for loop */
317 /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
318 using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
319 According to RFC 1542 section 3.1.1, referred by RFC 2131). */
321 /* remote port is DHCP server? */
322 if(IPH_PROTO(iphdr) == IP_PROTO_UDP) {
323 DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n",
324 ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
325 if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
326 DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));
331 #endif /* LWIP_DHCP */
332 /* packet not for us? */
334 /* packet not for us, route or discard */
335 DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
337 /* non-broadcast packet? */
338 if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) {
339 /* try to forward IP packet on (other) interfaces */
340 ip_forward(p, iphdr, inp);
343 #endif /* IP_FORWARD */
345 snmp_inc_ipindiscards();
352 if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
353 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));
360 #else /* IP_REASSEMBLY */
361 if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
363 DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
364 ntohs(IPH_OFFSET(iphdr))));
366 ++lwip_stats.ip.opterr;
367 ++lwip_stats.ip.drop;
368 #endif /* IP_STATS */
369 snmp_inc_ipunknownprotos();
372 #endif /* IP_REASSEMBLY */
375 if (iphdrlen > IP_HLEN) {
376 DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
379 ++lwip_stats.ip.opterr;
380 ++lwip_stats.ip.drop;
381 #endif /* IP_STATS */
382 snmp_inc_ipunknownprotos();
385 #endif /* IP_OPTIONS == 0 */
387 /* send to upper layers */
389 DEBUGF(IP_DEBUG, ("ip_input: \n"));
391 DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
392 #endif /* IP_DEBUG */
394 switch(IPH_PROTO(iphdr)) {
397 snmp_inc_ipindelivers();
400 #endif /* LWIP_UDP */
403 snmp_inc_ipindelivers();
406 #endif /* LWIP_TCP */
408 snmp_inc_ipindelivers();
412 /* send ICMP destination protocol unreachable unless is was a broadcast */
413 if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) &&
414 !ip_addr_ismulticast(&(iphdr->dest))) {
416 icmp_dest_unreach(p, ICMP_DUR_PROTO);
420 DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %d\n", IPH_PROTO(iphdr)));
423 ++lwip_stats.ip.proterr;
424 ++lwip_stats.ip.drop;
425 #endif /* IP_STATS */
426 snmp_inc_ipunknownprotos();
432 /*-----------------------------------------------------------------------------------*/
435 * Sends an IP packet on a network interface. This function constructs
436 * the IP header and calculates the IP header checksum. If the source
437 * IP address is NULL, the IP address of the outgoing network
438 * interface is filled in as source address.
440 /*-----------------------------------------------------------------------------------*/
442 ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
444 u8_t proto, struct netif *netif)
446 static struct ip_hdr *iphdr;
447 static u16_t ip_id = 0;
449 snmp_inc_ipoutrequests();
451 if(dest != IP_HDRINCL) {
452 if(pbuf_header(p, IP_HLEN)) {
453 DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
457 #endif /* IP_STATS */
458 snmp_inc_ipoutdiscards();
464 IPH_TTL_SET(iphdr, ttl);
465 IPH_PROTO_SET(iphdr, proto);
467 ip_addr_set(&(iphdr->dest), dest);
469 IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
470 IPH_LEN_SET(iphdr, htons(p->tot_len));
471 IPH_OFFSET_SET(iphdr, htons(IP_DF));
472 IPH_ID_SET(iphdr, htons(ip_id));
475 if(ip_addr_isany(src)) {
476 ip_addr_set(&(iphdr->src), &(netif->ip_addr));
478 ip_addr_set(&(iphdr->src), src);
481 IPH_CHKSUM_SET(iphdr, 0);
482 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
485 dest = &(iphdr->dest);
489 /* don't fragment if interface has mtu set to 0 [loopif] */
490 if (netif->mtu && (p->tot_len > netif->mtu))
491 return ip_frag(p,netif,dest);
495 lwip_stats.ip.xmit++;
496 #endif /* IP_STATS */
497 DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%u\n", netif->name[0], netif->name[1], netif->num));
500 #endif /* IP_DEBUG */
502 DEBUGF(IP_DEBUG, ("netif->output()"));
504 return netif->output(netif, p, dest);
506 /*-----------------------------------------------------------------------------------*/
509 * Simple interface to ip_output_if. It finds the outgoing network
510 * interface and calls upon ip_output_if to do the actual work.
512 /*-----------------------------------------------------------------------------------*/
514 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
515 u8_t ttl, u8_t proto)
519 if((netif = ip_route(dest)) == NULL) {
520 DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
523 ++lwip_stats.ip.rterr;
524 #endif /* IP_STATS */
525 snmp_inc_ipoutdiscards();
529 return ip_output_if(p, src, dest, ttl, proto, netif);
531 /*-----------------------------------------------------------------------------------*/
534 ip_debug_print(struct pbuf *p)
536 struct ip_hdr *iphdr = p->payload;
539 payload = (u8_t *)iphdr + IP_HLEN;
541 DEBUGF(IP_DEBUG, ("IP header:\n"));
542 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
543 DEBUGF(IP_DEBUG, ("|%2d |%2d | %2u | %4u | (v, hl, tos, len)\n",
547 ntohs(IPH_LEN(iphdr))));
548 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
549 DEBUGF(IP_DEBUG, ("| %5u |%u%u%u| %4u | (id, flags, offset)\n",
550 ntohs(IPH_ID(iphdr)),
551 ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
552 ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
553 ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
554 ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
555 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
556 DEBUGF(IP_DEBUG, ("| %2u | %2u | 0x%04x | (ttl, proto, chksum)\n",
559 ntohs(IPH_CHKSUM(iphdr))));
560 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
561 DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (src)\n",
562 ntohl(iphdr->src.addr) >> 24 & 0xff,
563 ntohl(iphdr->src.addr) >> 16 & 0xff,
564 ntohl(iphdr->src.addr) >> 8 & 0xff,
565 ntohl(iphdr->src.addr) & 0xff));
566 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
567 DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (dest)\n",
568 ntohl(iphdr->dest.addr) >> 24 & 0xff,
569 ntohl(iphdr->dest.addr) >> 16 & 0xff,
570 ntohl(iphdr->dest.addr) >> 8 & 0xff,
571 ntohl(iphdr->dest.addr) & 0xff));
572 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
574 #endif /* IP_DEBUG */
575 /*-----------------------------------------------------------------------------------*/