diff options
Diffstat (limited to 'usr/src/lib/nsswitch/files/common/ether_addr.c')
-rw-r--r-- | usr/src/lib/nsswitch/files/common/ether_addr.c | 89 |
1 files changed, 74 insertions, 15 deletions
diff --git a/usr/src/lib/nsswitch/files/common/ether_addr.c b/usr/src/lib/nsswitch/files/common/ether_addr.c index 4731e0c354..b8900cf043 100644 --- a/usr/src/lib/nsswitch/files/common/ether_addr.c +++ b/usr/src/lib/nsswitch/files/common/ether_addr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,9 +19,9 @@ * CDDL HEADER END */ /* - * files/ether_addr.c -- "files" backend for nsswitch "ethers" database + * files/ether_addr.c -- "files" backend for nsswitch "ethers" database * - * Copyright 1988-1995,2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -44,14 +43,38 @@ #include <nss_dbdefs.h> #include "files_common.h" #include <strings.h> +#include <ctype.h> #define _PATH_ETHERS "/etc/ethers" +#define DIGIT(x) \ + (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A') static int -check_host(args) - nss_XbyY_args_t *args; +check_host(nss_XbyY_args_t *argp, const char *line, int linelen) { - return (strcmp(args->buf.buffer, args->key.name) == 0); + const char *limit, *linep, *keyp; + linep = line; + limit = line + linelen; + + /* skip leading spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* skip mac address */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + + /* compare the host name */ + keyp = argp->key.name; + while (*keyp != '\0' && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (*keyp == '\0' && linep == limit); } static nss_status_t @@ -63,21 +86,57 @@ getbyhost(be, a) char hostname[MAXHOSTNAMELEN]; nss_status_t res; - argp->buf.buffer = hostname; - argp->buf.buflen = MAXHOSTNAMELEN; + /* + * use the buffer passed in if result is to be returned + * in /etc file format + */ + if (argp->buf.result != NULL) { + argp->buf.buffer = hostname; + argp->buf.buflen = MAXHOSTNAMELEN; + } res = _nss_files_XY_all(be, argp, 0, argp->key.name, check_host); - argp->buf.buffer = NULL; - argp->buf.buflen = 0; + if (argp->buf.result != NULL) { + argp->buf.buffer = NULL; + argp->buf.buflen = 0; + } + return (res); } static int -check_ether(args) - nss_XbyY_args_t *args; +check_ether(nss_XbyY_args_t *argp, const char *line, int linelen) { - return (ether_cmp(args->buf.result, args->key.ether) == 0); + + const char *limit, *linep; + uchar_t ether[6]; + ptrdiff_t i; + int n; + + linep = line; + limit = line + linelen; + + /* skip leading spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + for (i = 0; i < 6; i++) { + n = 0; + while (linep < limit && isxdigit(*linep)) { + n = 16 * n + DIGIT(*linep); + linep++; + } + if (*linep != ':' && i < 5) { + return (0); + } else if (*linep == ':' && i == 5) { + return (0); + } else { + linep++; + ether[i] = (uchar_t)n; + } + } + return (ether_cmp((void *)ether, (void *)argp->key.ether) == 0); } static nss_status_t |