Should have thought of this...
[icmp-dn.git] / nss-icmp.c
index 803acbc..5bc5ec7 100644 (file)
@@ -1,3 +1,24 @@
+/*
+ *  nss-icmp or libnss_icmp - GNU C Library NSS module to query host
+ *  names by ICMP.
+ *  Copyright (C) 2005 Fredrik Tolf <fredrik@dolda2000.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ *  MA 02111-1307, USA
+ */
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <nss.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <sys/wait.h>
 
 #define CONFIGFILE "/etc/nss-icmp.conf"
+#if 0
+#define DEBUGP(format...) fprintf(stderr, "nss-icmp: " format);
+#else
+#define DEBUGP(format...)
+#endif
 
 struct cache {
     struct cache *next, *prev;
@@ -191,6 +218,7 @@ enum nss_status _nss_icmp_gethostbyaddr_r(const void *addr, socklen_t len, int a
     pid_t child;
     int pfd[2];
     int rl;
+    int status;
     struct cache *cc;
     
     if(!inited) {
@@ -205,6 +233,8 @@ enum nss_status _nss_icmp_gethostbyaddr_r(const void *addr, socklen_t len, int a
        return(NSS_STATUS_UNAVAIL);
     }
     
+    DEBUGP("starting lookup\n");
+    
     if(usecache) {
        expirecache();
        for(cc = cache; cc != NULL; cc = cc->next) {
@@ -216,12 +246,14 @@ enum nss_status _nss_icmp_gethostbyaddr_r(const void *addr, socklen_t len, int a
     }
     
     if(cc == NULL) {
+       DEBUGP("address not in cache, looking up for real\n");
        ap = (u_int8_t *)addr;
        if(inet_ntop(af, addr, addrbuf, sizeof(addrbuf)) == NULL) {
            *errnop = errno;
            *h_errnop = NETDB_INTERNAL;
            return(NSS_STATUS_UNAVAIL);
        }
+       DEBUGP("address is %s\n", addrbuf);
     
        if(pipe(pfd)) {
            *errnop = errno;
@@ -280,6 +312,8 @@ enum nss_status _nss_icmp_gethostbyaddr_r(const void *addr, socklen_t len, int a
        addrbuf[rl] = 0;
        close(pfd[0]);
        
+       waitpid(child, &status, 0);
+       
        if((p = strchr(addrbuf, '\n')) == NULL) {
            if(usecache)
                cachenotfound(addr, len, af, nfttl);
@@ -322,6 +356,7 @@ enum nss_status _nss_icmp_gethostbyaddr_r(const void *addr, socklen_t len, int a
        if(usecache)
            updatecache(addr, len, af, retbuf->aliaslist, ttl);
     } else {
+       DEBUGP("address found in cache\n");
        if(cc->notfound) {
            *h_errnop = TRY_AGAIN; /* XXX: Is this correct? */
            return(NSS_STATUS_NOTFOUND);
@@ -330,22 +365,20 @@ enum nss_status _nss_icmp_gethostbyaddr_r(const void *addr, socklen_t len, int a
        p3 = buffer + sizeof(*retbuf);
        for(i = 0; cc->names[i] != NULL; i++) {
            thislen = strlen(cc->names[i]);
+           DEBUGP("filling in address %s, length %i\n", cc->names[i], thislen);
            if((p3 - buffer) + thislen + 1 > buflen) {
                *errnop = ENOMEM;
                *h_errnop = NETDB_INTERNAL;
                return(NSS_STATUS_UNAVAIL);
            }
            memcpy(p3, cc->names[i], thislen + 1);
-           retbuf->aliaslist[an] = p3;
+           retbuf->aliaslist[i] = p3;
            p3 += thislen + 1;
-           if(++an == 16) {
-               *errnop = ENOMEM;
-               *h_errnop = NETDB_INTERNAL;
-               return(NSS_STATUS_UNAVAIL);
-           }
        }
+       retbuf->aliaslist[i] = NULL;
     }
     
+    DEBUGP("returning hostent\n");
     memcpy(retbuf->retaddr, addr, len);
     retbuf->addrlist[0] = retbuf->retaddr;
     retbuf->addrlist[1] = NULL;
@@ -356,5 +389,12 @@ enum nss_status _nss_icmp_gethostbyaddr_r(const void *addr, socklen_t len, int a
     result->h_length = len;
     
     *h_errnop = NETDB_SUCCESS;
+    DEBUGP("returning\n");
     return(NSS_STATUS_SUCCESS);
 }
+
+/*
+ * Local Variables:
+ * compile-command: "gcc -shared -Wall -g -o libnss_icmp.so.2 nss-icmp.c"
+ * End:
+ */