48 #if LWIP_ARP || LWIP_ETHERNET 66 const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
67 const struct eth_addr ethzero = {{0,0,0,0,0,0}};
70 #define LL_MULTICAST_ADDR_0 0x01 71 #define LL_MULTICAST_ADDR_1 0x00 72 #define LL_MULTICAST_ADDR_2 0x5e 74 #if LWIP_IPV4 && LWIP_ARP 78 #define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30) 79 #define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15) 88 #define ARP_MAXPENDING 5 90 #define HWTYPE_ETHERNET 1 93 ETHARP_STATE_EMPTY = 0,
96 ETHARP_STATE_STABLE_REREQUESTING_1,
97 ETHARP_STATE_STABLE_REREQUESTING_2
98 #if ETHARP_SUPPORT_STATIC_ENTRIES 103 struct etharp_entry {
106 struct etharp_q_entry *q;
113 struct eth_addr ethaddr;
120 #if !LWIP_NETIF_HWADDRHINT 121 static u8_t etharp_cached_entry;
126 #define ETHARP_FLAG_TRY_HARD 1 127 #define ETHARP_FLAG_FIND_ONLY 2 128 #if ETHARP_SUPPORT_STATIC_ENTRIES 129 #define ETHARP_FLAG_STATIC_ENTRY 4 132 #if LWIP_NETIF_HWADDRHINT 133 #define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ 134 *((netif)->addr_hint) = (hint); 136 #define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) 141 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) 142 #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" 146 static err_t etharp_request_dst(
struct netif *
netif,
const ip4_addr_t *ipaddr,
const struct eth_addr* hw_dst_addr);
156 free_etharp_q(
struct etharp_q_entry *q)
158 struct etharp_q_entry *r;
172 #define free_etharp_q(q) pbuf_free(q) 178 etharp_free_entry(
int i)
183 if (arp_table[i].q !=
NULL) {
186 free_etharp_q(arp_table[i].q);
187 arp_table[i].q =
NULL;
190 arp_table[i].state = ETHARP_STATE_EMPTY;
193 arp_table[i].ctime = 0;
194 arp_table[i].netif =
NULL;
195 ip4_addr_set_zero(&arp_table[i].ipaddr);
196 arp_table[i].ethaddr = ethzero;
214 u8_t state = arp_table[i].state;
215 if (state != ETHARP_STATE_EMPTY
217 && (state != ETHARP_STATE_STATIC)
220 arp_table[i].ctime++;
222 ((arp_table[i].state == ETHARP_STATE_PENDING) &&
223 (arp_table[i].ctime >= ARP_MAXPENDING))) {
226 arp_table[i].state >= ETHARP_STATE_STABLE ?
"stable" :
"pending", (
u16_t)i));
228 etharp_free_entry(i);
229 }
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
231 arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
232 }
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) {
235 arp_table[i].state = ETHARP_STATE_STABLE;
236 }
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
238 etharp_request(arp_table[i].
netif, &arp_table[i].ipaddr);
266 etharp_find_entry(
const ip4_addr_t *ipaddr,
u8_t flags,
struct netif*
netif)
274 u16_t age_queue = 0, age_pending = 0, age_stable = 0;
294 u8_t state = arp_table[i].state;
296 if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
300 }
else if (state != ETHARP_STATE_EMPTY) {
301 LWIP_ASSERT(
"state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
302 state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
304 if (ipaddr && ip4_addr_cmp(ipaddr, &arp_table[i].ipaddr)
306 && ((netif ==
NULL) || (netif == arp_table[i].netif))
314 if (state == ETHARP_STATE_PENDING) {
316 if (arp_table[i].q !=
NULL) {
317 if (arp_table[i].ctime >= age_queue) {
319 age_queue = arp_table[i].ctime;
324 if (arp_table[i].ctime >= age_pending) {
326 age_pending = arp_table[i].ctime;
330 }
else if (state >= ETHARP_STATE_STABLE) {
331 #if ETHARP_SUPPORT_STATIC_ENTRIES 333 if (state < ETHARP_STATE_STATIC)
337 if (arp_table[i].ctime >= age_stable) {
339 age_stable = arp_table[i].ctime;
348 if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
350 ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
365 if (empty < ARP_TABLE_SIZE) {
370 if (old_stable < ARP_TABLE_SIZE) {
377 }
else if (old_pending < ARP_TABLE_SIZE) {
382 }
else if (old_queue < ARP_TABLE_SIZE) {
393 LWIP_ASSERT(
"i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
394 etharp_free_entry(i);
397 LWIP_ASSERT(
"i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
398 LWIP_ASSERT(
"arp_table[i].state == ETHARP_STATE_EMPTY",
399 arp_table[i].state == ETHARP_STATE_EMPTY);
402 if (ipaddr !=
NULL) {
404 ip4_addr_copy(arp_table[i].ipaddr, *ipaddr);
406 arp_table[i].ctime = 0;
407 #if ETHARP_TABLE_MATCH_NETIF 408 arp_table[i].netif = netif;
424 etharp_send_ip(
struct netif *netif,
struct pbuf *p,
struct eth_addr *src,
const struct eth_addr *dst)
426 struct eth_hdr *ethhdr = (
struct eth_hdr *)p->
payload;
428 struct eth_vlan_hdr *vlanhdr;
431 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
433 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) 434 ethhdr->type =
PP_HTONS(ETHTYPE_VLAN);
435 vlanhdr = (
struct eth_vlan_hdr*)(((
u8_t*)ethhdr) + SIZEOF_ETH_HDR);
436 vlanhdr->prio_vid = 0;
437 vlanhdr->tpid =
PP_HTONS(ETHTYPE_IP);
438 if (!LWIP_HOOK_VLAN_SET(netif, ethhdr, vlanhdr)) {
441 ethhdr = (
struct eth_hdr *)p->
payload;
443 ethhdr->type =
PP_HTONS(ETHTYPE_IP);
444 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) 447 ETHADDR32_COPY(ðhdr->dest, dst);
448 ETHADDR16_COPY(ðhdr->src, src);
473 etharp_update_arp_entry(
struct netif *netif,
const ip4_addr_t *ipaddr,
struct eth_addr *ethaddr,
u8_t flags)
478 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
479 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
480 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
482 if (ip4_addr_isany(ipaddr) ||
483 ip4_addr_isbroadcast(ipaddr, netif) ||
484 ip4_addr_ismulticast(ipaddr)) {
489 i = etharp_find_entry(ipaddr, flags, netif);
495 #if ETHARP_SUPPORT_STATIC_ENTRIES 496 if (flags & ETHARP_FLAG_STATIC_ENTRY) {
498 arp_table[i].state = ETHARP_STATE_STATIC;
503 arp_table[i].state = ETHARP_STATE_STABLE;
507 arp_table[i].netif = netif;
513 ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
515 arp_table[i].ctime = 0;
518 while (arp_table[i].q !=
NULL) {
521 struct etharp_q_entry *q = arp_table[i].q;
523 arp_table[i].q = q->
next;
529 if (arp_table[i].q !=
NULL) {
530 struct pbuf *p = arp_table[i].q;
531 arp_table[i].q =
NULL;
534 etharp_send_ip(netif, p, (
struct eth_addr*)(netif->
hwaddr), ethaddr);
541 #if ETHARP_SUPPORT_STATIC_ENTRIES 551 etharp_add_static_entry(
const ip4_addr_t *ipaddr,
struct eth_addr *ethaddr)
555 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
556 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
557 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
559 netif = ip4_route(ipaddr);
564 return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
576 etharp_remove_static_entry(
const ip4_addr_t *ipaddr)
580 ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
583 i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY,
NULL);
589 if (arp_table[i].state != ETHARP_STATE_STATIC) {
594 etharp_free_entry(i);
604 void etharp_cleanup_netif(
struct netif *netif)
609 u8_t state = arp_table[i].state;
610 if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
611 etharp_free_entry(i);
628 etharp_find_addr(
struct netif *netif,
const ip4_addr_t *ipaddr,
629 struct eth_addr **eth_ret,
const ip4_addr_t **ip_ret)
638 i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif);
639 if ((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
640 *eth_ret = &arp_table[i].ethaddr;
641 *ip_ret = &arp_table[i].ipaddr;
657 etharp_get_entry(
u8_t i, ip4_addr_t **ipaddr,
struct netif **netif,
struct eth_addr **eth_ret)
663 if((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
664 *ipaddr = &arp_table[i].ipaddr;
665 *netif = arp_table[i].netif;
666 *eth_ret = &arp_table[i].ethaddr;
673 #if ETHARP_TRUST_IP_MAC 690 etharp_ip_input(
struct netif *netif,
struct pbuf *p)
692 struct eth_hdr *ethhdr;
693 struct ip_hdr *iphdr;
694 ip4_addr_t iphdr_src;
699 ethhdr = (
struct eth_hdr *)p->
payload;
700 iphdr = (
struct ip_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
701 #if ETHARP_SUPPORT_VLAN 702 if (ethhdr->type ==
PP_HTONS(ETHTYPE_VLAN)) {
703 iphdr = (
struct ip_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
707 ip4_addr_copy(iphdr_src, iphdr->src);
710 if (!ip4_addr_netcmp(&iphdr_src, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
719 etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
739 etharp_arp_input(
struct netif *netif,
struct eth_addr *ethaddr,
struct pbuf *p)
741 struct etharp_hdr *hdr;
742 struct eth_hdr *ethhdr;
744 ip4_addr_t sipaddr, dipaddr;
747 const u8_t * ethdst_hwaddr;
754 if (p->
len < SIZEOF_ETHARP_PACKET) {
756 (
"etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->
tot_len,
757 (
s16_t)SIZEOF_ETHARP_PACKET));
764 ethhdr = (
struct eth_hdr *)p->
payload;
765 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
766 #if ETHARP_SUPPORT_VLAN 767 if (ethhdr->type ==
PP_HTONS(ETHTYPE_VLAN)) {
768 hdr = (
struct etharp_hdr *)(((
u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
773 if ((hdr->hwtype !=
PP_HTONS(HWTYPE_ETHERNET)) ||
774 (hdr->hwlen != ETHARP_HWADDR_LEN) ||
775 (hdr->protolen !=
sizeof(ip4_addr_t)) ||
776 (hdr->proto !=
PP_HTONS(ETHTYPE_IP))) {
778 (
"etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F
"/%"U16_F
"/%"U16_F
"/%"U16_F
")\n",
779 hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen));
791 autoip_arp_reply(netif, hdr);
796 IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
797 IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
800 if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
804 for_us = (
u8_t)ip4_addr_cmp(&dipaddr, netif_ip4_addr(netif));
812 etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
813 for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
816 switch (hdr->opcode) {
831 hdr->opcode =
htons(ARP_REPLY);
833 IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr);
834 IPADDR2_COPY(&hdr->sipaddr, netif_ip4_addr(netif));
836 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
842 ethdst_hwaddr = ip4_addr_islinklocal(netif_ip4_addr(netif)) ? (
const u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr;
845 ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
847 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
849 ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr);
851 ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
852 ETHADDR16_COPY(ðhdr->src, ethaddr);
860 }
else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
872 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) 877 dhcp_arp_reply(netif, &sipaddr);
893 etharp_output_to_arp_index(
struct netif *netif,
struct pbuf *q,
u8_t arp_idx)
895 LWIP_ASSERT(
"arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
896 arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
900 if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) {
901 if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) {
903 if (etharp_request(netif, &arp_table[arp_idx].ipaddr) ==
ERR_OK) {
904 arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
906 }
else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) {
908 if (etharp_request_dst(netif, &arp_table[arp_idx].ipaddr, &arp_table[arp_idx].ethaddr) ==
ERR_OK) {
909 arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
914 return etharp_send_ip(netif, q, (
struct eth_addr*)(netif->
hwaddr),
915 &arp_table[arp_idx].ethaddr);
937 etharp_output(
struct netif *netif,
struct pbuf *q,
const ip4_addr_t *ipaddr)
939 const struct eth_addr *dest;
940 struct eth_addr mcastaddr;
941 const ip4_addr_t *dst_addr = ipaddr;
948 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) 949 if (
pbuf_header(q,
sizeof(
struct eth_hdr) + SIZEOF_VLAN_HDR) != 0) {
955 (
"etharp_output: could not allocate room for header.\n"));
964 if (ip4_addr_isbroadcast(ipaddr, netif)) {
966 dest = (
const struct eth_addr *)ðbroadcast;
968 }
else if (ip4_addr_ismulticast(ipaddr)) {
970 mcastaddr.addr[0] = LL_MULTICAST_ADDR_0;
971 mcastaddr.addr[1] = LL_MULTICAST_ADDR_1;
972 mcastaddr.addr[2] = LL_MULTICAST_ADDR_2;
973 mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
974 mcastaddr.addr[4] = ip4_addr3(ipaddr);
975 mcastaddr.addr[5] = ip4_addr4(ipaddr);
983 if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) &&
984 !ip4_addr_islinklocal(ipaddr)) {
986 struct ip_hdr *iphdr = (
struct ip_hdr*)((
u8_t*)q->
payload +
987 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) 990 sizeof(
struct eth_hdr));
995 if (!ip4_addr_islinklocal(&iphdr->src))
998 #ifdef LWIP_HOOK_ETHARP_GET_GW 1001 dst_addr = LWIP_HOOK_ETHARP_GET_GW(netif, ipaddr);
1002 if (dst_addr ==
NULL)
1006 if (!ip4_addr_isany_val(*netif_ip4_gw(netif))) {
1008 dst_addr = netif_ip4_gw(netif);
1017 #if LWIP_NETIF_HWADDRHINT 1018 if (netif->addr_hint !=
NULL) {
1020 u8_t etharp_cached_entry = *(netif->addr_hint);
1021 if (etharp_cached_entry < ARP_TABLE_SIZE) {
1023 if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
1024 (ip4_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) {
1027 return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
1029 #if LWIP_NETIF_HWADDRHINT 1037 if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
1038 (ip4_addr_cmp(dst_addr, &arp_table[i].ipaddr))) {
1040 ETHARP_SET_HINT(netif, i);
1041 return etharp_output_to_arp_index(netif, q, i);
1046 return etharp_query(netif, dst_addr, q);
1052 return etharp_send_ip(netif, q, (
struct eth_addr*)(netif->
hwaddr), dest);
1089 etharp_query(
struct netif *netif,
const ip4_addr_t *ipaddr,
struct pbuf *q)
1091 struct eth_addr * srcaddr = (
struct eth_addr *)netif->
hwaddr;
1093 int is_new_entry = 0;
1097 if (ip4_addr_isbroadcast(ipaddr, netif) ||
1098 ip4_addr_ismulticast(ipaddr) ||
1099 ip4_addr_isany(ipaddr)) {
1105 i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif);
1118 if (arp_table[i].state == ETHARP_STATE_EMPTY) {
1120 arp_table[i].state = ETHARP_STATE_PENDING;
1122 arp_table[i].netif = netif;
1126 LWIP_ASSERT(
"arp_table[i].state == PENDING or STABLE",
1127 ((arp_table[i].state == ETHARP_STATE_PENDING) ||
1128 (arp_table[i].state >= ETHARP_STATE_STABLE)));
1131 if (is_new_entry || (q ==
NULL)) {
1133 result = etharp_request(netif, ipaddr);
1148 if (arp_table[i].state >= ETHARP_STATE_STABLE) {
1150 ETHARP_SET_HINT(netif, i);
1152 result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
1154 }
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
1157 int copy_needed = 0;
1188 struct etharp_q_entry *new_entry;
1190 new_entry = (
struct etharp_q_entry *)
memp_malloc(MEMP_ARP_QUEUE);
1191 if (new_entry !=
NULL) {
1192 unsigned int qlen = 0;
1193 new_entry->next = 0;
1195 if (arp_table[i].q !=
NULL) {
1197 struct etharp_q_entry *r;
1200 while (r->next !=
NULL) {
1204 r->
next = new_entry;
1207 arp_table[i].q = new_entry;
1211 struct etharp_q_entry *old;
1212 old = arp_table[i].q;
1213 arp_table[i].q = arp_table[i].q->
next;
1228 if (arp_table[i].q !=
NULL) {
1264 etharp_raw(
struct netif *netif,
const struct eth_addr *ethsrc_addr,
1265 const struct eth_addr *ethdst_addr,
1266 const struct eth_addr *hwsrc_addr,
const ip4_addr_t *ipsrc_addr,
1267 const struct eth_addr *hwdst_addr,
const ip4_addr_t *ipdst_addr,
1272 struct eth_hdr *ethhdr;
1273 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) 1274 struct eth_vlan_hdr *vlanhdr;
1276 struct etharp_hdr *hdr;
1278 const u8_t * ethdst_hwaddr;
1288 (
"etharp_raw: could not allocate pbuf for ARP request.\n"));
1292 LWIP_ASSERT(
"check that first pbuf can hold struct etharp_hdr",
1293 (p->
len >= SIZEOF_ETHARP_PACKET_TX));
1295 ethhdr = (
struct eth_hdr *)p->
payload;
1297 vlanhdr = (
struct eth_vlan_hdr*)(((
u8_t*)ethhdr) + SIZEOF_ETH_HDR);
1298 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
1300 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
1303 hdr->opcode =
htons(opcode);
1305 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
1311 ethdst_hwaddr = ip4_addr_islinklocal(ipsrc_addr) ? (
const u8_t*)(ethbroadcast.addr) : ethdst_addr->addr;
1314 ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
1315 ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
1318 IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr);
1319 IPADDR2_COPY(&hdr->dipaddr, ipdst_addr);
1321 hdr->hwtype =
PP_HTONS(HWTYPE_ETHERNET);
1324 hdr->hwlen = ETHARP_HWADDR_LEN;
1325 hdr->protolen =
sizeof(ip4_addr_t);
1327 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) 1328 ethhdr->type =
PP_HTONS(ETHTYPE_VLAN);
1329 vlanhdr->tpid =
PP_HTONS(ETHTYPE_ARP);
1330 vlanhdr->prio_vid = 0;
1331 if (!LWIP_HOOK_VLAN_SET(netif, ethhdr, vlanhdr)) {
1334 ethhdr = (
struct eth_hdr *)p->
payload;
1336 ethhdr->type =
PP_HTONS(ETHTYPE_ARP);
1337 #if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) 1343 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
1345 ETHADDR16_COPY(ðhdr->dest, ethdst_addr);
1347 ETHADDR16_COPY(ðhdr->src, ethsrc_addr);
1373 etharp_request_dst(
struct netif *netif,
const ip4_addr_t *ipaddr,
const struct eth_addr* hw_dst_addr)
1375 return etharp_raw(netif, (
struct eth_addr *)netif->
hwaddr, hw_dst_addr,
1376 (
struct eth_addr *)netif->
hwaddr, netif_ip4_addr(netif), ðzero,
1377 ipaddr, ARP_REQUEST);
1390 etharp_request(
struct netif *netif,
const ip4_addr_t *ipaddr)
1393 return etharp_request_dst(netif, ipaddr, ðbroadcast);
1406 ethernet_input(
struct pbuf *p,
struct netif *netif)
1408 struct eth_hdr* ethhdr;
1410 #if LWIP_ARP || ETHARP_SUPPORT_VLAN || LWIP_IPV6 1411 s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
1414 if (p->
len <= SIZEOF_ETH_HDR) {
1419 goto free_and_return;
1423 ethhdr = (
struct eth_hdr *)p->
payload;
1426 (
unsigned)ethhdr->dest.addr[0], (
unsigned)ethhdr->dest.addr[1], (
unsigned)ethhdr->dest.addr[2],
1427 (
unsigned)ethhdr->dest.addr[3], (
unsigned)ethhdr->dest.addr[4], (
unsigned)ethhdr->dest.addr[5],
1428 (
unsigned)ethhdr->src.addr[0], (
unsigned)ethhdr->src.addr[1], (
unsigned)ethhdr->src.addr[2],
1429 (
unsigned)ethhdr->src.addr[3], (
unsigned)ethhdr->src.addr[4], (
unsigned)ethhdr->src.addr[5],
1430 (
unsigned)
htons(ethhdr->type)));
1432 type = ethhdr->type;
1433 #if ETHARP_SUPPORT_VLAN 1434 if (type ==
PP_HTONS(ETHTYPE_VLAN)) {
1435 struct eth_vlan_hdr *vlan = (
struct eth_vlan_hdr*)(((
char*)ethhdr) + SIZEOF_ETH_HDR);
1436 if (p->
len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
1441 goto free_and_return;
1443 #if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) 1444 #ifdef LWIP_HOOK_VLAN_CHECK 1445 if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) {
1446 #elif defined(ETHARP_VLAN_CHECK_FN) 1447 if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
1448 #elif defined(ETHARP_VLAN_CHECK) 1449 if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
1457 ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
1461 #if LWIP_ARP_FILTER_NETIF 1462 netif = LWIP_ARP_FILTER_NETIF_FN(p, netif,
htons(type));
1465 if (ethhdr->dest.addr[0] & 1) {
1467 if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) {
1468 if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) &&
1469 (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) {
1473 }
else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) {
1480 #if LWIP_IPV4 && LWIP_ARP 1484 goto free_and_return;
1486 #if ETHARP_TRUST_IP_MAC 1488 etharp_ip_input(netif, p);
1493 (
"ethernet_input: IPv4 packet dropped, too short (%"S16_F"/%"S16_F")\n",
1496 goto free_and_return;
1499 ip4_input(p, netif);
1505 goto free_and_return;
1508 etharp_arp_input(netif, (
struct eth_addr*)(netif->
hwaddr), p);
1513 pppoe_disc_input(netif, p);
1517 pppoe_data_input(netif, p);
1526 (
"ethernet_input: IPv6 packet dropped, too short (%"S16_F"/%"S16_F")\n",
1528 goto free_and_return;
1531 ip6_input(p, netif);
1540 goto free_and_return;
#define mib2_remove_arp_entry(ni, ip)
#define LWIP_DBG_LEVEL_SERIOUS
#define LWIP_DBG_LEVEL_WARNING
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
#define ETHARP_SUPPORT_STATIC_ENTRIES
#define PBUF_FLAG_LLBCAST
void memp_free(memp_t type, void *mem)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
#define ETHARP_SUPPORT_VLAN
netif_linkoutput_fn linkoutput
#define mib2_add_arp_entry(ni, ip)
u8_t pbuf_free(struct pbuf *p)
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
#define NETIF_FLAG_ETHARP
#define LINK_STATS_INC(x)
#define LWIP_ASSERT(message, assertion)
void pbuf_ref(struct pbuf *p)
#define PBUF_FLAG_LLMCAST
#define ETHARP_STATS_INC(x)
#define MIB2_STATS_NETIF_INC(n, x)
#define LWIP_ERROR(message, expression, handler)
#define ETHARP_TABLE_MATCH_NETIF
void * memp_malloc(memp_t type)
#define LWIP_DEBUGF(debug, message)
#define LWIP_UNUSED_ARG(x)