patterncMinor
Simple C Port Scanner
Viewed 0 times
simplescannerport
Problem
I have been writing a Simple Port scanner in C, once I got it to work I decided I wanted to make it faster because it takes a very long time for it to get done with scanning all of the ports.Is there anything I can improve on in my code to make it faster? Here is my Code :
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 65536
int main(int argc, char ** argv)
{
time_t begin, end;
time(&begin);
printf("Scanning ports 0 - 65535 for IP address : %s\n", argv[1]);
FILE * file = fopen("/home/ether/Desktop/Projects/Ports_log.txt", "w");//open log file
for (unsigned short port = 0; port < MAX; port++)//loop through and scan all ports
{
int Connection = socket(AF_INET,SOCK_STREAM, 0);
sockaddr_in temp = { 0 };
//fill the struct with information on the computer you wish to scan
temp.sin_addr.s_addr = inet_addr(argv[1]);
temp.sin_family = AF_INET;
temp.sin_port = htons(port);
int error = connect(Connection, (sockaddr*)&temp, sizeof temp);
if(error != -1)
{
//if the port is open then get information about that port and print it to the log file
char host[128];
char service[128];
getnameinfo((sockaddr*)&temp, sizeof temp, host, (sizeof host), service, sizeof service, 0);
printf("Port : %d, Service : %s, Open\n", port, service);
fprintf(file, "Port : %d, Service : %s, Open\n", port, service);
}
close(Connection); //Destroy socket
}
fclose(file);//Close the file
//calculate the time that elapsed since the program was started and rint it
time(&end);
double elapsed_secs = difftime(end, begin);
printf("Elapsed Seconds : %lf", elapsed_secs);
return 0;
}Solution
After creating a socket make it non-blocking. Then call
http://developerweb.net/viewtopic.php?id=3196
But this sample shows waiting on single socket only. You need to wait on a bunch of them at the same time. So have a table of socket connections with some fixed size, e.g. 32:
First fill this table in a loop calling
After the
This approach could be further optimised. You could close a socket as soon as you get info about it, print that info, and immediately open another socket in its place in the table. This will be faster but perhaps this also requires more careful coding.
connect(). If connect returns 0 then the connection has been established and you can use it already. If it retuned -1 and errno is equal to EINPROGRESS then you need to wait until it becomes write-ready using select() or poll(). When it becomes write-ready use getsockopt(sock, SOL_SOCKET, SO_ERROR, ...) to tell if the connection has failed or succeeded. The example code for using non-blocking connect is here:http://developerweb.net/viewtopic.php?id=3196
But this sample shows waiting on single socket only. You need to wait on a bunch of them at the same time. So have a table of socket connections with some fixed size, e.g. 32:
#define MAX_CONNECT 32
struct socket_info {
int sock; /* the socket */
int ready; /* initialize to 0 when filling the table, set to 1 when the connection has established or failed */
int error; /* set to errno got with getsockopt() for failed connections, set to 0 if connection succeeded */
sockaddr_in addr;
};
struct socket_info pending_connect[MAX_CONNECT];First fill this table in a loop calling
socket/connect. Then wait in another loop with select until all of the sockets become ready. Set appropriate flags in the table as the sockets become ready.After the
select loop you have info about 32 ports. Print it. Close the sockets. Then proceed with a next bunch of 32 ports.This approach could be further optimised. You could close a socket as soon as you get info about it, print that info, and immediately open another socket in its place in the table. This will be faster but perhaps this also requires more careful coding.
Code Snippets
#define MAX_CONNECT 32
struct socket_info {
int sock; /* the socket */
int ready; /* initialize to 0 when filling the table, set to 1 when the connection has established or failed */
int error; /* set to errno got with getsockopt() for failed connections, set to 0 if connection succeeded */
sockaddr_in addr;
};
struct socket_info pending_connect[MAX_CONNECT];Context
StackExchange Code Review Q#85553, answer score: 7
Revisions (0)
No revisions yet.