]>
git.ipfire.org Git - thirdparty/strongswan.git/blob - linux/lib/libfreeswan/rangetosubnet.c
2 * express an address range as a subnet (if possible)
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: rangetosubnet.c,v 1.1 2004/03/15 20:35:26 as Exp $
21 - rangetosubnet - turn an address range into a subnet, if possible
23 * A range which is a valid subnet will have a network part which is the
24 * same in the from value and the to value, followed by a host part which
25 * is all 0 in the from value and all 1 in the to value.
28 rangetosubnet(from
, to
, dst
)
29 const ip_address
*from
;
33 unsigned const char *fp
;
34 unsigned const char *tp
;
37 unsigned const char *f
;
38 unsigned const char *t
;
45 if (addrtypeof(from
) != addrtypeof(to
))
46 return "mismatched address types";
47 n
= addrbytesptr(from
, &fp
);
49 return "unknown address type";
50 n2
= addrbytesptr(to
, &tp
);
52 return "internal size mismatch in rangetosubnet";
57 for (i
= n
; i
> 0 && *f
== *t
; i
--, f
++, t
++)
59 if (i
> 0 && !(*f
== 0x00 && *t
== 0xff)) { /* mid-byte bdry. */
64 while ((fb
&m
) == (tb
&m
)) {
70 if (fb
!= 0x00 || tb
!= 0xff)
71 return "not a valid subnet";
73 for (; i
> 0 && *f
== 0x00 && *t
== 0xff; i
--, f
++, t
++)
77 return "invalid subnet";
79 return initsubnet(from
, nnet
, 'x', dst
);
84 #ifdef RANGETOSUBNET_MAIN
91 main(int argc
, char *argv
[])
102 if (argc
== 2 && strcmp(argv
[1], "-r") == 0) {
104 fprintf(stderr
, "regress() returned?!?\n");
109 fprintf(stderr
, "Usage: %s [-6] start stop\n", argv
[0]);
110 fprintf(stderr
, " or: %s -r\n", argv
[0]);
116 if (strcmp(argv
[i
], "-6") == 0) {
121 oops
= ttoaddr(argv
[i
], 0, af
, &start
);
123 fprintf(stderr
, "%s: start conversion failed: %s\n", argv
[0], oops
);
126 oops
= ttoaddr(argv
[i
+1], 0, af
, &stop
);
128 fprintf(stderr
, "%s: stop conversion failed: %s\n", argv
[0], oops
);
131 oops
= rangetosubnet(&start
, &stop
, &sub
);
133 fprintf(stderr
, "%s: rangetosubnet failed: %s\n", argv
[0], oops
);
136 n
= subnettot(&sub
, 0, buf
, sizeof(buf
));
137 if (n
> sizeof(buf
)) {
138 fprintf(stderr
, "%s: reverse conversion", argv
[0]);
139 fprintf(stderr
, " failed: need %ld bytes, have only %ld\n",
140 (long)n
, (long)sizeof(buf
));
152 char *output
; /* NULL means error expected */
154 {4, "1.2.3.0", "1.2.3.255", "1.2.3.0/24"},
155 {4, "1.2.3.0", "1.2.3.7", "1.2.3.0/29"},
156 {4, "1.2.3.240", "1.2.3.255", "1.2.3.240/28"},
157 {4, "0.0.0.0", "255.255.255.255", "0.0.0.0/0"},
158 {4, "1.2.3.4", "1.2.3.4", "1.2.3.4/32"},
159 {4, "1.2.3.0", "1.2.3.254", NULL
},
160 {4, "1.2.3.0", "1.2.3.126", NULL
},
161 {4, "1.2.3.0", "1.2.3.125", NULL
},
162 {4, "1.2.0.0", "1.2.255.255", "1.2.0.0/16"},
163 {4, "1.2.0.0", "1.2.0.255", "1.2.0.0/24"},
164 {4, "1.2.255.0", "1.2.255.255", "1.2.255.0/24"},
165 {4, "1.2.255.0", "1.2.254.255", NULL
},
166 {4, "1.2.255.1", "1.2.255.255", NULL
},
167 {4, "1.2.0.1", "1.2.255.255", NULL
},
168 {6, "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:ffff", "1:2:3:4:5:6:7:0/112"},
169 {6, "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:fff", "1:2:3:4:5:6:7:0/116"},
170 {6, "1:2:3:4:5:6:7:f0", "1:2:3:4:5:6:7:ff", "1:2:3:4:5:6:7:f0/124"},
171 {4, NULL
, NULL
, NULL
},
187 for (r
= rtab
; r
->start
!= NULL
; r
++) {
188 af
= (r
->family
== 4) ? AF_INET
: AF_INET6
;
189 oops
= ttoaddr(r
->start
, 0, af
, &start
);
191 printf("surprise failure converting `%s'\n", r
->start
);
194 oops
= ttoaddr(r
->stop
, 0, af
, &stop
);
196 printf("surprise failure converting `%s'\n", r
->stop
);
199 oops
= rangetosubnet(&start
, &stop
, &sub
);
200 if (oops
!= NULL
&& r
->output
== NULL
)
201 {} /* okay, error expected */
202 else if (oops
!= NULL
) {
203 printf("`%s'-`%s' rangetosubnet failed: %s\n",
204 r
->start
, r
->stop
, oops
);
206 } else if (r
->output
== NULL
) {
207 printf("`%s'-`%s' rangetosubnet succeeded unexpectedly\n",
211 n
= subnettot(&sub
, 0, buf
, sizeof(buf
));
212 if (n
> sizeof(buf
)) {
213 printf("`%s'-`%s' subnettot failed: need %ld\n",
214 r
->start
, r
->stop
, (long)n
);
216 } else if (strcmp(r
->output
, buf
) != 0) {
217 printf("`%s'-`%s' gave `%s', expected `%s'\n",
218 r
->start
, r
->stop
, buf
, r
->output
);
226 #endif /* RANGETOSUBNET_MAIN */