igmp_group.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /****************************************************************************
  2. * net/igmp/igmp_group.c
  3. * IGMP group data structure management logic
  4. *
  5. * Copyright (C) 2010, 2013-2014, 2016, 2018 Gregory Nutt.
  6. * All rights reserved.
  7. * Author: Gregory Nutt <gnutt@nuttx.org>
  8. *
  9. * The NuttX implementation of IGMP was inspired by the IGMP add-on for the
  10. * lwIP TCP/IP stack by Steve Reynolds:
  11. *
  12. * Copyright (c) 2002 CITEL Technologies Ltd.
  13. * All rights reserved.
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions
  17. * are met:
  18. *
  19. * 1. Redistributions of source code must retain the above copyright
  20. * notice, this list of conditions and the following disclaimer.
  21. * 2. Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. * 3. Neither the name of CITEL Technologies Ltd nor the names of its
  25. * contributors may be used to endorse or promote products derived
  26. * from this software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS''
  29. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31. * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  34. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  35. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  36. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  37. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  38. * THE POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. ****************************************************************************/
  41. /****************************************************************************
  42. * Included Files
  43. ****************************************************************************/
  44. #include <nuttx/config.h>
  45. #include <nuttx/compiler.h>
  46. #include <inttypes.h>
  47. #include <stdint.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50. #include <queue.h>
  51. #include <assert.h>
  52. #include <debug.h>
  53. #include <arch/irq.h>
  54. #include <nuttx/arch.h>
  55. #include <nuttx/wdog.h>
  56. #include <nuttx/kmalloc.h>
  57. #include <nuttx/semaphore.h>
  58. #include <nuttx/net/net.h>
  59. #include <nuttx/net/ip.h>
  60. #include <nuttx/net/igmp.h>
  61. #include "devif/devif.h"
  62. #include "igmp/igmp.h"
  63. #ifdef CONFIG_NET_IGMP
  64. /****************************************************************************
  65. * Pre-processor Definitions
  66. ****************************************************************************/
  67. /* Debug ********************************************************************/
  68. #undef IGMP_GRPDEBUG /* Define to enable detailed IGMP group debug */
  69. #ifndef CONFIG_NET_IGMP
  70. # undef IGMP_GRPDEBUG
  71. #endif
  72. #ifdef IGMP_GRPDEBUG
  73. # define grperr nerr
  74. # define grpinfo ninfo
  75. #else
  76. # define grperr _none
  77. # define grpinfo _none
  78. #endif
  79. /****************************************************************************
  80. * Public Functions
  81. ****************************************************************************/
  82. /****************************************************************************
  83. * Name: igmp_grpalloc
  84. *
  85. * Description:
  86. * Allocate a new group from heap memory.
  87. *
  88. * Assumptions:
  89. * The network is locked.
  90. *
  91. ****************************************************************************/
  92. FAR struct igmp_group_s *igmp_grpalloc(FAR struct net_driver_s *dev,
  93. FAR const in_addr_t *addr)
  94. {
  95. FAR struct igmp_group_s *group;
  96. ninfo("addr: %08" PRIx32 " dev: %p\n", (uint32_t)*addr, dev);
  97. group = (FAR struct igmp_group_s *)kmm_zalloc(sizeof(struct igmp_group_s));
  98. grpinfo("group: %p\n", group);
  99. /* Check if we successfully allocated a group structure */
  100. if (group != NULL)
  101. {
  102. /* Initialize the non-zero elements of the group structure */
  103. net_ipv4addr_copy(group->grpaddr, *addr);
  104. /* This semaphore is used for signaling and, hence, should not have
  105. * priority inheritance enabled.
  106. */
  107. nxsem_init(&group->sem, 0, 0);
  108. nxsem_set_protocol(&group->sem, SEM_PRIO_NONE);
  109. /* Save the interface index */
  110. group->ifindex = dev->d_ifindex;
  111. /* Add the group structure to the list in the device structure */
  112. sq_addfirst((FAR sq_entry_t *)group, &dev->d_igmp_grplist);
  113. }
  114. return group;
  115. }
  116. /****************************************************************************
  117. * Name: igmp_grpfind
  118. *
  119. * Description:
  120. * Find an existing group.
  121. *
  122. * Assumptions:
  123. * The network is locked.
  124. *
  125. ****************************************************************************/
  126. FAR struct igmp_group_s *igmp_grpfind(FAR struct net_driver_s *dev,
  127. FAR const in_addr_t *addr)
  128. {
  129. FAR struct igmp_group_s *group;
  130. grpinfo("Searching for addr %08x\n", (int)*addr);
  131. for (group = (FAR struct igmp_group_s *)dev->d_igmp_grplist.head;
  132. group;
  133. group = group->next)
  134. {
  135. grpinfo("Compare: %08" PRIx32 " vs. %08" PRIx32 "\n",
  136. (uint32_t)group->grpaddr, (uint32_t)*addr);
  137. if (net_ipv4addr_cmp(group->grpaddr, *addr))
  138. {
  139. grpinfo("Match!\n");
  140. DEBUGASSERT(group->ifindex == dev->d_ifindex);
  141. break;
  142. }
  143. }
  144. return group;
  145. }
  146. /****************************************************************************
  147. * Name: igmp_grpallocfind
  148. *
  149. * Description:
  150. * Find an existing group. If not found, create a new group for the
  151. * address.
  152. *
  153. * Assumptions:
  154. * The network is locked.
  155. *
  156. ****************************************************************************/
  157. FAR struct igmp_group_s *igmp_grpallocfind(FAR struct net_driver_s *dev,
  158. FAR const in_addr_t *addr)
  159. {
  160. FAR struct igmp_group_s *group = igmp_grpfind(dev, addr);
  161. grpinfo("group: %p addr: %08x\n", group, (int)*addr);
  162. if (!group)
  163. {
  164. group = igmp_grpalloc(dev, addr);
  165. }
  166. grpinfo("group: %p\n", group);
  167. return group;
  168. }
  169. /****************************************************************************
  170. * Name: igmp_grpfree
  171. *
  172. * Description:
  173. * Release a previously allocated group.
  174. *
  175. * Assumptions:
  176. * The network is locked.
  177. *
  178. ****************************************************************************/
  179. void igmp_grpfree(FAR struct net_driver_s *dev,
  180. FAR struct igmp_group_s *group)
  181. {
  182. grpinfo("Free: %p flags: %02x\n", group, group->flags);
  183. /* Cancel the wdog */
  184. wd_cancel(&group->wdog);
  185. /* Remove the group structure from the group list in the device structure */
  186. sq_rem((FAR sq_entry_t *)group, &dev->d_igmp_grplist);
  187. /* Destroy the wait semaphore */
  188. nxsem_destroy(&group->sem);
  189. /* Cancel the watchdog timer */
  190. wd_cancel(&group->wdog);
  191. /* Then release the group structure resources. */
  192. grpinfo("Call kmm_free()\n");
  193. kmm_free(group);
  194. }
  195. #endif /* CONFIG_NET_IGMP */