~clint-fewbar/ubuntu/precise/squid3/ignore-sighup-early

« back to all changes in this revision

Viewing changes to lib/inet_pton.c

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2010-05-04 11:15:49 UTC
  • mfrom: (1.3.1 upstream)
  • mto: (20.3.1 squeeze) (21.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20100504111549-1apjh2g5sndki4te
Tags: upstream-3.1.3
ImportĀ upstreamĀ versionĀ 3.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Shamelessly duplicated from the bind9 public sources
 
3
 *  for use by the Squid Project under ISC written permission
 
4
 *  included "as found" below.
 
5
 *
 
6
 * Update/Maintenance History:
 
7
 *
 
8
 *    24-Sep-2007 : Copied from bind 9.3.3
 
9
 *                      - Added protection around libray headers
 
10
 *                      - Altered configure checks to import
 
11
 *
 
12
 *    06-Oct-2007 : Various fixes to allow the build on MinGW
 
13
 *
 
14
 *    28-Oct-2007: drop some dead code. now tested working without.
 
15
 *
 
16
 * Squid CVS $Id$
 
17
 *
 
18
 *  Original License and code follows.
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#ifndef HAVE_INET_PTON
 
24
 
 
25
/*
 
26
 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
 
27
 * Copyright (c) 1996,1999 by Internet Software Consortium.
 
28
 *
 
29
 * Permission to use, copy, modify, and distribute this software for any
 
30
 * purpose with or without fee is hereby granted, provided that the above
 
31
 * copyright notice and this permission notice appear in all copies.
 
32
 *
 
33
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
 
34
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 
35
 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
 
36
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 
37
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 
38
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 
39
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
40
 */
 
41
 
 
42
#if defined(LIBC_SCCS) && !defined(lint)
 
43
static const char rcsid[] = "inet_pton.c,v 1.2.206.2 2005/07/28 07:43:18 marka Exp";
 
44
#endif /* LIBC_SCCS and not lint */
 
45
 
 
46
#if HAVE_SYS_PARAM_H
 
47
#include <sys/param.h>
 
48
#endif
 
49
#if HAVE_SYS_TYPES_H
 
50
#include <sys/types.h>
 
51
#endif
 
52
#if HAVE_SYS_SOCKET_H
 
53
#include <sys/socket.h>
 
54
#endif
 
55
#if HAVE_NETINET_IN_H
 
56
#include <netinet/in.h>
 
57
#endif
 
58
#if ARPA_INET_H
 
59
#include <arpa/inet.h>
 
60
#endif
 
61
#if HAVE_ARPA_NAMESER_H
 
62
#include <arpa/nameser.h>
 
63
#endif
 
64
#if HAVE_STRING_H
 
65
#include <string.h>
 
66
#endif
 
67
#if HAVE_ERRNO_H
 
68
#include <errno.h>
 
69
#endif
 
70
 
 
71
#if ! defined(NS_INADDRSZ)
 
72
#define NS_INADDRSZ      4
 
73
#endif
 
74
#if ! defined(NS_IN6ADDRSZ)
 
75
#define NS_IN6ADDRSZ    16
 
76
#endif
 
77
#if ! defined(NS_INT16SZ)
 
78
#define NS_INT16SZ      2
 
79
#endif
 
80
 
 
81
/*
 
82
 * WARNING: Don't even consider trying to compile this on a system where
 
83
 * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
 
84
 */
 
85
 
 
86
static int      inet_pton4 (const char *src, u_char *dst);
 
87
static int      inet_pton6 (const char *src, u_char *dst);
 
88
 
 
89
/* int
 
90
 * inet_pton(af, src, dst)
 
91
 *      convert from presentation format (which usually means ASCII printable)
 
92
 *      to network format (which is usually some kind of binary format).
 
93
 * return:
 
94
 *      1 if the address was valid for the specified address family
 
95
 *      0 if the address wasn't valid (`dst' is untouched in this case)
 
96
 *      -1 if some other error occurred (`dst' is untouched in this case, too)
 
97
 * author:
 
98
 *      Paul Vixie, 1996.
 
99
 */
 
100
int
 
101
xinet_pton(af, src, dst)
 
102
int af;
 
103
const char *src;
 
104
void *dst;
 
105
{
 
106
    switch (af) {
 
107
    case AF_INET:
 
108
        return (inet_pton4(src, dst));
 
109
    case AF_INET6:
 
110
        return (inet_pton6(src, dst));
 
111
    default:
 
112
        errno = EAFNOSUPPORT;
 
113
        return (-1);
 
114
    }
 
115
    /* NOTREACHED */
 
116
}
 
117
 
 
118
/* int
 
119
 * inet_pton4(src, dst)
 
120
 *      like inet_aton() but without all the hexadecimal and shorthand.
 
121
 * return:
 
122
 *      1 if `src' is a valid dotted quad, else 0.
 
123
 * notice:
 
124
 *      does not touch `dst' unless it's returning 1.
 
125
 * author:
 
126
 *      Paul Vixie, 1996.
 
127
 */
 
128
static int
 
129
inet_pton4(src, dst)
 
130
const char *src;
 
131
u_char *dst;
 
132
{
 
133
    static const char digits[] = "0123456789";
 
134
    int saw_digit, octets, ch;
 
135
    u_char tmp[NS_INADDRSZ], *tp;
 
136
 
 
137
    saw_digit = 0;
 
138
    octets = 0;
 
139
    *(tp = tmp) = 0;
 
140
    while ((ch = *src++) != '\0') {
 
141
        const char *pch;
 
142
 
 
143
        if ((pch = strchr(digits, ch)) != NULL) {
 
144
            u_int new = *tp * 10 + (pch - digits);
 
145
 
 
146
            if (saw_digit && *tp == 0)
 
147
                return (0);
 
148
            if (new > 255)
 
149
                return (0);
 
150
            *tp = new;
 
151
            if (!saw_digit) {
 
152
                if (++octets > 4)
 
153
                    return (0);
 
154
                saw_digit = 1;
 
155
            }
 
156
        } else if (ch == '.' && saw_digit) {
 
157
            if (octets == 4)
 
158
                return (0);
 
159
            *++tp = 0;
 
160
            saw_digit = 0;
 
161
        } else
 
162
            return (0);
 
163
    }
 
164
    if (octets < 4)
 
165
        return (0);
 
166
    memcpy(dst, tmp, NS_INADDRSZ);
 
167
    return (1);
 
168
}
 
169
 
 
170
/* int
 
171
 * inet_pton6(src, dst)
 
172
 *      convert presentation level address to network order binary form.
 
173
 * return:
 
174
 *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
 
175
 * notice:
 
176
 *      (1) does not touch `dst' unless it's returning 1.
 
177
 *      (2) :: in a full address is silently ignored.
 
178
 * credit:
 
179
 *      inspired by Mark Andrews.
 
180
 * author:
 
181
 *      Paul Vixie, 1996.
 
182
 */
 
183
static int
 
184
inet_pton6(src, dst)
 
185
const char *src;
 
186
u_char *dst;
 
187
{
 
188
    static const char xdigits_l[] = "0123456789abcdef",
 
189
                                    xdigits_u[] = "0123456789ABCDEF";
 
190
    u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
 
191
    const char *xdigits, *curtok;
 
192
    int ch, seen_xdigits;
 
193
    u_int val;
 
194
 
 
195
    memset((tp = tmp), '\0', NS_IN6ADDRSZ);
 
196
    endp = tp + NS_IN6ADDRSZ;
 
197
    colonp = NULL;
 
198
    /* Leading :: requires some special handling. */
 
199
    if (*src == ':')
 
200
        if (*++src != ':')
 
201
            return (0);
 
202
    curtok = src;
 
203
    seen_xdigits = 0;
 
204
    val = 0;
 
205
    while ((ch = *src++) != '\0') {
 
206
        const char *pch;
 
207
 
 
208
        if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
 
209
            pch = strchr((xdigits = xdigits_u), ch);
 
210
        if (pch != NULL) {
 
211
            val <<= 4;
 
212
            val |= (pch - xdigits);
 
213
            if (++seen_xdigits > 4)
 
214
                return (0);
 
215
            continue;
 
216
        }
 
217
        if (ch == ':') {
 
218
            curtok = src;
 
219
            if (!seen_xdigits) {
 
220
                if (colonp)
 
221
                    return (0);
 
222
                colonp = tp;
 
223
                continue;
 
224
            } else if (*src == '\0') {
 
225
                return (0);
 
226
            }
 
227
            if (tp + NS_INT16SZ > endp)
 
228
                return (0);
 
229
            *tp++ = (u_char) (val >> 8) & 0xff;
 
230
            *tp++ = (u_char) val & 0xff;
 
231
            seen_xdigits = 0;
 
232
            val = 0;
 
233
            continue;
 
234
        }
 
235
        if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
 
236
                inet_pton4(curtok, tp) > 0) {
 
237
            tp += NS_INADDRSZ;
 
238
            seen_xdigits = 0;
 
239
            break;      /* '\0' was seen by inet_pton4(). */
 
240
        }
 
241
        return (0);
 
242
    }
 
243
    if (seen_xdigits) {
 
244
        if (tp + NS_INT16SZ > endp)
 
245
            return (0);
 
246
        *tp++ = (u_char) (val >> 8) & 0xff;
 
247
        *tp++ = (u_char) val & 0xff;
 
248
    }
 
249
    if (colonp != NULL) {
 
250
        /*
 
251
         * Since some memmove()'s erroneously fail to handle
 
252
         * overlapping regions, we'll do the shift by hand.
 
253
         */
 
254
        const int n = tp - colonp;
 
255
        int i;
 
256
 
 
257
        if (tp == endp)
 
258
            return (0);
 
259
        for (i = 1; i <= n; i++) {
 
260
            endp[- i] = colonp[n - i];
 
261
            colonp[n - i] = 0;
 
262
        }
 
263
        tp = endp;
 
264
    }
 
265
    if (tp != endp)
 
266
        return (0);
 
267
    memcpy(dst, tmp, NS_IN6ADDRSZ);
 
268
    return (1);
 
269
}
 
270
 
 
271
#endif /* HAVE_INET_PTON */