int inet_aton(const char * ddaddress, struct in_addr * address);
Данная функция ожидает строку, содержащую десятичный IP-адрес, и размещает двоичное представление этого адреса в структуре
struct in_addr
, на которую указывает параметр
address
. В отличие от большинства библиотечных функций
inet_aton
возвращает нуль в случае ошибки и ненулевое значение, если преобразование прошло успешно.
17.8.2. Преобразование имен хостов
Функции
getaddrinfo
,
getnameinfo
, позволяющие
легко создавать программы, которые поддерживают и IPv4, и IPv6, были введены именно с этой целью. Исходные функции имен хостов было сложно расширить на IPv6, их интерфейсы требовали, чтобы приложения учитывали множество особенностей версии в структурах, сохраняющих IP-адрес. Новые интерфейсы абстрактны, поэтому поддерживают IPv4 и IPv6 одинаково.
Вместо того чтобы возвращать связный список, как это делает
getaddrinfo
, старые функции имен хостов используют
struct hostent
, которая может содержать все имена хостов и адреса для одного хоста.
char** h_addr_list; /* список адресов (завершающийся NULL) */
};
Здесь
h_name
— каноническое имя хоста. Массив
h_aliases
содержит все псевдонимы данного хоста. Последняя запись в
h_aliases
— это указатель NULL, сигнализирующий о конце массива.
Параметр
h_addrtype
сообщает тип адреса хоста. В данной главе будет применяться только
AF_INET
. Приложения, которые создавались для поддержки IPv6, получат и другие типы адресов [147] . Следующий член
h_length
указывает длину двоичных адресов для данного хоста. Для адресов
AF_INET
эта длина равна
sizeof(struct in_addr)
. Последний элемент
h_addr_list
представляет собой массив указателей на адреса данного хоста, последний из которых равен
NULL
для обозначения конца списка. Если
h_addrtype
равен
AF_INET
, то каждый указатель в этом списке указывает на структуру
struct in_addr
.
147
Наверное, не существует IPv6-программ, использующих
struct hostaddr
, однако они могут это делать. Функции, которые мы обсуждаем здесь, по умолчанию возвращают только информацию IPv4. Мы не будем рассматривать применение этих функций с IPv6.
Две библиотечные функции выполняют преобразования между IP-номерами и именами хостов. Первая из них
gethostbyname
возвращает
struct hostent
для имени хоста. Вторая —
gethostbyaddr
— возвращает информацию о машине с данным IP-адресом.
struct hostent * gethostbyaddr(const char * addr, int len, int type);
Обе функции возвращают указатель на
struct hostent
. Структура может быть перезаписана при последующем
вызове одной из функций, поэтому все значения, которые могут понадобиться позже, программа должна сохранять.
Функция
gethostbyname
принимает один параметр — строку, содержащую имя хоста. Функция
gethostbyaddr
принимает три параметра, которые вместе определяют адрес. Первый из них
addr
указывает на
struct in_addr
. Следующий
len
устанавливает длину информации, на которую указывает параметр
addr
. Последний
type
излагает тип адреса, который нужно преобразовать в имя хоста (
AF_INET
для IPv4-адресов).
Если во время поиска имени хоста происходят ошибки, то код ошибки передается в
h_errno
. Вызов функции
herror
распечатывает описание ошибки (данная функция почти идентична стандартной функции
perror
).
Единственный код ошибки, на котором тестируется большинство программ, это
NETDB_INTERNAL
, который указывает на неудачный системный вызов. При возвращении этой ошибки параметр errno содержит описание той проблемы, которая привела к отказу.
17.8.3. Пример поиска информации хоста с использованием унаследованных функций
Ниже приводится пример программы, использующей
inet_aton
,
inet_ntoa
,
gethostbyname
,
gethostbyaddr
. Она принимает единственный аргумент, который может быть либо именем хоста, либо IP-адресом в десятичном представлении с точками. Она отыскивает хост и распечатывает все имена хоста и IP-адреса, ассоциированные с ним.
Любой аргумент, который является действительным десятичным адресом, считается IP-номером, а не именем хоста.
1: /* lookup.с */
2:
3: /* Получает либо имя хоста, либо IP-адрес в командной строке, выводит
4: каноническое имя хоста для данного хоста и все IP-номера и имена
5: хостов, ассоциированные с ним. */
6:
7: #include <netdb.h> /* для gethostby* */
8: #include <sys/socket.h>
9: #include <netinet/in.h> /* для адресных структур */
10: #include <arpa/inet.h> /* для inet_ntoa */
11: #include <stdio.h>
12:
13: int main(int argc, const char ** argv) {
14: struct hostent * answer;
15: struct in_addr address, ** addrptr;
16: char ** next;
17:
18: if (argc != 2) {
19: fprintf(stderr, "поддерживается только одиночный аргумент\n");
20: return 1;
21: }
22:
23: /* Если аргумент выглядит как IP, то принимаем его как таковой