/*-----------------------------------------------------------------------------------*/ static void timeout(void *arg) { struct netif *netif; struct pcapif *pcapif; struct pbuf *p, *q; u8_t *bufptr; struct eth_hdr *ethhdr; netif = (struct netif *)arg; pcapif = netif->state; ethhdr = (struct eth_hdr *)pcapif->pkt; if(htons(ethhdr->type) != ETHTYPE_IP || ip_lookup(pcapif->pkt + 14, netif)) { /* We allocate a pbuf chain of pbufs from the pool. */ p = pbuf_alloc(PBUF_LINK, pcapif->len, PBUF_POOL); if(p != NULL) { /* We iterate over the pbuf chain until we have read the entire packet into the pbuf. */ bufptr = (u_char *)pcapif->pkt; for(q = p; q != NULL; q = q->next) { /* Read enough bytes to fill this pbuf in the chain. The avaliable data in the pbuf is given by the q->len variable. */ /* read data into(q->payload, q->len); */ bcopy(bufptr, q->payload, q->len); bufptr += q->len; } ethhdr = p->payload; switch(htons(ethhdr->type)) { case ETHTYPE_IP: arp_ip_input(netif, p); pbuf_header(p, -14); netif->input(p, netif); break; case ETHTYPE_ARP: p = arp_arp_input(netif, pcapif->ethaddr, p); if(p != NULL) { printf("ARP outout\n"); pbuf_free(p); } break; default: pbuf_free(p); break; } } } else { printf("ip_lookup dropped\n"); } sys_sem_signal(pcapif->sem); }
/*-----------------------------------------------------------------------------------*/ 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; } }
void ether_dispatcher(void *arg) { struct ether_msg *msg; struct pbuf *p; struct netif *netif; struct eth_hdr *ethhdr; while (1) { msg = dequeue(ether_queue, INFINITE); if (!msg) panic("error retrieving message from ethernet packet queue\n"); p = msg->p; netif = msg->netif; kfree(msg); if (p != NULL) { ethhdr = p->payload; //if (!eth_addr_isbroadcast(ðhdr->dest)) kprintf("ether: recv src=%la dst=%la type=%04X len=%d\n", ðhdr->src, ðhdr->dest, htons(ethhdr->type), p->len); switch (htons(ethhdr->type)) { case ETHTYPE_IP: arp_ip_input(netif, p); pbuf_header(p, -ETHER_HLEN); if (netif->input(p, netif) < 0) pbuf_free(p); break; case ETHTYPE_ARP: p = arp_arp_input(netif, &netif->hwaddr, p); if (p != NULL) { if (dev_transmit((dev_t) netif->state, p) < 0) pbuf_free(p); } break; default: pbuf_free(p); break; } } //yield(); } }