Back to index

glibc  2.9
Functions
inet_addr.c File Reference
#include <sys/types.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>

Go to the source code of this file.

Functions

in_addr_t inet_addr (const char *cp)
int __inet_aton (const char *cp, struct in_addr *addr)

Function Documentation

int __inet_aton ( const char *  cp,
struct in_addr addr 
)

Definition at line 109 of file inet_addr.c.

{
       static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
       in_addr_t val;
#ifndef _LIBC
       int base;
#endif
       char c;
       union iaddr {
         uint8_t bytes[4];
         uint32_t word;
       } res;
       uint8_t *pp = res.bytes;
       int digit;

#ifdef _LIBC
       int saved_errno = errno;
       __set_errno (0);
#endif

       res.word = 0;

       c = *cp;
       for (;;) {
              /*
               * Collect number up to ``.''.
               * Values are specified as for C:
               * 0x=hex, 0=octal, isdigit=decimal.
               */
              if (!isdigit(c))
                     goto ret_0;
#ifdef _LIBC
              {
                     char *endp;
                     unsigned long ul = strtoul (cp, (char **) &endp, 0);
                     if (ul == ULONG_MAX && errno == ERANGE)
                            goto ret_0;
                     if (ul > 0xfffffffful)
                            goto ret_0;
                     val = ul;
                     digit = cp != endp;
                     cp = endp;
              }
              c = *cp;
#else
              val = 0; base = 10; digit = 0;
              if (c == '0') {
                     c = *++cp;
                     if (c == 'x' || c == 'X')
                            base = 16, c = *++cp;
                     else {
                            base = 8;
                            digit = 1 ;
                     }
              }
              for (;;) {
                     if (isascii(c) && isdigit(c)) {
                            if (base == 8 && (c == '8' || c == '9'))
                                   return (0);
                            val = (val * base) + (c - '0');
                            c = *++cp;
                            digit = 1;
                     } else if (base == 16 && isascii(c) && isxdigit(c)) {
                            val = (val << 4) |
                                   (c + 10 - (islower(c) ? 'a' : 'A'));
                            c = *++cp;
                            digit = 1;
                     } else
                            break;
              }
#endif
              if (c == '.') {
                     /*
                      * Internet format:
                      *     a.b.c.d
                      *     a.b.c  (with c treated as 16 bits)
                      *     a.b    (with b treated as 24 bits)
                      */
                     if (pp > res.bytes + 2 || val > 0xff)
                            goto ret_0;
                     *pp++ = val;
                     c = *++cp;
              } else
                     break;
       }
       /*
        * Check for trailing characters.
        */
       if (c != '\0' && (!isascii(c) || !isspace(c)))
              goto ret_0;
       /*
        * Did we get a valid digit?
        */
       if (!digit)
              goto ret_0;

       /* Check whether the last part is in its limits depending on
          the number of parts in total.  */
       if (val > max[pp - res.bytes])
         goto ret_0;

       if (addr != NULL)
              addr->s_addr = res.word | htonl (val);

#ifdef _LIBC
       __set_errno (saved_errno);
#endif
       return (1);

ret_0:
#ifdef _LIBC
       __set_errno (saved_errno);
#endif
       return (0);
}

Here is the call graph for this function:

in_addr_t inet_addr ( const char *  cp)

Definition at line 93 of file inet_addr.c.

                          {
       struct in_addr val;

       if (__inet_aton(cp, &val))
              return (val.s_addr);
       return (INADDR_NONE);
}