// 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 = ðernet_input; i->link_output = ðernet_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; }
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 = ðernet_input; i->link_output = ðernet_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; }