48 #if LWIP_ARP || LWIP_ETHERNET 69 const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
70 const struct eth_addr ethzero = {{0,0,0,0,0,0}};
78 #define ARP_MAXAGE 240 81 #define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12) 89 #define ARP_MAXPENDING 2 91 #define HWTYPE_ETHERNET 1 94 ETHARP_STATE_EMPTY = 0,
97 ETHARP_STATE_STABLE_REREQUESTING
100 struct etharp_entry {
103 struct etharp_q_entry *q;
109 struct eth_addr ethaddr;
110 #if LWIP_SNMP || LWIP_ARP 115 #if ETHARP_SUPPORT_STATIC_ENTRIES 122 #if !LWIP_NETIF_HWADDRHINT 123 static u8_t etharp_cached_entry;
128 #define ETHARP_FLAG_TRY_HARD 1 129 #define ETHARP_FLAG_FIND_ONLY 2 130 #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)) 143 #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) 144 #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" 155 free_etharp_q(
struct etharp_q_entry *q)
157 struct etharp_q_entry *r;
171 #define free_etharp_q(q) pbuf_free(q) 182 if (arp_table[i].q !=
NULL) {
185 free_etharp_q(arp_table[i].q);
186 arp_table[i].q =
NULL;
189 arp_table[i].state = ETHARP_STATE_EMPTY;
190 #if ETHARP_SUPPORT_STATIC_ENTRIES 191 arp_table[i].static_entry = 0;
195 arp_table[i].ctime = 0;
197 arp_table[i].netif =
NULL;
200 arp_table[i].ethaddr = ethzero;
219 if (state != ETHARP_STATE_EMPTY
221 && (arp_table[i].static_entry == 0)
224 arp_table[i].ctime++;
225 if ((arp_table[i].ctime >= ARP_MAXAGE) ||
226 ((arp_table[i].state == ETHARP_STATE_PENDING) &&
227 (arp_table[i].ctime >= ARP_MAXPENDING))) {
230 arp_table[i].state >= ETHARP_STATE_STABLE ?
"stable" :
"pending", (
u16_t)i));
234 else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) {
237 arp_table[i].state = ETHARP_STATE_STABLE;
241 if (arp_table[i].state == ETHARP_STATE_PENDING) {
275 u8_t i = 0, age_pending = 0, age_stable = 0;
297 u8_t state = arp_table[i].state;
299 if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
303 }
else if (state != ETHARP_STATE_EMPTY) {
304 LWIP_ASSERT(
"state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
305 state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
307 if (ipaddr &&
ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
313 if (state == ETHARP_STATE_PENDING) {
315 if (arp_table[i].q !=
NULL) {
316 if (arp_table[i].ctime >= age_queue) {
318 age_queue = arp_table[i].ctime;
323 if (arp_table[i].ctime >= age_pending) {
325 age_pending = arp_table[i].ctime;
329 }
else if (state >= ETHARP_STATE_STABLE) {
330 #if ETHARP_SUPPORT_STATIC_ENTRIES 332 if (arp_table[i].static_entry == 0)
336 if (arp_table[i].ctime >= age_stable) {
338 age_stable = arp_table[i].ctime;
347 if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
349 ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
364 if (empty < ARP_TABLE_SIZE) {
369 if (old_stable < ARP_TABLE_SIZE) {
376 }
else if (old_pending < ARP_TABLE_SIZE) {
381 }
else if (old_queue < ARP_TABLE_SIZE) {
392 LWIP_ASSERT(
"i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
396 LWIP_ASSERT(
"i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
397 LWIP_ASSERT(
"arp_table[i].state == ETHARP_STATE_EMPTY",
398 arp_table[i].state == ETHARP_STATE_EMPTY);
401 if (ipaddr !=
NULL) {
405 arp_table[i].ctime = 0;
406 #if ETHARP_SUPPORT_STATIC_ENTRIES 407 arp_table[i].static_entry = 0;
423 etharp_send_ip(
struct netif *
netif,
struct pbuf *p,
struct eth_addr *src,
struct eth_addr *dst)
425 struct eth_hdr *ethhdr = (
struct eth_hdr *)p->
payload;
427 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
429 ETHADDR32_COPY(ðhdr->dest, dst);
430 ETHADDR16_COPY(ðhdr->src, src);
431 ethhdr->type =
PP_HTONS(ETHTYPE_IP);
456 update_arp_entry(
struct netif *netif,
ip_addr_t *ipaddr,
struct eth_addr *ethaddr,
u8_t flags)
462 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
463 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
472 i = find_entry(ipaddr, flags);
478 #if ETHARP_SUPPORT_STATIC_ENTRIES 479 if (flags & ETHARP_FLAG_STATIC_ENTRY) {
481 arp_table[i].static_entry = 1;
486 arp_table[i].state = ETHARP_STATE_STABLE;
490 arp_table[i].netif = netif;
497 ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
499 arp_table[i].ctime = 0;
502 while (arp_table[i].q !=
NULL) {
505 struct etharp_q_entry *q = arp_table[i].q;
507 arp_table[i].q = q->
next;
513 if (arp_table[i].q !=
NULL) {
514 struct pbuf *p = arp_table[i].q;
515 arp_table[i].q =
NULL;
518 etharp_send_ip(netif, p, (
struct eth_addr*)(netif->
hwaddr), ethaddr);
525 #if ETHARP_SUPPORT_STATIC_ENTRIES 535 etharp_add_static_entry(
ip_addr_t *ipaddr,
struct eth_addr *ethaddr)
540 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
541 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
548 return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
560 etharp_remove_static_entry(
ip_addr_t *ipaddr)
567 i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
573 if ((arp_table[i].state != ETHARP_STATE_STABLE) ||
574 (arp_table[i].static_entry == 0)) {
594 u8_t state = arp_table[i].state;
595 if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
613 etharp_find_addr(
struct netif *netif,
ip_addr_t *ipaddr,
614 struct eth_addr **eth_ret,
ip_addr_t **ip_ret)
623 i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
624 if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
625 *eth_ret = &arp_table[i].ethaddr;
626 *ip_ret = &arp_table[i].ipaddr;
632 #if ETHARP_TRUST_IP_MAC 649 etharp_ip_input(
struct netif *netif,
struct pbuf *p)
651 struct eth_hdr *ethhdr;
658 ethhdr = (
struct eth_hdr *)p->
payload;
659 iphdr = (
struct ip_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
660 #if ETHARP_SUPPORT_VLAN 661 if (ethhdr->type == ETHTYPE_VLAN) {
662 iphdr = (
struct ip_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
678 update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
698 etharp_arp_input(
struct netif *netif,
struct eth_addr *ethaddr,
struct pbuf *p)
700 struct etharp_hdr *hdr;
701 struct eth_hdr *ethhdr;
706 const u8_t * ethdst_hwaddr;
716 if (p->
len < SIZEOF_ETHARP_PACKET) {
718 (
"etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->
tot_len,
719 (
s16_t)SIZEOF_ETHARP_PACKET));
726 ethhdr = (
struct eth_hdr *)p->
payload;
727 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
728 #if ETHARP_SUPPORT_VLAN 729 if (ethhdr->type == ETHTYPE_VLAN) {
730 hdr = (
struct etharp_hdr *)(((
u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
735 if ((hdr->hwtype !=
PP_HTONS(HWTYPE_ETHERNET)) ||
736 (hdr->hwlen != ETHARP_HWADDR_LEN) ||
738 (hdr->proto !=
PP_HTONS(ETHTYPE_IP)) ||
739 (ethhdr->type !=
PP_HTONS(ETHTYPE_ARP))) {
741 (
"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",
742 hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen, ethhdr->type));
754 autoip_arp_reply(netif, hdr);
775 update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
776 for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
779 switch (hdr->opcode) {
794 hdr->opcode =
htons(ARP_REPLY);
799 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
808 ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
810 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
812 ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr);
814 ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
815 ETHADDR16_COPY(ðhdr->src, ethaddr);
853 #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) 858 dhcp_arp_reply(netif, &sipaddr);
874 etharp_output_to_arp_index(
struct netif *netif,
struct pbuf *q,
u8_t arp_idx)
876 LWIP_ASSERT(
"arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
877 arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
881 if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) &&
882 (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) {
883 if (etharp_request(netif, &arp_table[arp_idx].ipaddr) ==
ERR_OK) {
884 arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING;
888 return etharp_send_ip(netif, q, (
struct eth_addr*)(netif->
hwaddr),
889 &arp_table[arp_idx].ethaddr);
911 etharp_output(
struct netif *netif,
struct pbuf *q,
ip_addr_t *ipaddr)
913 struct eth_addr *dest, mcastaddr;
919 (
"etharp_output: could not allocate room for header.\n"));
932 dest = (
struct eth_addr *)ðbroadcast;
936 mcastaddr.addr[0] = 0x01;
937 mcastaddr.addr[1] = 0x00;
938 mcastaddr.addr[2] = 0x5e;
939 mcastaddr.addr[3] =
ip4_addr2(ipaddr) & 0x7f;
953 sizeof(
struct eth_hdr));
964 ipaddr = &(netif->
gw);
972 #if LWIP_NETIF_HWADDRHINT 973 if (netif->addr_hint !=
NULL) {
975 u8_t etharp_cached_entry = *(netif->addr_hint);
976 if (etharp_cached_entry < ARP_TABLE_SIZE) {
978 if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
979 (
ip_addr_cmp(ipaddr, &arp_table[etharp_cached_entry].ipaddr))) {
982 return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
984 #if LWIP_NETIF_HWADDRHINT 991 if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
994 ETHARP_SET_HINT(netif, i);
995 return etharp_output_to_arp_index(netif, q, i);
999 return etharp_query(netif, ipaddr, q);
1005 return etharp_send_ip(netif, q, (
struct eth_addr*)(netif->
hwaddr), dest);
1042 etharp_query(
struct netif *netif,
ip_addr_t *ipaddr,
struct pbuf *q)
1044 struct eth_addr * srcaddr = (
struct eth_addr *)netif->
hwaddr;
1057 i = find_entry(ipaddr, ETHARP_FLAG_TRY_HARD);
1070 if (arp_table[i].state == ETHARP_STATE_EMPTY) {
1071 arp_table[i].state = ETHARP_STATE_PENDING;
1075 LWIP_ASSERT(
"arp_table[i].state == PENDING or STABLE",
1076 ((arp_table[i].state == ETHARP_STATE_PENDING) ||
1077 (arp_table[i].state >= ETHARP_STATE_STABLE)));
1080 if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q ==
NULL)) {
1082 result = etharp_request(netif, ipaddr);
1097 if (arp_table[i].state >= ETHARP_STATE_STABLE) {
1099 ETHARP_SET_HINT(netif, i);
1101 result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
1103 }
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
1106 int copy_needed = 0;
1137 struct etharp_q_entry *new_entry;
1139 new_entry = (
struct etharp_q_entry *)
memp_malloc(MEMP_ARP_QUEUE);
1140 if (new_entry !=
NULL) {
1141 unsigned int qlen = 0;
1142 new_entry->next = 0;
1144 if(arp_table[i].q !=
NULL) {
1146 struct etharp_q_entry *r;
1149 while (r->next !=
NULL) {
1153 r->
next = new_entry;
1156 arp_table[i].q = new_entry;
1159 struct etharp_q_entry *old;
1160 old = arp_table[i].q;
1161 arp_table[i].q = arp_table[i].q->
next;
1175 if (arp_table[i].q !=
NULL) {
1211 etharp_raw(
struct netif *netif,
const struct eth_addr *ethsrc_addr,
1212 const struct eth_addr *ethdst_addr,
1213 const struct eth_addr *hwsrc_addr,
const ip_addr_t *ipsrc_addr,
1214 const struct eth_addr *hwdst_addr,
const ip_addr_t *ipdst_addr,
1219 struct eth_hdr *ethhdr;
1220 struct etharp_hdr *hdr;
1222 const u8_t * ethdst_hwaddr;
1230 (
"etharp_raw: could not allocate pbuf for ARP request.\n"));
1234 LWIP_ASSERT(
"check that first pbuf can hold struct etharp_hdr",
1235 (p->
len >= SIZEOF_ETHARP_PACKET));
1237 ethhdr = (
struct eth_hdr *)p->
payload;
1238 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
1240 hdr->opcode =
htons(opcode);
1242 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
1251 ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
1252 ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
1255 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
1257 ETHADDR16_COPY(ðhdr->dest, ethdst_addr);
1259 ETHADDR16_COPY(ðhdr->src, ethsrc_addr);
1265 hdr->hwtype =
PP_HTONS(HWTYPE_ETHERNET);
1268 hdr->hwlen = ETHARP_HWADDR_LEN;
1271 ethhdr->type =
PP_HTONS(ETHTYPE_ARP);
1293 etharp_request(
struct netif *netif,
ip_addr_t *ipaddr)
1296 return etharp_raw(netif, (
struct eth_addr *)netif->
hwaddr, ðbroadcast,
1297 (
struct eth_addr *)netif->
hwaddr, &netif->
ip_addr, ðzero,
1298 ipaddr, ARP_REQUEST);
1311 ethernet_input(
struct pbuf *p,
struct netif *netif)
1313 struct eth_hdr* ethhdr;
1315 s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
1317 if (p->
len <= SIZEOF_ETH_HDR) {
1321 goto free_and_return;
1325 ethhdr = (
struct eth_hdr *)p->
payload;
1328 (
unsigned)ethhdr->dest.addr[0], (
unsigned)ethhdr->dest.addr[1], (
unsigned)ethhdr->dest.addr[2],
1329 (
unsigned)ethhdr->dest.addr[3], (
unsigned)ethhdr->dest.addr[4], (
unsigned)ethhdr->dest.addr[5],
1330 (
unsigned)ethhdr->src.addr[0], (
unsigned)ethhdr->src.addr[1], (
unsigned)ethhdr->src.addr[2],
1331 (
unsigned)ethhdr->src.addr[3], (
unsigned)ethhdr->src.addr[4], (
unsigned)ethhdr->src.addr[5],
1332 (
unsigned)
htons(ethhdr->type)));
1334 type = ethhdr->type;
1335 #if ETHARP_SUPPORT_VLAN 1336 if (type ==
PP_HTONS(ETHTYPE_VLAN)) {
1337 struct eth_vlan_hdr *vlan = (
struct eth_vlan_hdr*)(((
char*)ethhdr) + SIZEOF_ETH_HDR);
1338 if (p->
len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
1342 goto free_and_return;
1344 #ifdef ETHARP_VLAN_CHECK 1345 if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
1352 ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
1356 #if LWIP_ARP_FILTER_NETIF 1357 netif = LWIP_ARP_FILTER_NETIF_FN(p, netif,
htons(type));
1365 goto free_and_return;
1367 #if ETHARP_TRUST_IP_MAC 1369 etharp_ip_input(netif, p);
1373 LWIP_ASSERT(
"Can't move over header in packet", 0);
1374 goto free_and_return;
1383 goto free_and_return;
1386 etharp_arp_input(netif, (
struct eth_addr*)(netif->
hwaddr), p);
1391 pppoe_disc_input(netif, p);
1395 pppoe_data_input(netif, p);
1402 goto free_and_return;
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
#define ip4_addr3_16(ipaddr)
void memp_free(memp_t type, void *mem) ICACHE_FLASH_ATTR
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) ICACHE_FLASH_ATTR
#define ip_addr_netcmp(addr1, addr2, mask)
#define ETHARP_SUPPORT_STATIC_ENTRIES
const ip_addr_t ip_addr_any ICACHE_RODATA_ATTR
#define ICACHE_FLASH_ATTR
void * memp_malloc(memp_t type) ICACHE_FLASH_ATTR
#define LWIP_ERROR(message, expression, handler)
struct netif * ip_route(ip_addr_t *dest) ICACHE_FLASH_ATTR
#define ip_addr_islinklocal(addr1)
#define snmp_delete_arpidx_tree(ni, ip)
#define NETIF_FLAG_ETHARP
#define LWIP_DEBUGF(debug, message)
#define ip_addr_cmp(addr1, addr2)
#define ip_addr_copy(dest, src)
#define LWIP_DBG_LEVEL_SERIOUS
#define IPADDR2_COPY(dest, src)
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
#define LINK_STATS_INC(x)
#define LWIP_DBG_LEVEL_WARNING
#define ip4_addr4_16(ipaddr)
#define snmp_insert_arpidx_tree(ni, ip)
#define ip_addr_isany(addr1)
#define ip4_addr3(ipaddr)
#define ip_addr_set_zero(ipaddr)
#define ETHARP_STATS_INC(x)
u8_t pbuf_free(struct pbuf *p) ICACHE_FLASH_ATTR
void pbuf_ref(struct pbuf *p) ICACHE_FLASH_ATTR
#define ip_addr_isbroadcast(ipaddr, netif)
u8_t pbuf_header(struct pbuf *p, s16_t header_size) ICACHE_FLASH_ATTR
#define ip4_addr1_16(ipaddr)
#define LWIP_ASSERT(message, assertion)
err_t ip_input(struct pbuf *p, struct netif *inp) ICACHE_FLASH_ATTR
#define ip4_addr2(ipaddr)
#define ip4_addr2_16(ipaddr)
#define ip4_addr4(ipaddr)
#define ip_addr_ismulticast(addr1)
netif_linkoutput_fn linkoutput
#define LWIP_UNUSED_ARG(x)
struct pbuf * pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type) ICACHE_FLASH_ATTR