// // ecosif_input(): // This function is called when the eCos hw independent driver // has some data to pass up to lwIP.It does it through ecosif_input. // static void ecosif_input(struct netif *netif, struct pbuf *p) { struct eth_hdr *ethhdr; ethhdr = p->payload; switch (htons(ethhdr->type)) { case ETHTYPE_IP: LWIP_DEBUGF(0, ("ecosif_input: IP packet\n")); etharp_ip_input(netif, p); pbuf_header(p, -14); netif->input(p, netif); break; case ETHTYPE_ARP: LWIP_DEBUGF(0, ("ecosif_input: ARP packet\n")); etharp_arp_input(netif, (struct eth_addr *) &netif->hwaddr, p); break; default: pbuf_free(p); break; } }
void jif_input(struct netif *netif, void *va) { struct jif *jif; struct eth_hdr *ethhdr; struct pbuf *p; jif = netif->state; /* move received packet into a new pbuf */ p = low_level_input(va); /* no packet could be read, silently ignore this */ if (p == NULL) return; /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; switch (htons(ethhdr->type)) { case ETHTYPE_IP: /* update ARP table */ etharp_ip_input(netif, p); /* skip Ethernet header */ pbuf_header(p, -(int)sizeof(struct eth_hdr)); /* pass to network layer */ netif->input(p, netif); break; case ETHTYPE_ARP: /* pass p to ARP module */ etharp_arp_input(netif, jif->ethaddr, p); break; default: pbuf_free(p); } }
/* * ethernetif_input(): This function should be called when a packet is ready to * be read from the interface. It uses the function low_level_input() that * should handle the actual reception of bytes from the network interface. */ static void ethernetif_input( void * pvParameters ) { struct ethernetif *ethernetif; struct eth_hdr *ethhdr; struct pbuf *p; ( void ) pvParameters; for( ;; ) { do { ethernetif = xNetIf->state; /* move received packet into a new pbuf */ p = low_level_input( xNetIf ); if( p == NULL ) { /* No packet could be read. Wait a for an interrupt to tell us there is more data available. */ vEMACWaitForInput(); } } while( p == NULL ); /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; #if LINK_STATS lwip_stats.link.recv++; #endif /* LINK_STATS */ ethhdr = p->payload; switch( htons( ethhdr->type ) ) { /* IP packet? */ case ETHTYPE_IP: /* update ARP table */ etharp_ip_input( xNetIf, p ); /* skip Ethernet header */ pbuf_header( p, (s16_t)-sizeof(struct eth_hdr) ); /* pass to network layer */ xNetIf->input( p, xNetIf ); break; case ETHTYPE_ARP: /* pass p to ARP module */ etharp_arp_input( xNetIf, ethernetif->ethaddr, p ); break; default: pbuf_free( p ); p = NULL; break; } } }
static void netfront_input(struct netif *netif, unsigned char* data, int len) { struct eth_hdr *ethhdr; struct pbuf *p, *q; #if ETH_PAD_SIZE len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif /* move received packet into a new pbuf */ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); if (p == NULL) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); return; } #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif /* We iterate over the pbuf chain until we have read the entire * packet into the pbuf. */ for(q = p; q != NULL && len > 0; q = q->next) { /* Read enough bytes to fill this pbuf in the chain. The * available data in the pbuf is given by the q->len * variable. */ memcpy(q->payload, data, len < q->len ? len : q->len); data += q->len; len -= q->len; } #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif LINK_STATS_INC(link.recv); /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; ethhdr = p->payload; switch (htons(ethhdr->type)) { /* IP packet? */ case ETHTYPE_IP: #if 0 /* CSi disabled ARP table update on ingress IP packets. This seems to work but needs thorough testing. */ /* update ARP table */ etharp_ip_input(netif, p); #endif /* skip Ethernet header */ pbuf_header(p, -(int16_t)sizeof(struct eth_hdr)); /* pass to network layer */ if (tcpip_input(p, netif) == ERR_MEM) /* Could not store it, drop */ pbuf_free(p); break; case ETHTYPE_ARP: /* pass p to ARP module */ etharp_arp_input(netif, (struct eth_addr *) netif->hwaddr, p); break; default: pbuf_free(p); p = NULL; break; } }
static void paulosif_input (struct netif *netif) { struct genericif *genericif; struct eth_hdr *ethhdr; struct pbuf *p, *q = NULL, *r = NULL; int len; u16_t ether_type; genericif = netif->state; ioctl (genericif->fd, FIONREAD, &len); if (len <= 0) return; p = low_level_input (genericif); if (!p) { DEBUGF (TAPIF_DEBUG, ("paulosif_input: low_level_input returned NULL\n")); return; } ethhdr = p->payload; ether_type = ntohs (ethhdr->type); if (pppoe_input_callback && (ether_type == 0x8863 || ether_type == 0x8864)) { //printf ("paulosif_input: got PPPoE packet, %d bytes\n", (int) p->len); (*pppoe_input_callback) (pppoe_user_data, p, ether_type); pbuf_free (p); return; } if (packet_validate (p, netif, genericif)) { pbuf_free (p); return; } if (packet_filter_callback) { if ((*packet_filter_callback) (packet_filter_data, (unsigned char *) p->payload, (int) p->len)) { pbuf_free (p); return; } } switch (ether_type) { case ETHTYPE_IP: DEBUGF (TAPIF_DEBUG, ("paulosif_input: IP packet\n")); q = etharp_ip_input (netif, p); pbuf_header (p, -14); netif->input (p, netif); /* segfault */ break; case ETHTYPE_ARP: DEBUGF (TAPIF_DEBUG, ("paulosif_input: ARP packet\n")); q = etharp_arp_input (netif, genericif->ethaddr, p, &r); pbuf_free (p); break; default: pbuf_free (p); break; } if (q != NULL) { magic (q, PBUF_MAGIC); low_level_output (genericif, q); pbuf_free (q); /* free'd */ } if (r != NULL) { magic (r, PBUF_MAGIC); low_level_output (genericif, r); pbuf_free (r); /* free'd */ } }
/** * Process received ethernet frames. Using this function instead of directly * calling ip_input and passing ARP frames through etharp in ethernetif_input, * the ARP cache is protected from concurrent access. * * @param p the recevied packet, p->payload pointing to the ethernet header * @param netif the network interface on which the packet was received */ err_t ethernet_input(struct pbuf *p, struct netif *netif) { struct eth_hdr* ethhdr; u16_t type; /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethernet_input: dest:%02x:%02x:%02x:%02x:%02x:%02x, src:%02x:%02x:%02x:%02x:%02x:%02x, type:%2x"NEWLINE, (unsigned )ethhdr->dest.addr[0], (unsigned )ethhdr->dest.addr[1], (unsigned )ethhdr->dest.addr[2], (unsigned )ethhdr->dest.addr[3], (unsigned )ethhdr->dest.addr[4], (unsigned )ethhdr->dest.addr[5], (unsigned )ethhdr->src.addr[0], (unsigned )ethhdr->src.addr[1], (unsigned )ethhdr->src.addr[2], (unsigned )ethhdr->src.addr[3], (unsigned )ethhdr->src.addr[4], (unsigned )ethhdr->src.addr[5], (unsigned )htons(ethhdr->type))); netif->rxpackets++; netif->rxbytes += p->tot_len; type = htons(ethhdr->type); #if ETHARP_SUPPORT_VLAN if (type == ETHTYPE_VLAN) { struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); #ifdef ETHARP_VLAN_CHECK /* if not, allow all VLANs */ if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { /* silently ignore this packet: not for our VLAN */ pbuf_free(p); return ERR_OK; } #endif /* ETHARP_VLAN_CHECK */ type = htons(vlan->tpid); } #endif /* ETHARP_SUPPORT_VLAN */ //acquireMutex(comStackMutex); switch (type) { /* IP packet? */ case ETHTYPE_IPV4: #if ETHARP_TRUST_IP_MAC /* update ARP table */ ethar_ip_input(netif, p); #endif /* ETHARP_TRUST_IP_MAC */ /* 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; } else { /* pass to IP layer */ ip4_input(p, netif); } break; case ETHTYPE_IPV6: #if ETHARP_TRUST_IP_MAC /* update AR table */ ethar_ip_input(netif, p); #endif /* ETHARP_TRUST_IP_MAC */ if (pbuf_header(p, -(s16_t) SIZEOF_ETH_HDR)) { LWIP_ASSERT("Can't move over header in packet", 0); pbuf_free(p); p = NULL; } else { ip6_input(p, netif); } break; #if LWIP_ARP case ETHTYPE_ARP: /* pass p to ARP module */ etharp_arp_input(netif, (struct eth_addr*) (netif->hwaddr), p); break; #endif #if PPPOE_SUPPORT case ETHTYPE_PPPOEDISC: /* PPP Over Ethernet Discovery Stage */ pppoe_disc_input(netif, p); break; case ETHTYPE_PPPOE: /* PPP Over Ethernet Session Stage */ pppoe_data_input(netif, p); break; #endif /* PPPOE_SUPPORT */ default: ETHARP_STATS_INC(etharp.proterr); ETHARP_STATS_INC(etharp.drop); pbuf_free(p); break; } //releaseMutex(comStackMutex); /* This means the pbuf is freed or consumed, so the caller doesn't have to free it again */ return (ERR_OK); }
/** * This function should be called when a packet is ready to be read * from the interface. It uses the function low_level_input() that * should handle the actual reception of bytes from the network * interface. Then the type of the received packet is determined and * the appropriate input function is called. * * @param netif the lwip network interface structure for this ethernetif */ static void ethernetif_input( void * pvParameters ) { struct ethernetif *ethernetif; struct eth_hdr *ethhdr; struct pbuf *p; for( ;; ) { do { ethernetif = s_pxNetIf->state; /* move received packet into a new pbuf */ p = low_level_input( s_pxNetIf ); if( p == NULL ) { /* No packet could be read. Wait a for an interrupt to tell us there is more data available. */ vEMACWaitForInput(); } } while( p == NULL ); /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; #if LINK_STATS lwip_stats.link.recv++; #endif /* LINK_STATS */ ethhdr = p->payload; switch (htons(ethhdr->type)) { /* IP packet? */ case ETHTYPE_IP: /* full packet send to tcpip_thread to process */ if (s_pxNetIf->input(p, s_pxNetIf) != ERR_OK) { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); pbuf_free(p); p = NULL; } break; case ETHTYPE_ARP: #if ETHARP_TRUST_IP_MAC etharp_ip_input(s_pxNetIf, p); #endif /* pass p to ARP module */ etharp_arp_input(s_pxNetIf, ethernetif->ethaddr, p); break; default: pbuf_free(p); p = NULL; break; } } }