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(); }
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]))); }
/**@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 */ }
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; }
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); }
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; }
/**@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 */ }
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); }