diff --git a/CHANGELOG b/CHANGELOG index fd106893..e09ad3ba 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -131,6 +131,13 @@ HISTORY ++ Bugfixes: + 2010-02-14: Simon Goldschmidt + * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be + disabled on netif used for PPPoE) by adding a new netif flag + (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet + device but prevents usage of ARP (so that ethernet_input can be used + for PPPoE). + 2010-02-12: Simon Goldschmidt * netif.c: netif_set_link_up/down: only do something if the link state actually changes diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 0abb0072..75142bbb 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -97,7 +97,7 @@ tcpip_thread(void *arg) case TCPIP_MSG_INPKT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); #if LWIP_ETHERNET - if (msg->msg.inp.netif->flags & NETIF_FLAG_ETHARP) { + if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); } else #endif /* LWIP_ETHERNET */ @@ -140,7 +140,8 @@ tcpip_thread(void *arg) * Pass a received packet to tcpip_thread for input processing * * @param p the received packet, p->payload pointing to the Ethernet header or - * to an IP header (if netif doesn't got NETIF_FLAG_ETHARP flag) + * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or + * NETIF_FLAG_ETHERNET flags) * @param inp the network interface on which the packet was received */ err_t diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index d0313715..6b993eed 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -87,9 +87,13 @@ extern "C" { * Set by the netif driver in its init function. * Used to check input packet types and use of DHCP. */ #define NETIF_FLAG_ETHARP 0x20U +/** If set, the netif is an ethernet device. It might not use + * ARP or TCP/IP if it is used for PPPoE only. + */ +#define NETIF_FLAG_ETHERNET 0x40U /** If set, the netif has IGMP capability. * Set by the netif driver in its init function. */ -#define NETIF_FLAG_IGMP 0x40U +#define NETIF_FLAG_IGMP 0x80U /** Function prototype for netif init functions. Set up flags and output/linkoutput * callback functions in this function. diff --git a/src/netif/etharp.c b/src/netif/etharp.c index d23f8f30..79872f56 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -586,6 +586,7 @@ etharp_ip_input(struct netif *netif, struct pbuf *p) struct eth_hdr *ethhdr; struct ip_hdr *iphdr; LWIP_ERROR("netif != NULL", (netif != NULL), return;); + /* Only insert an entry if the source IP address of the incoming IP packet comes from a host on the local network. */ ethhdr = (struct eth_hdr *)p->payload; @@ -639,7 +640,7 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) #endif /* LWIP_AUTOIP */ LWIP_ERROR("netif != NULL", (netif != NULL), return;); - + /* drop short ARP packets: we have to check for p->len instead of p->tot_len here since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */ if (p->len < SIZEOF_ETHARP_PACKET) { @@ -1185,6 +1186,9 @@ ethernet_input(struct pbuf *p, struct netif *netif) #if LWIP_ARP /* IP packet? */ case ETHTYPE_IP: + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + goto free_and_return; + } #if ETHARP_TRUST_IP_MAC /* update ARP table */ etharp_ip_input(netif, p); @@ -1192,8 +1196,7 @@ ethernet_input(struct pbuf *p, struct netif *netif) /* skip Ethernet header */ if(pbuf_header(p, -(s16_t)SIZEOF_ETH_HDR)) { LWIP_ASSERT("Can't move over header in packet", 0); - pbuf_free(p); - p = NULL; + goto free_and_return; } else { /* pass to IP layer */ ip_input(p, netif); @@ -1201,6 +1204,9 @@ ethernet_input(struct pbuf *p, struct netif *netif) break; case ETHTYPE_ARP: + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + goto free_and_return; + } /* pass p to ARP module */ etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); break; @@ -1218,13 +1224,15 @@ ethernet_input(struct pbuf *p, struct netif *netif) default: ETHARP_STATS_INC(etharp.proterr); ETHARP_STATS_INC(etharp.drop); - pbuf_free(p); - p = NULL; - break; + goto free_and_return; } /* This means the pbuf is freed or consumed, so the caller doesn't have to free it again */ return ERR_OK; + +free_and_return: + pbuf_free(p); + return ERR_OK; } #endif /* LWIP_ARP || LWIP_ETHERNET */