48 #if LWIP_ARP || LWIP_ETHERNET
50 #include "lwip/ip_addr.h"
65 const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
66 const struct eth_addr ethzero = {{0,0,0,0,0,0}};
74 #define ARP_MAXAGE 240
82 #define ARP_MAXPENDING 2
84 #define HWTYPE_ETHERNET 1
87 ETHARP_STATE_EMPTY = 0,
95 struct etharp_q_entry *q;
101 struct eth_addr ethaddr;
107 #if ETHARP_SUPPORT_STATIC_ENTRIES
114 #if !LWIP_NETIF_HWADDRHINT
115 static u8_t etharp_cached_entry;
120 #define ETHARP_FLAG_TRY_HARD 1
121 #define ETHARP_FLAG_FIND_ONLY 2
122 #define ETHARP_FLAG_STATIC_ENTRY 4
124 #if LWIP_NETIF_HWADDRHINT
125 #define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \
126 *((netif)->addr_hint) = (hint);
128 #define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint))
135 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
136 #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h"
147 free_etharp_q(
struct etharp_q_entry *q)
149 struct etharp_q_entry *r;
163 #define free_etharp_q(q) pbuf_free(q)
174 if (arp_table[i].q !=
NULL) {
177 free_etharp_q(arp_table[i].q);
178 arp_table[i].q =
NULL;
181 arp_table[i].state = ETHARP_STATE_EMPTY;
182 #if ETHARP_SUPPORT_STATIC_ENTRIES
183 arp_table[i].static_entry = 0;
187 arp_table[i].ctime = 0;
189 arp_table[i].netif =
NULL;
192 arp_table[i].ethaddr = ethzero;
210 u8_t state = arp_table[i].state;
211 if (state != ETHARP_STATE_EMPTY
213 && (arp_table[i].static_entry == 0)
216 arp_table[i].ctime++;
217 if ((arp_table[i].ctime >= ARP_MAXAGE) ||
218 ((arp_table[i].state == ETHARP_STATE_PENDING) &&
219 (arp_table[i].ctime >= ARP_MAXPENDING))) {
222 arp_table[i].state == ETHARP_STATE_STABLE ?
"stable" :
"pending", (
u16_t)i));
228 if (arp_table[i].state == ETHARP_STATE_PENDING) {
262 u8_t i = 0, age_pending = 0, age_stable = 0;
284 u8_t state = arp_table[i].state;
286 if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
290 }
else if (state != ETHARP_STATE_EMPTY) {
291 LWIP_ASSERT(
"state == ETHARP_STATE_PENDING || state == ETHARP_STATE_STABLE",
292 state == ETHARP_STATE_PENDING || state == ETHARP_STATE_STABLE);
294 if (ipaddr &&
ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
300 if (state == ETHARP_STATE_PENDING) {
302 if (arp_table[i].q !=
NULL) {
303 if (arp_table[i].ctime >= age_queue) {
305 age_queue = arp_table[i].ctime;
310 if (arp_table[i].ctime >= age_pending) {
312 age_pending = arp_table[i].ctime;
316 }
else if (state == ETHARP_STATE_STABLE) {
317 #if ETHARP_SUPPORT_STATIC_ENTRIES
319 if (arp_table[i].static_entry == 0)
323 if (arp_table[i].ctime >= age_stable) {
325 age_stable = arp_table[i].ctime;
334 if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
336 ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
351 if (empty < ARP_TABLE_SIZE) {
356 if (old_stable < ARP_TABLE_SIZE) {
363 }
else if (old_pending < ARP_TABLE_SIZE) {
368 }
else if (old_queue < ARP_TABLE_SIZE) {
379 LWIP_ASSERT(
"i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
383 LWIP_ASSERT(
"i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
384 LWIP_ASSERT(
"arp_table[i].state == ETHARP_STATE_EMPTY",
385 arp_table[i].state == ETHARP_STATE_EMPTY);
388 if (ipaddr !=
NULL) {
392 arp_table[i].ctime = 0;
393 #if ETHARP_SUPPORT_STATIC_ENTRIES
394 arp_table[i].static_entry = 0;
410 etharp_send_ip(
struct netif *
netif,
struct pbuf *p,
struct eth_addr *src,
struct eth_addr *dst)
412 struct eth_hdr *ethhdr = (
struct eth_hdr *)p->
payload;
414 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
416 ETHADDR32_COPY(ðhdr->dest, dst);
417 ETHADDR16_COPY(ðhdr->src, src);
418 ethhdr->type =
PP_HTONS(ETHTYPE_IP);
443 update_arp_entry(
struct netif *netif,
ip_addr_t *ipaddr,
struct eth_addr *ethaddr,
u8_t flags)
449 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
450 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
459 i = find_entry(ipaddr, flags);
465 #if ETHARP_SUPPORT_STATIC_ENTRIES
466 if (flags & ETHARP_FLAG_STATIC_ENTRY) {
468 arp_table[i].static_entry = 1;
473 arp_table[i].state = ETHARP_STATE_STABLE;
477 arp_table[i].netif = netif;
484 ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
486 arp_table[i].ctime = 0;
489 while (arp_table[i].q !=
NULL) {
492 struct etharp_q_entry *q = arp_table[i].q;
494 arp_table[i].q = q->
next;
500 if (arp_table[i].q !=
NULL) {
501 struct pbuf *p = arp_table[i].q;
502 arp_table[i].q =
NULL;
505 etharp_send_ip(netif, p, (
struct eth_addr*)(netif->
hwaddr), ethaddr);
512 #if ETHARP_SUPPORT_STATIC_ENTRIES
522 etharp_add_static_entry(
ip_addr_t *ipaddr,
struct eth_addr *ethaddr)
527 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
528 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
535 return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
547 etharp_remove_static_entry(
ip_addr_t *ipaddr)
554 i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
560 if ((arp_table[i].state != ETHARP_STATE_STABLE) ||
561 (arp_table[i].static_entry == 0)) {
583 etharp_find_addr(
struct netif *netif,
ip_addr_t *ipaddr,
584 struct eth_addr **eth_ret,
ip_addr_t **ip_ret)
593 i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
594 if((i >= 0) && arp_table[i].state == ETHARP_STATE_STABLE) {
595 *eth_ret = &arp_table[i].ethaddr;
596 *ip_ret = &arp_table[i].ipaddr;
602 #if ETHARP_TRUST_IP_MAC
619 etharp_ip_input(
struct netif *netif,
struct pbuf *p)
621 struct eth_hdr *ethhdr;
628 ethhdr = (
struct eth_hdr *)p->
payload;
629 iphdr = (
struct ip_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
630 #if ETHARP_SUPPORT_VLAN
631 if (ethhdr->type == ETHTYPE_VLAN) {
632 iphdr = (
struct ip_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
648 update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
668 etharp_arp_input(
struct netif *netif,
struct eth_addr *ethaddr,
struct pbuf *p)
670 struct etharp_hdr *hdr;
671 struct eth_hdr *ethhdr;
676 const u8_t * ethdst_hwaddr;
683 if (p->
len < SIZEOF_ETHARP_PACKET) {
685 (
"etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->
tot_len,
686 (
s16_t)SIZEOF_ETHARP_PACKET));
693 ethhdr = (
struct eth_hdr *)p->
payload;
694 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
695 #if ETHARP_SUPPORT_VLAN
696 if (ethhdr->type == ETHTYPE_VLAN) {
697 hdr = (
struct etharp_hdr *)(((
u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
702 if ((hdr->hwtype !=
PP_HTONS(HWTYPE_ETHERNET)) ||
703 (hdr->hwlen != ETHARP_HWADDR_LEN) ||
705 (hdr->proto !=
PP_HTONS(ETHTYPE_IP)) ||
706 (ethhdr->type !=
PP_HTONS(ETHTYPE_ARP))) {
708 (
"etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F
"/%"U16_F
"/%"U16_F
"/%"U16_F
"/%"U16_F
")\n",
709 hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen, ethhdr->type));
721 autoip_arp_reply(netif, hdr);
742 update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
743 for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
746 switch (hdr->opcode) {
761 hdr->opcode =
htons(ARP_REPLY);
766 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
775 ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
777 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
779 ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr);
781 ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
782 ETHADDR16_COPY(ðhdr->src, ethaddr);
802 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
807 dhcp_arp_reply(netif, &sipaddr);
838 etharp_output(
struct netif *netif,
struct pbuf *q,
ip_addr_t *ipaddr)
840 struct eth_addr *dest, mcastaddr;
846 (
"etharp_output: could not allocate room for header.\n"));
859 dest = (
struct eth_addr *)ðbroadcast;
863 mcastaddr.addr[0] = 0x01;
864 mcastaddr.addr[1] = 0x00;
865 mcastaddr.addr[2] = 0x5e;
866 mcastaddr.addr[3] =
ip4_addr2(ipaddr) & 0x7f;
878 sizeof(
struct eth_hdr));
889 ipaddr = &(netif->
gw);
897 #if LWIP_NETIF_HWADDRHINT
898 if (netif->addr_hint !=
NULL) {
900 u8_t etharp_cached_entry = *(netif->addr_hint);
901 if (etharp_cached_entry < ARP_TABLE_SIZE) {
903 if ((arp_table[etharp_cached_entry].state == ETHARP_STATE_STABLE) &&
904 (
ip_addr_cmp(ipaddr, &arp_table[etharp_cached_entry].ipaddr))) {
907 return etharp_send_ip(netif, q, (
struct eth_addr*)(netif->
hwaddr),
908 &arp_table[etharp_cached_entry].ethaddr);
910 #if LWIP_NETIF_HWADDRHINT
915 return etharp_query(netif, ipaddr, q);
921 return etharp_send_ip(netif, q, (
struct eth_addr*)(netif->
hwaddr), dest);
958 etharp_query(
struct netif *netif,
ip_addr_t *ipaddr,
struct pbuf *q)
960 struct eth_addr * srcaddr = (
struct eth_addr *)netif->
hwaddr;
973 i = find_entry(ipaddr, ETHARP_FLAG_TRY_HARD);
986 if (arp_table[i].state == ETHARP_STATE_EMPTY) {
987 arp_table[i].state = ETHARP_STATE_PENDING;
991 LWIP_ASSERT(
"arp_table[i].state == PENDING or STABLE",
992 ((arp_table[i].state == ETHARP_STATE_PENDING) ||
993 (arp_table[i].state == ETHARP_STATE_STABLE)));
996 if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q ==
NULL)) {
998 result = etharp_request(netif, ipaddr);
1013 if (arp_table[i].state == ETHARP_STATE_STABLE) {
1015 ETHARP_SET_HINT(netif, i);
1017 result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
1019 }
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
1022 int copy_needed = 0;
1053 struct etharp_q_entry *new_entry;
1055 new_entry = (
struct etharp_q_entry *)
memp_malloc(MEMP_ARP_QUEUE);
1056 if (new_entry !=
NULL) {
1057 new_entry->next = 0;
1059 if(arp_table[i].q !=
NULL) {
1061 struct etharp_q_entry *r;
1063 while (r->next !=
NULL) {
1066 r->
next = new_entry;
1069 arp_table[i].q = new_entry;
1081 if (arp_table[i].q !=
NULL) {
1117 etharp_raw(
struct netif *netif,
const struct eth_addr *ethsrc_addr,
1118 const struct eth_addr *ethdst_addr,
1119 const struct eth_addr *hwsrc_addr,
const ip_addr_t *ipsrc_addr,
1120 const struct eth_addr *hwdst_addr,
const ip_addr_t *ipdst_addr,
1125 struct eth_hdr *ethhdr;
1126 struct etharp_hdr *hdr;
1128 const u8_t * ethdst_hwaddr;
1136 (
"etharp_raw: could not allocate pbuf for ARP request.\n"));
1140 LWIP_ASSERT(
"check that first pbuf can hold struct etharp_hdr",
1141 (p->
len >= SIZEOF_ETHARP_PACKET));
1143 ethhdr = (
struct eth_hdr *)p->
payload;
1144 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
1146 hdr->opcode =
htons(opcode);
1148 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
1157 ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
1158 ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
1161 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
1163 ETHADDR16_COPY(ðhdr->dest, ethdst_addr);
1165 ETHADDR16_COPY(ðhdr->src, ethsrc_addr);
1171 hdr->hwtype =
PP_HTONS(HWTYPE_ETHERNET);
1174 hdr->hwlen = ETHARP_HWADDR_LEN;
1177 ethhdr->type =
PP_HTONS(ETHTYPE_ARP);
1199 etharp_request(
struct netif *netif,
ip_addr_t *ipaddr)
1202 return etharp_raw(netif, (
struct eth_addr *)netif->
hwaddr, ðbroadcast,
1203 (
struct eth_addr *)netif->
hwaddr, &netif->
ip_addr, ðzero,
1204 ipaddr, ARP_REQUEST);
1217 ethernet_input(
struct pbuf *p,
struct netif *netif)
1219 struct eth_hdr* ethhdr;
1223 ethhdr = (
struct eth_hdr *)p->
payload;
1226 (
unsigned)ethhdr->dest.addr[0], (
unsigned)ethhdr->dest.addr[1], (
unsigned)ethhdr->dest.addr[2],
1227 (
unsigned)ethhdr->dest.addr[3], (
unsigned)ethhdr->dest.addr[4], (
unsigned)ethhdr->dest.addr[5],
1228 (
unsigned)ethhdr->src.addr[0], (
unsigned)ethhdr->src.addr[1], (
unsigned)ethhdr->src.addr[2],
1229 (
unsigned)ethhdr->src.addr[3], (
unsigned)ethhdr->src.addr[4], (
unsigned)ethhdr->src.addr[5],
1230 (
unsigned)
htons(ethhdr->type)));
1232 type = ethhdr->type;
1233 #if ETHARP_SUPPORT_VLAN
1234 if (type ==
PP_HTONS(ETHTYPE_VLAN)) {
1235 struct eth_vlan_hdr *vlan = (
struct eth_vlan_hdr*)(((
char*)ethhdr) + SIZEOF_ETH_HDR);
1236 #ifdef ETHARP_VLAN_CHECK
1237 if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
1247 #if LWIP_ARP_FILTER_NETIF
1248 netif = LWIP_ARP_FILTER_NETIF_FN(p, netif,
htons(type));
1256 goto free_and_return;
1258 #if ETHARP_TRUST_IP_MAC
1260 etharp_ip_input(netif, p);
1264 LWIP_ASSERT(
"Can't move over header in packet", 0);
1265 goto free_and_return;
1274 goto free_and_return;
1277 etharp_arp_input(netif, (
struct eth_addr*)(netif->
hwaddr), p);
1282 pppoe_disc_input(netif, p);
1286 pppoe_data_input(netif, p);
1293 goto free_and_return;