Пример #1
0
void notify_add_route(struct brreq *brreq, char *mac)
{
    t_client *client;
    t_redir_node *node;

    LOCK_REDIR();

    node = redir_list_find(mac);
    if (!node) {
        debug(LOG_NOTICE, "%s: %s node not present, creating it with src interface %s\n",__func__,mac, brreq->ifname);
        node = redir_list_append(mac);
        if(node){
            node->expiry = time(NULL);
            fw_mark_mangle(mac,1);
        }
    }
    if (!node) {
        UNLOCK_REDIR();
        return;
    }

    node->ifindex = get_ifIndex(brreq->ifname);
    node->redir_pending = 1;

    //  if (!node->redir_pending) {
    {
        struct in_addr src_ip;
        char cmd[256];
        char *tmp_ptr;
        /* Get the Host IP address */
        src_ip.s_addr = brreq->iph.saddr;
        memset(node->host_ip, 0, sizeof(node->host_ip));
        tmp_ptr = inet_ntoa(src_ip);
        if (tmp_ptr)
            strcpy(node->host_ip, tmp_ptr);
        /* Copy the device name to node */
        strcpy(node->dev, brreq->dev);
        /* Get the interface IP address */
        memset(node->dev_ip, 0, sizeof(node->dev_ip));
        tmp_ptr = get_iface_ip(node->dev);
        if (tmp_ptr)
            strcpy(node->dev_ip, tmp_ptr);
        /* Set the host route */
        memset(cmd, 0, sizeof(cmd));
        sprintf(cmd, "/sbin/ip route add %s/32 src %s dev %s", node->host_ip, node->dev_ip, node->dev);
        //printf("\nexecuting %s\n", cmd);
        execute(cmd, 0);
        node->route_added = 1;
        free(tmp_ptr);
    }
    UNLOCK_REDIR();
}
Пример #2
0
Файл: oink.c Проект: huap/pig
static int should_route(const unsigned int addr[4], const unsigned int nt_mask[4], const char *loiface) {
    static unsigned int lo_addr[4] = { 0, 0, 0, 0 };
    char *temp = NULL;
    if (lo_addr[0] == 0 && lo_addr[1] == 0 && lo_addr[2] == 0 && lo_addr[3] == 0) {
        temp = get_iface_ip(loiface);
        if (temp != NULL) {
            if (*temp != 0) {
                //  WARN(Santiago): until now IPv4 only.
                lo_addr[0] = htonl(inet_addr(temp));
            }
            free(temp);
        }
    }
    return !((pig_get_net_mask_from_addr(addr[0], nt_mask[0]) == pig_get_net_mask_from_addr(lo_addr[0], nt_mask[0])) &&
             (pig_get_net_mask_from_addr(addr[1], nt_mask[1]) == pig_get_net_mask_from_addr(lo_addr[1], nt_mask[1])) &&
             (pig_get_net_mask_from_addr(addr[2], nt_mask[2]) == pig_get_net_mask_from_addr(lo_addr[2], nt_mask[2])) &&
             (pig_get_net_mask_from_addr(addr[3], nt_mask[3]) == pig_get_net_mask_from_addr(lo_addr[3], nt_mask[3])));
}
Пример #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 */
}
Пример #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 */
}
Пример #5
0
int main(int argc, char *argv[])
{
	struct sockaddr_in addr;
	int fd, nbytes,addrlen;
	struct ip_mreq mreq;
	char msgbuf[MSGBUFSIZE];

	u_int yes=1; /*** MODIFICATION TO ORIGINAL */

	/* create what looks like an ordinary UDP socket */
	if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) 
	{
		perror("socket");
		exit(1);
	}


	/**** MODIFICATION TO ORIGINAL */
	/* allow multiple sockets to use the same PORT number */
	if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) 
	{
		perror("Reusing ADDR failed");
		exit(1);
	}
	/*** END OF MODIFICATION TO ORIGINAL */

	/* set up destination address */
	char *brlan = NULL;
	brlan = get_iface_ip("wlan0");
    if (brlan)
    {
		printf("ip:%s\n", brlan);
        inet_pton(AF_INET, brlan, &szIPNet);
    }
	else
	{
		printf("wlan0 ip error\n");
		//exit(0);
	}

	memset(&addr,0,sizeof(addr));
	addr.sin_family=AF_INET;
	addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */
	//addr.sin_addr.s_addr=szIPNet;
	//addr.sin_addr.s_addr = inet_addr("192.168.99.5");
	addr.sin_port=htons(HELLO_PORT);

	/* bind to receive address */
	if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0)
	{
		perror("bind");
		exit(1);
	}

	/* use setsockopt() to request that the kernel join a multicast group */
	mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP);
	mreq.imr_interface.s_addr=htonl(INADDR_ANY);
	if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) 
	{
		perror("setsockopt");
		exit(1);
	}

	/* now just enter a read-print loop */
	int i = 0;
	int j = 0;
	while (1) 
	{
		memset(msgbuf, 0, MSGBUFSIZE);
		addrlen=sizeof(addr);
		if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0, (struct sockaddr *) &addr,(socklen_t*)&addrlen)) < 0) 
		{
			perror("recvfrom");
			exit(1);
		}
		printf("%d:%d:", i++, nbytes);
		puts(msgbuf);
		//for (j = 0; j < nbytes; j++)
		//{
		//	printf("%02x", msgbuf[j]);
		//}
		//printf("%s", msgbuf);
		//printf("\n");
	}

	return 0;
}
Пример #6
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;
}
Пример #7
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 */
}
Пример #8
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);
}
Пример #9
0
int start_sip(int s, char *ip, char *lip, int port, int lport, unsigned char options, char *miscptr, FILE * fp) {
  char *login, *pass, *host, buffer[SIP_MAX_BUF];
  int i;
  char buf[SIP_MAX_BUF];

  if (strlen(login = hydra_get_next_login()) == 0)
    login = NULL;
  if (strlen(pass = hydra_get_next_password()) == 0)
    pass = NULL;

  if (external_ip_addr[0])
    lip = external_ip_addr;

  host = miscptr;
  cseq = 1;

  empty_register(buffer, host, lip, port, lport, login);
  cseq++;

  if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
    return 3;
  }

  int has_sip_cred = 0;
  int try = 0;

  /* We have to check many times because server may begin to send "100 Trying"
   * before "401 Unauthorized" */
  while (try < 2 && !has_sip_cred) {
    try++;
    if (hydra_data_ready_timed(s, 3, 0) > 0) {
      i = hydra_recv(s, (char *) buf, sizeof(buf));
      buf[sizeof(buf) - 1] = '\0';
      if (strncmp(buf, "SIP/2.0 404", 11) == 0) {
	hydra_report(stdout, "[ERROR] Get error code 404 : user '%s' not found\n", login);
	return 2;
      }
      if (strncmp(buf, "SIP/2.0 606", 11) == 0) {
        char *ptr=NULL;
        int i = 0;

        // if we already tried to connect, exit
        if (external_ip_addr[0]) {
          hydra_report(stdout, "[ERROR] Get error code 606 : session is not acceptable by the server\n");          
          return 2;
        }
        
        if (verbose)
          hydra_report(stdout, "[VERBOSE] Get error code 606 : session is not acceptable by the server,\n"
                                          "maybe it's an addressing issue as you are using NAT, trying to reconnect\n"
                                          "using addr from the server reply\n");
        /* 
        SIP/2.0 606 Not Acceptable
        Via: SIP/2.0/UDP 192.168.0.21:46759;received=82.227.229.137
        */
#ifdef HAVE_PCRE
        if (hydra_string_match(buf, "Via: SIP.*received=")) {
          ptr=strstr(buf, "received=");
#else
        if ((ptr=strstr(buf, "received="))) {
#endif
        strncpy(external_ip_addr, ptr+strlen("received="), sizeof(external_ip_addr));
        external_ip_addr[sizeof(external_ip_addr) - 1] = '\0';
        for (i = 0; i < strlen(external_ip_addr); i++) {
          if (external_ip_addr[i] <= 32) {
            external_ip_addr[i] = '\0';
          }
        }
        if (verbose)
          hydra_report(stderr, "[VERBOSE] Will reconnect using external IP address %s\n", external_ip_addr);
        return 1;
        }
        hydra_report(stderr, "[ERROR] Could not find external IP address in server answer\n");
        return 2;
      }
    }
  }
  if (!strstr(buf, "WWW-Authenticate: Digest")) {
    hydra_report(stderr, "[ERROR] no www-authenticate header found!\n");
    return -1;
  }
  if (verbose)
    hydra_report(stderr, "[INFO] S: %s\n", buf);
  char buffer2[512];
  sasl_digest_md5(buffer2, login, pass, strstr(buf, "WWW-Authenticate: Digest") + strlen("WWW-Authenticate: Digest") + 1, host, "sip", NULL, 0, NULL);

  memset(buffer, 0, SIP_MAX_BUF);
  snprintf(buffer, SIP_MAX_BUF,
           "REGISTER sip:%s SIP/2.0\n"
           "Via: SIP/2.0/UDP %s:%i\n"
           "From: <sip:%s@%s>\n"
           "To: <sip:%s@%s>\n"
           "Call-ID: 1337@%s\n"
           "CSeq: %i REGISTER\n"
           "Authorization: Digest %s\n"
           "Content-Length: 0\n\n", host, lip, lport, login, host, login, host, host, cseq, buffer2);

  cseq++;
  if (verbose)
    hydra_report(stderr, "[INFO] C: %s\n", buffer);
  if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
    return 3;
  }
  try = 0;
  int has_resp = 0;
  int sip_code = 0;

  while (try < 2 && !has_resp) {
    try++;
    if (hydra_data_ready_timed(s, 5, 0) > 0) {
      memset(buf, 0, sizeof(buf));
      i = hydra_recv(s, (char *) buf, sizeof(buf));
      if (verbose)
        hydra_report(stderr, "[INFO] S: %s\n", buf);
      sip_code = get_sip_code(buf);
      if (sip_code >= 200 && sip_code < 300) {
        hydra_report_found_host(port, ip, "sip", fp);
        hydra_completed_pair_found();
        has_resp = 1;
      }
      if (sip_code >= 400 && sip_code < 500) {
        has_resp = 1;
      }
    }
  }

  hydra_completed_pair();
  if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
    return 3;

  return 1;
}

void service_sip(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) {
  int run = 1, next_run = 1, sock = -1;
  int myport = PORT_SIP, mysslport = PORT_SIP_SSL;

  char *lip = get_iface_ip((int) *(&ip[1]));
  hydra_register_socket(sp);

  // FIXME IPV6
  if (ip[0] != 4) {
    fprintf(stderr, "[ERROR] sip module is not ipv6 enabled yet, patches are appreciated.\n");
    hydra_child_exit(2);
  }

  if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
    run = 3;

  int lport = 0;

  while (1) {
    switch (run) {
    case 1:
      if (sock < 0) {
        if (port != 0)
          myport = port;
        lport = rand() % (65535 - 1024) + 1024;
        hydra_set_srcport(lport);

        if ((options & OPTION_SSL) == 0) {
          if (port != 0)
            myport = port;
          sock = hydra_connect_udp(ip, myport);
          port = myport;
        } else {
          if (port != 0)
            mysslport = port;
          sock = hydra_connect_ssl(ip, mysslport);
          port = mysslport;
        }

        if (sock < 0) {
          if (verbose || debug)
            hydra_report(stderr, "[ERROR] Child with pid %d terminating, can not connect\n", (int) getpid());
          free(lip);
          hydra_child_exit(1);
        }
      }
      next_run = start_sip(sock, ip, lip, port, lport, options, miscptr, fp);
      break;
    case 2:
      if (sock >= 0)
        sock = hydra_disconnect(sock);
      free(lip);
      hydra_child_exit(2);
      break;
    case 3:
      if (sock >= 0)
        sock = hydra_disconnect(sock);
      free(lip);
      hydra_child_exit(2);
      return;
    default:
      hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n");
      free(lip);
      hydra_child_exit(2);
    }
    run = next_run;
  }
}

char *get_iface_ip(unsigned long int ip) {

  int sfd;

  sfd = socket(AF_INET, SOCK_DGRAM, 0);

  struct sockaddr_in tparamet;

  tparamet.sin_family = AF_INET;
  tparamet.sin_port = htons(2000);
  tparamet.sin_addr.s_addr = ip;

  if (connect(sfd, (const struct sockaddr *) &tparamet, sizeof(struct sockaddr_in))) {
    perror("connect");
    close(sfd);
    return NULL;
  }
  struct sockaddr_in *local = malloc(sizeof(struct sockaddr_in));
  int size = sizeof(struct sockaddr_in);

  if (getsockname(sfd, (void *) local, (socklen_t *) & size)) {
    perror("getsockname");
    close(sfd);
    free(local);
    return NULL;
  }
  close(sfd);

  char buff[32];

  if (!inet_ntop(AF_INET, (void *) &local->sin_addr, buff, 32)) {
    perror("inet_ntop");
    free(local);
    return NULL;
  }
  char *str = malloc(sizeof(char) * (strlen(buff) + 1));

  strcpy(str, buff);
  free(local);
  return str;
}

#endif

int service_sip_init(char *ip, int sp, unsigned char options, char *miscptr, FILE *fp, int port) {
  // called before the childrens are forked off, so this is the function
  // which should be filled if initial connections and service setup has to be
  // performed once only.
  //
  // fill if needed.
  // 
  // return codes:
  //   0 all OK
  //   -1  error, hydra will exit, so print a good error message here

  return 0;
}
Пример #10
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;
  FILE *fh;
  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);
    }
    debug(LOG_NOTICE, "Detected gateway %s at %s", config->gw_interface, config->gw_address);
  }

  /* 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");
  created_httpd_threads = 0;
  current_httpd_threads = 0;
  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
       *
       * We create another thread to handle the request,
       * possibly sleeping first if there are too many already
       */
      debug(LOG_DEBUG,"%d current httpd threads.", current_httpd_threads);
      if(config->decongest_httpd_threads && current_httpd_threads >= config->httpd_thread_threshold) {
	msec = current_httpd_threads * config->httpd_thread_delay_ms;
	wait_time.tv_sec = msec / 1000;
	wait_time.tv_nsec = (msec % 1000) * 1000000;
	debug(LOG_INFO, "Httpd thread creation delayed %ld sec %ld nanosec for congestion.",
	      wait_time.tv_sec, wait_time.tv_nsec);
	nanosleep(&wait_time,NULL);
      }
      thread_serial_num_p = (int*) malloc(sizeof(int)); /* thread_httpd() must free */
      *thread_serial_num_p = created_httpd_threads;
      debug(LOG_INFO, "Creating httpd request thread %d for %s", *thread_serial_num_p, r->clientAddr);
      /* The void**'s are a simulation of the normal C
       * function calling sequence. */
      params = safe_malloc(3 * sizeof(void *)); /* thread_httpd() must free */
      *params = webserver;
      *(params + 1) = r;
      *(params + 2) = thread_serial_num_p;
      created_httpd_threads++;
      result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params);
      if (result != 0) {
	debug(LOG_ERR, "FATAL: pthread_create failed to create httpd request thread - 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... */
    }
  }

  /* never reached */
}
Пример #11
0
void processArgs(int argc, char **argv)
{
    globalArgs.attack_port = 0;
    globalArgs.syn_delay = DEFAULT_SYN_DELAY;
    globalArgs.payload_size = 0;

    int opt = 0;
    while((opt = getopt(argc, argv, optString)) != -1)
    {
        switch(opt)
        {
            case 'p':
                loadPayload(optarg);
                break;
            case 'd':
                globalArgs.syn_delay = atoi(optarg);
                if(globalArgs.syn_delay == 0)
                    printUsage("Invalid delay.");
                break;
            case 'h':
            case '?':
                printUsage(NULL);
            default:
                break;
        }
    }

    char **remArgv = argv + optind;
    int remArgc = argc - optind;
    if(remArgc > 2)
        printUsage("Too many arguments.");
    if(remArgc < 2)
        printUsage("Too few arguments.");

    int ip_index = 0;
    int iface_index = 1;

    // If they put the interface before the ip:port, swap the indexes. 
    if(get_iface_ip(&globalArgs.iface_addr, remArgv[iface_index]) == 0)
    {
        ip_index = 1;
        iface_index = 0;
        if(get_iface_ip(&globalArgs.iface_addr, remArgv[iface_index]) == 0)
            printUsage("Invalid interface.");
    }

    char *ip = remArgv[ip_index];
    char *port = remArgv[ip_index];
    while(*port != ':' && *port != '\0')
        port++;
    if(*port == '\0')
        printUsage("Please specify a port.");
    *port = '\0';
    port++;

    globalArgs.attack_port = atoi(port);
    if(globalArgs.attack_port == 0)
        printUsage("Invalid port.");

    if(inet_aton(ip, &globalArgs.attack_ip) == 0)
        printUsage("Invalid IP address.");

    printf("[+] Sending packets from %s (%s)\n", remArgv[iface_index], inet_ntoa(globalArgs.iface_addr.sin_addr));
    printf("[+] Attacking: %s:%hu...\n", ip, globalArgs.attack_port);
}