OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [libc/] [inet_net_pton.c] - Blame information for rev 279

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 * Copyright (c) 1996 by Internet Software Consortium.
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15
 * SOFTWARE.
16
 */
17
 
18
#if defined(LIBC_SCCS) && !defined(lint)
19
static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 1.8 1996/11/21 10:28:12 vixie Exp $";
20
static const char rcsid[] = "$Id: inet_net_pton.c,v 1.2 2001-09-27 12:01:53 chris Exp $";
21
#endif
22
 
23
#include <sys/types.h>
24
#include <sys/socket.h>
25
#include <netinet/in.h>
26
#include <arpa/inet.h>
27
 
28
#include <assert.h>
29
#include <ctype.h>
30
#include <errno.h>
31
#include <stdio.h>
32
#include <string.h>
33
#include <stdlib.h>
34
 
35
#ifdef SPRINTF_CHAR
36
# define SPRINTF(x) strlen(sprintf/**/x)
37
#else
38
# define SPRINTF(x) ((size_t)sprintf x)
39
#endif
40
 
41
static int      inet_net_pton_ipv4 __P((const char *src, u_char *dst,
42
                                        size_t size));
43
 
44
/*
45
 * static int
46
 * inet_net_pton(af, src, dst, size)
47
 *      convert network number from presentation to network format.
48
 *      accepts hex octets, hex strings, decimal octets, and /CIDR.
49
 *      "size" is in bytes and describes "dst".
50
 * return:
51
 *      number of bits, either imputed classfully or specified with /CIDR,
52
 *      or -1 if some failure occurred (check errno).  ENOENT means it was
53
 *      not a valid network specification.
54
 * author:
55
 *      Paul Vixie (ISC), June 1996
56
 */
57
int
58
inet_net_pton(af, src, dst, size)
59
        int af;
60
        const char *src;
61
        void *dst;
62
        size_t size;
63
{
64
        switch (af) {
65
        case AF_INET:
66
                return (inet_net_pton_ipv4(src, dst, size));
67
        default:
68
                errno = EAFNOSUPPORT;
69
                return (-1);
70
        }
71
}
72
 
73
/*
74
 * static int
75
 * inet_net_pton_ipv4(src, dst, size)
76
 *      convert IPv4 network number from presentation to network format.
77
 *      accepts hex octets, hex strings, decimal octets, and /CIDR.
78
 *      "size" is in bytes and describes "dst".
79
 * return:
80
 *      number of bits, either imputed classfully or specified with /CIDR,
81
 *      or -1 if some failure occurred (check errno).  ENOENT means it was
82
 *      not an IPv4 network specification.
83
 * note:
84
 *      network byte order assumed.  this means 192.5.5.240/28 has
85
 *      0x11110000 in its fourth octet.
86
 * author:
87
 *      Paul Vixie (ISC), June 1996
88
 */
89
static int
90
inet_net_pton_ipv4(src, dst, size)
91
        const char *src;
92
        u_char *dst;
93
        size_t size;
94
{
95
        static const char
96
                xdigits[] = "0123456789abcdef",
97
                digits[] = "0123456789";
98
        int n, ch, tmp, dirty, bits;
99
        const u_char *odst = dst;
100
 
101
        ch = *src++;
102
        if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
103
            && isascii(src[1]) && isxdigit(src[1])) {
104
                /* Hexadecimal: Eat nybble string. */
105
                if (size <= 0)
106
                        goto emsgsize;
107
                *dst = 0, dirty = 0;
108
                src++;  /* skip x or X. */
109
                while ((ch = *src++) != '\0' &&
110
                       isascii(ch) && isxdigit(ch)) {
111
                        if (isupper(ch))
112
                                ch = tolower(ch);
113
                        n = strchr(xdigits, ch) - xdigits;
114
                        assert(n >= 0 && n <= 15);
115
                        *dst |= n;
116
                        if (!dirty++)
117
                                *dst <<= 4;
118
                        else if (size-- > 0)
119
                                *++dst = 0, dirty = 0;
120
                        else
121
                                goto emsgsize;
122
                }
123
                if (dirty)
124
                        size--;
125
        } else if (isascii(ch) && isdigit(ch)) {
126
                /* Decimal: eat dotted digit string. */
127
                for (;;) {
128
                        tmp = 0;
129
                        do {
130
                                n = strchr(digits, ch) - digits;
131
                                assert(n >= 0 && n <= 9);
132
                                tmp *= 10;
133
                                tmp += n;
134
                                if (tmp > 255)
135
                                        goto enoent;
136
                        } while ((ch = *src++) != '\0' &&
137
                                 isascii(ch) && isdigit(ch));
138
                        if (size-- <= 0)
139
                                goto emsgsize;
140
                        *dst++ = (u_char) tmp;
141
                        if (ch == '\0' || ch == '/')
142
                                break;
143
                        if (ch != '.')
144
                                goto enoent;
145
                        ch = *src++;
146
                        if (!isascii(ch) || !isdigit(ch))
147
                                goto enoent;
148
                }
149
        } else
150
                goto enoent;
151
 
152
        bits = -1;
153
        if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
154
                /* CIDR width specifier.  Nothing can follow it. */
155
                ch = *src++;    /* Skip over the /. */
156
                bits = 0;
157
                do {
158
                        n = strchr(digits, ch) - digits;
159
                        assert(n >= 0 && n <= 9);
160
                        bits *= 10;
161
                        bits += n;
162
                } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
163
                if (ch != '\0')
164
                        goto enoent;
165
                if (bits > 32)
166
                        goto emsgsize;
167
        }
168
 
169
        /* Firey death and destruction unless we prefetched EOS. */
170
        if (ch != '\0')
171
                goto enoent;
172
 
173
        /* If nothing was written to the destination, we found no address. */
174
        if (dst == odst)
175
                goto enoent;
176
        /* If no CIDR spec was given, infer width from net class. */
177
        if (bits == -1) {
178
                if (*odst >= 240)       /* Class E */
179
                        bits = 32;
180
                else if (*odst >= 224)  /* Class D */
181
                        bits = 4;
182
                else if (*odst >= 192)  /* Class C */
183
                        bits = 24;
184
                else if (*odst >= 128)  /* Class B */
185
                        bits = 16;
186
                else                    /* Class A */
187
                        bits = 8;
188
                /* If imputed mask is narrower than specified octets, widen. */
189
                if (bits >= 8 && bits < ((dst - odst) * 8))
190
                        bits = (dst - odst) * 8;
191
        }
192
        /* Extend network to cover the actual mask. */
193
        while (bits > ((dst - odst) * 8)) {
194
                if (size-- <= 0)
195
                        goto emsgsize;
196
                *dst++ = '\0';
197
        }
198
        return (bits);
199
 
200
 enoent:
201
        errno = ENOENT;
202
        return (-1);
203
 
204
 emsgsize:
205
        errno = EMSGSIZE;
206
        return (-1);
207
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.