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>
37 * This is the code for the IP layer.
48 #include "lwip/ip_frag.h"
49 #include "lwip/inet.h"
50 #include "lwip/netif.h"
51 #include "lwip/icmp.h"
56 #include "lwip/stats.h"
58 #include "arch/perf.h"
60 #include "lwip/snmp.h"
62 # include "lwip/dhcp.h"
63 #endif /* LWIP_DHCP */
68 * Initializes the IP layer.
78 * An experimental feature that will be changed in future versions. Do
79 * not depend on it yet...
84 ip_lookup(void *header, struct netif *inp)
91 if (IPH_V(iphdr) != 4) {
95 /* Immediately accept/decline packets that are fragments or has
97 #if IP_REASSEMBLY == 0
98 /* if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
101 #endif /* IP_REASSEMBLY == 0 */
104 if (IPH_HL(iphdr) != 5) {
107 #endif /* IP_OPTIONS == 0 */
109 switch (IPH_PROTO(iphdr)) {
112 case IP_PROTO_UDPLITE:
113 return udp_lookup(iphdr, inp);
114 #endif /* LWIP_UDP */
118 #endif /* LWIP_TCP */
125 #endif /* LWIP_DEBUG */
129 * Finds the appropriate network interface for a given IP address. It
130 * searches the list of network interfaces linearly. A match is found
131 * if the masked IP address of the network interface equals the masked
132 * IP address given to the function.
136 ip_route(struct ip_addr *dest)
140 /* iterate through netifs */
141 for(netif = netif_list; netif != NULL; netif = netif->next) {
142 /* network mask matches? */
143 if (ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
144 /* return netif on which to forward IP packet */
148 /* no matching netif found, use default netif */
149 return netif_default;
155 * Forwards an IP packet. It finds an appropriate route for the
156 * packet, decrements the TTL value of the packet, adjusts the
157 * checksum and outputs the packet on the appropriate interface.
161 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
166 /* Find network interface where to forward this IP packet to. */
167 netif = ip_route((struct ip_addr *)&(iphdr->dest));
169 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",
171 snmp_inc_ipnoroutes();
174 /* Do not forward packets onto the same network interface on which
177 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
178 snmp_inc_ipnoroutes();
183 IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
184 /* send ICMP if TTL == 0 */
185 if (IPH_TTL(iphdr) == 0) {
186 /* Don't send ICMP messages in response to ICMP messages */
187 if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
188 icmp_time_exceeded(p, ICMP_TE_TTL);
189 snmp_inc_icmpouttimeexcds();
194 /* Incrementally update the IP checksum. */
195 if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
196 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
198 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
201 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",
205 IP_STATS_INC(ip.xmit);
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 */
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.
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;
231 IP_STATS_INC(ip.recv);
232 snmp_inc_ipinreceives();
234 /* identify the IP header */
236 if (IPH_V(iphdr) != 4) {
237 LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %u\n", IPH_V(iphdr)));
240 IP_STATS_INC(ip.err);
241 IP_STATS_INC(ip.drop);
242 snmp_inc_ipunknownprotos();
245 /* obtain IP header length in number of 32-bit words */
246 iphdrlen = IPH_HL(iphdr);
247 /* calculate IP header length in bytes */
250 /* header length exceeds first pbuf length? */
251 if (iphdrlen > p->len) {
252 LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
254 /* free (drop) packet pbufs */
256 IP_STATS_INC(ip.lenerr);
257 IP_STATS_INC(ip.drop);
258 snmp_inc_ipindiscards();
262 /* verify checksum */
263 if (inet_chksum(iphdr, iphdrlen) != 0) {
265 LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
268 IP_STATS_INC(ip.chkerr);
269 IP_STATS_INC(ip.drop);
270 snmp_inc_ipindiscards();
274 /* Trim pbuf. This should have been done at the netif layer,
275 but we'll do it anyway just to be sure that its done. */
276 pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
278 /* is this packet for us? */
279 for(netif = netif_list; netif != NULL; netif = netif->next) {
281 LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",
282 iphdr->dest.addr, netif->ip_addr.addr,
283 iphdr->dest.addr & netif->netmask.addr,
284 netif->ip_addr.addr & netif->netmask.addr,
285 iphdr->dest.addr & ~(netif->netmask.addr)));
287 /* interface configured? */
288 if (!ip_addr_isany(&(netif->ip_addr)))
290 /* unicast to this interface address? */
291 if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
292 /* or broadcast matching this interface network address? */
293 (ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) &&
294 ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
295 /* or restricted broadcast? */
296 ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
297 LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
298 netif->name[0], netif->name[1]));
299 /* break out of for loop */
305 /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
306 using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
307 According to RFC 1542 section 3.1.1, referred by RFC 2131). */
309 /* remote port is DHCP server? */
310 if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
311 LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n",
312 ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
313 if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
314 LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));
319 #endif /* LWIP_DHCP */
320 /* packet not for us? */
322 /* packet not for us, route or discard */
323 LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
325 /* non-broadcast packet? */
326 if (!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) {
327 /* try to forward IP packet on (other) interfaces */
328 ip_forward(p, iphdr, inp);
331 #endif /* IP_FORWARD */
333 snmp_inc_ipindiscards();
340 if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
341 LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n",
342 ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
349 #else /* IP_REASSEMBLY */
350 if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
352 LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
353 ntohs(IPH_OFFSET(iphdr))));
354 IP_STATS_INC(ip.opterr);
355 IP_STATS_INC(ip.drop);
356 snmp_inc_ipunknownprotos();
359 #endif /* IP_REASSEMBLY */
362 if (iphdrlen > IP_HLEN) {
363 LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
365 IP_STATS_INC(ip.opterr);
366 IP_STATS_INC(ip.drop);
367 snmp_inc_ipunknownprotos();
370 #endif /* IP_OPTIONS == 0 */
372 /* send to upper layers */
373 LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
375 LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
378 if (!raw_input(p, inp)) {
379 #endif /* LWIP_RAW */
381 switch (IPH_PROTO(iphdr)) {
384 case IP_PROTO_UDPLITE:
385 snmp_inc_ipindelivers();
388 #endif /* LWIP_UDP */
391 snmp_inc_ipindelivers();
394 #endif /* LWIP_TCP */
396 snmp_inc_ipindelivers();
400 /* send ICMP destination protocol unreachable unless is was a broadcast */
401 if (!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) &&
402 !ip_addr_ismulticast(&(iphdr->dest))) {
404 icmp_dest_unreach(p, ICMP_DUR_PROTO);
408 LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %d\n", IPH_PROTO(iphdr)));
410 IP_STATS_INC(ip.proterr);
411 IP_STATS_INC(ip.drop);
412 snmp_inc_ipunknownprotos();
424 * Sends an IP packet on a network interface. This function constructs
425 * the IP header and calculates the IP header checksum. If the source
426 * IP address is NULL, the IP address of the outgoing network
427 * interface is filled in as source address.
431 ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
433 u8_t proto, struct netif *netif)
435 static struct ip_hdr *iphdr;
436 static u16_t ip_id = 0;
438 snmp_inc_ipoutrequests();
440 if (dest != IP_HDRINCL) {
441 if (pbuf_header(p, IP_HLEN)) {
442 LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
444 IP_STATS_INC(ip.err);
445 snmp_inc_ipoutdiscards();
451 IPH_TTL_SET(iphdr, ttl);
452 IPH_PROTO_SET(iphdr, proto);
454 ip_addr_set(&(iphdr->dest), dest);
456 IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);
457 IPH_LEN_SET(iphdr, htons(p->tot_len));
458 IPH_OFFSET_SET(iphdr, htons(IP_DF));
459 IPH_ID_SET(iphdr, htons(ip_id));
462 if (ip_addr_isany(src)) {
463 ip_addr_set(&(iphdr->src), &(netif->ip_addr));
465 ip_addr_set(&(iphdr->src), src);
468 IPH_CHKSUM_SET(iphdr, 0);
469 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
472 dest = &(iphdr->dest);
476 /* don't fragment if interface has mtu set to 0 [loopif] */
477 if (netif->mtu && (p->tot_len > netif->mtu))
478 return ip_frag(p,netif,dest);
481 IP_STATS_INC(ip.xmit);
483 LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%u\n", netif->name[0], netif->name[1], netif->num));
486 LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
488 return netif->output(netif, p, dest);
493 * Simple interface to ip_output_if. It finds the outgoing network
494 * interface and calls upon ip_output_if to do the actual work.
498 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
499 u8_t ttl, u8_t tos, u8_t proto)
503 if ((netif = ip_route(dest)) == NULL) {
504 LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
506 IP_STATS_INC(ip.rterr);
507 snmp_inc_ipoutdiscards();
511 return ip_output_if(p, src, dest, ttl, tos, proto, netif);
516 ip_debug_print(struct pbuf *p)
518 struct ip_hdr *iphdr = p->payload;
521 payload = (u8_t *)iphdr + IP_HLEN;
523 LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
524 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
525 LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d | 0x%02x | %5u | (v, hl, tos, len)\n",
529 ntohs(IPH_LEN(iphdr))));
530 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
531 LWIP_DEBUGF(IP_DEBUG, ("| %5u |%u%u%u| %4u | (id, flags, offset)\n",
532 ntohs(IPH_ID(iphdr)),
533 ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
534 ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
535 ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
536 ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
537 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
538 LWIP_DEBUGF(IP_DEBUG, ("| %3u | %3u | 0x%04x | (ttl, proto, chksum)\n",
541 ntohs(IPH_CHKSUM(iphdr))));
542 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
543 LWIP_DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (src)\n",
544 ntohl(iphdr->src.addr) >> 24 & 0xff,
545 ntohl(iphdr->src.addr) >> 16 & 0xff,
546 ntohl(iphdr->src.addr) >> 8 & 0xff,
547 ntohl(iphdr->src.addr) & 0xff));
548 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
549 LWIP_DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (dest)\n",
550 ntohl(iphdr->dest.addr) >> 24 & 0xff,
551 ntohl(iphdr->dest.addr) >> 16 & 0xff,
552 ntohl(iphdr->dest.addr) >> 8 & 0xff,
553 ntohl(iphdr->dest.addr) & 0xff));
554 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
556 #endif /* IP_DEBUG */