ParseNetworkString не будет анализировать 21DA: 00D3: 0000: 2F3B: 02AA: 00FF: FE28: 9C5A: 8080 - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь найти способ анализа введенной пользователем информации IP-адреса, например:

  • 192.168.100.10
  • 192.168.100.10:80
  • 21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A%2
  • 21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A
  • [21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A%2]:8080
  • 21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A:8080
  • www.microsoft.com
  • www.microsoft.com:80

Функция WinAPI ParseNetworkString утверждает, что может анализировать все эти форматы (список взят из документации). И многие из них действительно разбираются. Но некоторые терпят неудачу:

  • 192.168.100.10
  • 192.168.100.10:80
  • 21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A%2
  • 21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A
  • [21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A%2]:8080
  • 21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A:8080
  • www.microsoft.com
  • www.microsoft.com:80

Итак, псевдокод:

NET_ADDRESS_INFO^ addressInfo;
UInt16^           portNumber;
UInt8^            prefixLength;

DWORD res = ParseNetworkString(
      "21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A:8080", //NetworkString
      NET_STRING_IPV6_SERVICE_NO_SCOPE, //Types
      addressInfo, portNumber, lengthPrefix);

возвращается 87 Параметр неверен. .

Что я делаю не так?

Бонус

В Точно так же API говорит, что может анализировать:

192.168.100.10:8080
\____________/ \__/
    |           |
 Address       Port

Он также утверждает, что может анализировать:

21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A:8080
\_____________________________________/ \__/
                   |                     |
                Address                 Port

Некоторые люди могут возразить и заявить, что единственный способ получить номер порта , включенный в канонический адрес IPv6, - это если адресная часть заключена в [квадратные отступы]. Эти люди просто неправы. Источник: RFC5952

В конце мы хотим, чтобы мы могли передать введенное пользователем значение WSAConnectByName , который принимает:

  • nodeName: например, "21DA: 00D3: 0000: 2F3B: 02AA: 00FF: FE28: 9C5A"
  • serviceName например, "3119"

1 Ответ

2 голосов
/ 26 апреля 2020

Документация просто неверна. Если вы разберете ParseNetworkString(), вы обнаружите, что он вызывает RtlIpv6StringToAddressEx(), что задокументировано как ( выделение добавлено):

Строка, на которую указывает Параметр AddressString должен быть представлен в форме для строки адреса IPv6, за которой следует необязательный символ процента и строка идентификатора области. Строка ID адреса и области IPv6 должна быть заключена в квадратные скобки . За правой квадратной скобкой после строки адреса IPv6 и идентификатора области может следовать необязательное двоеточие и строковое представление номера порта.

...