Ejemplo n.º 1
0
void slirp_input(const uint8_t *pkt, int pkt_len)
{
    struct mbuf *m;
    int proto;

    if (pkt_len < ETH_HLEN)
        return;
    
    proto = (pkt[12] << 8) | pkt[13];
    switch(proto) {
    case ETH_P_ARP:
        arp_input(pkt, pkt_len);
        break;
    case ETH_P_IP:
        m = m_get();
        if (!m)
            return;
        /* Note: we add to align the IP header */
        m->m_len = pkt_len + 2;
        memcpy(m->m_data + 2, pkt, pkt_len);

        m->m_data += 2 + ETH_HLEN;
        m->m_len -= 2 + ETH_HLEN;

        ip_input(m);
        break;
    default:
        break;
    }
}
Ejemplo n.º 2
0
void slirp_input(const uint8_t *pkt, int pkt_len)
{
    struct mbuf *m;
    int proto;

    if (pkt_len < ETH_HLEN)
        return;

    proto = ntohs(*(uint16_t *)(pkt + 12));
    switch(proto) {
    case ETH_P_ARP:
        arp_input(pkt, pkt_len);
        break;
    case ETH_P_IP:
        m = m_get();
        if (!m)
            return;
        
        if (M_FREEROOM(m) < pkt_len + 2) {
            m_inc(m, pkt_len + 2);
        }
        m->m_len = pkt_len + 2;
        memcpy(m->m_data + 2, pkt, pkt_len);

        m->m_data += 2 + ETH_HLEN;
        m->m_len -= 2 + ETH_HLEN;

        ip_input(m);
        break;
    default:
        break;
    }
}
Ejemplo n.º 3
0
int ethernet_input(cbuf *buf, ifnet *i)
{
    int err;
    ethernet2_header *e2_head;
    uint16 type;

    if(cbuf_get_len(buf) < MIN_ETHERNET2_LEN)
    {
        cbuf_free_chain(buf);
        return -1;
    }

    e2_head = cbuf_get_ptr(buf, 0);
    type = ntohs(e2_head->type);

    dump_ethernet_header(e2_head);

    // strip out the ethernet header
    buf = cbuf_truncate_head(buf, sizeof(ethernet2_header), true);

    switch(type) {
    case PROT_TYPE_IPV4:
        err = ipv4_input(buf, i);
        break;
    case PROT_TYPE_ARP:
        err = arp_input(buf, i);
        break;
    default:
        dprintf("ethernet_receive: unknown ethernet type 0x%x\n", type);
        err = -1;
    }

    return err;
}
Ejemplo n.º 4
0
int
ether_input(struct nm_if *nmif, int ring, char *buf, int len)
{
	int err;
	struct ether_header *eh;
	struct ether_vlan_header *evl;
	struct nm_if_vlan *vlan;

	if (len < ETHER_HDR_LEN) {
		DPRINTF("%s: discarding packet, too short.\n", __func__);
		pktcnt.rx_drop++;
		return (-1);
	}
	err = 0;
	eh = (struct ether_header *)buf;
	switch (ntohs(eh->ether_type)) {
	case ETHERTYPE_ARP:
		pktcnt.rx_arp++;
		err = arp_input(nmif, ring, buf + ETHER_HDR_LEN,
		    len - ETHER_HDR_LEN);
		break;
	case ETHERTYPE_IP:
		pktcnt.rx_ip++;
		err = ip_input(nmif, ring, buf + ETHER_HDR_LEN,
		    len - ETHER_HDR_LEN);
		break;
	case ETHERTYPE_VLAN:
		//pktcnt.rx_vlan++;
		if (len < ETHER_VLAN_ENCAP_LEN) {
			DPRINTF("%s: discarding vlan packet, too short.\n",
			    __func__);
			pktcnt.rx_drop++;
			return (-1);
		}
		evl = (struct ether_vlan_header *)buf;
		vlan = if_find_vlan(nmif, ntohs(evl->evl_tag));
		if (vlan == NULL) {
			pktcnt.rx_drop++;
			DPRINTF("%s: unknown vlan tag %d, discanding packet.\n",
			    __func__, ntohs(evl->evl_tag));
			return (-1);
		}
		memmove(buf + ETHER_VLAN_ENCAP_LEN, buf, ETHER_ADDR_LEN * 2);
		err = ether_input(vlan->nmif, ring, buf + ETHER_VLAN_ENCAP_LEN,
		    len - ETHER_VLAN_ENCAP_LEN);
		if (!nohostring && err == 1) {
			memmove(buf, buf + ETHER_VLAN_ENCAP_LEN,
			    ETHER_ADDR_LEN * 2);
			evl = (struct ether_vlan_header *)buf;
			evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
			evl->evl_tag = htons(vlan->nmif->nm_if_vtag);
			ether_bridge(vlan->nmif, ring, buf, len);
			return (0);
		}
		break;
	default:
		pktcnt.rx_drop++;
		DPRINTF("%s: protocol %#04x not supported, discanding packet.\n",
		    __func__, ntohs(eh->ether_type));
		err = -1;
	}

	return (err);
}