Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сканер портов

65K
29 апреля 2013 года
Snaiffer
1 / / 12.01.2011
Всем добрый день!
У меня возникла проблема при реализации сканера портов под Линукc:
Программа почему то себя по разному ведет при запуске на разных дистрибутивах Линукса. Пробовал всего на двух: на Red Hat'e и на Ubuntu. При чем на Red Hat'e поведение корректное, а на Ubuntu на все порты выдает "open"
ПС Так же хотелось бы чтобы знающие люди оценили программу и по возможности что нибудь подсказали, как ее можно улучшить

Задание на программу:
Цитата:
Сканер открытых TCP портов.
Сканирует порты в заданном диапазоне, пытаясь установить соединение с каждым из них.
Ответ ожидается в течение заданного интервала, чтобы исключить резкое замедление сканирования из-за возможного блокирования.
В результате для каждого сканированного порта должен быть выведен один из трех возможных результатов: open, closed, blocked.
Использовать перевод сокета в неблокирующий режим и функцию select() для ожидания готовности сокета или ошибки в течение заданного интервала времени.
Пример вызова программы:

./scan_ports 127.0.0.1 20 25 0.8
20: closed
21: closed
22: open
23: closed
24: closed
25: blocked
done



Собственно код программы:

Код:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <algorithm>
#include <set>
#include <map>
#include <iostream>
#include <errno.h>
#include <arpa/inet.h>
#include <string>
#include <sstream>
#include <math.h>
 
using namespace std;
 
typedef map<unsigned int, unsigned int> portmap;
 
 
//List must be: <ip_addr> <from_port> <to_port> <max_delay>
//  Example: 127.0.0.1 20 50 3.9
int main(int argc, char* argv[])
    {
    char* ip_addr;
    int port_from;
    int port_to;
    float max_delay;
 
    cout << "Settings:" << endl;
    if ( argc == 5 )
        {
        ip_addr = argv[1];
        cout << "\tIP address for scan:\t" << ip_addr << endl;
 
        string tempstr;
        stringstream convert1(tempstr.assign(argv[2],sizeof(argv[2])));
        if ( ! (convert1 >> port_from))
            {
            cerr << "Error: Format of <port_from> isnt correct\n";
            exit(1);
            }
        cout << "\tFrom port:\t\t" << port_from << endl;
 
        stringstream convert2(tempstr.assign(argv[3],sizeof(argv[3])));
        if ( ! (convert2 >> port_to))
            {
            cerr << "Error: Format of <port_to> isnt correct\n";
            exit(1);
            }
        cout << "\tTill port:\t\t" << port_to << endl;
 
        stringstream convert3(tempstr.assign(argv[4],sizeof(argv[4])));
        if ( ! (convert3 >> max_delay) || max_delay < 0)
            {
            cerr << "Error: Format of <max_delay> isnt correct\n";
            exit(1);
            }
        cout << "\tTill port:\t\t" << max_delay << endl;
        }
    else
        {
        cerr << "List of argument isnt correct. List must be: <ip_addr> <from_port> <to_port> <max_delay>";
        exit(1);
        }
 
 
    int sock;
 
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip_addr);
 
 
    portmap port_status;
    port_status.clear();
 
    portmap connections;
    connections.clear();
 
    for (int cur_port=port_from; cur_port < port_to; cur_port++)
        {
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if(sock < 0)
            {
            perror("socket");
            exit(1);
            }
 
        if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) //turn on nonblock mode
            {
            perror("fcntl");
            exit(2);
            }
 
        addr.sin_port = htons(cur_port);
 
        if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0 && errno != EINPROGRESS)
            {
            perror("connect");
            exit(3);
            }
 
      connections[sock]=cur_port;
        port_status[cur_port]=0;
        }
 
 
   // set value of timeout
   timeval timeout;
    double b;
    timeout.tv_usec=(int)(modf(max_delay,&b)*10);
    timeout.tv_sec=(int)(max_delay-modf(max_delay,&b));
 
 
    fd_set wset;
    int mx;
    bool istimeout=false;
 
    while(!connections.empty())
        {
        // fill in array of sockets
        FD_ZERO(&wset);
        for(portmap::iterator it = connections.begin(); it != connections.end(); it++)
            FD_SET((*it).first, &wset);
 
        // waiting events
        mx = max_element(connections.begin(), connections.end())->first;
        if(int err=select(mx+1, NULL, &wset, NULL, &timeout) <= 0)
            {
            if (err == -1)
                {
                perror("select");
                exit(4);
                }
            else
                istimeout = true;   //timeout
            }
 
        for(portmap::iterator it = connections.begin(); it != connections.end(); it++)
            {
            if(FD_ISSET((*it).first, &wset))
                {
                int error;
                socklen_t err_len = sizeof(error);
                if( getsockopt((*it).first, SOL_SOCKET, SO_ERROR, &error, &err_len) < 0 || error != 0)
                    {
                    switch (errno)
                        {
                        case EINPROGRESS:
                            break;
 
                        case EISCONN:
                        case EALREADY:
                            port_status[(*it).second]=3; //blocked
                            close((*it).first);
                            connections.erase(it);
                            break;
 
                        case ETIMEDOUT:
                        case ECONNREFUSED:
                            port_status[(*it).second]=2; //closed
                            close((*it).first);
                            connections.erase(it);
                            break;
 
                        case EPERM:
                        case EACCES:
                        case EAFNOSUPPORT:
                            cout << "Address isn't correct" << endl;
                            exit(1); //
                            break;
 
                        case ENETUNREACH:
                            cout << "The network is unreachable" << endl;
                            break;
 
 
                        default:
                            cout << "Unknown error" << endl;
                            break;
                        }
                        }
                  else
                    {
                    port_status[(*it).second]=1; //open
                    close((*it).first);
                   connections.erase(it);
                    }
                }
 
            if (istimeout)
                {
                port_status[(*it).second]=2; //closed
                close((*it).first);
               connections.erase(it);
                }
 
            }
        }
 
    //output results
    cout << "\nResults:" << endl;
    for(portmap::iterator it = port_status.begin(); it != port_status.end(); it++)
        {
        cout << (*it).first << ": ";
        switch((*it).second)
            {
            case 1:
                cout << "open" << endl;
                break;
 
            case 2:
                cout << "closed" << endl;
                break;
 
            case 3:
                cout << "blocked" << endl;
                break;
            }
        }
 
    return 0;
    }
326
30 апреля 2013 года
sadovoya
757 / / 19.11.2005
Прогнал у себя в Kubuntu. Тот-же результат - все порты открыты. У вас есть опечатка -- cout << "\tTill port:\t\t" << max_delay << endl;
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог