#include <string>
#include <sstream>
#include <iostream>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void ipStrToInt(unsigned int (&ip)[4], std::string);
const std::string get_ip();
const std::string inttostr(const unsigned int);
void *scan(void *ptr);
unsigned int IP[4] = {0,0,0,0};
unsigned int beginIP[4] = {0,0,0,0};
unsigned int endIP[4] = {0,0,0,0};
unsigned int startPort=0, stopPort=0;
unsigned int thread_cnt = 0, upIPcnt = 0;
bool done = false, first = true;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t cntMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t prtMutex = PTHREAD_MUTEX_INITIALIZER;
int main(void) {
std::string startIP, stopIP;
std::string mPorts;
std::cout << "Enter IP Range <start end> ";
std::cin >> startIP >> stopIP;
while(1) {
std::cout << "Scan Multiple Ports (Y/N) ";
std::cin >> mPorts;
if(mPorts == "Y" || mPorts == "y") {
std::cout << "Enter port range <start end> ";
std::cin >> startPort >> stopPort;
break;
} else if(mPorts == "N" || mPorts == "n") {
std::cout << "Setting scan port to default (80)\n";
startPort = stopPort = 80;
break;
} else {
std::cout << "Bad Input try again";
}
}
// Parse begin IP
ipStrToInt(beginIP, startIP);
// Parse end IP
ipStrToInt(endIP, stopIP);
// Set IP to starting value
IP[0] = beginIP[0];
IP[1] = beginIP[1];
IP[2] = beginIP[2];
IP[3] = beginIP[3];
const unsigned int max_threads = 100;
pthread_t thread[100];
while(thread_cnt < max_threads && !done) {
pthread_create(&thread[thread_cnt], NULL, &scan, &thread_cnt);
// Lock thread_cnt before incrementing
pthread_mutex_lock(&cntMutex);
thread_cnt++;
pthread_mutex_unlock(&cntMutex);
}
// wait for threads to finish before cleaning up
for(unsigned int x=0; x < thread_cnt; ++x) {
pthread_join(thread[x], NULL);
}
std::cout << "Finished\nNumber of Active IPs: " << upIPcnt << std::endl;
pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(&cntMutex);
pthread_mutex_destroy(&prtMutex);
pthread_exit(NULL);
return 0;
}
void *scan(void *arg) {
unsigned int port = startPort;
std::string curIP = "";
int sock, cnx;
struct sockaddr_in host;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0) {
std::cout << "ERROR: Could not open socket\n";
} else {
while(1) {
pthread_mutex_lock(&mutex);
curIP = get_ip(); // get the next ip address
pthread_mutex_unlock(&mutex);
if(curIP.empty()) {
done = true;
break;
}
host.sin_family = AF_INET;
host.sin_addr.s_addr = inet_addr(curIP.c_str());
if(!curIP.empty()) {
while(port <= stopPort) {
host.sin_port = htons(port);
cnx = connect(sock, (struct sockaddr*)&host, sizeof(host));
pthread_mutex_lock(&prtMutex);
if(cnx < 0) {
std::cout << inet_ntoa(host.sin_addr) << " ... connection failed. Host possibly down\n";
} else {
std::cout << inet_ntoa(host.sin_addr) << " ... Host appears to be up.\n";
pthread_mutex_lock(&cntMutex);
upIPcnt++;
pthread_mutex_unlock(&cntMutex);
}
pthread_mutex_unlock(&prtMutex);
port++;
}
}
}
}
close(sock);
// lock thread_cnt before decrementing
pthread_mutex_lock(&cntMutex);
thread_cnt--;
pthread_mutex_unlock(&cntMutex);
pthread_exit((void*)0);
}
void ipStrToInt(unsigned int (&ip)[4], std::string strIP) {
int found=0, cnt=0;
std::string temp;
temp = strIP;
found = temp.find_first_of(".");
while(found != std::string::npos && cnt < 4) {
if(found > 0) {
ip[cnt] = (unsigned)atoi(temp.substr(0,found).c_str());
}
temp = temp.substr(found+1);
found = temp.find_first_of(".");
cnt++;
}
if(temp.length() > 0 && cnt < 4) {
ip[cnt] = atoi(temp.c_str());
}
}
// Works
const std::string get_ip() {
if(!first) {
if(memcmp(&IP, &endIP, 4*sizeof(int)) != 0) {
if(IP[3] == 255 || IP[3] == endIP[3]) {
if(IP[2] == 255 || IP[2] == endIP[2]) {
if(IP[1] == 255 || IP[1] == endIP[1]) {
if(IP[0] <= 255 || IP[0] <= endIP[0]) {
IP[0]++;
IP[1] = IP[2] = IP[3] = 0;
} else {
return "";
}
} else {
IP[1]++;
IP[2] = IP[3] = 0;
}
} else {
IP[2]++;
IP[3] = 0;
}
} else {
IP[3]++;
}
} else {
done = true;
return "";
}
} else
first = false;
return inttostr(IP[0]) + "." + inttostr(IP[1]) + "." + inttostr(IP[2]) + "." + inttostr(IP[3]);
}
const std::string inttostr(const unsigned int x) {
std::ostringstream o;
if (!(o << x))
return "";
return o.str();
}