struct ip_addr2 is only used as a hack in etharp.c and should be removed.
etharp_arp_input() should use simple memcpy()s to copy the struct ip_addr,
because that code isn't in a critical path.
memcpy(&sipaddr, &hdr->sipaddr, sizeof(sipaddr));
memcpy(&dipaddr, &hdr->dipaddr, sizeof(dipaddr));
The following comment in etharp_arp_input() is wrong:
/* these are aligned properly, whereas the ARP header fields might not be */
struct ip_addr sipaddr, dipaddr;
Because struct ip_addr is packed, sipaddr and dipaddr have an alignment
requirement of 1. This booby trap results in really erratic behavior, say if
the "u8_t i" is moved up. I was using struct ip_addr in my code and this
problem cost me a few hours. struct ip_addr should not be packed. Only the
packet format structures that contain it need to be packed.