Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
/**@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 */
}
Example #4
0
/**@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 */
}
Example #5
0
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(&eth.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;
}
Example #6
0
/**@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 */
}
Example #7
0
/**@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);
}
Example #8
0
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;
}