Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/net Extend getnameinfo() to support AF_LINK sockadd...



details:   https://anonhg.NetBSD.org/src/rev/7da96424fc6c
branches:  trunk
changeset: 515791:7da96424fc6c
user:      bjh21 <bjh21%NetBSD.org@localhost>
date:      Thu Oct 04 23:09:04 2001 +0000

description:
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.

diffstat:

 lib/libc/net/getnameinfo.c |  141 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 139 insertions(+), 2 deletions(-)

diffs (191 lines):

diff -r c62096f3d07b -r 7da96424fc6c lib/libc/net/getnameinfo.c
--- a/lib/libc/net/getnameinfo.c        Thu Oct 04 19:44:48 2001 +0000
+++ b/lib/libc/net/getnameinfo.c        Thu Oct 04 23:09:04 2001 +0000
@@ -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 @@
        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,10 +114,41 @@
 #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;
        size_t hostlen;
        char *serv;
@@ -397,3 +437,100 @@
                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;
+}



Home | Main Index | Thread Index | Old Index