static int _init(netdev2_t *netdev) { DEBUG("%s:%s:%u\n", RIOT_FILE_RELATIVE, __func__, __LINE__); netdev2_tap_t *dev = (netdev2_tap_t*)netdev; /* check device parametrs */ if (dev == NULL) { return -ENODEV; } char *name = dev->tap_name; #ifdef __MACH__ /* OSX */ char clonedev[255] = "/dev/"; /* XXX bad size */ strncpy(clonedev + 5, name, 250); #elif defined(__FreeBSD__) char clonedev[255] = "/dev/"; /* XXX bad size */ strncpy(clonedev + 5, name, 250); #else /* Linux */ struct ifreq ifr; const char *clonedev = "/dev/net/tun"; #endif /* initialize device descriptor */ dev->promiscous = 0; /* implicitly create the tap interface */ if ((dev->tap_fd = real_open(clonedev, O_RDWR | O_NONBLOCK)) == -1) { err(EXIT_FAILURE, "open(%s)", clonedev); } #if (defined(__MACH__) || defined(__FreeBSD__)) /* OSX/FreeBSD */ struct ifaddrs *iflist; if (real_getifaddrs(&iflist) == 0) { for (struct ifaddrs *cur = iflist; cur; cur = cur->ifa_next) { if ((cur->ifa_addr->sa_family == AF_LINK) && (strcmp(cur->ifa_name, name) == 0) && cur->ifa_addr) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)cur->ifa_addr; memcpy(dev->addr, LLADDR(sdl), sdl->sdl_alen); break; } } real_freeifaddrs(iflist); } #else /* Linux */ memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, name, IFNAMSIZ); if (real_ioctl(dev->tap_fd, TUNSETIFF, (void *)&ifr) == -1) { _native_in_syscall++; warn("ioctl TUNSETIFF"); warnx("probably the tap interface (%s) does not exist or is already in use", name); real_exit(EXIT_FAILURE); } /* get MAC address */ memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", name); if (real_ioctl(dev->tap_fd, SIOCGIFHWADDR, &ifr) == -1) { _native_in_syscall++; warn("ioctl SIOCGIFHWADDR"); if (real_close(dev->tap_fd) == -1) { warn("close"); } real_exit(EXIT_FAILURE); } memcpy(dev->addr, ifr.ifr_hwaddr.sa_data, ETHERNET_ADDR_LEN); /* change mac addr so it differs from what the host is using */ dev->addr[5]++; #endif DEBUG("gnrc_tapnet_init(): dev->addr = %02x:%02x:%02x:%02x:%02x:%02x\n", dev->addr[0], dev->addr[1], dev->addr[2], dev->addr[3], dev->addr[4], dev->addr[5]); /* configure signal handler for fds */ native_async_read_setup(); native_async_read_add_handler(dev->tap_fd, NULL, _tap_isr); #ifdef MODULE_NETSTATS_L2 memset(&netdev->stats, 0, sizeof(netstats_t)); #endif DEBUG("gnrc_tapnet: initialized.\n"); return 0; }
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) { if (uart >= UART_NUMOF) { return UART_NODEV; } struct termios termios; memset(&termios, 0, sizeof(termios)); termios.c_iflag = 0; termios.c_oflag = 0; termios.c_cflag = CS8 | CREAD | CLOCAL; termios.c_lflag = 0; speed_t speed; switch (baudrate) { case 0: speed = B0; break; case 50: speed = B50; break; case 75: speed = B75; break; case 110: speed = B110; break; case 134: speed = B134; break; case 150: speed = B150; break; case 200: speed = B200; break; case 300: speed = B300; break; case 600: speed = B600; break; case 1200: speed = B1200; break; case 1800: speed = B1800; break; case 2400: speed = B2400; break; case 4800: speed = B4800; break; case 9600: speed = B9600; break; case 19200: speed = B19200; break; case 38400: speed = B38400; break; case 57600: speed = B57600; break; case 115200: speed = B115200; break; case 230400: speed = B230400 ; break; default: return UART_NOBAUD; break; } cfsetospeed(&termios, speed); cfsetispeed(&termios, speed); tty_fds[uart] = real_open(tty_device_filenames[uart], O_RDWR | O_NONBLOCK); if (tty_fds[uart] < 0) { return UART_INTERR; } tcsetattr(tty_fds[uart], TCSANOW, &termios); uart_config[uart].rx_cb = rx_cb; uart_config[uart].arg = arg; native_async_read_setup(); native_async_read_add_handler(tty_fds[uart], NULL, io_signal_handler); return UART_OK; }