本节概述了可供使用的映射例程。这些例程会返回网络名称或将其转换为各自的网络地址。请注意,netdir_getbyname(3NSL)、netdir_getbyaddr(3NSL) 和 taddr2uaddr(3NSL) 可返回指向必须通过 netdir_free(3NSL) 调用来释放的数据的指针。
int netdir_getbyname(struct netconfig *nconf, struct nd_hostserv *service, struct nd_addrlist **addrs);
netdir_getbyname(3NSL) 可将 service 中指定的主机名和服务名映射到一组与 nconf 中标识的传输一致的地址。nd_hostserv 和 nd_addrlist 结构在 netdir(3NSL) 手册页中定义。addrs 中会返回一个指向上述地址的指针。
要查找所有可用传输上的主机和服务的所有地址,请使用 getnetpath(3NSL) 或 getnetconfig(3NSL) 返回的每个 netconfig(4) 结构来调用 netdir_getbyname(3NSL)。
int netdir_getbyaddr(struct netconfig *nconf, struct nd_hostservlist **service, struct netbuf *netaddr);
netdir_getbyaddr(3NSL) 可将地址映射到主机名和服务名。此接口使用 netaddr 中的地址进行调用,并会返回 service 中主机名和服务名对的列表。nd_hostservlist 结构在 netdir(3NSL) 中定义。
void netdir_free(void *ptr, int struct_type);
netdir_free(3NSL) 例程可释放由名称到地址的转换例程所分配的结构。参数可采用下表中显示的值。
表 9–2 netdir_free(3NSL) 例程|
struct_type |
ptr |
|---|---|
|
ND_HOSTSERV |
指向 nd_hostserv 结构的指针 |
|
ND_HOSTSERVLIST |
指向 nd_hostservlist 结构的指针 |
|
ND_ADDR |
指向 netbuf 结构的指针 |
|
ND_ADDRLIST |
指向 nd_addrlist 结构的指针 |
char *taddr2uaddr(struct netconfig *nconf, struct netbuf *addr);
taddr2uaddr(3NSL) 可转换 addr 指向的地址,并返回该地址与传输无关的字符表示形式。此字符表示形式称为通用地址。nconf 中给定的值可指定该地址针对其有效的传输。通用地址可通过 free(3C) 进行释放。
struct netbuf *uaddr2taddr(struct netconfig *nconf, char *uaddr);
uaddr 指向的通用地址会转换为 netbuf 结构。nconf 可指定该地址针对其有效的传输。
int netdir_options(const struct netconfig *config, const int option, const int fildes, char *point_to_args);
netdir_options(3NSL) 提供了特定于传输的功能(如 TCP 和 UDP 的广播地址和保留端口功能)的接口。nconf 的值指定传输,而 option 则指定要执行的特定于传输的操作。option 中的值可能会导致忽略 fd 中的值。第四个参数指向特定于操作的数据。
下表说明了用于 option 的值。
表 9–3 netdir_options 的值|
选项 |
说明 |
|---|---|
|
ND_SET_BROADCAST |
在传输支持广播时设置广播的传输 |
|
ND_SET_RESERVEDPORT |
在传输允许的情况下使应用程序绑定到保留端口 |
|
ND_CHECK_RESERVEDPORT |
在传输支持保留端口的情况下验证地址是否对应于保留端口 |
|
ND_MERGEADDR |
将本地有意义的地址转换为客户机主机可连接到的地址 |
netdir_perror(3NSL) 例程会在 stderr 中显示一条消息,说明用来将名称映射到地址的例程之一失败的原因。
void netdir_perror(char *s);
netdir_sperror(3NSL) 返回一个字符串,其中包含的错误消息说明了用来将名称映射到地址的例程之一失败的原因。
char *netdir_sperror(void);
以下示例说明了如何执行网络选择和名称到地址的映射。
#include <netconfig.h>
#include <netdir.h>
#include <sys/tiuser.h>
struct nd_hostserv nd_hostserv; /* host and service information */
struct nd_addrlist *nd_addrlistp; /* addresses for the service */
struct netbuf *netbufp; /* the address of the service */
struct netconfig *nconf; /* transport information*/
int i; /* the number of addresses */
char *uaddr; /* service universal address */
void *handlep; /* a handle into network selection */
/*
* Set the host structure to reference the "date"
* service on host "gandalf"
*/
nd_hostserv.h_host = "gandalf";
nd_hostserv.h_serv = "date";
/*
* Initialize the network selection mechanism.
*/
if ((handlep = setnetpath()) == (void *)NULL) {
nc_perror(argv[0]);
exit(1);
}
/*
* Loop through the transport providers.
*/
while ((nconf = getnetpath(handlep)) != (struct netconfig *)NULL)
{
/*
* Print out the information associated with the
* transport provider described in the "netconfig"
* structure.
*/
printf("Transport provider name: %s\n", nconf->nc_netid);
printf("Transport protocol family: %s\n", nconf->nc_protofmly);
printf("The transport device file: %s\n", nconf->nc_device);
printf("Transport provider semantics: ");
switch (nconf->nc_semantics) {
case NC_TPI_COTS:
printf("virtual circuit\n");
break;
case NC_TPI_COTS_ORD:
printf("virtual circuit with orderly release\n");
break;
case NC_TPI_CLTS:
printf("datagram\n");
break;
}
/*
* Get the address for service "date" on the host
* named "gandalf" over the transport provider
* specified in the netconfig structure.
*/
if (netdir_getbyname(nconf, &nd_hostserv, &nd_addrlistp) != ND_OK) {
printf("Cannot determine address for service\n");
netdir_perror(argv[0]);
continue;
}
printf("<%d> addresses of date service on gandalf:\n",
nd_addrlistp->n_cnt);
/*
* Print out all addresses for service "date" on
* host "gandalf" on current transport provider.
*/
netbufp = nd_addrlistp->n_addrs;
for (i = 0; i < nd_addrlistp->n_cnt; i++, netbufp++) {
uaddr = taddr2uaddr(nconf,netbufp);
printf("%s\n",uaddr);
free(uaddr);
}
netdir_free( nd_addrlistp, ND_ADDRLIST );
}
endnetconfig(handlep);