diff --git a/CHANGELOG b/CHANGELOG index 662d01dd..a81a7c8c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -237,6 +237,9 @@ HISTORY ++ Bugfixes: + 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: + * etharp.h/.c: Fixed broken VLAN support. + 2011-03-27: Simon Goldschmidt * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp pcbs) by checking if the pcb was bound (local_port != 0). diff --git a/src/include/netif/etharp.h b/src/include/netif/etharp.h index 02a3d8bc..691575fa 100644 --- a/src/include/netif/etharp.h +++ b/src/include/netif/etharp.h @@ -94,8 +94,8 @@ PACK_STRUCT_BEGIN * if 'type' in ethernet header is ETHTYPE_VLAN. * See IEEE802.Q */ struct eth_vlan_hdr { - PACK_STRUCT_FIELD(u16_t tpid); PACK_STRUCT_FIELD(u16_t prio_vid); + PACK_STRUCT_FIELD(u16_t tpid); } PACK_STRUCT_STRUCT; PACK_STRUCT_END #ifdef PACK_STRUCT_USE_INCLUDES diff --git a/src/netif/etharp.c b/src/netif/etharp.c index 5d7c34da..b60dadd0 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -628,7 +628,7 @@ etharp_ip_input(struct netif *netif, struct pbuf *p) ethhdr = (struct eth_hdr *)p->payload; iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); #if ETHARP_SUPPORT_VLAN - if (ethhdr->type == ETHTYPE_VLAN) { + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); } #endif /* ETHARP_SUPPORT_VLAN */ @@ -693,7 +693,7 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) ethhdr = (struct eth_hdr *)p->payload; hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); #if ETHARP_SUPPORT_VLAN - if (ethhdr->type == ETHTYPE_VLAN) { + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); } #endif /* ETHARP_SUPPORT_VLAN */ @@ -702,11 +702,10 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || (hdr->hwlen != ETHARP_HWADDR_LEN) || (hdr->protolen != sizeof(ip_addr_t)) || - (hdr->proto != PP_HTONS(ETHTYPE_IP)) || - (ethhdr->type != PP_HTONS(ETHTYPE_ARP))) { + (hdr->proto != PP_HTONS(ETHTYPE_IP))) { LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("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", - hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen, ethhdr->type)); + ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", + hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen)); ETHARP_STATS_INC(etharp.proterr); ETHARP_STATS_INC(etharp.drop); pbuf_free(p); @@ -1218,9 +1217,10 @@ ethernet_input(struct pbuf *p, struct netif *netif) { struct eth_hdr* ethhdr; u16_t type; + s16_t ip_hdr_offset = SIZEOF_ETH_HDR; - if (p->tot_len <= SIZEOF_ETH_HDR) { - /* a packet with only an ethernet header (or less) is not valid */ + if (p->len <= SIZEOF_ETH_HDR) { + /* a packet with only an ethernet header (or less) is not valid for us */ ETHARP_STATS_INC(etharp.proterr); ETHARP_STATS_INC(etharp.drop); goto free_and_return; @@ -1239,8 +1239,13 @@ ethernet_input(struct pbuf *p, struct netif *netif) type = ethhdr->type; #if ETHARP_SUPPORT_VLAN if (type == PP_HTONS(ETHTYPE_VLAN)) { - /* @todo: check for minimum packet length */ struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); + if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) { + /* a packet with only an ethernet/vlan header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } #ifdef ETHARP_VLAN_CHECK /* if not, allow all VLANs */ if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { /* silently ignore this packet: not for our VLAN */ @@ -1249,6 +1254,7 @@ ethernet_input(struct pbuf *p, struct netif *netif) } #endif /* ETHARP_VLAN_CHECK */ type = vlan->tpid; + ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; } #endif /* ETHARP_SUPPORT_VLAN */ @@ -1268,7 +1274,7 @@ ethernet_input(struct pbuf *p, struct netif *netif) etharp_ip_input(netif, p); #endif /* ETHARP_TRUST_IP_MAC */ /* skip Ethernet header */ - if(pbuf_header(p, -(s16_t)SIZEOF_ETH_HDR)) { + if(pbuf_header(p, -ip_hdr_offset)) { LWIP_ASSERT("Can't move over header in packet", 0); goto free_and_return; } else {