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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libnetworking/] [libc/] [inet_ntop.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/* Copyright (c) 1996 by Internet Software Consortium.
2
 *
3
 * Permission to use, copy, modify, and distribute this software for any
4
 * purpose with or without fee is hereby granted, provided that the above
5
 * copyright notice and this permission notice appear in all copies.
6
 *
7
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
8
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
9
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
10
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
11
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
12
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
13
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
14
 * SOFTWARE.
15
 */
16
 
17
#if defined(LIBC_SCCS) && !defined(lint)
18
static char rcsid[] = "inet_ntop.c,v 1.1 1998/08/19 21:32:14 joel Exp";
19
#endif /* LIBC_SCCS and not lint */
20
 
21
#include <sys/param.h>
22
#include <sys/types.h>
23
#include <sys/socket.h>
24
#include <netinet/in.h>
25
#include <arpa/inet.h>
26
#include <arpa/nameser.h>
27
#include <errno.h>
28
#include <stdio.h>
29
#include <string.h>
30
 
31
#define SPRINTF(x) ((size_t)sprintf x)
32
 
33
/*
34
 * WARNING: Don't even consider trying to compile this on a system where
35
 * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
36
 */
37
 
38
static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
39
static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
40
 
41
/* char *
42
 * inet_ntop(af, src, dst, size)
43
 *      convert a network format address to presentation format.
44
 * return:
45
 *      pointer to presentation format address (`dst'), or NULL (see errno).
46
 * author:
47
 *      Paul Vixie, 1996.
48
 */
49
const char *
50
inet_ntop(af, src, dst, size)
51
        int af;
52
        const void *src;
53
        char *dst;
54
        size_t size;
55
{
56
        switch (af) {
57
        case AF_INET:
58
                return (inet_ntop4(src, dst, size));
59
        case AF_INET6:
60
                return (inet_ntop6(src, dst, size));
61
        default:
62
                errno = EAFNOSUPPORT;
63
                return (NULL);
64
        }
65
        /* NOTREACHED */
66
}
67
 
68
/* const char *
69
 * inet_ntop4(src, dst, size)
70
 *      format an IPv4 address, more or less like inet_ntoa()
71
 * return:
72
 *      `dst' (as a const)
73
 * notes:
74
 *      (1) uses no statics
75
 *      (2) takes a u_char* not an in_addr as input
76
 * author:
77
 *      Paul Vixie, 1996.
78
 */
79
static const char *
80
inet_ntop4(src, dst, size)
81
        const u_char *src;
82
        char *dst;
83
        size_t size;
84
{
85
        static const char fmt[] = "%u.%u.%u.%u";
86
        char tmp[sizeof "255.255.255.255"];
87
 
88
        if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
89
                errno = ENOSPC;
90
                return (NULL);
91
        }
92
        strcpy(dst, tmp);
93
        return (dst);
94
}
95
 
96
/* const char *
97
 * inet_ntop6(src, dst, size)
98
 *      convert IPv6 binary address into presentation (printable) format
99
 * author:
100
 *      Paul Vixie, 1996.
101
 */
102
static const char *
103
inet_ntop6(src, dst, size)
104
        const u_char *src;
105
        char *dst;
106
        size_t size;
107
{
108
        /*
109
         * Note that int32_t and int16_t need only be "at least" large enough
110
         * to contain a value of the specified size.  On some systems, like
111
         * Crays, there is no such thing as an integer variable with 16 bits.
112
         * Keep this in mind if you think this function should have been coded
113
         * to use pointer overlays.  All the world's not a VAX.
114
         */
115
        char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
116
        struct { int base, len; } best, cur;
117
        u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
118
        int i;
119
 
120
        /*
121
         * Preprocess:
122
         *      Copy the input (bytewise) array into a wordwise array.
123
         *      Find the longest run of 0x00's in src[] for :: shorthanding.
124
         */
125
        memset(words, '\0', sizeof words);
126
        for (i = 0; i < NS_IN6ADDRSZ; i++)
127
                words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
128
        best.base = -1;
129
        cur.base = -1;
130
        for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
131
                if (words[i] == 0) {
132
                        if (cur.base == -1)
133
                                cur.base = i, cur.len = 1;
134
                        else
135
                                cur.len++;
136
                } else {
137
                        if (cur.base != -1) {
138
                                if (best.base == -1 || cur.len > best.len)
139
                                        best = cur;
140
                                cur.base = -1;
141
                        }
142
                }
143
        }
144
        if (cur.base != -1) {
145
                if (best.base == -1 || cur.len > best.len)
146
                        best = cur;
147
        }
148
        if (best.base != -1 && best.len < 2)
149
                best.base = -1;
150
 
151
        /*
152
         * Format the result.
153
         */
154
        tp = tmp;
155
        for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
156
                /* Are we inside the best run of 0x00's? */
157
                if (best.base != -1 && i >= best.base &&
158
                    i < (best.base + best.len)) {
159
                        if (i == best.base)
160
                                *tp++ = ':';
161
                        continue;
162
                }
163
                /* Are we following an initial run of 0x00s or any real hex? */
164
                if (i != 0)
165
                        *tp++ = ':';
166
                /* Is this address an encapsulated IPv4? */
167
                if (i == 6 && best.base == 0 &&
168
                    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
169
                        if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
170
                                return (NULL);
171
                        tp += strlen(tp);
172
                        break;
173
                }
174
                tp += SPRINTF((tp, "%x", words[i]));
175
        }
176
        /* Was it a trailing run of 0x00's? */
177
        if (best.base != -1 && (best.base + best.len) ==
178
            (NS_IN6ADDRSZ / NS_INT16SZ))
179
                *tp++ = ':';
180
        *tp++ = '\0';
181
 
182
        /*
183
         * Check for overflow, copy, and we're done.
184
         */
185
        if ((size_t)(tp - tmp) > size) {
186
                errno = ENOSPC;
187
                return (NULL);
188
        }
189
        strcpy(dst, tmp);
190
        return (dst);
191
}

powered by: WebSVN 2.1.0

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