MFC:
AF_LINK support for getnameinfo(). Obtained from: NetBSD
This commit is contained in:
parent
f3e0084665
commit
5c96749150
@ -18,7 +18,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 20, 2004
|
||||
.Dd February 28, 2007
|
||||
.Dt GETNAMEINFO 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -47,15 +47,29 @@ functions and is the converse of the
|
||||
.Xr getaddrinfo 3
|
||||
function.
|
||||
.Pp
|
||||
If a link-layer address is passed to
|
||||
.Fn getnameinfo ,
|
||||
its ASCII representation will be stored in
|
||||
.Fa host .
|
||||
The string pointed to by
|
||||
.Fa serv
|
||||
will be set to the empty string if non-NULL;
|
||||
.Fa flags
|
||||
will always be ignored.
|
||||
This is intended as a replacement for the legacy
|
||||
.Xr link_ntoa 3
|
||||
function.
|
||||
.Pp
|
||||
The
|
||||
.Li sockaddr
|
||||
structure
|
||||
.Fa sa
|
||||
should point to either a
|
||||
.Li sockaddr_in
|
||||
or
|
||||
.Li sockaddr_in ,
|
||||
.Li sockaddr_in6
|
||||
structure (for IPv4 or IPv6 respectively) that is
|
||||
or
|
||||
.Li sockaddr_dl
|
||||
structure (for IPv4, IPv6 or link-layer respectively) that is
|
||||
.Fa salen
|
||||
bytes long.
|
||||
.Pp
|
||||
@ -166,6 +180,7 @@ printf("host=%s\en", hbuf);
|
||||
.Xr gethostbyaddr 3 ,
|
||||
.Xr getservbyport 3 ,
|
||||
.Xr inet_ntop 3 ,
|
||||
.Xr link_ntoa 3 ,
|
||||
.Xr resolver 3 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr resolv.conf 5 ,
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* Copyright (c) 2000 Ben Harris.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -49,6 +50,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
@ -58,6 +61,38 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int getnameinfo_inet(const struct sockaddr *, socklen_t, char *,
|
||||
size_t, char *, size_t, int);
|
||||
#ifdef INET6
|
||||
static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
|
||||
size_t, int);
|
||||
static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
|
||||
#endif
|
||||
static int getnameinfo_link(const struct sockaddr *, socklen_t, char *,
|
||||
size_t, char *, size_t, int);
|
||||
static int hexname(const u_int8_t *, size_t, char *, size_t);
|
||||
|
||||
int
|
||||
getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, size_t hostlen, char *serv, size_t servlen,
|
||||
int flags)
|
||||
{
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
#endif
|
||||
return getnameinfo_inet(sa, salen, host, hostlen, serv,
|
||||
servlen, flags);
|
||||
case AF_LINK:
|
||||
return getnameinfo_link(sa, salen, host, hostlen, serv,
|
||||
servlen, flags);
|
||||
default:
|
||||
return EAI_FAMILY;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct afd {
|
||||
int a_af;
|
||||
size_t a_addrlen;
|
||||
@ -79,14 +114,8 @@ struct sockinet {
|
||||
u_short si_port;
|
||||
};
|
||||
|
||||
#ifdef INET6
|
||||
static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
|
||||
size_t, int);
|
||||
static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
|
||||
#endif
|
||||
|
||||
int
|
||||
getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||
static int
|
||||
getnameinfo_inet(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, size_t hostlen, char *serv, size_t servlen,
|
||||
int flags)
|
||||
{
|
||||
@ -343,3 +372,82 @@ ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf, size_t bufsiz, int flags)
|
||||
return n;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
/*
|
||||
* getnameinfo_link():
|
||||
* Format a link-layer address into a printable format, paying attention to
|
||||
* the interface type.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
getnameinfo_link(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, size_t hostlen, char *serv, size_t servlen, int flags)
|
||||
{
|
||||
const struct sockaddr_dl *sdl =
|
||||
(const struct sockaddr_dl *)(const void *)sa;
|
||||
int n;
|
||||
|
||||
if (serv != NULL && servlen > 0)
|
||||
*serv = '\0';
|
||||
|
||||
if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && sdl->sdl_slen == 0) {
|
||||
n = snprintf(host, hostlen, "link#%d", sdl->sdl_index);
|
||||
if (n > hostlen) {
|
||||
*host = '\0';
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (sdl->sdl_type) {
|
||||
/*
|
||||
* The following have zero-length addresses.
|
||||
* IFT_ATM (net/if_atmsubr.c)
|
||||
* IFT_FAITH (net/if_faith.c)
|
||||
* IFT_GIF (net/if_gif.c)
|
||||
* IFT_LOOP (net/if_loop.c)
|
||||
* IFT_PPP (net/if_ppp.c, net/if_spppsubr.c)
|
||||
* IFT_SLIP (net/if_sl.c, net/if_strip.c)
|
||||
* IFT_STF (net/if_stf.c)
|
||||
* IFT_L2VLAN (net/if_vlan.c)
|
||||
* IFT_BRIDGE (net/if_bridge.h>
|
||||
*/
|
||||
/*
|
||||
* The following use IPv4 addresses as link-layer addresses:
|
||||
* IFT_OTHER (net/if_gre.c)
|
||||
* IFT_OTHER (netinet/ip_ipip.c)
|
||||
*/
|
||||
/* default below is believed correct for all these. */
|
||||
case IFT_ARCNET:
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
case IFT_HIPPI:
|
||||
case IFT_ISO88025:
|
||||
default:
|
||||
return hexname((u_int8_t *)LLADDR(sdl), (size_t)sdl->sdl_alen,
|
||||
host, hostlen);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hexname(cp, len, host, hostlen)
|
||||
const u_int8_t *cp;
|
||||
char *host;
|
||||
size_t len, hostlen;
|
||||
{
|
||||
int i, n;
|
||||
char *outp = host;
|
||||
|
||||
*outp = '\0';
|
||||
for (i = 0; i < len; i++) {
|
||||
n = snprintf(outp, hostlen, "%s%02x",
|
||||
i ? ":" : "", cp[i]);
|
||||
if (n < 0 || n >= hostlen) {
|
||||
*host = '\0';
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
outp += n;
|
||||
hostlen -= n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user