Ein Portscanner

Dieses Programm ist ein einfacher TCP Portscanner, der mit connect() nach offenen Ports sucht. Unter Windows kann das erfahrungsgemäß lange dauern, da ein der Timeout für eine fehlgeschlagene Verbindung höher ist (die TCP/IP-Implementierung unternimmt mehrere Versuche nacheinander). Dieses Beispiel soll auch zeigen, wie man IP-Adressen "hochzählen" kann. Es werden nur die well-known ports gescannt. Außerdem werden die Ports in Namen aufgelöst, damit dient dieses Programm auch als Beispiel für die Anwendung von getservbyport().

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>

int main(int argc, char *argv[])
{
    struct sockaddr_in addr;
    struct servent *serv;
    int s, i;
    unsigned long begin, end, curr;

    if (argc < 3)
    {
        fprintf(stderr, "usage: %s <begin> <end>\n", argv[0]);
        return 1;
    }

    begin = ntohl(inet_addr(argv[1]));
    end = ntohl(inet_addr(argv[2]));

    if (begin > end)
    {
        curr = end;
        end = begin;
        begin = curr;
    }

    for (curr = begin; curr <= end; curr++)
    {
        addr.sin_addr.s_addr = htonl(curr);
        printf("%s:\n", inet_ntoa(addr.sin_addr));

        for (i = 0; i < 1024; i++)
        {
            s = socket(PF_INET, SOCK_STREAM, 0);
            if (s == -1)
            {
                perror("socket() failed");
                return 3;
            }

            addr.sin_addr.s_addr = htonl(curr);
            addr.sin_port = htons(i);
            addr.sin_family = AF_INET;

            printf("%i\r", i);
            fflush(stdout);

            if (!connect(s, (struct sockaddr*)&addr, sizeof(addr)))
            {
                serv = getservbyport(addr.sin_port, "tcp");
                if (serv)
                    printf("%i (%s) open\n", i, serv->s_name);
                else
                    printf("%i (unknown) open\n", i);
            }

            close(s);
        }

        puts("----");
    }

    return 0;
}