48#if LWIP_ARP || LWIP_ETHERNET
50#include "lwip/ip_addr.h"
65const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
66const struct eth_addr ethzero = {{0,0,0,0,0,0}};
69#define LL_MULTICAST_ADDR_0 0x01
70#define LL_MULTICAST_ADDR_1 0x00
71#define LL_MULTICAST_ADDR_2 0x5e
82#define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12)
91#define ARP_MAXPENDING 2
93#define HWTYPE_ETHERNET 1
96 ETHARP_STATE_EMPTY = 0,
99 ETHARP_STATE_STABLE_REREQUESTING
100#if ETHARP_SUPPORT_STATIC_ENTRIES
108 struct etharp_q_entry *q;
115 struct eth_addr ethaddr;
122#if !LWIP_NETIF_HWADDRHINT
123static u8_t etharp_cached_entry;
128#define ETHARP_FLAG_TRY_HARD 1
129#define ETHARP_FLAG_FIND_ONLY 2
130#if ETHARP_SUPPORT_STATIC_ENTRIES
131#define ETHARP_FLAG_STATIC_ENTRY 4
134#if LWIP_NETIF_HWADDRHINT
135#define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \
136 *((netif)->addr_hint) = (hint);
138#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"
155free_etharp_q(
struct etharp_q_entry *q)
157 struct etharp_q_entry *r;
171#define free_etharp_q(q) pbuf_free(q)
177etharp_free_entry(
int i)
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;
192 arp_table[i].ctime = 0;
193 arp_table[i].netif =
NULL;
195 arp_table[i].ethaddr = ethzero;
213 u8_t state = arp_table[i].state;
214 if (state != ETHARP_STATE_EMPTY
216 && (state != ETHARP_STATE_STATIC)
219 arp_table[i].ctime++;
220 if ((arp_table[i].ctime >= ARP_MAXAGE) ||
221 ((arp_table[i].state == ETHARP_STATE_PENDING) &&
222 (arp_table[i].ctime >= ARP_MAXPENDING))) {
225 arp_table[i].state >= ETHARP_STATE_STABLE ?
"stable" :
"pending", (
u16_t)i));
227 etharp_free_entry(i);
229 else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) {
232 arp_table[i].state = ETHARP_STATE_STABLE;
236 if (arp_table[i].state == ETHARP_STATE_PENDING) {
270 u8_t i = 0, age_pending = 0, age_stable = 0;
292 u8_t state = arp_table[i].state;
298 }
else if (state != ETHARP_STATE_EMPTY) {
299 LWIP_ASSERT(
"state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
300 state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
308 if (state == ETHARP_STATE_PENDING) {
310 if (arp_table[i].q !=
NULL) {
311 if (arp_table[i].ctime >= age_queue) {
313 age_queue = arp_table[i].ctime;
318 if (arp_table[i].ctime >= age_pending) {
320 age_pending = arp_table[i].ctime;
324 }
else if (state >= ETHARP_STATE_STABLE) {
325#if ETHARP_SUPPORT_STATIC_ENTRIES
327 if (state < ETHARP_STATE_STATIC)
331 if (arp_table[i].ctime >= age_stable) {
333 age_stable = arp_table[i].ctime;
342 if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
344 ((empty ==
ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
388 etharp_free_entry(i);
392 LWIP_ASSERT(
"arp_table[i].state == ETHARP_STATE_EMPTY",
393 arp_table[i].state == ETHARP_STATE_EMPTY);
400 arp_table[i].ctime = 0;
415etharp_send_ip(
struct netif *
netif,
struct pbuf *p,
struct eth_addr *src,
struct eth_addr *dst)
417 struct eth_hdr *ethhdr = (
struct eth_hdr *)p->
payload;
419 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
421 ETHADDR32_COPY(ðhdr->dest, dst);
422 ETHADDR16_COPY(ðhdr->src, src);
423 ethhdr->type =
PP_HTONS(ETHTYPE_IP);
454 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
455 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
464 i = etharp_find_entry(
ipaddr, flags);
470#if ETHARP_SUPPORT_STATIC_ENTRIES
471 if (flags & ETHARP_FLAG_STATIC_ENTRY) {
473 arp_table[i].state = ETHARP_STATE_STATIC;
478 arp_table[i].state = ETHARP_STATE_STABLE;
482 arp_table[i].netif =
netif;
488 ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
490 arp_table[i].ctime = 0;
493 while (arp_table[i].q !=
NULL) {
496 struct etharp_q_entry *q = arp_table[i].q;
498 arp_table[i].q = q->
next;
504 if (arp_table[i].q !=
NULL) {
505 struct pbuf *p = arp_table[i].q;
506 arp_table[i].q =
NULL;
516#if ETHARP_SUPPORT_STATIC_ENTRIES
531 ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
532 ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
539 return etharp_update_arp_entry(
netif,
ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
558 i = etharp_find_entry(
ipaddr, ETHARP_FLAG_FIND_ONLY);
564 if (arp_table[i].
state != ETHARP_STATE_STATIC) {
569 etharp_free_entry(i);
586 etharp_free_entry(i);
604 struct eth_addr **eth_ret,
ip_addr_t **ip_ret)
613 i = etharp_find_entry(
ipaddr, ETHARP_FLAG_FIND_ONLY);
614 if((i >= 0) && (arp_table[i].
state >= ETHARP_STATE_STABLE)) {
615 *eth_ret = &arp_table[i].ethaddr;
616 *ip_ret = &arp_table[i].ipaddr;
622#if ETHARP_TRUST_IP_MAC
641 struct eth_hdr *ethhdr;
648 ethhdr = (
struct eth_hdr *)p->
payload;
649 iphdr = (
struct ip_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
650#if ETHARP_SUPPORT_VLAN
651 if (ethhdr->type ==
PP_HTONS(ETHTYPE_VLAN)) {
652 iphdr = (
struct ip_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
668 etharp_update_arp_entry(
netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
688etharp_arp_input(
struct netif *
netif,
struct eth_addr *ethaddr,
struct pbuf *p)
690 struct etharp_hdr *hdr;
691 struct eth_hdr *ethhdr;
696 const u8_t * ethdst_hwaddr;
703 if (p->
len < SIZEOF_ETHARP_PACKET) {
705 (
"etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->
tot_len,
706 (
s16_t)SIZEOF_ETHARP_PACKET));
713 ethhdr = (
struct eth_hdr *)p->
payload;
714 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
715#if ETHARP_SUPPORT_VLAN
716 if (ethhdr->type ==
PP_HTONS(ETHTYPE_VLAN)) {
717 hdr = (
struct etharp_hdr *)(((
u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
722 if ((hdr->hwtype !=
PP_HTONS(HWTYPE_ETHERNET)) ||
723 (hdr->hwlen != ETHARP_HWADDR_LEN) ||
725 (hdr->proto !=
PP_HTONS(ETHTYPE_IP))) {
727 (
"etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
728 hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen));
740 autoip_arp_reply(
netif, hdr);
761 etharp_update_arp_entry(
netif, &sipaddr, &(hdr->shwaddr),
762 for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
765 switch (hdr->opcode) {
780 hdr->opcode =
htons(ARP_REPLY);
785 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
794 ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
796 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
798 ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr);
800 ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
801 ETHADDR16_COPY(ðhdr->src, ethaddr);
821#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
826 dhcp_arp_reply(
netif, &sipaddr);
844 LWIP_ASSERT(
"arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
845 arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
849 if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) &&
850 (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) {
852 arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING;
857 &arp_table[arp_idx].ethaddr);
881 struct eth_addr *dest;
882 struct eth_addr mcastaddr;
893 (
"etharp_output: could not allocate room for header.\n"));
904 dest = (
struct eth_addr *)ðbroadcast;
908 mcastaddr.addr[0] = LL_MULTICAST_ADDR_0;
909 mcastaddr.addr[1] = LL_MULTICAST_ADDR_1;
910 mcastaddr.addr[2] = LL_MULTICAST_ADDR_2;
925 sizeof(
struct eth_hdr));
944#if LWIP_NETIF_HWADDRHINT
947 u8_t etharp_cached_entry = *(
netif->addr_hint);
950 if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
954 return etharp_output_to_arp_index(
netif, q, etharp_cached_entry);
956#if LWIP_NETIF_HWADDRHINT
964 if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
967 ETHARP_SET_HINT(
netif, i);
968 return etharp_output_to_arp_index(
netif, q, i);
973 return etharp_query(
netif, dst_addr, q);
1018 struct eth_addr * srcaddr = (
struct eth_addr *)
netif->
hwaddr;
1031 i = etharp_find_entry(
ipaddr, ETHARP_FLAG_TRY_HARD);
1044 if (arp_table[i].state == ETHARP_STATE_EMPTY) {
1045 arp_table[i].state = ETHARP_STATE_PENDING;
1049 LWIP_ASSERT(
"arp_table[i].state == PENDING or STABLE",
1050 ((arp_table[i].state == ETHARP_STATE_PENDING) ||
1051 (arp_table[i].state >= ETHARP_STATE_STABLE)));
1054 if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q ==
NULL)) {
1071 if (arp_table[i].state >= ETHARP_STATE_STABLE) {
1073 ETHARP_SET_HINT(
netif, i);
1075 result = etharp_send_ip(
netif, q, srcaddr, &(arp_table[i].ethaddr));
1077 }
else if (arp_table[i].state == ETHARP_STATE_PENDING) {
1080 int copy_needed = 0;
1111 struct etharp_q_entry *new_entry;
1113 new_entry = (
struct etharp_q_entry *)
memp_malloc(MEMP_ARP_QUEUE);
1114 if (new_entry !=
NULL) {
1115 new_entry->next = 0;
1117 if(arp_table[i].q !=
NULL) {
1119 struct etharp_q_entry *r;
1121 while (r->next !=
NULL) {
1124 r->
next = new_entry;
1127 arp_table[i].q = new_entry;
1139 if (arp_table[i].q !=
NULL) {
1175etharp_raw(
struct netif *
netif,
const struct eth_addr *ethsrc_addr,
1176 const struct eth_addr *ethdst_addr,
1177 const struct eth_addr *hwsrc_addr,
const ip_addr_t *ipsrc_addr,
1178 const struct eth_addr *hwdst_addr,
const ip_addr_t *ipdst_addr,
1183 struct eth_hdr *ethhdr;
1184 struct etharp_hdr *hdr;
1186 const u8_t * ethdst_hwaddr;
1196 (
"etharp_raw: could not allocate pbuf for ARP request.\n"));
1200 LWIP_ASSERT(
"check that first pbuf can hold struct etharp_hdr",
1201 (p->
len >= SIZEOF_ETHARP_PACKET));
1203 ethhdr = (
struct eth_hdr *)p->
payload;
1204 hdr = (
struct etharp_hdr *)((
u8_t*)ethhdr + SIZEOF_ETH_HDR);
1206 hdr->opcode =
htons(opcode);
1208 LWIP_ASSERT(
"netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
1217 ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
1218 ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
1221 ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr);
1223 ETHADDR16_COPY(ðhdr->dest, ethdst_addr);
1225 ETHADDR16_COPY(ðhdr->src, ethsrc_addr);
1231 hdr->hwtype =
PP_HTONS(HWTYPE_ETHERNET);
1234 hdr->hwlen = ETHARP_HWADDR_LEN;
1237 ethhdr->type =
PP_HTONS(ETHTYPE_ARP);
1279 struct eth_hdr* ethhdr;
1281#if LWIP_ARP || ETHARP_SUPPORT_VLAN
1282 s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
1285 if (p->
len <= SIZEOF_ETH_HDR) {
1289 goto free_and_return;
1293 ethhdr = (
struct eth_hdr *)p->
payload;
1296 (
unsigned)ethhdr->dest.addr[0], (
unsigned)ethhdr->dest.addr[1], (
unsigned)ethhdr->dest.addr[2],
1297 (
unsigned)ethhdr->dest.addr[3], (
unsigned)ethhdr->dest.addr[4], (
unsigned)ethhdr->dest.addr[5],
1298 (
unsigned)ethhdr->src.addr[0], (
unsigned)ethhdr->src.addr[1], (
unsigned)ethhdr->src.addr[2],
1299 (
unsigned)ethhdr->src.addr[3], (
unsigned)ethhdr->src.addr[4], (
unsigned)ethhdr->src.addr[5],
1300 (
unsigned)
htons(ethhdr->type)));
1302 type = ethhdr->type;
1303#if ETHARP_SUPPORT_VLAN
1305 struct eth_vlan_hdr *vlan = (
struct eth_vlan_hdr*)(((
char*)ethhdr) + SIZEOF_ETH_HDR);
1306 if (p->
len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
1310 goto free_and_return;
1312#if defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN)
1313#ifdef ETHARP_VLAN_CHECK_FN
1314 if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
1315#elif defined(ETHARP_VLAN_CHECK)
1316 if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
1324 ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
1328#if LWIP_ARP_FILTER_NETIF
1332 if (ethhdr->dest.addr[0] & 1) {
1334 if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) {
1335 if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) &&
1336 (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) {
1340 }
else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) {
1351 goto free_and_return;
1353#if ETHARP_TRUST_IP_MAC
1355 etharp_ip_input(
netif, p);
1359 LWIP_ASSERT(
"Can't move over header in packet", 0);
1360 goto free_and_return;
1369 goto free_and_return;
1377 pppoe_disc_input(
netif, p);
1381 pppoe_data_input(
netif, p);
1388 goto free_and_return;
#define LWIP_UNUSED_ARG(x)
#define LWIP_DBG_LEVEL_SERIOUS
#define LWIP_DEBUGF(debug, message)
#define LWIP_DBG_LEVEL_WARNING
#define LWIP_ERROR(message, expression, handler)
#define LWIP_ASSERT(message, assertion)
err_t ip_input(struct pbuf *p, struct netif *inp)
struct netif * ip_route(ip_addr_t *dest)
#define ip_addr_cmp(addr1, addr2)
#define ip_addr_isany(addr1)
#define ip4_addr1_16(ipaddr)
#define ip_addr_ismulticast(addr1)
#define ip_addr_netcmp(addr1, addr2, mask)
#define ip4_addr2_16(ipaddr)
#define ip_addr_islinklocal(addr1)
#define ip_addr_copy(dest, src)
#define ip4_addr4(ipaddr)
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
#define ip_addr_isbroadcast(ipaddr, netif)
#define ip4_addr3_16(ipaddr)
#define ip_addr_set_zero(ipaddr)
#define IPADDR2_COPY(dest, src)
#define ip4_addr4_16(ipaddr)
#define ip4_addr3(ipaddr)
#define ip4_addr2(ipaddr)
void * memp_malloc(memp_t type)
void memp_free(memp_t type, void *mem)
#define NETIF_FLAG_ETHARP
int link(const char *existing, const char *new)
#define ETHARP_SUPPORT_STATIC_ENTRIES
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
void pbuf_ref(struct pbuf *p)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
#define PBUF_FLAG_LLBCAST
#define PBUF_FLAG_LLMCAST
#define snmp_delete_arpidx_tree(ni, ip)
#define snmp_insert_arpidx_tree(ni, ip)
#define LINK_STATS_INC(x)
#define ETHARP_STATS_INC(x)
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
netif_linkoutput_fn linkoutput