Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Проверка IPv4 на правильность с учётом маски, Сравнивание IP по маске 
:(
    Опции темы
MuForum
Дата 8.6.2009, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Доброе время суток.
Пишу систему фильтрации входящих пользователей по IPv4. (BannedList)

# Задача: Написать две функции:
    1-я: Проверяет IP-Адрес на правильность;
    2-я: Сравнивает два IP-Адреса на вхождения учитывая маску(*);
То есть, В моём списке есть IP-Адрес "15.48.*.17", а входящий IP-Адрес "15.48.78.17", моя функция должна вернуть bool значение.

Пытался реализовать следующим образом:
Код

#include <stdio.h>
...
bool __fastcall TFFMain::IsCorrectIPv4Part(char *cip)
{
    bool Result = false;
    // ----
    if(stricmp(cip, "*") == 0)
    {
        Result = true;
    }
    else
    {
        int iip = 0;
        if(sscanf(cip, "%d", &iip) == 1) Result = (iip >= 0 && iip < 256);
    }
    // ----
    return Result;
}
//---------------------------------------------------------------------------

bool __fastcall TFFMain::IsCorrectIPv4(AnsiString cIP)
{
    bool Result = false;
    // ----
    bool bip1, bip2, bip3, bip4;
    char *cip1, *cip2, *cip3, *cip4;
    // ----
    if(sscanf(cIP.c_str(), "%c.%c.%c.%c", &cip1, &cip2, &cip3, &cip4) == 4) // Но на этой строчке происходит проблема; Символ '.' считывается тоже в первую переменную =(
    {
        bip1 = IsCorrectIPv4Part(cip1);
        bip2 = IsCorrectIPv4Part(cip2);
        bip3 = IsCorrectIPv4Part(cip3);
        bip4 = IsCorrectIPv4Part(cip4);
        // -----
        Result = (bip1 && bip2 && bip3 && bip4);
    }
    // ----
    return Result;
}

- Можно конечно реализовать в лоб, считывания кол-во '.', и если 3, то затем уже разбивать на 4 части и уже проверять, но хотелось бы как-то по красивее.


# Добавлено: Более подробно о функции sscanf();

Это сообщение отредактировал(а) MuForum - 8.6.2009, 14:28


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
InvalidProperty
Дата 8.6.2009, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 356
Регистрация: 31.10.2007
Где: Россия, Казань

Репутация: 2
Всего: 9



в принципе, можно использовать регулярные выражения. sscanf() лучше в этом случае не использовать. Если не нравятся регулярные выражения, тогда можно использовать ф-ию strtok(), чтобы распилить строку по точкам. Каждую группу цифр проверить на правильность, т.е. то, что это цифра, перевести, скажем atoi() в целое, проверить, не слишком ли оно большое, перед переводом проверить, что число не превышает 3х знаков. Потом проверять маски.

sscanf() здесь плохо


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
MuForum
Дата 8.6.2009, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



#2, InvalidProperty - Решил старым, дедовским способом, однако хотелось бы услышать комментарии по этому коду.

Код

#include <Windows.h>
#include <stdio.h>
//---------------------------------------------------------------------------
class TCheckIPv4
{
    private:
        bool IsCorrectIPv4Part(char *cip, int len);
        bool IsCorrectIPv4PartCompare(char *ip1, int len1, char *ip2, int len2);
        bool GetIPParts(char *cIP, int len, char *ip1, char *ip2, char *ip3, char *ip4);
    public:
        TCheckIPv4();
        ~TCheckIPv4();
        // ----
        bool IsCorrectIPv4(char *cIP, int len);
        bool IsIPsMatch(char *IP1, int len1, char *IP2, int len2);
};
//---------------------------------------------------------------------------

TCheckIPv4::TCheckIPv4()
{
    // ----
}
//---------------------------------------------------------------------------

TCheckIPv4::~TCheckIPv4()
{
    // ----
}
//---------------------------------------------------------------------------

bool TCheckIPv4::IsCorrectIPv4Part(char *cip, int len)
{
    bool Result = false;
    // ----
    if(len > 0 && len < 4)
    {
        if(stricmp(cip, "*") == 0)
        {
            Result = true;
        }
        else
        {
            int iip = 0;
            if(sscanf(cip, "%d", &iip) == 1) Result = (iip >= 0 && iip < 256);
        }
    }
    // ----
    return Result;
}
//---------------------------------------------------------------------------

bool TCheckIPv4::IsCorrectIPv4PartCompare(char *ipsrc, int len1, char *ipdes, int len2)
{
    bool Result = false;
    // ----
    if(len1 > 0 && len1 < 4 && len2 > 0 && len2 < 4)
    {
        if(stricmp(ipsrc, "*") == 0 || stricmp(ipdes, "*") == 0)
        {
            Result = true;
        }
        else
        {
            int iip1, iip2 = 0;
            if(sscanf(ipsrc, "%d", &iip1) == 1 && sscanf(ipdes, "%d", &iip2) == 1)
            {
                Result = (iip1 >= 0 && iip1 < 256 && iip2 >= 0 && iip2 < 256 && iip1 == iip2);
            }
        }
    }
    // ----
    return Result;
}
//---------------------------------------------------------------------------

bool TCheckIPv4::GetIPParts(char *cIP, int len, char *ip1, char *ip2, char *ip3, char *ip4)
{
    bool Result = false;
    // ----
    char sTemp[16];
    int i = 0, k = 0, n = 0;
    bool bip1, bip2, bip3, bip4;
    // ----
    if(cIP != NULL && len > 6 && len < 17)
    {
        for(i = 0; i < len; i++) if(cIP[i] == '.') k++;
        // ----
        if(k == 3)
        {
            for(i = 0, k = 0; i < len; i++)
            {
                if(cIP[i] == '.')
                {
                    k++;
                    n = 0;
                }
                else
                {
                    switch(k)
                    {
                        case 0: ip1[n] = cIP[i]; break;
                        case 1: ip2[n] = cIP[i]; break;
                        case 2: ip3[n] = cIP[i]; break;
                        case 3: ip4[n] = cIP[i]; break;
                    }
                    // ----
                    n++;
                }
            }
            // ----
            memset(&sTemp, 0, sizeof(sTemp));
            strcpy(sTemp, ip1);
            bip1 = IsCorrectIPv4Part(sTemp, strlen(sTemp));
            memset(&sTemp, 0, sizeof(sTemp));
            strcpy(sTemp, ip2);
            bip2 = IsCorrectIPv4Part(sTemp, strlen(sTemp));
            memset(&sTemp, 0, sizeof(sTemp));
            strcpy(sTemp, ip3);
            bip3 = IsCorrectIPv4Part(sTemp, strlen(sTemp));
            memset(&sTemp, 0, sizeof(sTemp));
            strcpy(sTemp, ip4);
            bip4 = IsCorrectIPv4Part(sTemp, strlen(sTemp));
            // -----
            Result = (bip1 && bip2 && bip3 && bip4);
        }
    }
    // ----
    return Result;
}
//---------------------------------------------------------------------------

bool TCheckIPv4::IsCorrectIPv4(char *cIP, int len)
{
    bool Result = false;
    // ----
    char cip[4][16];
    // ----
    memset(&cip, 0, sizeof(cip));
    // ----
    Result = GetIPParts(cIP, len, cip[0], cip[1], cip[2], cip[3]);
    // ----
    return Result;
}
//---------------------------------------------------------------------------

bool TCheckIPv4::IsIPsMatch(char *IPsrc, int len1, char *IPdes, int len2)
{
    bool Result = false;
    // ----
    char sTemp1[16], sTemp2[16];
    char cip1[4][16], cip2[4][16];
    bool bip1, bip2, bip3, bip4;
    // ----
    memset(&cip1, 0, sizeof(cip1));
    memset(&cip2, 0, sizeof(cip2));
    // ----
    if(GetIPParts(IPsrc, len1, cip1[0], cip1[1], cip1[2], cip1[3]) &&
        GetIPParts(IPdes, len2, cip2[0], cip2[1], cip2[2], cip2[3]))
    {
        memset(&sTemp1, 0, sizeof(sTemp1)); memset(&sTemp2, 0, sizeof(sTemp2));
        strcpy(sTemp1, cip1[0]); strcpy(sTemp2, cip2[0]);
        bip1 = IsCorrectIPv4PartCompare(sTemp1, strlen(sTemp1), sTemp2, strlen(sTemp2));
        memset(&sTemp1, 0, sizeof(sTemp1)); memset(&sTemp2, 0, sizeof(sTemp2));
        strcpy(sTemp1, cip1[1]); strcpy(sTemp2, cip2[1]);
        bip2 = IsCorrectIPv4PartCompare(sTemp1, strlen(sTemp1), sTemp2, strlen(sTemp2));
        memset(&sTemp1, 0, sizeof(sTemp1)); memset(&sTemp2, 0, sizeof(sTemp2));
        strcpy(sTemp1, cip1[2]); strcpy(sTemp2, cip2[2]);
        bip3 = IsCorrectIPv4PartCompare(sTemp1, strlen(sTemp1), sTemp2, strlen(sTemp2));
        memset(&sTemp1, 0, sizeof(sTemp1)); memset(&sTemp2, 0, sizeof(sTemp2));
        strcpy(sTemp1, cip1[3]); strcpy(sTemp2, cip2[3]);
        bip4 = IsCorrectIPv4PartCompare(sTemp1, strlen(sTemp1), sTemp2, strlen(sTemp2));
        // -----
        Result = (bip1 && bip2 && bip3 && bip4);
    }
    // ----
    return Result;
}
//---------------------------------------------------------------------------




P.S. -> Просьба прокомментировать данный код.

Это сообщение отредактировал(а) MuForum - 8.6.2009, 14:06


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 8.6.2009, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# for all - Парни, помогите пожалуйста решить задачу через регулярные выражения.
Необходимо обрабатывать все диапозоны.
Цитата

12*.123.123.123
1*3.123.123.123
*23.123.123.123
*.123.123.123
и так для каждого сегмента
+ где 1*3 это может быть:
103
113
123
....
193




--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 8.6.2009, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Интернет лаганул, продублировало сообщение.
Просьба модераторов удалить.

Это сообщение отредактировал(а) MuForum - 8.6.2009, 15:29


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
xvr
Дата 8.6.2009, 15:34 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Коментирую - жуть  smile 
Заданный IP нужно просто перевести в 2 числа - собственно IP и маску (для каждого '*').
Сравнения потом делаются исключительно битовыми операциями:

Код

class IPv4 {
 int ip;
 int mask;
public:
 IPv4(const char* inp)
  {
   ip=mask=0;
   for(int i=0;i<4;++i,++inp)
    {
     if (*inp=='*')
      {
       mask|=0xFF<<(i*8);
       if (* ++inp != '.') throw "Invalid IP";
      }
     else
      {
       int v=strtoul(inp,(char**)&inp,10);
       if (v<0 || v>=256 || (*inp && *inp!='.')) throw "Invalid IP";
       ip|=v<<(i*8);
      }
    }
   if (*inp) throw "Invalid IP";
  }

 bool operator== (const IPv4& v) const 
  {
   return ((ip^v.ip)&~(mask|v.mask))==0;
  }
};



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0496 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.