ethernet.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /**
  2. * @file
  3. * Ethernet common functions
  4. *
  5. * @defgroup ethernet Ethernet
  6. * @ingroup callbackstyle_api
  7. */
  8. /*
  9. * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
  10. * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
  11. * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without modification,
  15. * are permitted provided that the following conditions are met:
  16. *
  17. * 1. Redistributions of source code must retain the above copyright notice,
  18. * this list of conditions and the following disclaimer.
  19. * 2. Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * 3. The name of the author may not be used to endorse or promote products
  23. * derived from this software without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  26. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  27. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  28. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  29. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  30. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  33. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  34. * OF SUCH DAMAGE.
  35. *
  36. * This file is part of the lwIP TCP/IP stack.
  37. *
  38. */
  39. #include "lwip/opt.h"
  40. #if LWIP_ARP || LWIP_ETHERNET
  41. #include "netif/ethernet.h"
  42. #include "lwip/def.h"
  43. #include "lwip/stats.h"
  44. #include "lwip/etharp.h"
  45. #include "lwip/ip.h"
  46. #include "lwip/snmp.h"
  47. #include <string.h>
  48. #include "netif/ppp/ppp_opts.h"
  49. #if PPPOE_SUPPORT
  50. #include "netif/ppp/pppoe.h"
  51. #endif /* PPPOE_SUPPORT */
  52. const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
  53. const struct eth_addr ethzero = {{0,0,0,0,0,0}};
  54. /**
  55. * @ingroup lwip_nosys
  56. * Process received ethernet frames. Using this function instead of directly
  57. * calling ip_input and passing ARP frames through etharp in ethernetif_input,
  58. * the ARP cache is protected from concurrent access.\n
  59. * Don't call directly, pass to netif_add() and call netif->input().
  60. *
  61. * @param p the received packet, p->payload pointing to the ethernet header
  62. * @param netif the network interface on which the packet was received
  63. *
  64. * @see LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
  65. * @see ETHARP_SUPPORT_VLAN
  66. * @see LWIP_HOOK_VLAN_CHECK
  67. */
  68. err_t
  69. ethernet_input(struct pbuf *p, struct netif *netif)
  70. {
  71. struct eth_hdr* ethhdr;
  72. u16_t type;
  73. #if LWIP_ARP || ETHARP_SUPPORT_VLAN || LWIP_IPV6
  74. s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
  75. #endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */
  76. if (p->len <= SIZEOF_ETH_HDR) {
  77. /* a packet with only an ethernet header (or less) is not valid for us */
  78. ETHARP_STATS_INC(etharp.proterr);
  79. ETHARP_STATS_INC(etharp.drop);
  80. MIB2_STATS_NETIF_INC(netif, ifinerrors);
  81. goto free_and_return;
  82. }
  83. /* points to packet payload, which starts with an Ethernet header */
  84. ethhdr = (struct eth_hdr *)p->payload;
  85. LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
  86. ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n",
  87. (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2],
  88. (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5],
  89. (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2],
  90. (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5],
  91. lwip_htons(ethhdr->type)));
  92. type = ethhdr->type;
  93. #if ETHARP_SUPPORT_VLAN
  94. if (type == PP_HTONS(ETHTYPE_VLAN)) {
  95. struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR);
  96. if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
  97. /* a packet with only an ethernet/vlan header (or less) is not valid for us */
  98. ETHARP_STATS_INC(etharp.proterr);
  99. ETHARP_STATS_INC(etharp.drop);
  100. MIB2_STATS_NETIF_INC(netif, ifinerrors);
  101. goto free_and_return;
  102. }
  103. #if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */
  104. #ifdef LWIP_HOOK_VLAN_CHECK
  105. if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) {
  106. #elif defined(ETHARP_VLAN_CHECK_FN)
  107. if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
  108. #elif defined(ETHARP_VLAN_CHECK)
  109. if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
  110. #endif
  111. /* silently ignore this packet: not for our VLAN */
  112. pbuf_free(p);
  113. return ERR_OK;
  114. }
  115. #endif /* defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */
  116. type = vlan->tpid;
  117. ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
  118. }
  119. #endif /* ETHARP_SUPPORT_VLAN */
  120. #if LWIP_ARP_FILTER_NETIF
  121. netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, lwip_htons(type));
  122. #endif /* LWIP_ARP_FILTER_NETIF*/
  123. if (ethhdr->dest.addr[0] & 1) {
  124. /* this might be a multicast or broadcast packet */
  125. if (ethhdr->dest.addr[0] == LL_IP4_MULTICAST_ADDR_0) {
  126. #if LWIP_IPV4
  127. if ((ethhdr->dest.addr[1] == LL_IP4_MULTICAST_ADDR_1) &&
  128. (ethhdr->dest.addr[2] == LL_IP4_MULTICAST_ADDR_2)) {
  129. /* mark the pbuf as link-layer multicast */
  130. p->flags |= PBUF_FLAG_LLMCAST;
  131. }
  132. #endif /* LWIP_IPV4 */
  133. }
  134. #if LWIP_IPV6
  135. else if ((ethhdr->dest.addr[0] == LL_IP6_MULTICAST_ADDR_0) &&
  136. (ethhdr->dest.addr[1] == LL_IP6_MULTICAST_ADDR_1)) {
  137. /* mark the pbuf as link-layer multicast */
  138. p->flags |= PBUF_FLAG_LLMCAST;
  139. }
  140. #endif /* LWIP_IPV6 */
  141. else if (eth_addr_cmp(&ethhdr->dest, &ethbroadcast)) {
  142. /* mark the pbuf as link-layer broadcast */
  143. p->flags |= PBUF_FLAG_LLBCAST;
  144. }
  145. }
  146. switch (type) {
  147. #if LWIP_IPV4 && LWIP_ARP
  148. /* IP packet? */
  149. case PP_HTONS(ETHTYPE_IP):
  150. if (!(netif->flags & NETIF_FLAG_ETHARP)) {
  151. goto free_and_return;
  152. }
  153. /* skip Ethernet header */
  154. if ((p->len < ip_hdr_offset) || pbuf_header(p, (s16_t)-ip_hdr_offset)) {
  155. LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
  156. ("ethernet_input: IPv4 packet dropped, too short (%"S16_F"/%"S16_F")\n",
  157. p->tot_len, ip_hdr_offset));
  158. LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet"));
  159. goto free_and_return;
  160. } else {
  161. /* pass to IP layer */
  162. ip4_input(p, netif);
  163. }
  164. break;
  165. case PP_HTONS(ETHTYPE_ARP):
  166. if (!(netif->flags & NETIF_FLAG_ETHARP)) {
  167. goto free_and_return;
  168. }
  169. /* skip Ethernet header */
  170. if ((p->len < ip_hdr_offset) || pbuf_header(p, (s16_t)-ip_hdr_offset)) {
  171. LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
  172. ("ethernet_input: ARP response packet dropped, too short (%"S16_F"/%"S16_F")\n",
  173. p->tot_len, ip_hdr_offset));
  174. LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet"));
  175. ETHARP_STATS_INC(etharp.lenerr);
  176. ETHARP_STATS_INC(etharp.drop);
  177. goto free_and_return;
  178. } else {
  179. /* pass p to ARP module */
  180. etharp_input(p, netif);
  181. }
  182. break;
  183. #endif /* LWIP_IPV4 && LWIP_ARP */
  184. #if PPPOE_SUPPORT
  185. case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */
  186. pppoe_disc_input(netif, p);
  187. break;
  188. case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */
  189. pppoe_data_input(netif, p);
  190. break;
  191. #endif /* PPPOE_SUPPORT */
  192. #if LWIP_IPV6
  193. case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */
  194. /* skip Ethernet header */
  195. if ((p->len < ip_hdr_offset) || pbuf_header(p, (s16_t)-ip_hdr_offset)) {
  196. LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
  197. ("ethernet_input: IPv6 packet dropped, too short (%"S16_F"/%"S16_F")\n",
  198. p->tot_len, ip_hdr_offset));
  199. goto free_and_return;
  200. } else {
  201. /* pass to IPv6 layer */
  202. ip6_input(p, netif);
  203. }
  204. break;
  205. #endif /* LWIP_IPV6 */
  206. default:
  207. #ifdef LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
  208. if(LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(p, netif) == ERR_OK) {
  209. break;
  210. }
  211. #endif
  212. ETHARP_STATS_INC(etharp.proterr);
  213. ETHARP_STATS_INC(etharp.drop);
  214. MIB2_STATS_NETIF_INC(netif, ifinunknownprotos);
  215. goto free_and_return;
  216. }
  217. /* This means the pbuf is freed or consumed,
  218. so the caller doesn't have to free it again */
  219. return ERR_OK;
  220. free_and_return:
  221. pbuf_free(p);
  222. return ERR_OK;
  223. }
  224. /**
  225. * @ingroup ethernet
  226. * Send an ethernet packet on the network using netif->linkoutput().
  227. * The ethernet header is filled in before sending.
  228. *
  229. * @see LWIP_HOOK_VLAN_SET
  230. *
  231. * @param netif the lwIP network interface on which to send the packet
  232. * @param p the packet to send. pbuf layer must be @ref PBUF_LINK.
  233. * @param src the source MAC address to be copied into the ethernet header
  234. * @param dst the destination MAC address to be copied into the ethernet header
  235. * @param eth_type ethernet type (@ref eth_type)
  236. * @return ERR_OK if the packet was sent, any other err_t on failure
  237. */
  238. err_t
  239. ethernet_output(struct netif* netif, struct pbuf* p,
  240. const struct eth_addr* src, const struct eth_addr* dst,
  241. u16_t eth_type)
  242. {
  243. struct eth_hdr* ethhdr;
  244. u16_t eth_type_be = lwip_htons(eth_type);
  245. #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
  246. s32_t vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type);
  247. if (vlan_prio_vid >= 0) {
  248. struct eth_vlan_hdr* vlanhdr;
  249. LWIP_ASSERT("prio_vid must be <= 0xFFFF", vlan_prio_vid <= 0xFFFF);
  250. if (pbuf_header(p, SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) != 0) {
  251. goto pbuf_header_failed;
  252. }
  253. vlanhdr = (struct eth_vlan_hdr*)(((u8_t*)p->payload) + SIZEOF_ETH_HDR);
  254. vlanhdr->tpid = eth_type_be;
  255. vlanhdr->prio_vid = lwip_htons((u16_t)vlan_prio_vid);
  256. eth_type_be = PP_HTONS(ETHTYPE_VLAN);
  257. } else
  258. #endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
  259. {
  260. if (pbuf_header(p, SIZEOF_ETH_HDR) != 0) {
  261. goto pbuf_header_failed;
  262. }
  263. }
  264. ethhdr = (struct eth_hdr*)p->payload;
  265. ethhdr->type = eth_type_be;
  266. ETHADDR32_COPY(&ethhdr->dest, dst);
  267. ETHADDR16_COPY(&ethhdr->src, src);
  268. LWIP_ASSERT("netif->hwaddr_len must be 6 for ethernet_output!",
  269. (netif->hwaddr_len == ETH_HWADDR_LEN));
  270. LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
  271. ("ethernet_output: sending packet %p\n", (void *)p));
  272. /* send the packet */
  273. return netif->linkoutput(netif, p);
  274. pbuf_header_failed:
  275. LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
  276. ("ethernet_output: could not allocate room for header.\n"));
  277. LINK_STATS_INC(link.lenerr);
  278. return ERR_BUF;
  279. }
  280. #endif /* LWIP_ARP || LWIP_ETHERNET */