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;
}
Beispiel #2
0
static void if_tx_thread(void *args)
{
    ifnet *i = args;
    cbuf *buf;
    ssize_t len;

    t_current_set_name("IF Xmit");

#if IF_PRIO
    thread_set_priority(i->tx_thread, THREAD_MAX_RT_PRIORITY - 2);
#endif
    //if(i->fd < 0)        return -1;


//printf("if %x tx thread inited", i);
    for(;;) {
        sem_acquire(i->tx_queue_sem);
//printf("if %x tx thread gogo\n", i);

        for(;;) {
            // pull a packet out of the queue
            mutex_lock(&i->tx_queue_lock);
            buf = fixed_queue_dequeue(&i->tx_queue);
            mutex_unlock(&i->tx_queue_lock);
            if(!buf)
                break;

#if LOSE_TX_PACKETS
            if(rand() % 100 < LOSE_TX_PERCENTAGE) {
                cbuf_free_chain(buf);
                continue;
            }
#endif

            // put the cbuf chain into a flat buffer
            len = cbuf_get_len(buf);
            cbuf_memcpy_from_chain(i->tx_buf, buf, 0, len);

            cbuf_free_chain(buf);

#if 0||NET_CHATTY
            dprintf("if_tx_thread: sending packet size %ld\n", (long)len);
#endif
            //sys_write(i->fd, i->tx_buf, 0, len);
            i->dev->dops.write(i->dev, i->tx_buf, len);
        }
    }
}
Beispiel #3
0
static int if_tx_thread(void *args)
{
	ifnet *i = args;
	cbuf *buf;
	ssize_t len;

	if(i->fd < 0)
		return -1;

	for(;;) {
 		sem_acquire(i->tx_queue_sem, 1);

		for(;;) {
	 		// pull a packet out of the queue
			mutex_lock(&i->tx_queue_lock);
			buf = fixed_queue_dequeue(&i->tx_queue);
			mutex_unlock(&i->tx_queue_lock);
			if(!buf)
				break;

#if LOSE_TX_PACKETS
			if(rand() % 100 < LOSE_TX_PERCENTAGE) {
				cbuf_free_chain(buf);
				continue;
			}
#endif

			// put the cbuf chain into a flat buffer
			len = cbuf_get_len(buf);
			cbuf_memcpy_from_chain(i->tx_buf, buf, 0, len);

			cbuf_free_chain(buf);

#if NET_CHATTY
		dprintf("if_tx_thread: sending packet size %Ld\n", (long long)len);
#endif
			sys_write(i->fd, i->tx_buf, 0, len);
		}
	}
}
Beispiel #4
0
int udp_input(cbuf *buf, ifnet *i, ipv4_addr source_address, ipv4_addr target_address)
{
    (void) i;

    udp_header *header;
    udp_endpoint *e;
    udp_queue_elem *qe;
    uint16 port;
    int err;

    STAT_INC_CNT(STAT_CNT_UDP_RX);

    header = cbuf_get_ptr(buf, 0);

#if NET_CHATTY
    dprintf("udp_input: src port %d, dest port %d, len %d, buf len %d, checksum 0x%x\n",
            ntohs(header->source_port), ntohs(header->dest_port), ntohs(header->length), (int)cbuf_get_len(buf), ntohs(header->checksum));
#endif
    if(ntohs(header->length) > (uint16)cbuf_get_len(buf)) {
        err = ERR_NET_BAD_PACKET;
        goto ditch_packet;
    }

    // deal with the checksum check
    if(header->checksum) {
        udp_pseudo_header pheader;
        uint16 checksum;

        // set up the pseudo header for checksum purposes
        pheader.source_addr = htonl(source_address);
        pheader.dest_addr = htonl(target_address);
        pheader.zero = 0;
        pheader.protocol = IP_PROT_UDP;
        pheader.udp_length = header->length;

        checksum = cbuf_ones_cksum16_2(buf, 0, ntohs(header->length), &pheader, sizeof(pheader));
        if(checksum != 0) {
#if NET_CHATTY
            dprintf("udp_receive: packet failed checksum\n");
#endif
            err = ERR_NET_BAD_PACKET;
            goto ditch_packet;
        }
    }

    // see if we have an endpoint
    port = ntohs(header->dest_port);
    mutex_lock(&endpoints_lock);
    e = hash_lookup(endpoints, &port);
    if(e)
        udp_endpoint_acquire_ref(e);
    mutex_unlock(&endpoints_lock);

    if(!e) {
        err = NO_ERROR;
#if NET_CHATTY
        dprintf("udp_receive: no endpoint found\n");
#endif
        goto ditch_packet;
    }

    // okay, we have an endpoint, lets queue our stuff up and move on
    qe = kmalloc(sizeof(udp_queue_elem));
    if(!qe) {
        udp_endpoint_release_ref(e);
        err = ERR_NO_MEMORY;
        goto ditch_packet;
    }
    qe->src_port = ntohs(header->source_port);
    qe->target_port = port;
    qe->src_address = source_address;
    qe->target_address = target_address;
    qe->len = ntohs(header->length) - sizeof(udp_header);

    // trim off the udp header
    buf = cbuf_truncate_head(buf, sizeof(udp_header), true);
    qe->buf = buf;

    mutex_lock(&e->lock);
    udp_queue_push(&e->q, qe);
    mutex_unlock(&e->lock);

    sem_release(e->blocking_sem);

    udp_endpoint_release_ref(e);

    err = NO_ERROR;
    return err;

ditch_packet:
#if NET_CHATTY
    dprintf("udp_receive: packet thrown away\n");
#endif
    cbuf_free_chain(buf);

    return err;
}