Пример #1
0
enum nss_status
_nss_dns_getnetbyname_r (const char *name, struct netent *result,
			 char *buffer, size_t buflen, int *errnop,
			 int *herrnop)
{
  /* Return entry for network with NAME.  */
  union
  {
    querybuf *buf;
    u_char *ptr;
  } net_buffer;
  querybuf *orig_net_buffer;
  int anslen;
  enum nss_status status;

  struct resolv_context *ctx = __resolv_context_get ();
  if (ctx == NULL)
    {
      *errnop = errno;
      *herrnop = NETDB_INTERNAL;
      return NSS_STATUS_UNAVAIL;
    }

  net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);

  anslen = __res_context_search
    (ctx, name, C_IN, T_PTR, net_buffer.buf->buf,
     1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
  if (anslen < 0)
    {
      /* Nothing found.  */
      *errnop = errno;
      if (net_buffer.buf != orig_net_buffer)
	free (net_buffer.buf);
      __resolv_context_put (ctx);
      return (errno == ECONNREFUSED
	      || errno == EPFNOSUPPORT
	      || errno == EAFNOSUPPORT)
	? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
    }

  status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen,
			errnop, herrnop, BYNAME);
  if (net_buffer.buf != orig_net_buffer)
    free (net_buffer.buf);
  __resolv_context_put (ctx);
  return status;
}
Пример #2
0
int
__nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
			    char **buffer, size_t *buffer_size,
			    size_t buflen, struct hostent **result,
			    enum nss_status *status, int af, int *h_errnop)
{
  /* We have to test for the use of IPv6 which can only be done by
     examining `_res'.  */
  struct resolv_context *ctx = __resolv_context_get ();
  if (ctx == NULL)
    {
      if (h_errnop)
	*h_errnop = NETDB_INTERNAL;
      if (buffer_size == NULL)
	*status = NSS_STATUS_TRYAGAIN;
      else
	*result = NULL;
      return -1;
    }
  int ret = __nss_hostname_digits_dots_context
    (ctx, name, resbuf, buffer, buffer_size, buflen,
     result, status, af, h_errnop);
  __resolv_context_put (ctx);
  return ret;
}
Пример #3
0
LOOKUP_TYPE *
FUNCTION_NAME (ADD_PARAMS)
{
  static size_t buffer_size;
  static LOOKUP_TYPE resbuf;
  LOOKUP_TYPE *result;
#ifdef NEED_H_ERRNO
  int h_errno_tmp = 0;
#endif

#ifdef HANDLE_DIGITS_DOTS
  /* Wrap both __nss_hostname_digits_dots and the actual lookup
     function call in the same context.  */
  struct resolv_context *res_ctx = __resolv_context_get ();
  if (res_ctx == NULL)
    {
# if NEED_H_ERRNO
      __set_h_errno (NETDB_INTERNAL);
# endif
      return NULL;
    }
#endif

  /* Get lock.  */
  __libc_lock_lock (lock);

  if (buffer == NULL)
    {
      buffer_size = BUFLEN;
      buffer = (char *) malloc (buffer_size);
    }

#ifdef HANDLE_DIGITS_DOTS
  if (buffer != NULL)
    {
      if (__nss_hostname_digits_dots_context
	  (res_ctx, name, &resbuf, &buffer, &buffer_size, 0, &result, NULL,
	   AF_VAL, H_ERRNO_VAR_P))
	goto done;
    }
#endif

  while (buffer != NULL
	 && (INTERNAL (REENTRANT_NAME) (ADD_VARIABLES, &resbuf, buffer,
					buffer_size, &result H_ERRNO_VAR)
	     == ERANGE)
#ifdef NEED_H_ERRNO
	 && h_errno_tmp == NETDB_INTERNAL
#endif
	 )
    {
      char *new_buf;
      buffer_size *= 2;
      new_buf = (char *) realloc (buffer, buffer_size);
      if (new_buf == NULL)
	{
	  /* We are out of memory.  Free the current buffer so that the
	     process gets a chance for a normal termination.  */
	  free (buffer);
	  __set_errno (ENOMEM);
	}
      buffer = new_buf;
    }

  if (buffer == NULL)
    result = NULL;

#ifdef HANDLE_DIGITS_DOTS
done:
#endif
  /* Release lock.  */
  __libc_lock_unlock (lock);

#ifdef HANDLE_DIGITS_DOTS
  __resolv_context_put (res_ctx);
#endif

#ifdef NEED_H_ERRNO
  if (h_errno_tmp != 0)
    __set_h_errno (h_errno_tmp);
#endif

  return result;
}
Пример #4
0
enum nss_status
_nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result,
			 char *buffer, size_t buflen, int *errnop,
			 int *herrnop)
{
  /* Return entry for network with NAME.  */
  enum nss_status status;
  union
  {
    querybuf *buf;
    u_char *ptr;
  } net_buffer;
  querybuf *orig_net_buffer;
  unsigned int net_bytes[4];
  char qbuf[MAXDNAME];
  int cnt, anslen;
  uint32_t net2;
  int olderr = errno;

  /* No net address lookup for IPv6 yet.  */
  if (type != AF_INET)
    return NSS_STATUS_UNAVAIL;

  struct resolv_context *ctx = __resolv_context_get ();
  if (ctx == NULL)
    {
      *errnop = errno;
      *herrnop = NETDB_INTERNAL;
      return NSS_STATUS_UNAVAIL;
    }

  net2 = (uint32_t) net;
  for (cnt = 4; net2 != 0; net2 >>= 8)
    net_bytes[--cnt] = net2 & 0xff;

  switch (cnt)
    {
    case 3:
      /* Class A network.  */
      sprintf (qbuf, "0.0.0.%u.in-addr.arpa", net_bytes[3]);
      break;
    case 2:
      /* Class B network.  */
      sprintf (qbuf, "0.0.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2]);
      break;
    case 1:
      /* Class C network.  */
      sprintf (qbuf, "0.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
	       net_bytes[1]);
      break;
    case 0:
      /* Class D - E network.  */
      sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
	       net_bytes[1], net_bytes[0]);
      break;
    }

  net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);

  anslen = __res_context_query (ctx, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
				1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
  if (anslen < 0)
    {
      /* Nothing found.  */
      int err = errno;
      __set_errno (olderr);
      if (net_buffer.buf != orig_net_buffer)
	free (net_buffer.buf);
      __resolv_context_put (ctx);
      return (err == ECONNREFUSED
	      || err == EPFNOSUPPORT
	      || err == EAFNOSUPPORT)
	? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
    }

  status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen,
			errnop, herrnop, BYADDR);
  if (net_buffer.buf != orig_net_buffer)
    free (net_buffer.buf);
  if (status == NSS_STATUS_SUCCESS)
    {
      /* Strip trailing zeros.  */
      unsigned int u_net = net;	/* Maybe net should be unsigned?  */

      while ((u_net & 0xff) == 0 && u_net != 0)
	u_net >>= 8;
      result->n_net = u_net;
    }