В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13 |
Сетевые средства
Функция getnetent() обслуживает последовательный доступ к базе, getnetbyaddr() осуществляет поиск по адресному семейству (аргумент type ) и номеру net сети, а getnetbyname() выбирает сеть с заданным (официальным) именем. Структура типа netent, указатель на которую возвращается в качестве результата этих функций, согласно стандарту POSIX-2001, должна содержать по крайней мере следующие поля.
char *n_name; /* Официальное имя сети */ char **n_aliases; /* Массив указателей на альтернативные */ /* имена сети, завершаемый пустым указателем */ int n_addrtype; /* Адресное семейство (тип адресов) сети */ uint32_t n_net; /* Номер сети (в хостовом порядке байт) */
Точно такой же программный интерфейс предоставляет база данных сетевых протоколов (см. листинг 11.13).
#include <netdb.h> void setprotoent (int stayopen); struct protoent *getprotoent (void); struct protoent *getprotobyname (const char *name); struct protoent *getprotobynumber (int proto); void endprotoent (void);Листинг 11.13. Описание функций доступа к базе данных сетевых протоколов.
Структура типа protoent содержит по крайней мере следующие поля.
char *p_name; /* Официальное имя протокола */ char **p_aliases; /* Массив указателей на альтернативные */ /* имена протокола, завершаемый пустым */ /* указателем */ int p_proto; /* Номер протокола */
В листинге 11.14 показан пример программы, осуществляющей последовательный и случайный доступ к базе данных сетевых протоколов. Листинг 11.15 содержит фрагмент возможных результатов работы этой программы.
#include <stdio.h> #include <netdb.h> int main (void) { struct protoent *pht; char *pct; int i; setprotoent (1); while ((pht = getprotoent ()) != NULL) { printf ("Официальное имя протокола: %s\n", pht->p_name); printf ("Альтернативные имена:\n"); for (i = 0; (pct = pht->p_aliases [i]) != NULL; i++) { printf (" %s\n", pct); } printf ("Номер протокола: %d\n\n", pht->p_proto); } if ((pht = getprotobyname ("ipv6")) != NULL) { printf ("Номер протокола ipv6: %d\n\n", pht->p_proto); } else { fprintf (stderr, "Протокол ip в базе не найден\n"); } if ((pht = getprotobyname ("IPV6")) != NULL) { printf ("Номер протокола IPV6: %d\n\n", pht->p_proto); } else { fprintf (stderr, "Протокол IPV6 в базе не найден\n"); } endprotoent (); return 0; }Листинг 11.14. Пример программы, осуществляющей последовательный и случайный доступ к базе данных сетевых протоколов.
Официальное имя протокола: ip Альтернативные имена: IP Номер протокола: 0 Официальное имя протокола: icmp Альтернативные имена: ICMP Номер протокола: 1 . . . Официальное имя протокола: tcp Альтернативные имена: TCP Номер протокола: 6 . . . Официальное имя протокола: udp Альтернативные имена: UDP Номер протокола: 17 . . . Официальное имя протокола: ipv6 Альтернативные имена: IPv6 Номер протокола: 41 . . . Официальное имя протокола: ipv6-crypt Альтернативные имена: IPv6-Crypt Номер протокола: 50 . . . Официальное имя протокола: visa Альтернативные имена: VISA Номер протокола: 70 . . . Официальное имя протокола: iso-ip Альтернативные имена: ISO-IP Номер протокола: 80 . . . Официальное имя протокола: sprite-rpc Альтернативные имена: Sprite-RPC Номер протокола: 90 . . . Официальное имя протокола: ipx-in-ip Альтернативные имена: IPX-in-IP Номер протокола: 111 . . . Официальное имя протокола: fc Альтернативные имена: FC Номер протокола: 133 Номер протокола ipv6: 41 Протокол IPV6 в базе не найденЛистинг 11.15. Фрагмент возможных результатов работы программы, осуществляющей последовательный и случайный доступ к базе данных сетевых протоколов.
Еще одно проявление той же логики работы - база данных сетевых сервисов (см. листинг 11.16).
#include <netdb.h> void setservent (int stayopen); struct servent *getservent (void); struct servent *getservbyname (const char *name, const char *proto); struct servent *getservbyport (int port, const char *proto); void endservent (void);Листинг 11.16. Описание функций доступа к базе данных сетевых сервисов.
Обратим внимание на то, что в данном случае можно указывать второй аргумент поиска - имя протокола. Впрочем, значение аргумента proto может быть пустым указателем, и тогда поиск производится только по имени сервиса (функция getservbyname() ) или номеру порта ( getservbyport() ), который должен быть задан с сетевым порядком байт.
Структура типа servent содержит по крайней мере следующие поля.
char *s_name; /* Официальное имя сервиса */ char **s_aliases; /* Массив указателей на альтернативные */ /* имена сервиса, завершаемый пустым */ /* указателем */ int s_port; /* Номер порта, соответствующий сервису */ /* (в сетевом порядке байт) */ char *s_proto; /* Имя протокола для взаимодействия с */ /* сервисом */
В листинге 11.17 приведен пример программы, использующей функции доступа к базе данных сервисов, а также функции преобразования между хостовым и сетевым порядками байт. В листинге 11.18 показан фрагмент возможных результатов работы этой программы.
#include <stdio.h> #include <netdb.h> int main (void) { struct servent *pht; char *pct; int i; setservent (1); while ((pht = getservent ()) != NULL) { printf ("Официальное имя сервиса: %s\n", pht->s_name); printf ("Альтернативные имена:\n"); for (i = 0; (pct = pht->s_aliases [i]) != NULL; i++) { printf (" %s\n", pct); } printf ("Номер порта: %d\n", ntohs ((in_port_t) pht->s_port)); printf ("Имя протокола: %s\n\n", pht->s_proto); } if ((pht = getservbyport (htons ((in_port_t) 21), "udp")) != NULL) { printf ("Официальное имя сервиса: %s\n", pht->s_name); printf ("Альтернативные имена:\n"); for (i = 0; (pct = pht->s_aliases [i]) != NULL; i++) { printf (" %s\n", pct); } printf ("Номер порта: %d\n", ntohs ((in_port_t) pht->s_port)); printf ("Имя протокола: %s\n\n", pht->s_proto); } else { perror ("GETSERVBYPORT"); } if ((pht = getservbyport (htons ((in_port_t) 21), (char *) NULL)) != NULL) { printf ("Официальное имя сервиса: %s\n", pht->s_name); printf ("Альтернативные имена:\n"); for (i = 0; (pct = pht->s_aliases [i]) != NULL; i++) { printf (" %s\n", pct); } printf ("Номер порта: %d\n", ntohs ((in_port_t) pht->s_port)); printf ("Имя протокола: %s\n\n", pht->s_proto); } else { perror ("GETSERVBYPORT"); } endservent (); return 0; }Листинг 11.17. Пример программы, использующей функции доступа к базе данных сервисов, а также функции преобразования между хостовым и сетевым порядками байт.
. . . Официальное имя сервиса: ftp-data Альтернативные имена: Номер порта: 20 Имя протокола: tcp Официальное имя сервиса: ftp-data Альтернативные имена: Номер порта: 20 Имя протокола: udp Официальное имя сервиса: ftp Альтернативные имена: Номер порта: 21 Имя протокола: tcp Официальное имя сервиса: ftp Альтернативные имена: fsp fspd Номер порта: 21 Имя протокола: udp . . . Официальное имя сервиса: kerberos Альтернативные имена: kerberos5 krb5 Номер порта: 88 Имя протокола: tcp Официальное имя сервиса: kerberos Альтернативные имена: kerberos5 krb5 Номер порта: 88 Имя протокола: udp . . . Официальное имя сервиса: auth Альтернативные имена: authentication tap ident Номер порта: 113 Имя протокола: tcp Официальное имя сервиса: auth Альтернативные имена: authentication tap ident Номер порта: 113 Имя протокола: udp . . . Официальное имя сервиса: printer Альтернативные имена: spooler Номер порта: 515 Имя протокола: tcp Официальное имя сервиса: printer Альтернативные имена: spooler Номер порта: 515 Имя протокола: udp . . . Официальное имя сервиса: fido Альтернативные имена: Номер порта: 60179 Имя протокола: tcp Официальное имя сервиса: fido Альтернативные имена: Номер порта: 60179 Имя протокола: udp Официальное имя сервиса: ftp Альтернативные имена: fsp fspd Номер порта: 21 Имя протокола: udp Официальное имя сервиса: ftp Альтернативные имена: Номер порта: 21 Имя протокола: tcpЛистинг 11.18. Фрагмент возможных результатов работы программы, использующей функции доступа к базе данных сервисов, а также функции преобразования между хостовым и сетевым порядками байт.
Отметим, что при поиске по ключу возвращается первый подходящий элемент базы данных. По этой причине, когда не был задан протокол (второе обращение к функции getservbyport() ), в качестве результата был возвращен элемент с протоколом tcp.