Back to index

courier  0.68.2
rfc1035an.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2000 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 #include      "config.h"
00006 #include      "rfc1035.h"
00007 #include      <sys/types.h>
00008 #include      <sys/socket.h>
00009 #include      <arpa/inet.h>
00010 #include      <errno.h>
00011 #include      <string.h>
00012 
00013 
00014 void rfc1035_ntoa_ipv4(const struct in_addr *in, char *buf)
00015 {
00016 union  {
00017        unsigned char addr[4];
00018        RFC1035_UINT32 n;
00019        } u;
00020 
00021 int    i;
00022 char   *p;
00023 char   pbuf[4];
00024 
00025        u.n=in->s_addr;
00026        for (i=0; i<4; i++)
00027        {
00028               if (i) *buf++='.';
00029               p=pbuf+3;
00030               *p=0;
00031               do
00032               {
00033                      *--p = '0' + (u.addr[i] % 10);
00034               } while ( (u.addr[i] /= 10) != 0);
00035               while (*p)
00036                      *buf++ = *p++;
00037        }
00038        *buf=0;
00039 }
00040 
00041 void rfc1035_ntoa(const RFC1035_ADDR *in, char *buf)
00042 {
00043 #if    RFC1035_IPV6
00044        inet_ntop(AF_INET6, in, buf, RFC1035_MAXNAMESIZE+1);
00045 #else
00046        rfc1035_ntoa_ipv4(in, buf);
00047 #endif
00048 }
00049 
00050 static RFC1035_UINT32 doaton(const char *p, int *err)
00051 {
00052 RFC1035_UINT32 octets[4];
00053 int    i;
00054 int    base;
00055 
00056        *err=1;
00057        for (i=0; i<4; i++)
00058        {
00059               if (i > 0)
00060               {
00061                      if (*p == '\0')      break;
00062                      if (*p != '.')       return ( -1 );
00063                      ++p;
00064               }
00065               if (*p < '0' || *p > '9')   return (-1);
00066               octets[i]=0;
00067               base=10;
00068               if (*p == '0')       base=8;
00069 
00070               while (*p >= '0' && *p < '0'+base)
00071                      octets[i] = octets[i] * base + (*p++ - '0');
00072        }
00073        if (*p)       return ( -1 );
00074        *err=0;
00075        if (i == 1)   return (octets[0]);
00076        *err=1;
00077        if (octets[0] > 255) return ( -1 );
00078        octets[0] <<= 24;
00079 
00080        if (i == 2)
00081        {
00082               if (octets[1] > 0x00FFFFFF) return ( -1 );
00083               *err=0;
00084               return (octets[0] | octets[1]);
00085        }
00086 
00087        if (octets[1] > 255) return ( -1 );
00088        octets[1] <<= 16;
00089        if (i == 3)
00090        {
00091               if (octets[2] > 0x0000FFFF) return ( -1 );
00092               *err=0;
00093               return (octets[0] | octets[1] | octets[2]);
00094        }
00095        if (octets[2] > 255 || octets[3] > 255)   return ( -1 );
00096        *err=0;
00097        return (octets[0] | octets[1] | (octets[2] << 8) | octets[3]);
00098 }
00099 
00100 int rfc1035_aton_ipv4(const char *p, struct in_addr *in4)
00101 {
00102 int    dummy;
00103 RFC1035_UINT32 n=doaton(p, &dummy);
00104 union  {
00105        unsigned char addr[4];
00106        struct in_addr n;
00107        } u;
00108 
00109        u.addr[3]=n;
00110        u.addr[2]=n >> 8;
00111        u.addr[1]=n >> 16;
00112        u.addr[0]=n >> 24;
00113 
00114        if (dummy)    errno=EINVAL;
00115        *in4=u.n;
00116        return (dummy);
00117 }
00118 
00119 #if    RFC1035_IPV6
00120 
00121 int rfc1035_aton(const char *p, RFC1035_ADDR *in6)
00122 {
00123 struct in_addr       in4;
00124 
00125        if (rfc1035_aton_ipv4(p, &in4) == 0)
00126        {
00127               rfc1035_ipv4to6(in6, &in4);
00128               return (0);
00129        }
00130        if (inet_pton(AF_INET6, p, in6) <= 0)
00131               return (-1);
00132        return (0);
00133 }
00134 
00135 #else
00136 
00137 int rfc1035_aton(const char *p, RFC1035_ADDR *in4)
00138 {
00139        return (rfc1035_aton_ipv4(p, in4));
00140 }
00141 #endif