err_t ethernetif_output(struct netif *netif, struct pbuf *p) { eth_lock(netif); err_t ret = low_level_output(netif, p); eth_unlock(netif); return ret; }
/*########################################################################## * * Sends an incoming Ethernet frame up the stack to a function that will * understand it (or just drops the frame). * *#########################################################################*/ static void eth_input(struct pbuf* p, struct netif* netif) { // Ethernet protocol layer struct eth_hdr* ethhdr; struct pbuf* q = NULL; ethhdr = p->payload; switch (htons(ethhdr->type)) { case ETHTYPE_IP: etharp_ip_input(netif, p); pbuf_header(p, -(s16_t)sizeof(struct eth_hdr)); netif->input(p, netif); break; case ETHTYPE_ARP: etharp_arp_input(netif, (struct eth_addr*)&(netif->hwaddr[0]), p); break; default: pbuf_free(p); break; } if (q != NULL) { low_level_output(netif, q); pbuf_free(q); } }
/*-----------------------------------------------------------------------------------*/ static err_t tunif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) { struct tunif *tunif; tunif = netif->state; return low_level_output(tunif, p); }
/*-----------------------------------------------------------------------------------*/ static err_t tunif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) { struct tunif *tunif; LWIP_UNUSED_ARG(ipaddr); tunif = (struct tunif *)netif->state; return low_level_output(tunif, p); }
static err_t paulosif_output (struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) { struct pbuf *q; struct genericif *genericif; genericif = netif->state; q = etharp_output (netif, ipaddr, p); if (q != NULL) { low_level_output (genericif, q); pbuf_free (q); } return ERR_OK; }
/*-----------------------------------------------------------------------------------*/ static void tapif_input(struct netif *netif) { struct tapif *tapif; struct eth_hdr *ethhdr; struct pbuf *p; tapif = netif->state; p = low_level_input(tapif); if(p == NULL) { DEBUGF(TAPIF_DEBUG, ("tapif_input: low_level_input returned NULL\n")); return; } ethhdr = p->payload; switch(htons(ethhdr->type)) { case ETHTYPE_IP: DEBUGF(TAPIF_DEBUG, ("tapif_input: IP packet\n")); arp_ip_input(netif, p); pbuf_header(p, -14); if(ip_lookup(p->payload, netif)) { netif->input(p, netif); } else { printf("tapif_input: lookup failed!\n"); } break; case ETHTYPE_ARP: DEBUGF(TAPIF_DEBUG, ("tapif_input: ARP packet\n")); p = arp_arp_input(netif, tapif->ethaddr, p); if(p != NULL) { DEBUGF(TAPIF_DEBUG, ("tapif_input: Sending ARP reply\n")); low_level_output(tapif, p); pbuf_free(p); } break; default: pbuf_free(p); 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 */ } }
/*-----------------------------------------------------------------------------------*/ static err_t tapif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) { struct tapif *tapif; struct pbuf *q; struct eth_hdr *ethhdr; struct eth_addr *dest, mcastaddr; struct ip_addr *queryaddr; err_t err; u8_t i; tapif = netif->state; /* Make room for Ethernet header. */ if(pbuf_header(p, sizeof(struct eth_hdr)) != 0) { /* The pbuf_header() call shouldn't fail, but we allocate an extra pbuf just in case. */ q = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr), PBUF_RAM); if(q == NULL) { 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->netmask))) { 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, tapif->ethaddr, queryaddr); if(q != NULL) { printf("Sending ARP after query\n"); err = low_level_output(tapif, q); pbuf_free(q); return err; } return ERR_MEM; } ethhdr = p->payload; for(i = 0; i < 6; i++) { ethhdr->dest.addr[i] = dest->addr[i]; ethhdr->src.addr[i] = tapif->ethaddr->addr[i]; } ethhdr->type = htons(ETHTYPE_IP); return low_level_output(tapif, p); }