Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_ethip6.c Source File

lwip_ethip6.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  *
00004  * Ethernet output for IPv6. Uses ND tables for link-layer addressing.
00005  */
00006 
00007 /*
00008  * Copyright (c) 2010 Inico Technologies Ltd.
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without modification,
00012  * are permitted provided that the following conditions are met:
00013  *
00014  * 1. Redistributions of source code must retain the above copyright notice,
00015  *    this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright notice,
00017  *    this list of conditions and the following disclaimer in the documentation
00018  *    and/or other materials provided with the distribution.
00019  * 3. The name of the author may not be used to endorse or promote products
00020  *    derived from this software without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00023  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00024  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00025  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00026  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00027  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00030  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00031  * OF SUCH DAMAGE.
00032  *
00033  * This file is part of the lwIP TCP/IP stack.
00034  *
00035  * Author: Ivan Delamer <delamer@inicotech.com>
00036  *
00037  *
00038  * Please coordinate changes and requests with Ivan Delamer
00039  * <delamer@inicotech.com>
00040  */
00041 
00042 #include "lwip/opt.h"
00043 
00044 #if LWIP_IPV6 && LWIP_ETHERNET
00045 
00046 #include "lwip/ethip6.h"
00047 #include "lwip/nd6.h"
00048 #include "lwip/pbuf.h"
00049 #include "lwip/ip6.h"
00050 #include "lwip/ip6_addr.h"
00051 #include "lwip/inet_chksum.h"
00052 #include "lwip/netif.h"
00053 #include "lwip/icmp6.h"
00054 #include "lwip/prot/lwip_ethernet.h"
00055 #include "netif/lwip_ethernet.h"
00056 
00057 #include <string.h>
00058 
00059 /**
00060  * Resolve and fill-in Ethernet address header for outgoing IPv6 packet.
00061  *
00062  * For IPv6 multicast, corresponding Ethernet addresses
00063  * are selected and the packet is transmitted on the link.
00064  *
00065  * For unicast addresses, ask the ND6 module what to do. It will either let us
00066  * send the the packet right away, or queue the packet for later itself, unless
00067  * an error occurs.
00068  *
00069  * @todo anycast addresses
00070  *
00071  * @param netif The lwIP network interface which the IP packet will be sent on.
00072  * @param q The pbuf(s) containing the IP packet to be sent.
00073  * @param ip6addr The IP address of the packet destination.
00074  *
00075  * @return
00076  * - ERR_OK or the return value of @ref nd6_get_next_hop_addr_or_queue.
00077  */
00078 err_t
00079 ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
00080 {
00081   struct eth_addr dest;
00082   const u8_t *hwaddr;
00083   err_t result;
00084 
00085   /* multicast destination IP address? */
00086   if (ip6_addr_ismulticast(ip6addr)) {
00087     /* Hash IP multicast address to MAC address.*/
00088     dest.addr[0] = 0x33;
00089     dest.addr[1] = 0x33;
00090     dest.addr[2] = ((const u8_t *)(&(ip6addr->addr[3])))[0];
00091     dest.addr[3] = ((const u8_t *)(&(ip6addr->addr[3])))[1];
00092     dest.addr[4] = ((const u8_t *)(&(ip6addr->addr[3])))[2];
00093     dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3];
00094 
00095     /* Send out. */
00096     return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
00097   }
00098 
00099   /* We have a unicast destination IP address */
00100   /* @todo anycast? */
00101 
00102   /* Ask ND6 what to do with the packet. */
00103   result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr);
00104   if (result != ERR_OK) {
00105     return result;
00106   }
00107 
00108   /* If no hardware address is returned, nd6 has queued the packet for later. */
00109   if (hwaddr == NULL) {
00110     return ERR_OK;
00111   }
00112 
00113   /* Send out the packet using the returned hardware address. */
00114   SMEMCPY(dest.addr, hwaddr, 6);
00115   return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
00116 }
00117 
00118 #endif /* LWIP_IPV6 && LWIP_ETHERNET */