icmpv6_rsolicit.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /****************************************************************************
  2. * net/icmpv6/icmpv6_rsolicit.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <stdint.h>
  25. #include <string.h>
  26. #include <debug.h>
  27. #include <nuttx/net/netdev.h>
  28. #include <nuttx/net/netstats.h>
  29. #include "devif/devif.h"
  30. #include "netdev/netdev.h"
  31. #include "inet/inet.h"
  32. #include "utils/utils.h"
  33. #include "icmpv6/icmpv6.h"
  34. #ifdef CONFIG_NET_ICMPv6_AUTOCONF
  35. /****************************************************************************
  36. * Pre-processor Definitions
  37. ****************************************************************************/
  38. #define IPv6BUF ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
  39. #define ICMPv6RSOLICIT \
  40. ((struct icmpv6_router_solicit_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
  41. /****************************************************************************
  42. * Public Functions
  43. ****************************************************************************/
  44. /****************************************************************************
  45. * Name: icmpv6_rsolicit
  46. *
  47. * Description:
  48. * Set up to send an ICMPv6 Router Solicitation message. This version
  49. * is for a standalone solicitation. If formats:
  50. *
  51. * - The IPv6 header
  52. * - The ICMPv6 Router Solicitation Message
  53. *
  54. * The device IP address should have been set to the link local address
  55. * prior to calling this function.
  56. *
  57. * Input Parameters:
  58. * dev - Reference to a device driver structure
  59. *
  60. * Returned Value:
  61. * None
  62. *
  63. ****************************************************************************/
  64. void icmpv6_rsolicit(FAR struct net_driver_s *dev)
  65. {
  66. FAR struct ipv6_hdr_s *ipv6;
  67. FAR struct icmpv6_router_solicit_s *sol;
  68. uint16_t lladdrsize;
  69. uint16_t l3size;
  70. /* Set up the IPv6 header (most is probably already in place) */
  71. ipv6 = IPv6BUF;
  72. ipv6->vtc = 0x60; /* Version/traffic class (MS) */
  73. ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
  74. ipv6->flow = 0; /* Flow label (LS) */
  75. /* Length excludes the IPv6 header */
  76. lladdrsize = netdev_lladdrsize(dev);
  77. l3size = SIZEOF_ICMPV6_ROUTER_SOLICIT_S(lladdrsize);
  78. ipv6->len[0] = (l3size >> 8);
  79. ipv6->len[1] = (l3size & 0xff);
  80. ipv6->proto = IP_PROTO_ICMP6; /* Next header */
  81. ipv6->ttl = 255; /* Hop limit */
  82. /* Set the multicast destination IP address to the IPv6 all link-
  83. * local routers address: ff02::2
  84. */
  85. net_ipv6addr_copy(ipv6->destipaddr, g_ipv6_allrouters);
  86. /* Add our link local IPv6 address as the source address */
  87. net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
  88. /* Set up the ICMPv6 Router Solicitation message */
  89. sol = ICMPv6RSOLICIT;
  90. sol->type = ICMPV6_ROUTER_SOLICIT; /* Message type */
  91. sol->code = 0; /* Message qualifier */
  92. sol->flags[0] = 0; /* flags */
  93. sol->flags[1] = 0;
  94. sol->flags[2] = 0;
  95. sol->flags[3] = 0;
  96. /* Set up the options */
  97. sol->opttype = ICMPv6_OPT_SRCLLADDR; /* Option type */
  98. sol->optlen = ICMPv6_OPT_OCTECTS(lladdrsize); /* Option length in octets */
  99. /* Copy our link layer address into the message */
  100. memcpy(sol->srclladdr, &dev->d_mac, lladdrsize);
  101. /* Calculate the checksum over both the ICMP header and payload */
  102. sol->chksum = 0;
  103. sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
  104. /* Set the size to the size of the IPv6 header and the payload size */
  105. dev->d_len = IPv6_HDRLEN + l3size;
  106. ninfo("Outgoing ICMPv6 Router Solicitation length: %d (%d)\n",
  107. dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
  108. #ifdef CONFIG_NET_STATISTICS
  109. g_netstats.icmpv6.sent++;
  110. g_netstats.ipv6.sent++;
  111. #endif
  112. }
  113. #endif /* CONFIG_NET_ICMPv6_AUTOCONF */