summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-02-05 09:43:07 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-02-05 09:43:07 -0600
commit0c356bb870fdef7a6976234257763266046f0a47 (patch)
tree9f358fc7201edcb6328dce2ef9fe74d2a5b71cd0
parent0baa34b6977a595b60c6e34e60e6172410676b97 (diff)
downloadpx4-nuttx-0c356bb870fdef7a6976234257763266046f0a47.tar.gz
px4-nuttx-0c356bb870fdef7a6976234257763266046f0a47.tar.bz2
px4-nuttx-0c356bb870fdef7a6976234257763266046f0a47.zip
Forgot to add this file before a previous commit
-rw-r--r--nuttx/net/icmpv6/icmpv6_radvertise.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/nuttx/net/icmpv6/icmpv6_radvertise.c b/nuttx/net/icmpv6/icmpv6_radvertise.c
new file mode 100644
index 000000000..09bd4c485
--- /dev/null
+++ b/nuttx/net/icmpv6/icmpv6_radvertise.c
@@ -0,0 +1,254 @@
+/****************************************************************************
+ * net/icmpv6/icmpv6_radvertise.c
+ * Send an ICMPv6 Router Advertisement
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Adapted for NuttX from logic in uIP which also has a BSD-like license:
+ *
+ * Original author Adam Dunkels <adam@dunkels.com>
+ * Copyright () 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <debug.h>
+
+#include <nuttx/net/netconfig.h>
+#include <nuttx/net/netstats.h>
+#include <nuttx/net/netdev.h>
+#include <nuttx/net/icmpv6.h>
+
+#include "utils/utils.h"
+#include "icmpv6/icmpv6.h"
+
+#ifdef CONFIG_NET_ICMPv6_ROUTER
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+/* This is the same as struct icmpv6_router_advertise_s, but with the
+ * source address and prefix options included for simplicity.
+ */
+
+struct icmpv6_radvertise_s
+{
+ uint8_t type; /* Message Type: ICMPV6_ROUTER_ADVERTISE */
+ uint8_t code; /* Further qualifies the ICMP messages */
+ uint16_t chksum; /* Checksum of ICMP header and data */
+ uint8_t hoplimit; /* Current hop limit */
+ uint8_t flags; /* See ICMPv6_RADV_FLAG_* definitions */
+ uint16_t lifetime; /* Router lifetime */
+ uint16_t reachable[2]; /* Reachable time */
+ uint16_t retrans[2]; /* Retransmission timer */
+
+ /* Options */
+
+ struct icmpv6_srclladdr_s srcaddr;
+ struct icmpv6_mtu_s mtu;
+ struct icmpv6_prefixinfo_s prefix;
+};
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
+#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+
+#define ICMPv6ADVERTISE \
+ ((struct icmpv6_radvertise_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const net_ipv6addr_t g_ipv6_prefix =
+{
+ HTONS(CONFIG_NET_ICMPv6_PREFIX_1),
+ HTONS(CONFIG_NET_ICMPv6_PREFIX_2),
+ HTONS(CONFIG_NET_ICMPv6_PREFIX_3),
+ HTONS(CONFIG_NET_ICMPv6_PREFIX_4),
+ HTONS(CONFIG_NET_ICMPv6_PREFIX_5),
+ HTONS(CONFIG_NET_ICMPv6_PREFIX_6),
+ HTONS(CONFIG_NET_ICMPv6_PREFIX_7),
+ HTONS(CONFIG_NET_ICMPv6_PREFIX_8)
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: icmpv6_radvertise
+ *
+ * Description:
+ * Send an ICMPv6 Router Advertisement
+ *
+ * Parameters:
+ * dev - The device driver structure containing the outgoing ICMPv6 packet
+ * buffer
+ *
+ * Return:
+ * None
+ *
+ * Assumptions:
+ * The network is locked
+ *
+ ****************************************************************************/
+
+void icmpv6_radvertise(FAR struct net_driver_s *dev)
+{
+ FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF;
+ FAR struct icmpv6_radvertise_s *adv;
+ FAR struct icmpv6_srclladdr_s *srcaddr;
+ FAR struct icmpv6_mtu_s *mtu;
+ FAR struct icmpv6_prefixinfo_s *prefix;
+
+ /* Set up the IPv6 header */
+
+ icmp->vtc = 0x60; /* Version/traffic class (MS) */
+ icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
+ icmp->flow = 0; /* Flow label (LS) */
+
+ /* Length excludes the IPv6 header */
+
+ icmp->len[0] = (sizeof(struct icmpv6_radvertise_s) >> 8);
+ icmp->len[1] = (sizeof(struct icmpv6_radvertise_s) & 0xff);
+
+ icmp->proto = IP_PROTO_ICMP6; /* Next header */
+ icmp->ttl = 255; /* Hop limit */
+
+ /* Swap source for destination IP address, add our source IP address */
+
+ net_ipv6addr_copy(icmp->destipaddr, g_ipv6_allnodes);
+ net_ipv6addr_copy(icmp->srcipaddr, dev->d_ipv6addr);
+
+ /* Set up the ICMPv6 Router Advertise response */
+
+ adv = ICMPv6ADVERTISE;
+ adv->type = ICMPV6_ROUTER_ADVERTISE; /* Message type */
+ adv->code = 0; /* Message qualifier */
+ adv->hoplimit = 64; /* Current hop limit */
+ adv->flags = ICMPv6_RADV_FLAG_M; /* Managed address flag. */
+ adv->lifetime = HTONS(1800); /* Router lifetime */
+ adv->reachable[0] = 0; /* Reachable time */
+ adv->reachable[1] = 0;
+ adv->retrans[0] = 0; /* Retransmission timer */
+ adv->retrans[1] = 0;
+
+ /* Set up the source address option */
+
+ srcaddr = &adv->srcaddr;
+ srcaddr->opttype = ICMPv6_OPT_SRCLLADDR;
+ srcaddr->optlen = 1;
+ memcpy(srcaddr->srclladdr, &dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
+
+ /* Set up the MTU option */
+
+ mtu = &adv->mtu;
+ mtu->opttype = ICMPv6_OPT_MTU;
+ mtu->optlen = 1;
+ mtu->reserved = 0;
+ mtu->mtu[0] = HTONS(CONFIG_NET_ETH_MTU >> 8);
+ mtu->mtu[1] = HTONS(CONFIG_NET_ETH_MTU & 0xff);
+
+ /* Set up the prefix option */
+
+ prefix = &adv->prefix;
+ prefix->opttype = ICMPv6_OPT_MTU;
+ prefix->optlen = 4;
+ prefix->preflen = CONFIG_NET_ICMPv6_PREFLEN;
+ prefix->flags = ICMPv6_PRFX_FLAG_L | ICMPv6_PRFX_FLAG_A;
+
+ prefix->vlifetime[0] = HTONS(2592000 >> 8);
+ prefix->vlifetime[1] = HTONS(2592000 & 0xff);
+ prefix->plifetime[0] = HTONS(604800 >> 8);
+ prefix->plifetime[1] = HTONS(604800 & 0xff);
+ prefix->reserved[0] = 0;
+ prefix->reserved[1] = 0;
+ net_ipv6addr_copy(prefix->prefix, g_ipv6_prefix);
+
+ /* Calculate the checksum over both the ICMP header and payload */
+
+ icmp->chksum = 0;
+ icmp->chksum = ~icmpv6_chksum(dev);
+
+ /* Set the size to the size of the IPv6 header and the payload size */
+
+ dev->d_len = IPv6_HDRLEN + sizeof(struct icmpv6_radvertise_s);
+
+#ifdef CONFIG_NET_ETHERNET
+ /* Add the size of the Ethernet header */
+
+ dev->d_len += ETH_HDRLEN;
+
+ /* Move the source and to the destination addresses in the Ethernet header
+ * and use our MAC as the new source address
+ */
+
+#ifdef CONFIG_NET_MULTILINK
+ if (dev->d_lltype == NET_LL_ETHERNET)
+#endif
+ {
+ FAR struct eth_hdr_s *eth = ETHBUF;
+
+ memcpy(eth->dest, g_ipv6_ethallnodes.ether_addr_octet, ETHER_ADDR_LEN);
+ memcpy(eth->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
+
+ /* Set the IPv6 Ethernet type */
+
+ eth->type = HTONS(ETHTYPE_IP6);
+ }
+#endif
+
+ /* No additional neighbor lookup is required on this packet (We are using
+ * a multicast address).
+ */
+
+ IFF_SET_NOARP(dev->d_flags);
+
+ nllvdbg("Outgoing ICMPv6 Router Advertise length: %d (%d)\n",
+ dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);
+
+#ifdef CONFIG_NET_STATISTICS
+ g_netstats.icmpv6.sent++;
+ g_netstats.ipv6.sent++;
+#endif
+}
+
+#endif /* CONFIG_NET_ICMPv6_ROUTER */