diff --git a/src/netif/ethernetif.c b/src/netif/ethernetif.c index b2a8315a..fe3dee8d 100644 --- a/src/netif/ethernetif.c +++ b/src/netif/ethernetif.c @@ -35,8 +35,6 @@ * drivers for lwIP. Add code to the low_level functions and do a * search-and-replace for the word "ethernetif" to replace it with * something that better describes your network interface. - * - * THIS CODE NEEDS TO BE FIXED - IT IS NOT In SYNC WITH CURRENT ETHARP API */ #include "lwip/opt.h" @@ -45,11 +43,11 @@ #include "lwip/pbuf.h" #include "lwip/sys.h" -#include "netif/arp.h" +#include "netif/etharp.h" /* Define those to better describe your network interface. */ #define IFNAME0 'e' -#define IFNAME1 't' +#define IFNAME1 'n' struct ethernetif { struct eth_addr *ethaddr; @@ -189,77 +187,18 @@ ethernetif_output(struct netif *netif, struct pbuf *p, ethernetif = netif->state; - /* Make room for Ethernet header. */ - if (pbuf_header(p, 14) != 0) { - /* The pbuf_header() call shouldn't fail, but we allocate an extra - pbuf just in case. */ - q = pbuf_alloc(PBUF_LINK, 14, PBUF_RAM); - if (q == NULL) { -#ifdef LINK_STATS - lwip_stats.link.drop++; - lwip_stats.link.memerr++; -#endif /* LINK_STATS */ - return ERR_MEM; - } - pbuf_chain(q, p); - p = q; - } - - /* Construct Ethernet header. Start with looking up deciding which - MAC address to use as a destination address. Broadcasts and - multicasts are special, all other addresses are looked up in the - ARP table. */ - queryaddr = ipaddr; - if (ip_addr_isany(ipaddr) || ip_addr_isbroadcast(ipaddr, netif)) { - dest = (struct eth_addr *)ðbroadcast; - } else if (ip_addr_ismulticast(ipaddr)) { - /* Hash IP multicast address to MAC address. */ - mcastaddr.addr[0] = 0x01; - mcastaddr.addr[1] = 0x0; - mcastaddr.addr[2] = 0x5e; - mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; - mcastaddr.addr[4] = ip4_addr3(ipaddr); - mcastaddr.addr[5] = ip4_addr4(ipaddr); - dest = &mcastaddr; - } else { - - if (ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) { - /* Use destination IP address if the destination is on the same - subnet as we are. */ - queryaddr = ipaddr; - } else { - /* Otherwise we use the default router as the address to send - the Ethernet frame to. */ - queryaddr = &(netif->gw); - } - dest = arp_lookup(queryaddr); - } - - - /* If the arp_lookup() didn't find an address, we send out an ARP - query for the IP address. */ - if (dest == NULL) { - q = arp_query(netif, ethernetif->ethaddr, queryaddr); - if (q != NULL) { - err = low_level_output(ethernetif, q); - pbuf_free(q); - return err; - } -#ifdef LINK_STATS - lwip_stats.link.drop++; - lwip_stats.link.memerr++; -#endif /* LINK_STATS */ - return ERR_MEM; - } - ethhdr = p->payload; - - for(i = 0; i < 6; i++) { - ethhdr->dest.addr[i] = dest->addr[i]; - ethhdr->src.addr[i] = ethernetif->ethaddr->addr[i]; - } - - ethhdr->type = htons(ETHTYPE_IP); + /* resolve the link destination hardware address */ + p = etharp_output(netif, ipaddr, p); + /* network hardware address obtained? */ + if (p == NULL) + { + /* we cannot tell if the packet was sent: the packet could */ + /* have been queued on an ARP entry that was already pending. */ + return ERR_OK; + } + + /* send out the packet */ return low_level_output(ethernetif, p); } @@ -279,45 +218,48 @@ ethernetif_input(struct netif *netif) { struct ethernetif *ethernetif; struct eth_hdr *ethhdr; - struct pbuf *p; - + struct pbuf *p, *q; ethernetif = netif->state; p = low_level_input(ethernetif); - if (p != NULL) { + if (p != NULL) + return; #ifdef LINK_STATS - lwip_stats.link.recv++; + lwip_stats.link.recv++; #endif /* LINK_STATS */ - ethhdr = p->payload; + ethhdr = p->payload; + q = NULL; - switch (htons(ethhdr->type)) { + switch (htons(ethhdr->type)) { case ETHTYPE_IP: - arp_ip_input(netif, p); + q = etharp_ip_input(netif, p); pbuf_header(p, -14); netif->input(p, netif); break; + case ETHTYPE_ARP: - p = arp_arp_input(netif, ethernetif->ethaddr, p); - if (p != NULL) { - low_level_output(ethernetif, p); - pbuf_free(p); - } + q = etharp_arp_input(netif, ethernetif->ethaddr, p); break; default: pbuf_free(p); + p = NULL; break; - } + } + if (q != NULL) { + low_level_output(ethernetif, q); + pbuf_free(q); + q = NULL; } } static void arp_timer(void *arg) { - arp_tmr(); + etharp_tmr(); sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); } @@ -336,6 +278,13 @@ ethernetif_init(struct netif *netif) struct ethernetif *ethernetif; ethernetif = mem_malloc(sizeof(struct ethernetif)); + + if (ethernetif == NULL) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); + return ERR_MEM; + } + netif->state = ethernetif; netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; @@ -345,7 +294,8 @@ ethernetif_init(struct netif *netif) ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); low_level_init(netif); - arp_init(); + + etharp_init(); sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); }