Как отфильтровать адреса IPv6 и IPv4?

Подробно остановиться на сообщении от Stéphane Gimenez, создавая новый каталог - процесс создания нового inode с st_mode значением S_IFDIR (с режимом полномочий), создавая две записи в первом блоке данных нового inode со ссылкой (2) системный вызов:'.' который указывает на этот новый inode и '..' который указывает на родительский каталог, затем создавая запись в родительском каталоге с inode и названием нового каталога - первая и последняя часть сделана системным вызовом mknod (2). Кроме того, только базируйтесь, может использовать mknod (2) в эти дни для таких задач, поскольку мы говорим о.

Например, mkdir("/home/larry.user/xyzzy", 0666) по существу следующее (это было кодом C со дней SysV [1]):

int mode = 0666;
char newdir[] = "/home/larry.user/xyzzy";
char path1[NAMESZ+4, path2[NAMESZ+4], *p;
mknod(newdir, S_IFDIR|mode);
strcpy(path1, newdir);
strcat(path1, "/."); /* "." link */
link(newdir, path1);
strcat(path1, ".");  /* ".." link */
strcpy(path2, newdir);
if ((p = strrchr(path2, '/') == (char *)0) /* root directory */
    link(".", path1);
else {
    *p = '\0';
    link(path2, path1);
}
  1. Haviland&Salama, "Системное Программирование UNIX", 1987, pp69-71.

Это было слишком подвержено ошибкам (и одна из главных причин для fsck) так mkdir (2), системный вызов был создан, чтобы смочь сделать это для Вас.

Обратите внимание, что amy объект файловой системы мог быть создан с mknod (2): регулярный файл, каталог, файл устройств, символьная ссылка, и т.д. Таким образом для ответа на один из вопросов OP, да, каталог является файлом, что означает говорить, "это - объект, представленный inode, находясь в файловой системе, которая ведет себя с интерфейсом i/o".

5
28.08.2011, 20:13
3 ответа

Существует несколько обычных нотаций для адресов IPv6 и IPv4. Вот расширенное регулярное выражение, подходящее для Perl m//x, это получает обычные нотации. При удалении комментариев и пробела можно использовать его с grep -E, awk, или любая другая утилита, которая использует расширенные регулярные выражения (ERE).

^(
  ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|0+[0-3][0-7][0-7]|0x0*[0-9a-fA-F][0-9a-fA-F])
  (\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|0+[0-3][0-7][0-7]|0x0*[0-9a-fA-F][0-9a-fA-F])){3}   # IPv4 dotted quad
| 0x[0-9a-fA-F]{1-8}             # IPv4 hexadecimal
| 0+[0-9]{0-10} | 0+[1-3]{11}    # IPv4 octal
| [1-9][0-9]{1-8}                # IPv4 decimal, small
| [1-3][0-9]{9}                  # IPv4 decimal, medium
| 4[0-9]{9}                      # IPv4 decimal, large (needs a further range check)
| [0-9a-fA-F]{1-4}(:[0-9a-fA-F]{1-4}){7}            # IPv6 with all groups
| ([0-9a-fA-F]{1-4}:){1-1}(:[0-9a-fA-F]{1-4}){1-6}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-2}(:[0-9a-fA-F]{1-4}){1-5}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-3}(:[0-9a-fA-F]{1-4}){1-4}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-4}(:[0-9a-fA-F]{1-4}){1-3}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-5}(:[0-9a-fA-F]{1-4}){1-2}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-6}(:[0-9a-fA-F]{1-4}){1-1}  # IPv6 with 1-6 middle groups omitted
)$

В случае десятичного значения Вам нужна дальнейшая проверка принадлежности к диапазону (можно сделать regexp из него, но это было бы большим):

if (!/[^0-9]/ && /^[^0]/) { # if it's a decimal number
    die if $_ > 4294967295 # reject numbers above 2^32-1
}

Если инструмент, Вы используете только поддержки 32-разрядные числа, можно сделать тест, только если число запускается с 4, и полоса 4 прежде, чем сделать проверку.

if (!/[^0-9]/ && /^4/) { # if it's a decimal number beginning with 4
    my $tmp = $_;
    $tmp =~ s/^4//;
    die if $tmp > 294967295;
}
5
27.01.2020, 20:40
  • 1
    ... И Вы не проверяете диапазон Верного :) –  rozcietrzewiacz 28.08.2011, 21:40
  • 2
    @rozcietrzewiacz я не? Я записал это быстро и не протестировал его, таким образом, я, возможно, сделал ошибку. Через что проходит плохое значение? Я сделал тест немного более точным и добавил способ протестировать диапазон на десятичные числа. –  Gilles 'SO- stop being evil' 28.08.2011, 21:52
  • 3
    О, право - Вы проверяете диапазон... Только Вы не добавили разделители вначале и конец, таким образом, вещи как 999.0.0.999, кажется, передают. –  rozcietrzewiacz 28.08.2011, 21:54
  • 4
    я добавил бы [^0-9] вначале и конец каждого... –  rozcietrzewiacz 28.08.2011, 22:01

Во-первых, тесты:

IPv4 0.0.0.0 # Standard IP
IPv4 1.2.3.4 # Standard IP
IPv4 255.255.255.255 # Standard IP
IPv4 8.08.008.0008 # Should not treat leading zero as octal
IPv4 1.1.1 || true # Too short
IPv4 1.1.1.1.1 || true # Too long
IPv4 a.b.c.d || true # Non-numeric
IPv4 0.0.0.-1 || true # Negative

Что-либо от 0.0.0.0 до 255.255.255.255 в оболочке:

IPv4() {
    quads=0
    while IFS= read -r quad
    do
        let quads++
        while [[ $quad = 0* ]]
        do
            quad=${quad#0}
        done
        if [[ $quads -gt 4 || ! "${quad:-0}" =~ [0-9]+ || "${quad:-0}" -lt 0 || "${quad:-0}" -gt 255 ]]
        then
            return 1
        fi
    done < <(echo "$1" | tr '.' '\n')
    if [[ ! $quads -eq 4 ]]
    then
        return 1
    fi
}
0
27.01.2020, 20:40
  • 1
    Вы неправильно рассматриваете числа с продвижением, обнуляет как десятичное число в точечных четверках: POSIX (соответствующий стандарт на Unix) inet_ntoa указывает, что в “десятичном представлении с разделением точками IPv4”, несмотря на его имя, “продвижение '0' подразумевает восьмеричный”. И почему Вы не позволяете мне записать ping 134744072? И что относительно IPv6? –  Gilles 'SO- stop being evil' 28.09.2011, 23:42
  • 2
    я просто никогда не имею, за семь лет профессиональной разработки, замеченной никто использовать что-либо кроме точечного десятичного числа для IPv4. Я, с другой стороны, видел, что люди перепутали это их 08 интерпретировался как восьмеричный. Я никогда не говорил, что мой код был завершен, но это просто и работает на канонический случай. –  l0b0 29.09.2011, 11:10

В ударе:

validIP4 () 
{ 
    IFS='.' read na nb nc nd;
    for n in "$na" "$nb" "$nc" "$nd";
    do
        [[ ${#n} -le 3 ]] && [[ "${n//[^0-9]/}" = "$n" ]] && [[ $n -lt 256 ]] || return 1;
    done
    echo OK
}

Примеры использования:

  • echo 142.24.045.33 | validIP4
  • echo sd3.3.4.6 | validIP4 || echo "nope :("
  • echo 342.0.0.2 | validIP4 || echo "Noo...."
  • echo 3.2.1.0 | validIP4 && echo "Yes, sir."

Как Gilles отметил, это проверяет только самую популярную точечную десятичную запись адреса IPv4.

IPv6 может быть сделан подобным образом, но нуждается в намного большем количестве проверки, потому что (1) это использует шестнадцатеричное число и (2) некоторые разделы все-нулей могут быть полностью опущены.

0
27.01.2020, 20:40
  • 1
    Вы только позволяете отмеченные точкой четверки, и, исключая шестнадцатеричный и некоторые восьмеричные числа. –  Gilles 'SO- stop being evil' 28.08.2011, 21:35
  • 2
    значений - я добавил не об этом. –  rozcietrzewiacz 28.08.2011, 21:43

Теги

Похожие вопросы