ipfwd_poll.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /****************************************************************************
  2. * net/ipforward/ipfwd_poll.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 <debug.h>
  26. #include <nuttx/net/netdev.h>
  27. #include <nuttx/net/net.h>
  28. #include "devif/devif.h"
  29. #include "sixlowpan/sixlowpan.h"
  30. #include "ipforward/ipforward.h"
  31. #ifdef CONFIG_NET_IPFORWARD
  32. /****************************************************************************
  33. * Private Functions
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Name: ipfwd_packet_proto
  37. *
  38. * Description:
  39. * Generic output conversion hook. Only needed for IEEE802.15.4 (and
  40. * other, non-standard packet radios) for now but this is a point where
  41. * support for other conversions may be provided.
  42. *
  43. ****************************************************************************/
  44. #ifdef CONFIG_NET_6LOWPAN
  45. static int ipfwd_packet_proto(FAR struct net_driver_s *dev)
  46. {
  47. FAR struct ipv6_hdr_s *ipv6;
  48. int llhdrlen = NET_LL_HDRLEN(dev);
  49. /* Make sure the there is something in buffer that is at least as large as
  50. * the IPv6_HDR.
  51. */
  52. if (dev->d_len > (IPv6_HDRLEN + llhdrlen))
  53. {
  54. if (dev->d_lltype == NET_LL_IEEE802154 ||
  55. dev->d_lltype == NET_LL_PKTRADIO)
  56. {
  57. /* There should be an IPv6 packet at the beginning of the buffer */
  58. ipv6 = (FAR struct ipv6_hdr_s *)&dev->d_buf[llhdrlen];
  59. if ((ipv6->vtc & IP_VERSION_MASK) == IPv6_VERSION)
  60. {
  61. /* Yes.. return the L2 protocol of the packet */
  62. return ipv6->proto;
  63. }
  64. }
  65. }
  66. return -EPROTO;
  67. }
  68. #endif /* CONFIG_NET_6LOWPAN */
  69. /****************************************************************************
  70. * Name: ipfwd_packet_conversion
  71. *
  72. * Description:
  73. * Generic output conversion hook. Only needed for IEEE802.15.4 (and
  74. * other, non-standard packet radios) for now but this is a point where
  75. * support for other conversions may be provided.
  76. *
  77. ****************************************************************************/
  78. #ifdef CONFIG_NET_6LOWPAN
  79. static void ipfwd_packet_conversion(FAR struct net_driver_s *dev, int proto)
  80. {
  81. if (dev->d_len > 0)
  82. {
  83. /* Check if this is a device served by 6LoWPAN */
  84. if (dev->d_lltype == NET_LL_IEEE802154 ||
  85. dev->d_lltype == NET_LL_PKTRADIO)
  86. {
  87. FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)dev->d_buf;
  88. #ifdef CONFIG_NET_TCP
  89. if (proto == IP_PROTO_TCP)
  90. {
  91. /* Let 6LoWPAN convert IPv6 TCP output into radio frames. */
  92. sixlowpan_tcp_send(dev, dev, ipv6);
  93. }
  94. else
  95. #endif
  96. #ifdef CONFIG_NET_UDP
  97. if (proto == IP_PROTO_UDP)
  98. {
  99. /* Let 6LoWPAN convert IPv6 UDP output into radio frames. */
  100. sixlowpan_udp_send(dev, dev, ipv6);
  101. }
  102. else
  103. #endif
  104. #ifdef CONFIG_NET_ICMPv6
  105. if (proto == IP_PROTO_ICMP6)
  106. {
  107. /* Let 6LoWPAN convert IPv6 UDP output into radio frames. */
  108. sixlowpan_icmpv6_send(dev, dev, ipv6);
  109. }
  110. else
  111. #endif
  112. {
  113. nwarn("WARNING: Unsupported protocol (%u). Packet dropped\n",
  114. proto);
  115. }
  116. dev->d_len = 0;
  117. }
  118. }
  119. }
  120. #endif /* CONFIG_NET_6LOWPAN */
  121. /****************************************************************************
  122. * Public Functions
  123. ****************************************************************************/
  124. /****************************************************************************
  125. * Name: ipfwd_poll
  126. *
  127. * Description:
  128. * Poll all pending transfer for ARP requests to send.
  129. *
  130. * Assumptions:
  131. * This function is called from the MAC device driver indirectly through
  132. * devif_poll() and devif_timer().
  133. *
  134. ****************************************************************************/
  135. void ipfwd_poll(FAR struct net_driver_s *dev)
  136. {
  137. uint16_t flags;
  138. /* Setup for the callback (most of these do not apply) */
  139. dev->d_appdata = NULL;
  140. dev->d_len = 0;
  141. dev->d_sndlen = 0;
  142. /* Perform the forwarding callbacks. Returns the new set of flags. If
  143. * the packet was forwarded, then the new set will be zero.
  144. */
  145. flags = devif_conn_event(dev, NULL, IPFWD_POLL, dev->d_conncb);
  146. #ifdef CONFIG_NET_6LOWPAN
  147. if ((flags & DEVPOLL_MASK) == 0)
  148. {
  149. /* Get the L2 protocol of packet in the device's d_buf */
  150. int proto = ipfwd_packet_proto(dev);
  151. if (proto >= 0)
  152. {
  153. /* Perform any necessary conversions on the forwarded packet */
  154. ipfwd_packet_conversion(dev, proto);
  155. }
  156. }
  157. #else
  158. UNUSED(flags);
  159. #endif
  160. }
  161. #endif /* CONFIG_NET_ARP_SEND */