ethdemux.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright (C) 2008 by egnite GmbH
  3. * Copyright (c) 1982, 1989, 1993 by The Regents of the University of California
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. Neither the name of the copyright holders nor the names of
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  30. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * For additional information see http://www.ethernut.de/
  34. */
  35. /*!
  36. * \file net/ethdemux.c
  37. * \brief Supports Ethernet protocol handlers, registered at runtime.
  38. *
  39. * This module is added to the application code only if
  40. * NutRegisterEthHandler() is called.
  41. *
  42. * \verbatim
  43. * $Id: ethdemux.c 3686 2011-12-04 14:20:38Z haraldkipp $
  44. * \endverbatim
  45. */
  46. #include <sys/types.h>
  47. #include <sys/heap.h>
  48. #include <netinet/if_ether.h>
  49. #include <net/ether.h>
  50. #include <stdlib.h>
  51. #include <memdebug.h>
  52. /*!
  53. * \addtogroup xgEthernet
  54. */
  55. /*@{*/
  56. /*!
  57. * \brief Linked list of registered Ethernet protocols.
  58. */
  59. typedef struct _ETH_PROTOCOLS ETH_PROTOCOLS;
  60. struct _ETH_PROTOCOLS {
  61. ETH_PROTOCOLS *ethp_next;
  62. uint16_t ethp_type;
  63. uint16_t ethp_mask;
  64. int (*ethp_input)(NUTDEVICE *, NETBUF *);
  65. };
  66. static ETH_PROTOCOLS *eth_prot;
  67. /*!
  68. * \brief Forward Ethernet frame to registered handler.
  69. *
  70. * \param dev Identifies the device that received the frame.
  71. * \param nb Pointer to a network buffer structure containing
  72. * the Ethernet frame.
  73. *
  74. * \return 0 if the frame will be processed by a handler. Otherwise
  75. * -1 is returned.
  76. */
  77. static int NutEtherDemux(NUTDEVICE * dev, NETBUF * nb)
  78. {
  79. ETH_PROTOCOLS *ep;
  80. uint16_t type = ntohs(((ETHERHDR *)nb->nb_dl.vp)->ether_type);
  81. for (ep = eth_prot; ep; ep = ep->ethp_next) {
  82. if ((type & ep->ethp_mask) == ep->ethp_type) {
  83. if (ep->ethp_input && (*ep->ethp_input) (dev, nb) == 0) {
  84. return 0;
  85. }
  86. }
  87. }
  88. return -1;
  89. }
  90. /*!
  91. * \brief Register an additional Ethernet protocol handler.
  92. *
  93. * The specified mask will be applied on the type field of incoming
  94. * frames before compared with the type that had been specified for
  95. * the handler. If more than one handler is registered for an incoming
  96. * Ethernet frame, the handler being registered last is called first.
  97. *
  98. * Each handler should return 0 if it processed the frame, in which
  99. * case it is also assumed, that the handler releases the memory
  100. * allocated for the NETBUF. Otherwise the handler should return -1,
  101. * in which case the frame is passed to the next handler that fits.
  102. *
  103. * The protocol types ETHERTYPE_IP and ETHERTYPE_ARP are pre-registered
  104. * by default and processed by internal handlers after all registered
  105. * handlers for that frame rejected processing. This allows to install
  106. * filters on the Ethernet level.
  107. *
  108. * \param type Ethernet protocol type processed by this handler.
  109. * \param mask Ethernet protocol type mask.
  110. * \param hdlr Pointer to the protocol handler function. If NULL,
  111. * the handler will be temporarily disabled.
  112. *
  113. * \return 0 on success, -1 otherwise.
  114. */
  115. int NutRegisterEthHandler(uint16_t type, uint16_t mask, int (*hdlr)(NUTDEVICE *, NETBUF *))
  116. {
  117. ETH_PROTOCOLS *ep;
  118. /* Check existing registrations. */
  119. for (ep = eth_prot; ep; ep = ep->ethp_next) {
  120. if (ep->ethp_type == type && ep->ethp_mask == mask) {
  121. /* Found one. */
  122. break;
  123. }
  124. }
  125. if (ep == NULL) {
  126. /* No existing entry. Allocate a new one. */
  127. ep = calloc(1, sizeof(ETH_PROTOCOLS));
  128. if (ep == NULL) {
  129. return -1;
  130. }
  131. /* Set type and mask of our new entry. */
  132. ep->ethp_type = type;
  133. ep->ethp_mask = mask;
  134. if (eth_prot == NULL) {
  135. /* This is the first registration. Set the list root ... */
  136. eth_prot = ep;
  137. /* ... and enable our demultiplexer. */
  138. ether_demux = NutEtherDemux;
  139. } else {
  140. /* Not the first registration. Insert new handler at the top. */
  141. ep->ethp_next = eth_prot;
  142. eth_prot = ep;
  143. }
  144. }
  145. /* Finally set the handler function pointer of the new or existing
  146. ** entry. */
  147. ep->ethp_input = hdlr;
  148. return 0;
  149. }
  150. /*@}*/