reverse name lookup (gethostbyaddr) seems not to function with wins in host entry in nsswitch.conf. Is this feature not implemented? We solved the issue for us with patching nsswitch/wins.c Found an old solaris patch (sorry, lost the name originator) and modified it to run with 3.0.24 for our purposes. I don't think the patch is fully ok for general purpose use!!! The if: (status[i].flags & 0x80 || !(status[i].type == 0x20 || status[i].type = 0x00 ) ) is modified for our purposes by try and error, I don't know what flags and type would be the correct ones (I think they come from windows (e.g. NetBios Client type)?). Here's the patch, mainly the new function _nss_wins_gethostbyaddr_r against 3.0.24: *** nsswitch/wins.c.org 2007-05-08 08:51:30.000000000 +0200 +++ nsswitch/wins.c 2007-05-08 11:42:14.000000000 +0200 @@ -125,8 +125,6 @@ return ret; } -#ifdef HAVE_NS_API_H - static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count) { int fd; @@ -150,6 +148,8 @@ return status; } +#ifdef HAVE_NS_API_H + /* IRIX version */ int init(void) @@ -375,4 +375,105 @@ return _nss_wins_gethostbyname_r( name, he, buffer, buflen, h_errnop); } + + /*************************************************************************** * + gethostbyaddr() + **************************************************************************/ + NSS_STATUS + _nss_wins_gethostbyaddr_r(const char *addr, int length, int type, + struct hostent *he, char *buffer, size_t buflen, + int *errnop, int *h_errnop) + { + enum { AddressStringSize = 16 }; + char **host_addresses, **host_aliases; + char address_string[AddressStringSize]; + NODE_STATUS_STRUCT *status; + int i, rc, count, true_count; + size_t namelen; + + memset(he, '\0', sizeof(*he)); + + /* I don't think you can do WINS over IPV6 - fv */ + if (length != INADDRSZ || type != AF_INET) { + return NSS_STATUS_NOTFOUND; + } + + rc = snprintf(address_string, AddressStringSize, "%d.%d.%d.%d", + (uchar) addr[0], (uchar) addr[1], (uchar) addr[2], + (uchar) addr[3]); + if (rc < 0 || rc > AddressStringSize) { + return NSS_STATUS_NOTFOUND; + } + + status = lookup_byaddr_backend(address_string, &count); + if (!status) { + return NSS_STATUS_NOTFOUND; + } + + true_count = 0; + for (i=0;i<count;i++) { + /* ignore group names */ + if (status[i].flags & 0x80 || !(status[i].type == 0x20 || status[i].type == 0x00 ) ) continue; + ++true_count; + } + + if (true_count < 1) { + return NSS_STATUS_NOTFOUND; + } + if (buflen < (true_count+3)*INADDRSZ) { + /* no ENOMEM error type?! */ + return NSS_STATUS_NOTFOUND; + } + host_addresses = (char **)buffer; + he->h_addr_list = host_addresses; + buffer += 2 * INADDRSZ; + buflen -= 2 * INADDRSZ; + host_addresses[0] = buffer; + host_addresses[1] = NULL; + memcpy(buffer, addr, INADDRSZ); + buffer += INADDRSZ; + buflen -= INADDRSZ; + he->h_addrtype = AF_INET; + he->h_length = INADDRSZ; + + if (true_count == 1) { + he->h_aliases = host_addresses + 1; + } else { + host_aliases = (char **)buffer; + he->h_aliases = host_aliases; + host_aliases[true_count-1] = NULL; + buffer += true_count * INADDRSZ; + buflen -= true_count * INADDRSZ; + } + + true_count = 0; + for (i=0;i<count;i++) { + /* ignore group names */ + if (status[i].flags & 0x80 || !(status[i].type == 0x20 || status[i].type == 0x00 ) ) continue; + /* assume first name is 'canonical' name */ + if (true_count == 0) { + he->h_name = buffer; + } else { + *host_aliases = buffer; + host_aliases++; + } + namelen = strlen(status[i].name); + if (buflen < namelen + 1) { + /* no ENOMEM error type?! */ + return NSS_STATUS_NOTFOUND; + } + memcpy(buffer, &status[i].name, namelen); + buffer += namelen; + *buffer = '\0'; + buffer++; + buflen -= namelen + 1; + true_count++; + } + + if (status) + free(status); + + return NSS_STATUS_SUCCESS; + } + #endif
please include the patch as an attachment and not an inline comment. Thanks.
no feedback, also gethostbyaddr() does not look usefull for the (quite dead) nss wins module