route.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * Copyright (C) 2001-2003 by egnite Software GmbH
  3. * Copyright (c) 1993 by Digital Equipment Corporation
  4. * Copyright (c) 1983, 1993 by The Regents of the University of California
  5. *
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. Neither the name of the copyright holders nor the names of
  18. * contributors may be used to endorse or promote products derived
  19. * from this software without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  30. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  31. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32. * SUCH DAMAGE.
  33. *
  34. * For additional information see http://www.ethernut.de/
  35. */
  36. /*!
  37. * \file net/route.c
  38. * \brief IP routing functions.
  39. *
  40. * \verbatim
  41. * $Id: route.c 5571 2014-01-30 18:38:37Z mifi $
  42. * \endverbatim
  43. */
  44. #include <cfg/os.h>
  45. #include <sys/heap.h>
  46. #include <net/if_var.h>
  47. #include <net/route.h>
  48. #include <netinet/ip.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <memdebug.h>
  52. #ifdef NUTDEBUG
  53. #include <sys/osdebug.h>
  54. #endif
  55. /*!
  56. * \addtogroup xgIP
  57. */
  58. /*@{*/
  59. RTENTRY *rteList; /*!< Linked list of routing entries. */
  60. /*!
  61. * \brief Add a new entry to the IP routing table.
  62. *
  63. * Note, that there is currently no support for detecting duplicates.
  64. * Anyway, newer entries will be found first, because they are inserted
  65. * in front of older entries. However, this works only for equal masks,
  66. * i.e. new network routes will never overwrite old host routes.
  67. *
  68. * \param ip Network or host IP address to be routed.
  69. * Set 0 for default route.
  70. * \param mask Mask for this entry. -1 for host routes,
  71. * 0 for default or net mask for net routes.
  72. * \param gate Route through this gateway, otherwise 0.
  73. * \param dev Network interface to use.
  74. *
  75. * \return 0 on success, -1 otherwise.
  76. */
  77. int NutIpRouteAdd(uint32_t ip, uint32_t mask, uint32_t gate, NUTDEVICE * dev)
  78. {
  79. int rc = -1;
  80. RTENTRY *rte;
  81. RTENTRY *rtp;
  82. RTENTRY **rtpp;
  83. /*
  84. * Insert a new entry into the list, which is
  85. * sorted based on the mask. Host routes are
  86. * in front, default routes at the end and
  87. * networks in between.
  88. */
  89. rtp = rteList;
  90. rtpp = &rteList;
  91. while (rtp && rtp->rt_mask > mask) {
  92. rtpp = &rtp->rt_next;
  93. rtp = rtp->rt_next;
  94. }
  95. if ((rte = malloc(sizeof(RTENTRY))) != NULL) {
  96. rte->rt_ip = ip & mask;
  97. rte->rt_mask = mask;
  98. rte->rt_gateway = gate;
  99. rte->rt_dev = dev;
  100. rte->rt_next = rtp;
  101. *rtpp = rte;
  102. rc = 0;
  103. }
  104. return rc;
  105. }
  106. /*!
  107. * \brief Delete all route table entries for the given device.
  108. *
  109. * \param dev Pointer to the device. If NULL, it deletes all route table entries.
  110. *
  111. * \return 0 on success, -1 otherwise.
  112. */
  113. int NutIpRouteDelAll(NUTDEVICE * dev)
  114. {
  115. RTENTRY **rtpp;
  116. RTENTRY *rte;
  117. rtpp = &rteList;
  118. while (*rtpp) {
  119. rte = *rtpp;
  120. if (rte->rt_dev == dev || dev == 0) {
  121. *rtpp = rte->rt_next;
  122. free(rte);
  123. } else
  124. *rtpp = (*rtpp)->rt_next;
  125. }
  126. return 0;
  127. }
  128. /*!
  129. * \brief Delete the specified route table entry.
  130. *
  131. * All fields must exactly match an existing entry.
  132. *
  133. * \param ip Network or host IP address of the route entry.
  134. * \param mask Mask for this entry. -1 for host routes,
  135. * 0 for default or net mask for net routes.
  136. * \param gate Route through this gateway, 0 for default gate.
  137. * \param dev Network interface to use.
  138. *
  139. * \return 0 on success, -1 otherwise.
  140. */
  141. int NutIpRouteDel(uint32_t ip, uint32_t mask, uint32_t gate, NUTDEVICE * dev)
  142. {
  143. int rc = -1;
  144. RTENTRY **rtpp;
  145. RTENTRY *rte;
  146. for (rtpp = &rteList; *rtpp; *rtpp = (*rtpp)->rt_next) {
  147. rte = *rtpp;
  148. if (rte->rt_ip == ip && rte->rt_mask == mask && rte->rt_gateway == gate && rte->rt_dev == dev) {
  149. *rtpp = rte->rt_next;
  150. free(rte);
  151. rc = 0;
  152. }
  153. }
  154. return rc;
  155. }
  156. /*!
  157. * \brief Return an array of RTENTRY structures which contain all the current route table entries.
  158. *
  159. * The calling function is responsible for deleting the array.
  160. *
  161. * \param numEntries Points to an integer, which receives the length of the array.
  162. *
  163. * \return Pointer to the array. Will be NULL in case of an error.
  164. */
  165. RTENTRY *NutIpRouteList(int *numEntries)
  166. {
  167. RTENTRY *rc;
  168. RTENTRY *rte;
  169. int i;
  170. /* First count the number of entries. */
  171. *numEntries = 0;
  172. for (rte = rteList; rte; rte = rte->rt_next) {
  173. (*numEntries)++;
  174. }
  175. /* Allocate space for the result. */
  176. rc = (RTENTRY *) malloc(sizeof(RTENTRY) * (*numEntries));
  177. /* Fill in the result. */
  178. if (rc) {
  179. i = 0;
  180. for (rte = rteList; rte; i++, rte = rte->rt_next) {
  181. memcpy(&rc[i], rte, sizeof(RTENTRY));
  182. }
  183. }
  184. else {
  185. *numEntries = 0;
  186. }
  187. return rc;
  188. }
  189. /*!
  190. * \brief Used to limit route lookup recursion for gateways.
  191. *
  192. * The returned pointer points directly into the linked
  193. * list of all route entries, which is safe, as entries
  194. * are never removed or modified.
  195. *
  196. * \param ip IP address in network byte order.
  197. * \param gate Points to a buffer which optionally
  198. * receives the IP address of a gateway.
  199. * The pointer may be NULL, if the caller
  200. * is not interested in this information.
  201. * \param level Recursion level.
  202. */
  203. static RTENTRY *NutIpRouteRecQuery(uint32_t ip, uint32_t * gate, uint8_t level)
  204. {
  205. RTENTRY *rte = 0;
  206. if (level < 4) {
  207. for (rte = rteList; rte; rte = rte->rt_next) {
  208. if ((ip & rte->rt_mask) == rte->rt_ip)
  209. break;
  210. }
  211. if (rte) {
  212. if (gate && rte->rt_gateway)
  213. *gate = rte->rt_gateway;
  214. if (rte->rt_dev == 0)
  215. rte = NutIpRouteRecQuery(rte->rt_gateway, gate, level + 1);
  216. }
  217. }
  218. return rte;
  219. }
  220. /*!
  221. * \brief Find a device associated with a particular IP route.
  222. *
  223. * Gateway routes will be automatically resolved up to
  224. * four levels of redirection.
  225. *
  226. * \param ip IP address to find a route for, given in
  227. * network byte order.
  228. * \param gate Points to a buffer which optionally
  229. * receives the IP address of a gateway.
  230. * The pointer may be NULL, if the caller
  231. * is not interested in this information.
  232. *
  233. * \return Pointer to the interface structure or NULL
  234. * if no route was found.
  235. */
  236. NUTDEVICE *NutIpRouteQuery(uint32_t ip, uint32_t * gate)
  237. {
  238. RTENTRY *rte;
  239. if (gate)
  240. *gate = 0;
  241. /* Return the first interface if the IP is broadcast. This solves the
  242. long existing problem with bad checksums on UDP broadcasts. Many
  243. thanks to Nicolas Moreau for this patch. */
  244. if ((ip == 0xFFFFFFFF) || (IP_IS_MULTICAST(ip)))
  245. rte = rteList;
  246. else
  247. rte = NutIpRouteRecQuery(ip, gate, 0);
  248. return rte ? rte->rt_dev : 0;
  249. }
  250. /*@}*/