Extend getnameinfo() to support AF_LINK sockaddrs. The intention is that
anything that wants to print a link-layer address should go through here, rather than re-inventing the wheel.
This commit is contained in:
parent
c7f73c3331
commit
5b533f601d
@ -1,7 +1,8 @@
|
||||
/* $NetBSD: getnameinfo.c,v 1.28 2001/08/19 01:37:39 itojun Exp $ */
|
||||
/* $NetBSD: getnameinfo.c,v 1.29 2001/10/04 23:09:04 bjh21 Exp $ */
|
||||
/* $KAME: getnameinfo.c,v 1.45 2000/09/25 22:43:56 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Ben Harris.
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -44,13 +45,16 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: getnameinfo.c,v 1.28 2001/08/19 01:37:39 itojun Exp $");
|
||||
__RCSID("$NetBSD: getnameinfo.c,v 1.29 2001/10/04 23:09:04 bjh21 Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_ieee1394.h>
|
||||
#include <net/if_types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
@ -90,11 +94,16 @@ struct sockinet {
|
||||
u_short si_port;
|
||||
};
|
||||
|
||||
static int getnameinfo_inet __P((const struct sockaddr *, socklen_t, char *,
|
||||
size_t, char *, size_t, int));
|
||||
#ifdef INET6
|
||||
static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *,
|
||||
size_t, int));
|
||||
static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int));
|
||||
#endif
|
||||
static int getnameinfo_link __P((const struct sockaddr *, socklen_t, char *,
|
||||
size_t, char *, size_t, int));
|
||||
static int hexname __P((u_int8_t *, size_t, char *, size_t));
|
||||
|
||||
/* 2553bis: use EAI_xx for getnameinfo */
|
||||
#define ENI_NOSOCKET EAI_FAIL /*XXX*/
|
||||
@ -105,8 +114,39 @@ static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int));
|
||||
#define ENI_FAMILY EAI_FAMILY
|
||||
#define ENI_SALEN EAI_FAMILY
|
||||
|
||||
/*
|
||||
* Top-level getnameinfo() code. Look at the address family, and pick an
|
||||
* appropriate function to call.
|
||||
*/
|
||||
int
|
||||
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
const struct sockaddr *sa;
|
||||
socklen_t salen;
|
||||
char *host, *serv;
|
||||
size_t hostlen, servlen;
|
||||
int flags;
|
||||
{
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getnameinfo_inet():
|
||||
* Format an IPv4 or IPv6 sockaddr into a printable string.
|
||||
*/
|
||||
static int
|
||||
getnameinfo_inet(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
const struct sockaddr *sa;
|
||||
socklen_t salen;
|
||||
char *host;
|
||||
@ -397,3 +437,100 @@ ip6_sa2str(sa6, buf, bufsiz, flags)
|
||||
return n;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
|
||||
/*
|
||||
* getnameinfo_link():
|
||||
* Format a link-layer address into a printable format, paying attention to
|
||||
* the interface type.
|
||||
*/
|
||||
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 *)sa;
|
||||
struct ieee1394_hwaddr *iha;
|
||||
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) {
|
||||
#ifdef IFT_ECONET
|
||||
case IFT_ECONET:
|
||||
if (sdl->sdl_alen < 2)
|
||||
return EAI_FAMILY;
|
||||
if (LLADDR(sdl)[1] == 0)
|
||||
n = snprintf(host, hostlen, "%d", LLADDR(sdl)[0]);
|
||||
else
|
||||
n = snprintf(host, hostlen, "%d.%d",
|
||||
LLADDR(sdl)[1], LLADDR(sdl)[0]);
|
||||
if (n >= hostlen) {
|
||||
*host = '\0';
|
||||
return EAI_MEMORY;
|
||||
} else
|
||||
return 0;
|
||||
#endif
|
||||
case IFT_IEEE1394:
|
||||
if (sdl->sdl_alen < sizeof(iha->iha_uid))
|
||||
return EAI_FAMILY;
|
||||
iha = (struct ieee1394_hwaddr *)LLADDR(sdl);
|
||||
return hexname(iha->iha_uid, sizeof(iha->iha_uid),
|
||||
host, hostlen);
|
||||
/*
|
||||
* 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_PROPVIRTUAL (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)
|
||||
*/
|
||||
case IFT_ARCNET: /* default below is believed correct for all these. */
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
case IFT_HIPPI:
|
||||
case IFT_ISO88025:
|
||||
default:
|
||||
return hexname(LLADDR(sdl), sdl->sdl_alen, host, hostlen);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hexname(cp, len, host, hostlen)
|
||||
u_int8_t *cp;
|
||||
char *host;
|
||||
size_t len, hostlen;
|
||||
{
|
||||
int i, n, space = hostlen;
|
||||
char *outp = host;
|
||||
|
||||
*outp = '\0';
|
||||
for (i = 0; i < len; i++) {
|
||||
n = snprintf(outp, hostlen, "%s%02x", i ? ":" : "", cp[i]);
|
||||
outp += n;
|
||||
space -= n;
|
||||
if (space <= 0) {
|
||||
*host = '\0';
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user