]>
git.ipfire.org Git - people/ms/strongswan.git/blob - linux/lib/libfreeswan/addrtot.c
f229789f0cb55d2ef8d3d16182c3f95fed6a8d93
3 * Copyright (C) 2000 Henry Spencer.
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Library General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 * License for more details.
15 * RCSID $Id: addrtot.c,v 1.1 2004/03/15 20:35:25 as Exp $
20 #define IP4BYTES 4 /* bytes in an IPv4 address */
21 #define PERBYTE 4 /* three digits plus a dot or NUL */
22 #define IP6BYTES 16 /* bytes in an IPv6 address */
25 static size_t normal4(const unsigned char *s
, size_t len
, char *b
, char **dp
);
26 static size_t normal6(const unsigned char *s
, size_t len
, char *b
, char **dp
, int squish
);
27 static size_t reverse4(const unsigned char *s
, size_t len
, char *b
, char **dp
);
28 static size_t reverse6(const unsigned char *s
, size_t len
, char *b
, char **dp
);
31 - addrtot - convert binary address to text (dotted decimal or IPv6 string)
33 size_t /* space needed for full conversion */
34 addrtot(src
, format
, dst
, dstlen
)
35 const ip_address
*src
;
36 int format
; /* character */
37 char *dst
; /* need not be valid if dstlen is 0 */
40 const unsigned char *b
;
42 char buf
[1+ADDRTOT_BUF
+1]; /* :address: */
44 int t
= addrtypeof(src
);
45 # define TF(t, f) (((t)<<8) | (f))
47 n
= addrbytesptr(src
, &b
);
51 switch (TF(t
, format
)) {
53 n
= normal4(b
, n
, buf
, &p
);
56 n
= normal6(b
, n
, buf
, &p
, 1);
58 case TF(AF_INET
, 'Q'):
59 n
= normal4(b
, n
, buf
, &p
);
61 case TF(AF_INET6
, 'Q'):
62 n
= normal6(b
, n
, buf
, &p
, 0);
64 case TF(AF_INET
, 'r'):
65 n
= reverse4(b
, n
, buf
, &p
);
67 case TF(AF_INET6
, 'r'):
68 n
= reverse6(b
, n
, buf
, &p
);
70 default: /* including (AF_INET, 'R') */
84 - normal4 - normal IPv4 address-text conversion
86 static size_t /* size of text, including NUL */
87 normal4(srcp
, srclen
, buf
, dstp
)
88 const unsigned char *srcp
;
90 char *buf
; /* guaranteed large enough */
91 char **dstp
; /* where to put result pointer */
96 if (srclen
!= IP4BYTES
) /* "can't happen" */
99 for (i
= 0; i
< IP4BYTES
; i
++) {
100 p
+= ultot(srcp
[i
], 10, p
, PERBYTE
);
101 if (i
!= IP4BYTES
- 1)
102 *(p
-1) = '.'; /* overwrites the NUL */
109 - normal6 - normal IPv6 address-text conversion
111 static size_t /* size of text, including NUL */
112 normal6(srcp
, srclen
, buf
, dstp
, squish
)
113 const unsigned char *srcp
;
115 char *buf
; /* guaranteed large enough, plus 2 */
116 char **dstp
; /* where to put result pointer */
117 int squish
; /* whether to squish out 0:0 */
124 if (srclen
!= IP6BYTES
) /* "can't happen" */
128 for (i
= 0; i
< IP6BYTES
/2; i
++) {
129 piece
= (srcp
[2*i
] << 8) + srcp
[2*i
+ 1];
130 p
+= ultot(piece
, 16, p
, 5); /* 5 = abcd + NUL */
131 *(p
-1) = ':'; /* overwrites the NUL */
134 q
= strstr(buf
, ":0:0:");
135 if (squish
&& q
!= NULL
) { /* zero squishing is possible */
137 while (*p
== '0' && *(p
+1) == ':')
140 *q
++ = ':'; /* overwrite first 0 */
144 if (!(*(q
-1) == ':' && *(q
-2) == ':'))
145 *--q
= '\0'; /* strip final : unless :: */
147 if (!(*p
== ':' && *(p
+1) == ':'))
148 p
++; /* skip initial : unless :: */
151 *--q
= '\0'; /* strip final : */
152 p
= buf
+ 1; /* skip initial : */
159 - reverse4 - IPv4 reverse-lookup conversion
161 static size_t /* size of text, including NUL */
162 reverse4(srcp
, srclen
, buf
, dstp
)
163 const unsigned char *srcp
;
165 char *buf
; /* guaranteed large enough */
166 char **dstp
; /* where to put result pointer */
171 if (srclen
!= IP4BYTES
) /* "can't happen" */
174 for (i
= IP4BYTES
-1; i
>= 0; i
--) {
175 p
+= ultot(srcp
[i
], 10, p
, PERBYTE
);
176 *(p
-1) = '.'; /* overwrites the NUL */
178 strcpy(p
, "IN-ADDR.ARPA.");
180 return strlen(buf
) + 1;
184 - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
185 * A trifle inefficient, really shouldn't use ultot...
187 static size_t /* size of text, including NUL */
188 reverse6(srcp
, srclen
, buf
, dstp
)
189 const unsigned char *srcp
;
191 char *buf
; /* guaranteed large enough */
192 char **dstp
; /* where to put result pointer */
198 if (srclen
!= IP6BYTES
) /* "can't happen" */
201 for (i
= IP6BYTES
-1; i
>= 0; i
--) {
203 p
+= ultot(piece
&0xf, 16, p
, 2);
205 p
+= ultot(piece
>>4, 16, p
, 2);
208 strcpy(p
, "IP6.ARPA.");
210 return strlen(buf
) + 1;
214 - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
215 * this version removed as it was obsoleted in the end.
221 #include <sys/socket.h>
222 #include <netinet/in.h>
223 #include <arpa/inet.h>
228 main(int argc
, char *argv
[])
231 fprintf(stderr
, "Usage: %s {addr|net/mask|begin...end|-r}\n",
236 if (strcmp(argv
[1], "-r") == 0) {
238 fprintf(stderr
, "regress() returned?!?\n");
247 char *output
; /* NULL means error expected */
249 {"1.2.3.0", 0, "1.2.3.0"},
250 {"1:2::3:4", 0, "1:2::3:4"},
251 {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
252 {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
253 {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
254 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */
255 {"1:2::3:4", 'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."},
270 for (r
= rtab
; r
->input
!= NULL
; r
++) {
271 strcpy(in
, r
->input
);
273 /* convert it *to* internal format */
274 oops
= ttoaddr(in
, strlen(in
), 0, &a
);
276 /* now convert it back */
278 n
= addrtot(&a
, r
->format
, buf
, sizeof(buf
));
280 if (n
== 0 && r
->output
== NULL
)
281 {} /* okay, error expected */
284 printf("`%s' atoasr failed\n", r
->input
);
287 } else if (r
->output
== NULL
) {
288 printf("`%s' atoasr succeeded unexpectedly '%c'\n",
289 r
->input
, r
->format
);
292 if (strcasecmp(r
->output
, buf
) != 0) {
293 printf("`%s' '%c' gave `%s', expected `%s'\n",
294 r
->input
, r
->format
, buf
, r
->output
);
302 #endif /* ADDRTOT_MAIN */