ipin.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * Copyright (C) 2008-2012 by egnite GmbH
  3. * Copyright (C) 2001-2007 by egnite Software GmbH
  4. * Copyright (c) 1983, 1993 by The Regents of the University of California
  5. * Copyright (c) 1993 by Digital Equipment Corporation
  6. *
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * 3. Neither the name of the copyright holders nor the names of
  19. * contributors may be used to endorse or promote products derived
  20. * from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  28. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  29. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  30. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  31. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  32. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33. * SUCH DAMAGE.
  34. *
  35. * For additional information see http://www.ethernut.de/
  36. */
  37. /*!
  38. * \file net/ipin.c
  39. * \brief IP input functions.
  40. *
  41. * \verbatim
  42. * $Id: ipin.c 4636 2012-09-20 09:02:23Z haraldkipp $
  43. * \endverbatim
  44. */
  45. #include <net/route.h>
  46. #include <netinet/in.h>
  47. #include <netinet/ip.h>
  48. #include <netinet/icmp.h>
  49. #include <netinet/ip_icmp.h>
  50. #include <netinet/igmp.h>
  51. #include <netinet/udp.h>
  52. #include <sys/socket.h>
  53. #include <arpa/inet.h>
  54. /*!
  55. * \addtogroup xgIP
  56. */
  57. /*@{*/
  58. static NutIpFilterFunc NutIpFilter;
  59. /*!
  60. * \brief Set filter function for incoming IP datagrams.
  61. *
  62. * The callbackFunc is called by the IP layer on every incoming IP
  63. * datagram. Thus it must not block. The implementer returns 0 for
  64. * allow, -1 for deny.
  65. *
  66. * It is recommended to set the filer after DHCP has done its thing,
  67. * just in case your DHCP server is on a different subnet for example.
  68. *
  69. * \param callbackFunc Pointer to callback function to filter IP packets.
  70. * Set to 0 to disable the filter again.
  71. */
  72. void NutIpSetInputFilter(NutIpFilterFunc callbackFunc)
  73. {
  74. NutIpFilter = callbackFunc;
  75. }
  76. /*!
  77. * \brief Pointer to an optional demultiplexer.
  78. *
  79. * This pointer will be set on the first call to NutRegisterIpHandler().
  80. */
  81. int (*ip_demux) (NUTDEVICE *, NETBUF *);
  82. /*!
  83. * \brief Process incoming IP datagrams.
  84. * \internal
  85. *
  86. * Datagrams addressed to other destinations and datagrams
  87. * whose version number is not 4 are silently discarded.
  88. *
  89. * This routine is called by the Ethernet layer on incoming IP datagrams.
  90. *
  91. * \param dev Identifies the device that received this datagram.
  92. * \param nb The network buffer received.
  93. */
  94. void NutIpInput(NUTDEVICE * dev, NETBUF * nb)
  95. {
  96. IPHDR *ip;
  97. uint_fast8_t hdrlen;
  98. uint32_t dst;
  99. uint_fast8_t bcast = 0;
  100. IFNET *nif;
  101. ip = nb->nb_nw.vp;
  102. /*
  103. * Silently discard datagrams of different IP version as well as
  104. * fragmented or filtered datagrams.
  105. */
  106. if (ip->ip_v != IPVERSION || /* Version check. */
  107. (ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)) != 0 || /* Fragmentation. */
  108. (NutIpFilter && NutIpFilter(ip->ip_src))) { /* Filter. */
  109. NutNetBufFree(nb);
  110. return;
  111. }
  112. /*
  113. ** IP header length is given in 32-bit fields. Calculate the size in
  114. ** bytes and make sure that the header we know will fit in. Check
  115. ** further, that the header length is not larger than the bytes we
  116. ** received.
  117. */
  118. hdrlen = ip->ip_hl * 4;
  119. if (hdrlen < sizeof(IPHDR) || hdrlen > nb->nb_nw.sz) {
  120. NutNetBufFree(nb);
  121. return;
  122. }
  123. #if NUT_IP_INCHKSUM
  124. /* Optional checksum calculation on incoming datagrams. */
  125. #endif
  126. dst = ip->ip_dst;
  127. nif = dev->dev_icb;
  128. /*
  129. * Check for limited broadcast.
  130. */
  131. if (dst == INADDR_BROADCAST) {
  132. bcast = 1;
  133. }
  134. /*
  135. * Check for multicast.
  136. */
  137. else if (IN_MULTICAST(dst)) {
  138. MCASTENTRY *mca;
  139. for (mca = nif->if_mcast; mca; mca = mca->mca_next) {
  140. if (dst == mca->mca_ip) {
  141. break;
  142. }
  143. }
  144. if (mca == NULL) {
  145. NutNetBufFree(nb);
  146. return;
  147. }
  148. bcast = 2;
  149. }
  150. /*
  151. * Check device's local IP address.
  152. */
  153. else if (nif->if_local_ip != 0) {
  154. /*
  155. * Check for unicast.
  156. */
  157. if (dst == nif->if_local_ip) {
  158. nb->nb_flags |= NBAF_UNICAST;
  159. }
  160. /*
  161. * Check for net-directed broadcast.
  162. */
  163. else if (~nif->if_mask && (dst & ~nif->if_mask) == ~nif->if_mask) {
  164. bcast = 1;
  165. }
  166. /*
  167. * Not for us, discard silently.
  168. */
  169. else {
  170. NutIpForward(nb);
  171. NutNetBufFree(nb);
  172. return;
  173. }
  174. }
  175. /*
  176. * Calculate IP data length.
  177. */
  178. nb->nb_tp.sz = htons(ip->ip_len);
  179. if (nb->nb_tp.sz < hdrlen || nb->nb_tp.sz > nb->nb_nw.sz) {
  180. NutNetBufFree(nb);
  181. return;
  182. }
  183. nb->nb_nw.sz = hdrlen;
  184. nb->nb_tp.sz -= hdrlen;
  185. if (nb->nb_tp.sz) {
  186. nb->nb_tp.vp = ((char *) ip) + hdrlen;
  187. }
  188. /*
  189. * Route valid datagram to the related handler.
  190. */
  191. if (ip_demux == NULL || (*ip_demux) (dev, nb)) {
  192. switch (ip->ip_p) {
  193. case IPPROTO_ICMP:
  194. NutIcmpInput(dev, nb);
  195. break;
  196. case IPPROTO_IGMP:
  197. NutIgmpInput(dev, nb);
  198. break;
  199. default:
  200. /* Unknown protocol, send ICMP destination (protocol)
  201. * unreachable message.
  202. */
  203. if (bcast || !NutIcmpResponse(ICMP_UNREACH, ICMP_UNREACH_PROTOCOL, 0, nb))
  204. NutNetBufFree(nb);
  205. break;
  206. }
  207. }
  208. }
  209. /*@}*/