C扫描远程服务器

时间:2016-08-17 18:04:58

标签: c server port

我正在尝试编写一个检查远程服务器上的开放端口的C程序。

重要提示:我知道有像nmap这样的解决方案,但这里的关键是我自己学习如何编写这样的东西。

我编写了以下代码,它会提示您提示IP和端口。

现在有两种解决方案:

a)已输入端口号 - >将测试与此端口的连接

b)将进入“扫描” - >将检查从1到5000的每个端口是否成功连接。

所以我的问题是,每当我进入“扫描”时,只有端口21会被列为“打开”。

    #include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>

#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2

static int getLine (char *prmpt, char *buff, size_t sz){

    int ch, extra;

    if (prmpt != NULL) {
        printf("%s", prmpt);
        fflush(stdout);
    }

    if (fgets(buff, sz, stdin) == NULL)
        return NO_INPUT;

    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF)){
            extra = 1;
        }
        return (extra == 1) ? TOO_LONG : OK;
    }

    buff[strlen(buff) - 1] = '\0';
    return OK;
}



int main (int argc, char *argv[])
{

int socket_desc;
struct sockaddr_in server;

socket_desc = socket(AF_INET, SOCK_STREAM, 0);

if (socket_desc == -1){
    printf("Could not open socket\n");
}

char ip[30];
char port[5];



getLine("IP> ", ip, sizeof(ip));
getLine("Port> ", port, sizeof(port));

if (strcmp("scan", port) == 0){
    puts("scanning....");
    server.sin_addr.s_addr = inet_addr(ip);
    server.sin_family = AF_INET;

    for (int i = 1; i < 5000; i++){
        server.sin_port = htons(i);
        if (connect(socket_desc, (struct sockaddr * )&server, sizeof(server)) < 0 ) {

        }
        else {
            printf("Open port: %d\n", i);
        }



    }


}
else {
int iport = atoi(port);

server.sin_addr.s_addr = inet_addr(ip);
server.sin_family = AF_INET;
server.sin_port = htons(iport);

if (connect(socket_desc, (struct sockaddr * )&server, sizeof(server)) < 0 )
{
puts("connect error");
return 1;
}

puts("Connected");
}

return 0;

}

为什么只有端口21(FTP)列为开放?是否由于我使用的功能的性质,那些仅用于数据连接(然后是端口21)。我应该使用不同的功能,甚至可能使用不同的方法(从我的头脑中,可能ping一个端口(如果可能)而不是尝试连接)

我的最终目标是编写一个扫描服务器的程序,列出打开的端口以及在那里运行的内容(SSH,SMTP等)

感谢您的帮助!!

1 个答案:

答案 0 :(得分:1)

连接套接字后,connect的进一步尝试将保证EISCONN失败。您需要在每次迭代中创建一个新套接字(并且不要忘记关闭它)。