How to write a port scanner in C++ for Linux

Hello,
I have this project where I have to implement a simple port scanner in C++ for Linux. The program should take as input a target IP address, beginning
port number, and ending port number.After recieving the above info, the program should display a list of open ports. This seems not too bad but I have NO IDEA where to begin to implement a port scanner. By any chance can anyone direct me in the right path! Any response/advice will be helpful.

Thanks in Advance
If you just want to see if the port is in use, write a loop and try and use each port in turn, picking up the error status if it can't open the port. If you want netstat type info, I think there is a proc filesystem file you can get the data from, /proc/net/tcp though I have never used it myself.
Read up on procfs to understand what these files are (a good idea because you can cause some serious problems writing to procfs).
bnbertha,
Thanks!! However, how do you check ports in C++ in Linux. I think if I knew how to even access ports I think I could do this. Any advice will be greatly appreciated.
Thanks in Advance!!
To try and use a port you need to create a socket and then bind it to a port. create a socket using socket() and bind using bind(). If you are not familiar with these commands then read up on your TCP/IP. If you want a book, Richard W Stevens network programing ones are about as good as you'll find.
bnbertha,
Thanks! I finally got it working but it takes a very long time to search a wide range of ports(100 to 1000). I was told that the run time would greatly decrease if I had several sockets open. However, I am confused about where to open several sockets. Currently, after a user enters ip and the start and end ports I open a socket inside a for loop(goes from the start port to end port). Any advice/input would greatly be appreciated.
I can't see a great deal of benefit with multiple sockets unless each one is in its own thread, so for your code, you'd have several copies of your for loop, each loop in it's own thread. And, they take the next port to try from a central 'pool' or each thread is given a block of ports.
bnbertha,
Several people have suggested this but I have never program threads and am reading on how to program them. With this in mind,this is how I think my program will work:
1. User enters ip, start port, end port
2. I store everything in variables
3. open first sockect within for loop(checks a portion of ports) in a thread
After this step I am confused, do I call a function that will open another sockect within for loop(checks a portion of ports) in a thread

I will really appreciate any advice/examples you can give. I am some what understand threads but don't fully understand how to get more than one going at a time!!
I'd do some serious reading on multi-threaded development. Writing software that is multi-threaded is exponentially harder than writing standard single-thread (linear) software.

There is no easy tricks to make it work, you will need to have a firm grasp of a few concepts including concurrency, memory management, synchronization, thread pooling, queuing.

Good luck :)
Yeah, I heard multi-threaded development is difficult but is there any easier way to do these? Someone told me to open several sockets and declare them as non-blocking and use poll(). I am not finding much on this, do you have any input!!I will really appreciate any advice/examples you can give.
If all you are doing is calling socket() and bind(), non-blocking won't really help, as they usually return straight away. It only really has an effect for reading and writing data.

Just for your info, this is an example of how to set a socket to asynchornous non-blocking. getErrStr() just builds a char array error message.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

void
openAsync(long *plFd)
{
    const char func[] = "openAsync()";
    long lStatus;
    long lFlags;
    struct sockaddr_in6 serv_addr;
    long lFd = socket(AF_INET6, SOCK_STREAM, 0); // open an IPv6 socket

    if (lFd == -1)
    {
    	throw runtime_error(getErrStr(errno, func, "Failure to open socket."));
    }

    lFlags = fcntl(lFd, F_GETFL);

    if (lFlags == -1)
    {
        throw runtime_error(getErrStr(errno, func, "Failure to get socket flags"));
    }

    lStatus = fcntl(lFd, F_SETFL, lFlags | FNDELAY | FASYNC);

    if (lStatus == -1)
    {
        throw runtime_error(getErrStr(errno, func, "Failure to set socket flags"));
    }

    lStatus = fcntl(lFd, F_SETOWN, getpid());

    if (lStatus == -1)
    {
        throw runtime_error(getErrStr(errno, func, "Failure to set SIGIO destination"));
    }

    serv_addr.sin6_family = AF_INET6;
    serv_addr.sin6_addr = in6addr_any;
    serv_addr.sin6_port = htons(9000); // set to network byte order

    lStatus = bind(lFd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

    if (lStatus == -1)
    {
        throw runtime_error(getErrStr(errno, func, "Failure to bind socket"));
    }
    *plFd = lFd;
}


I think you will need to use threads to get any benefit from multiple sockets.
Last edited on
Topic archived. No new replies allowed.