Exemple #1
0
// type is IF_TYPE_LOOPBACK, IF_TYPE_ETHERNET
//int if_register_interface(const char *path, ifnet **_i)
int if_register_interface(int type, ifnet **_i, phantom_device_t *dev)
{
    ifnet *i;
    //int type;
    int err;
    ifaddr *address;

    i = kmalloc(sizeof(ifnet));
    if(!i) {
        err = ERR_NO_MEMORY;
        goto err;
    }
    memset(i, 0, sizeof(ifnet));

    i->dev = dev;

    if(dev != 0 && (i->dev->dops.write == 0 || i->dev->dops.read == 0) )
        panic("dev has no read or write!");



    /* open the device * /
     if(!strcmp(path, "loopback")) {
     // the 'loopback' device is special
     type = IF_TYPE_LOOPBACK;
     i->fd = -1;
     } else {
     i->fd = sys_open(path, 0);
     if(i->fd < 0) {
     err = i->fd;
     goto err1;
     }
     // find the device's type
      err = sys_ioctl(i->fd, IOCTL_NET_IF_GET_TYPE, &type, sizeof(type));
      if(err < 0) {
      goto err2;
      }
      } */

    // find the appropriate function calls to the link layer drivers
    switch(type) {
    case IF_TYPE_LOOPBACK:
        i->link_input = &loopback_input;
        i->link_output = &loopback_output;
        i->mtu = 65535;
        break;
    case IF_TYPE_ETHERNET:

        assert(dev);

        i->link_input = &ethernet_input;
        i->link_output = &ethernet_output;
        i->mtu = ETHERNET_MAX_SIZE - ETHERNET_HEADER_SIZE;

        /* bind the ethernet link address */
        address = kmalloc(sizeof(ifaddr));
        address->addr.len = 6;
        address->addr.type = ADDR_TYPE_ETHERNET;

        if( dev->dops.get_address == 0 )
        {
            err = ERR_NET_GENERAL;
            kfree(address);
            goto err2;
        }

        err = dev->dops.get_address(dev, &address->addr.addr[0], 6);
        if(err < 0) {
            err = ERR_NET_GENERAL;
            kfree(address);
            goto err2;
        }

        /*err = sys_ioctl(i->fd, IOCTL_NET_IF_GET_ADDR, &address->addr.addr[0], 6);
        if(err < 0) {
            kfree(address);
            goto err2;
        }*/

        address->broadcast.len = 6;
        address->broadcast.type = ADDR_TYPE_ETHERNET;
        memset(&address->broadcast.addr[0], 0xff, 6);
        address->netmask.type = ADDR_TYPE_NULL;
        if_bind_link_address(i, address);
        break;
    default:
        err = ERR_NET_GENERAL;
        goto err1;
    }

    i->id = ATOMIC_ADD_AND_FETCH(&next_id, 1);
    //strlcpy(i->path, path, sizeof(i->path));
    i->type = type;
    i->rx_thread = -1;
    i->tx_thread = -1;

    //i->tx_queue_sem = sem_create(0, "tx_queue_sem");
    hal_sem_init( &(i->tx_queue_sem), "IF TX sem" );
    hal_mutex_init(&i->tx_queue_lock, "IF TX Q");
    fixed_queue_init(&i->tx_queue, TX_QUEUE_SIZE);

    mutex_lock(&ifhash_lock);
    hash_insert(ifhash, i);
    mutex_unlock(&ifhash_lock);

    // don't need threads for loopback if
    if(type != IF_TYPE_LOOPBACK)
    {
        /* start the rx and tx threads on this interface */
        err = if_boot_interface(i);
        if(err < 0)
            goto err2;

        //bootp(i);
    }
    *_i = i;


    return NO_ERROR;

err2:
    //sys_close(i->fd);
err1:
    kfree(i);
err:
    return err;
}
Exemple #2
0
int if_register_interface(const char *path, ifnet **_i)
{
	ifnet *i;
	int type;
	int err;
	ifaddr *address;

	i = kmalloc(sizeof(ifnet));
	if(!i) {
		err = ERR_NO_MEMORY;
		goto err;
	}
	memset(i, 0, sizeof(ifnet));

	/* open the device */
	if(!strcmp(path, "loopback")) {
		// the 'loopback' device is special
		type = IF_TYPE_LOOPBACK;
		i->fd = -1;
	} else {
		i->fd = sys_open(path, 0);
		if(i->fd < 0) {
			err = i->fd;
			goto err1;
		}
		/* find the device's type */
		err = sys_ioctl(i->fd, IOCTL_NET_IF_GET_TYPE, &type, sizeof(type));
		if(err < 0) {
			goto err2;
		}
	}

	// find the appropriate function calls to the link layer drivers
	switch(type) {
		case IF_TYPE_LOOPBACK:
			i->link_input = &loopback_input;
			i->link_output = &loopback_output;
			i->mtu = 65535;
			break;
		case IF_TYPE_ETHERNET:
			i->link_input = &ethernet_input;
			i->link_output = &ethernet_output;
			i->mtu = ETHERNET_MAX_SIZE - ETHERNET_HEADER_SIZE;

			/* bind the ethernet link address */
			address = kmalloc(sizeof(ifaddr));
			address->addr.len = 6;
			address->addr.type = ADDR_TYPE_ETHERNET;
			err = sys_ioctl(i->fd, IOCTL_NET_IF_GET_ADDR, &address->addr.addr[0], 6);
			if(err < 0) {
				kfree(address);
				goto err2;
			}
			address->broadcast.len = 6;
			address->broadcast.type = ADDR_TYPE_ETHERNET;
			memset(&address->broadcast.addr[0], 0xff, 6);
			address->netmask.type = ADDR_TYPE_NULL;
			if_bind_link_address(i, address);
			break;
		default:
			err = ERR_NET_GENERAL;
			goto err1;
	}

	i->id = atomic_add(&next_id, 1);
	strlcpy(i->path, path, sizeof(i->path));
	i->type = type;
	i->rx_thread = -1;
	i->tx_thread = -1;
	i->tx_queue_sem = sem_create(0, "tx_queue_sem");
	mutex_init(&i->tx_queue_lock, "tx_queue_lock");
	fixed_queue_init(&i->tx_queue, TX_QUEUE_SIZE);

	mutex_lock(&ifhash_lock);
	hash_insert(ifhash, i);
	mutex_unlock(&ifhash_lock);

	/* start the rx and tx threads on this interface */
	err = if_boot_interface(i);
	if(err < 0)
		goto err2;

	*_i = i;

	return NO_ERROR;

err2:
	sys_close(i->fd);
err1:
	kfree(i);
err:
	return err;
}