Exemplo n.º 1
0
/*
 * Parse the IP address and convert to a reverse domain name.
 */
static char *ipaddr2domain(char *start, char **addr, char **rest) {
  static char buf[30]; /* "123.123.123.123.in-addr.arpa.\0" */
  char *ptrs[5];
  int i;

  ptrs[0]= start;
retry:
  while (!sensible_ctype(isdigit,*ptrs[0]))
    if (!*ptrs[0]++) {
      strcpy(buf, "invalid.");
      *addr= *rest= NULL;
      return buf;
    }
  for (i= 1; i < 5; i++) {
    ptrs[i]= ptrs[i-1];
    while (sensible_ctype(isdigit,*ptrs[i]++));
    if ((i == 4 && !sensible_ctype(isspace,ptrs[i][-1])) ||
	(i != 4 && ptrs[i][-1] != '.') ||
	(ptrs[i]-ptrs[i-1] > 4)) {
      ptrs[0]= ptrs[i]-1;
      goto retry;
    }
  }
  sprintf(buf, "%.*s.%.*s.%.*s.%.*s.in-addr.arpa.",
	  (int)(ptrs[4]-ptrs[3]-1), ptrs[3],
	  (int)(ptrs[3]-ptrs[2]-1), ptrs[2],
	  (int)(ptrs[2]-ptrs[1]-1), ptrs[1],
	  (int)(ptrs[1]-ptrs[0]-1), ptrs[0]);
  *addr= ptrs[0];
  *rest= ptrs[4]-1;
  return buf;
}
Exemplo n.º 2
0
/* Expand an IPv6 address string by inserting missing '0', changing
   letters to lowercase, and removing the the colons.  Returns a
   pointer to a static buffer or NULL on error.  Example:
   "2001:aA8:fff1:2100::60" gives
   "20010aa8fff121000000000000000060".  */
static char *
expand_v6 (const char *addrstr)
{
  static char buffer[32+1];
  char tmpbuf[4];
  int tmpidx, idx, i;
  const char *s;
  int ncolon;

  for (s=addrstr, ncolon=0; *s && !sensible_ctype (isspace, *s); s++)
    {
      if (*s == ':')
        ncolon++;
    }
  if (ncolon > 8)
    return NULL;  /* Oops.  */

  memset (buffer, '0', 32);
  buffer[32] = 0;
  idx = tmpidx = 0;
  for (s=addrstr; *s && !sensible_ctype (isspace, *s); s++)
    {
      if (*s == ':')
        {
          idx += 4 - tmpidx;
          for (i=0; i < tmpidx; i++)
            {
              if (idx >= sizeof buffer)
                return NULL;
              buffer[idx++] = tmpbuf[i];
            }
          tmpidx = 0;
          if (s[1] == ':') /* Double colon.  */
            {
              s++;
              if (!ncolon || s[1] == ':')
                return NULL;  /* More than one double colon. */
              idx += 4*(8 - ncolon);
              ncolon = 0;
            }
        }
      else if (tmpidx > 3)
        return NULL;  /* Invalid address.  */
      else if (!sensible_ctype (isxdigit, *s))
        return NULL;  /* Invalid character.  */
      else
        tmpbuf[tmpidx++] = sensible_ctype (tolower, *s);
    }

  idx += 4 - tmpidx;
  for (i=0; i < tmpidx; i++)
    {
      if (idx >= sizeof buffer)
        return NULL;
      buffer[idx++] = tmpbuf[i];
    }

  return buffer;
}
Exemplo n.º 3
0
/*
 * Parse the IP address and convert to a reverse domain name.  On
 * return the full IP address is stored at FULLIP which is
 * expected to be a buffer of at least FULLIPBUFLEN bytes.
 */
static char *
ipaddr2domain(char *start, char **addr, char **rest, char *fullip,
              int *r_is_v6, int opts)
{
  /* Sample values BUF needs to hold:
   * "123.123.123.123.in-addr.arpa."
   * "0.6.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.2.1.f.f.f.8.a.a.0.1.0.0.2.ip6.arpa."
   */
  static char buf[74];
  int i;
  char *endp;
  int ndots = 0;

  *r_is_v6 = 0;

  /* Better skip leading spaces which might have been created by some
     log processing scripts.  */
  while (sensible_ctype(isspace, *start))
    start++;

  if ((opts & OPT_VHOST))
    {
      while (!sensible_ctype(isspace, *start))
        start++;
      while (sensible_ctype(isspace, *start))
        start++;
    }
  if ((opts & OPT_FTP))
    {
      /* Sample FTP log line (after the xfer tag):

         Mon Mar 11 05:18:16 2013 1 124.0.0.0 287 /gcrypt/gnupg/foo \
            b _ o a anonymous ftp 0 * c

         Timestamp, time (rounded up, so that it is never zero),
         remote host IP,
         file size, filename, transfer type, special action flag,
         direction, access mode, username, service name,
         authentication method, authenticated user ID, completion status.  */
      if (strlen (start) < 38)
        {
          strcpy (buf, "invalid");
          *addr = *rest = NULL;
          goto leave;
        }
      start += 25;
      while (!sensible_ctype(isspace, *start))
        start++;
      while (sensible_ctype(isspace, *start))
        start++;
    }

  for (endp = start; !sensible_ctype(isspace, *endp); endp++)
    {
      if (*endp == ':')
        *r_is_v6 = 1;
      else if (*endp == '.')
        ndots++;
    }
  if (endp == start)
    {
      strcpy (buf, "invalid");
      *addr = *rest = NULL;
      goto leave;
    }

  if (*r_is_v6)
    {
      const char *exp = expand_v6 (start);
      const char *s;
      char *p;
      size_t len;

      if (!exp)
        {
          strcpy (buf, "invalid_v6");
          *addr = *rest = NULL;
          goto leave;
        }

      len = strlen (exp);
      assert (len + 9 + 1 <= sizeof buf);
      assert (len < FULLIPBUFLEN);
      strcpy (fullip, exp);

      p = buf;
      for (s = exp + len - 1; s >= exp; s--)
        {
          *p++ = *s;
          *p++ = '.';
        }
      strcpy (p, "ip6.arpa.");
      *addr = start;
      *rest = endp;
    }
  else /* v4 */
    {
      char *ptrs[5];

      /* Largest expected string is "255.255.255.255".  */
      if ((endp - start) > 15 || ndots != 3)
        {
          strcpy (buf, "invalid_v4");
          *addr = *rest = NULL;
          goto leave;
        }
      snprintf (fullip, FULLIPBUFLEN, "%.*s", (int)(endp-start), start);

      ptrs[0] = start;
      for (i = 1; i < 5; i++)
        {
          ptrs[i] = ptrs[i-1];
          while (sensible_ctype (isdigit, *ptrs[i]++))
            ;
          if ((i == 4 && !sensible_ctype (isspace, ptrs[i][-1]))
              || (i != 4 && ptrs[i][-1] != '.')
              || (ptrs[i]-ptrs[i-1] > 4)
              || (i!=4 && !sensible_ctype (isdigit, ptrs[i][0])))
            {
              strcpy (buf, "invalid_v4");
              *addr = *rest = NULL;
              goto leave;
            }
        }

      snprintf (buf, sizeof buf, "%.*s.%.*s.%.*s.%.*s.in-addr.arpa.",
                (int)(ptrs[4]-ptrs[3]-1), ptrs[3],
                (int)(ptrs[3]-ptrs[2]-1), ptrs[2],
                (int)(ptrs[2]-ptrs[1]-1), ptrs[1],
                (int)(ptrs[1]-ptrs[0]-1), ptrs[0]);
      *addr= ptrs[0];
      *rest= ptrs[4]-1;
    }

 leave:
  return buf;
}