void* handle_socket_machine(void *arg) { int fd = 0; get_iface_mac("eth0",devicemac); while(1) { if(! is_wifi_connected()) { debug(LOG_NOTICE, "tcp Waiting WIFI connected...\n"); sleep_intp_s(5); continue; } if(! check_valid_id_name()) { debug(LOG_NOTICE, "--- waitting deviceid and devicename from uart...\n"); sleep_intp_s(5); continue; } fd = init_connect(glb_cfg.svr.ip, glb_cfg.svr.port, glb_cfg.svr.noneblock); debug(LOG_NOTICE,"Remote Socket thread init %s:%d ret %d\n",glb_cfg.svr.ip, glb_cfg.svr.port, fd); if(fd < 0) { sleep_intp_s(15); continue; } loop_socket_handle(fd, glb_cfg.svr.tt_ms); if(fd > 0) close(fd); sleep_intp_s(5); } return NULL; }
int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr) { int err = 0, savederrno = 0; if (!ether_addr) { errno = EINVAL; return -1; } savederrno = pthread_mutex_lock(&config_mutex); if (savederrno) { errno = savederrno; return -1; } if (!is_valid_nozzle(nozzle)) { savederrno = EINVAL; err = -1; goto out_clean; } err = get_iface_mac(nozzle, ether_addr); out_clean: pthread_mutex_unlock(&config_mutex); errno = savederrno; return err; }
/**@internal * Main execution loop */ static void main_loop(void) { int result; pthread_t tid; s_config *config = config_get_config(); request *r; void **params; /* Set the time when wifidog started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* If we don't have the Gateway IP address, get it. Can't fail. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); } /* If we don't have the Gateway ID, construct it from the internal MAC address. * "Can't fail" so exit() if the impossible happens. */ if (!config->gw_mac) { debug(LOG_DEBUG, "Finding MAC address of %s", config->gw_interface); if ((config->gw_mac = get_iface_mac(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_mac); } /* Initializes the web server */ debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } debug(LOG_DEBUG, "Assigning callbacks to web server"); httpdAddCContent(webserver, "/", "ctbrihuang", 0, NULL, http_callback_wifidog); httpdAddCContent(webserver, "/ctbrihuang", "", 0, NULL, http_callback_wifidog); httpdAddCContent(webserver, "/debug", "", 0, NULL, http_callback_404); httpdAddCContent(webserver, "/ctbrihuang", "about", 0, NULL, http_callback_about); httpdAddCContent(webserver, "/ctbrihuang", "status", 0, NULL, http_callback_status); httpdAddCContent(webserver, "/smartwifi", "auth", 0, NULL, http_callback_auth); /*httpdAddCContent(webserver, "/ctbrihuang", "logout", 0, NULL, http_callback_logout); */ httpdAddC404Content(webserver, http_callback_404); fw_destroy(); if (!fw_init()) { debug(LOG_ERR, "FATAL: Failed to initialize firewall"); exit(1); } /* Start update thread */ result = pthread_create(&tid_update, NULL, (void *)thread_update, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (update) - exiting"); termination_handler(0); } pthread_detach(tid_update); /* Start clean up thread */ result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (fw_counter) - exiting"); termination_handler(0); } pthread_detach(tid_fw_counter); /* Start control thread */ result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting"); termination_handler(0); } pthread_detach(tid); /* Start heartbeat thread */ result = pthread_create(&tid_ping, NULL, (void *)thread_ping, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (ping) - exiting"); termination_handler(0); } pthread_detach(tid_ping); result = pthread_create(&tid_ding, NULL, (void *)thread_ding, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (ding) - exiting"); termination_handler(0); } pthread_detach(tid_ding); result = pthread_create(&tid_authlog, NULL, (void *)thread_client_timeout_log, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread authlog - exiting"); termination_handler(0); } pthread_detach(tid_authlog); debug(LOG_NOTICE, "Waiting for connections"); while(1) { webserver->lastError = 0; r = httpdGetConnection(webserver, NULL); /* We can't convert this to a switch because there might be * values that are not -1, 0 or 1. */ if (webserver->lastError == -1) { /* Interrupted system call */ debug(LOG_DEBUG, "lastError is -1"); continue; /* restart loop */ } else if (webserver->lastError < -1) { /* * FIXME * An error occurred - should we abort? * reboot the device ? */ debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); termination_handler(0); } else if (r != NULL) { /* * We got a connection * * We should create another thread */ debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); /* The void**'s are a simulation of the normal C * function calling sequence. */ params = safe_malloc(2 * sizeof(void *)); *params = webserver; *(params + 1) = r; result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting"); termination_handler(0); } pthread_detach(tid); } else { debug(LOG_DEBUG, "lastError=%d", webserver->lastError); /* webserver->lastError should be 2 */ /* XXX We failed an ACL.... No handling because * we don't set any... */ } } /* never reached */ }
/**@internal * Main execution loop */ static void main_loop(void) { int result; pthread_t tid; s_config *config = config_get_config(); struct timespec wait_time; int msec; request *r; void **params; int* thread_serial_num_p; /* Set the time when nodogsplash started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* If we don't have the Gateway IP address, get it. Exit on failure. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } if ((config->gw_mac = get_iface_mac(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_NOTICE, "Detected gateway %s at %s (%s)", config->gw_interface, config->gw_address, config->gw_mac); } /* Initializes the web server */ if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } debug(LOG_NOTICE, "Created web server on %s:%d", config->gw_address, config->gw_port); /* Set web root for server */ debug(LOG_DEBUG, "Setting web root: %s",config->webroot); httpdSetFileBase(webserver,config->webroot); /* Add images files to server: any file in config->imagesdir can be served */ debug(LOG_DEBUG, "Setting images subdir: %s",config->imagesdir); httpdAddWildcardContent(webserver,config->imagesdir,NULL,config->imagesdir); /* Add pages files to server: any file in config->pagesdir can be served */ debug(LOG_DEBUG, "Setting pages subdir: %s",config->pagesdir); httpdAddWildcardContent(webserver,config->pagesdir,NULL,config->pagesdir); debug(LOG_DEBUG, "Registering callbacks to web server"); httpdAddCContent(webserver, "/", "", 0, NULL, http_nodogsplash_callback_index); httpdAddCWildcardContent(webserver, config->authdir, NULL, http_nodogsplash_callback_auth); httpdAddCWildcardContent(webserver, config->denydir, NULL, http_nodogsplash_callback_deny); httpdAddC404Content(webserver, http_nodogsplash_callback_404); /* Reset the firewall (cleans it, in case we are restarting after nodogsplash crash) */ fw_destroy(); /* Then initialize it */ debug(LOG_NOTICE, "Initializing firewall rules"); if( fw_init() != 0 ) { debug(LOG_ERR, "Error initializing firewall rules! Cleaning up"); fw_destroy(); debug(LOG_ERR, "Exiting because of error initializing firewall rules"); exit(1); } /* Start client statistics and timeout clean-up thread */ result = pthread_create(&tid_client_check, NULL, (void *)thread_client_timeout_check, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_client_timeout_check - exiting"); termination_handler(0); } pthread_detach(tid_client_check); /* Start control thread */ result = pthread_create(&tid, NULL, (void *)thread_ndsctl, (void *)safe_strdup(config->ndsctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_ndsctl - exiting"); termination_handler(0); } pthread_detach(tid); /* * Enter the httpd request handling loop */ debug(LOG_NOTICE, "Waiting for connections"); while(1) { r = httpdGetConnection(webserver, NULL); /* We can't convert this to a switch because there might be * values that are not -1, 0 or 1. */ if (webserver->lastError == -1) { /* Interrupted system call */ continue; /* continue loop from the top */ } else if (webserver->lastError < -1) { /* * FIXME * An error occurred - should we abort? * reboot the device ? */ debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); termination_handler(0); } else if (r != NULL) { /* We got a connection */ handle_http_request(webserver, r); } else { /* webserver->lastError should be 2 */ /* XXX We failed an ACL.... No handling because * we don't set any... */ } } /* never reached */ }
char *get_mac_by_addr(in_addr_t addr, const char *loiface, const int max_tries) { struct ethernet_frame eth; struct arp arp; char *mac, *ip; unsigned char *mac_in_bytes, *rawpkt; size_t rawpkt_sz; int bytes_total; int sk; char buf[0xffff]; int ntry = max_tries; unsigned short ether_type; struct arp *arp_reply; struct in_addr sin_addr; struct timeval tv; if (strcmp(loiface, "lo") == 0) { return NULL; // INFO(Santiago): this is software instead of hardware and does not make sense. } sin_addr.s_addr = addr; memset(&tv, 0, sizeof(tv)); tv.tv_sec = 5; sk = lin_rsk_create(loiface); if (sk == -1) return NULL; setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); setsockopt(sk, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); eth.payload = NULL; memset(&arp, 0, sizeof(struct arp)); memset(eth.dest_hw_addr, 0xff, sizeof(eth.dest_hw_addr)); mac = get_iface_mac(loiface); mac_in_bytes = mac2byte(mac, 6); memcpy(eth.src_hw_addr, mac_in_bytes, 6); free(mac); mac = NULL; free(mac_in_bytes); eth.ether_type = ETHER_TYPE_ARP; arp.hwtype = ARP_HW_TYPE_ETHERNET; arp.ptype = ARP_PROTO_TYPE_IP; arp.hw_addr_len = 6; arp.pt_addr_len = 4; arp.opcode = ARP_OPCODE_REQUEST; arp.src_hw_addr = (unsigned char *) pig_newseg(arp.hw_addr_len); memcpy(arp.src_hw_addr, eth.src_hw_addr, 6); ip = get_iface_ip(loiface); if (ip == NULL) { free(arp.src_hw_addr); return NULL; } arp.src_pt_addr = addr2byte(ip, 4); free(ip); arp.dest_hw_addr = (unsigned char *) pig_newseg(arp.hw_addr_len); memset(arp.dest_hw_addr, 0, arp.hw_addr_len); arp.dest_pt_addr = (unsigned char *)&addr; eth.payload = mk_arp_dgram(ð.payload_size, arp); rawpkt = mk_ethernet_frame(&rawpkt_sz, eth); while (ntry-- > 0 && mac == NULL) { bytes_total = sendto(sk, rawpkt, rawpkt_sz, 0, NULL, 0); if (bytes_total > 0) { bytes_total = recvfrom(sk, buf, sizeof(buf), 0, NULL, 0); if (bytes_total > 0) { ether_type = (unsigned short) buf[12] << 8 | buf[13]; if (ether_type == ETHER_TYPE_ARP) { arp_reply = parse_arp_dgram((unsigned char *)&buf[14], bytes_total - 14); if (arp_reply != NULL && arp_reply->opcode == ARP_OPCODE_REPLY) { ip = (char *) pig_newseg(20); sprintf(ip, "%d.%d.%d.%d", arp_reply->src_pt_addr[0], arp_reply->src_pt_addr[1], arp_reply->src_pt_addr[2], arp_reply->src_pt_addr[3]); if (strcmp(inet_ntoa(sin_addr), ip) == 0) { mac = (char *) pig_newseg(20); sprintf(mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", arp_reply->src_hw_addr[0], arp_reply->src_hw_addr[1], arp_reply->src_hw_addr[2], arp_reply->src_hw_addr[3], arp_reply->src_hw_addr[4], arp_reply->src_hw_addr[5]); } free(ip); } arp_header_free(arp_reply); free(arp_reply); } } } } free(rawpkt); lin_rsk_close(sk); free(eth.payload); free(arp.src_hw_addr); free(arp.src_pt_addr); free(arp.dest_hw_addr); return mac; }
/**@internal * Main execution loop */ static void main_loop(void) { int result; pthread_t tid; s_config *config = config_get_config(); request *r; void **params; /* Set the time when wifidog started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* save the pid file if needed */ if ((!config) && (!config->pidfile)) save_pid_file(config->pidfile); /* If we don't have the Gateway IP address, get it. Can't fail. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); } /* If we don't have the Gateway ID, construct it from the internal MAC address. * "Can't fail" so exit() if the impossible happens. */ if (!config->gw_id) { debug(LOG_DEBUG, "Finding MAC address of %s", config->external_interface); if ((config->gw_id = get_iface_mac(config->external_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->external_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_id); } /* Initializes the web server */ debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } register_fd_cleanup_on_fork(webserver->serverSock); debug(LOG_DEBUG, "Assigning callbacks to web server"); httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about); httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status); httpdAddCContent(webserver, "/wifidog", "release", 0, NULL, http_callback_release); httpdAddCContent(webserver, "/wifidog", "allow", 0, NULL, http_callback_allow_redirect); httpdSetErrorFunction(webserver, 404, http_callback_404); /* Set the auth server ip address. */ set_auth_svr_lastip(config); /* Reset the firewall (if WiFiDog crashed) */ fw_destroy(); /* Then initialize it */ if (!fw_init()) { debug(LOG_ERR, "FATAL: Failed to initialize firewall"); exit(1); } /* Start control thread */ result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting"); termination_handler(0); } pthread_detach(tid); debug(LOG_NOTICE, "Waiting for connections"); while (1) { r = httpdGetConnection(webserver, NULL); /* We can't convert this to a switch because there might be * values that are not -1, 0 or 1. */ if (webserver->lastError == -1) { /* Interrupted system call */ if (NULL != r) { httpdEndRequest(r); } } else if (webserver->lastError < -1) { /* * FIXME * An error occurred - should we abort? * reboot the device ? */ debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); termination_handler(0); } else if (r != NULL) { /* * We got a connection * * We should create another thread */ debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); /* The void**'s are a simulation of the normal C * function calling sequence. */ params = safe_malloc(2 * sizeof(void *)); *params = webserver; *(params + 1) = r; result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting"); termination_handler(0); } pthread_detach(tid); } else { /* webserver->lastError should be 2 */ /* XXX We failed an ACL.... No handling because * we don't set any... */ } //update the auth server ip update_auth_svr_lastip(config); } /* never reached */ }
/**@internal * Main execution loop */ static void main_loop(void) { int result = 0; pthread_t tid; s_config *config; config = config_get_config(); /* Set the time when nodogsplash started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* If we don't have the Gateway IP address, get it. Exit on failure. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } } if ((config->gw_mac = get_iface_mac(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_NOTICE, "Detected gateway %s at %s (%s)", config->gw_interface, config->gw_address, config->gw_mac); /* Initializes the web server */ if ((webserver = MHD_start_daemon( MHD_USE_EPOLL_INTERNALLY, config->gw_port, NULL, NULL, libmicrohttpd_cb, NULL, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120, MHD_OPTION_LISTENING_ADDRESS_REUSE, 1, MHD_OPTION_END)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } /* TODO: set listening socket */ debug(LOG_NOTICE, "Created web server on %s:%d", config->gw_address, config->gw_port); /* httpdAddCContent(webserver, "/", "", 0, NULL, http_nodogsplash_callback_index); httpdAddCWildcardContent(webserver, config->authdir, NULL, http_nodogsplash_callback_auth); httpdAddCWildcardContent(webserver, config->denydir, NULL, http_nodogsplash_callback_deny); httpdAddC404Content(webserver, http_nodogsplash_callback_404); */ /* Reset the firewall (cleans it, in case we are restarting after nodogsplash crash) */ fw_destroy(); /* Then initialize it */ debug(LOG_NOTICE, "Initializing firewall rules"); if (fw_init() != 0) { debug(LOG_ERR, "Error initializing firewall rules! Cleaning up"); fw_destroy(); debug(LOG_ERR, "Exiting because of error initializing firewall rules"); exit(1); } /* Start client statistics and timeout clean-up thread */ result = pthread_create(&tid_client_check, NULL, thread_client_timeout_check, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_client_timeout_check - exiting"); termination_handler(0); } pthread_detach(tid_client_check); /* Start control thread */ result = pthread_create(&tid, NULL, thread_ndsctl, (void *)(config->ndsctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_ndsctl - exiting"); termination_handler(1); } result = pthread_join(tid, NULL); if (result) { debug(LOG_INFO, "Failed to wait for nodogsplash thread."); } MHD_stop_daemon(webserver); termination_handler(result); }
nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath) { int savederrno = 0; nozzle_t nozzle = NULL; char *temp_mac = NULL; #ifdef KNET_LINUX struct ifreq ifr; #endif #ifdef KNET_BSD uint16_t i; long int nozzlenum = 0; char curnozzle[IFNAMSIZ]; #endif if (devname == NULL) { errno = EINVAL; return NULL; } if (devname_size < IFNAMSIZ) { errno = EINVAL; return NULL; } if (strlen(devname) > IFNAMSIZ) { errno = E2BIG; return NULL; } #ifdef KNET_BSD /* * BSD does not support named devices like Linux * but it is possible to force a nozzleX device number * where X is 0 to 255. */ if (strlen(devname)) { if (strncmp(devname, "tap", 3)) { errno = EINVAL; return NULL; } errno = 0; nozzlenum = strtol(devname+3, NULL, 10); if (errno) { errno = EINVAL; return NULL; } if ((nozzlenum < 0) || (nozzlenum > 255)) { errno = EINVAL; return NULL; } } #endif if (updownpath) { /* only absolute paths */ if (updownpath[0] != '/') { errno = EINVAL; return NULL; } if (strlen(updownpath) >= UPDOWN_PATH_MAX) { errno = E2BIG; return NULL; } } savederrno = pthread_mutex_lock(&config_mutex); if (savederrno) { errno = savederrno; return NULL; } if (!lib_init) { lib_cfg.head = NULL; #ifdef KNET_LINUX lib_cfg.nlsock = nl_socket_alloc(); if (!lib_cfg.nlsock) { savederrno = errno; goto out_error; } if (nl_connect(lib_cfg.nlsock, NETLINK_ROUTE) < 0) { savederrno = EBUSY; goto out_error; } lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0); #endif #ifdef KNET_BSD lib_cfg.ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0); #endif if (lib_cfg.ioctlfd < 0) { savederrno = errno; goto out_error; } lib_init = 1; } nozzle = malloc(sizeof(struct nozzle_iface)); if (!nozzle) { savederrno = ENOMEM; goto out_error; } memset(nozzle, 0, sizeof(struct nozzle_iface)); #ifdef KNET_BSD if (!strlen(devname)) { for (i = 0; i < 256; i++) { snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i); nozzle->fd = open(curnozzle, O_RDWR); savederrno = errno; if (nozzle->fd > 0) { break; } } snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i); } else { snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname); nozzle->fd = open(curnozzle, O_RDWR); savederrno = errno; snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname); } if (nozzle->fd < 0) { savederrno = EBUSY; goto out_error; } strncpy(devname, curnozzle, IFNAMSIZ); strncpy(nozzle->name, curnozzle, IFNAMSIZ); #endif #ifdef KNET_LINUX if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0) { savederrno = errno; goto out_error; } memset(&ifr, 0, sizeof(struct ifreq)); memmove(ifname, devname, IFNAMSIZ); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) { savederrno = errno; goto out_error; } if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) { savederrno = EBUSY; goto out_error; } strncpy(devname, ifname, IFNAMSIZ); strncpy(nozzle->name, ifname, IFNAMSIZ); #endif nozzle->default_mtu = get_iface_mtu(nozzle); if (nozzle->default_mtu < 0) { savederrno = errno; goto out_error; } if (get_iface_mac(nozzle, &temp_mac) < 0) { savederrno = errno; goto out_error; } strncpy(nozzle->default_mac, temp_mac, 18); free(temp_mac); if (updownpath) { int len = strlen(updownpath); strcpy(nozzle->updownpath, updownpath); if (nozzle->updownpath[len-1] != '/') { nozzle->updownpath[len] = '/'; } nozzle->hasupdown = 1; } nozzle->next = lib_cfg.head; lib_cfg.head = nozzle; pthread_mutex_unlock(&config_mutex); errno = savederrno; return nozzle; out_error: destroy_iface(nozzle); pthread_mutex_unlock(&config_mutex); errno = savederrno; return NULL; }