]> git.ipfire.org Git - people/ms/strongswan.git/blob - src/libfreeswan.tmp/sameaddr.c
(no commit message)
[people/ms/strongswan.git] / src / libfreeswan.tmp / sameaddr.c
1 /*
2 * comparisons
3 * Copyright (C) 2000 Henry Spencer.
4 *
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>.
9 *
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.
14 *
15 * RCSID $Id: sameaddr.c,v 1.1 2004/03/15 20:35:26 as Exp $
16 */
17 #include "internal.h"
18 #include "freeswan.h"
19
20 static int samenbits(const ip_address *a, const ip_address *b, int n);
21
22 /*
23 - addrcmp - compare two addresses
24 * Caution, the order of the tests is subtle: doing type test before
25 * size test can yield cases where a<b, b<c, but a>c.
26 */
27 int /* like memcmp */
28 addrcmp(a, b)
29 const ip_address *a;
30 const ip_address *b;
31 {
32 int at = addrtypeof(a);
33 int bt = addrtypeof(b);
34 const unsigned char *ap;
35 const unsigned char *bp;
36 size_t as = addrbytesptr(a, &ap);
37 size_t bs = addrbytesptr(b, &bp);
38 size_t n = (as < bs) ? as : bs; /* min(as, bs) */
39 int c = memcmp(ap, bp, n);
40
41 if (c != 0) /* bytes differ */
42 return (c < 0) ? -1 : 1;
43 if (as != bs) /* comparison incomplete: lexical order */
44 return (as < bs) ? -1 : 1;
45 if (at != bt) /* bytes same but not same type: break tie */
46 return (at < bt) ? -1 : 1;
47 return 0;
48 }
49
50 /*
51 - sameaddr - are two addresses the same?
52 */
53 int
54 sameaddr(a, b)
55 const ip_address *a;
56 const ip_address *b;
57 {
58 return (addrcmp(a, b) == 0) ? 1 : 0;
59 }
60
61 /*
62 - samesubnet - are two subnets the same?
63 */
64 int
65 samesubnet(a, b)
66 const ip_subnet *a;
67 const ip_subnet *b;
68 {
69 if (!sameaddr(&a->addr, &b->addr)) /* also does type check */
70 return 0;
71 if (a->maskbits != b->maskbits)
72 return 0;
73 return 1;
74 }
75
76 /*
77 - subnetishost - is a subnet in fact a single host?
78 */
79 int
80 subnetishost(a)
81 const ip_subnet *a;
82 {
83 return (a->maskbits == addrlenof(&a->addr)*8) ? 1 : 0;
84 }
85
86 /*
87 - samesaid - are two SA IDs the same?
88 */
89 int
90 samesaid(a, b)
91 const ip_said *a;
92 const ip_said *b;
93 {
94 if (a->spi != b->spi) /* test first, most likely to be different */
95 return 0;
96 if (!sameaddr(&a->dst, &b->dst))
97 return 0;
98 if (a->proto != b->proto)
99 return 0;
100 return 1;
101 }
102
103 /*
104 - sameaddrtype - do two addresses have the same type?
105 */
106 int
107 sameaddrtype(a, b)
108 const ip_address *a;
109 const ip_address *b;
110 {
111 return (addrtypeof(a) == addrtypeof(b)) ? 1 : 0;
112 }
113
114 /*
115 - samesubnettype - do two subnets have the same type?
116 */
117 int
118 samesubnettype(a, b)
119 const ip_subnet *a;
120 const ip_subnet *b;
121 {
122 return (subnettypeof(a) == subnettypeof(b)) ? 1 : 0;
123 }
124
125 /*
126 - addrinsubnet - is this address in this subnet?
127 */
128 int
129 addrinsubnet(a, s)
130 const ip_address *a;
131 const ip_subnet *s;
132 {
133 if (addrtypeof(a) != subnettypeof(s))
134 return 0;
135 if (!samenbits(a, &s->addr, s->maskbits))
136 return 0;
137 return 1;
138 }
139
140 /*
141 - subnetinsubnet - is one subnet within another?
142 */
143 int
144 subnetinsubnet(a, b)
145 const ip_subnet *a;
146 const ip_subnet *b;
147 {
148 if (subnettypeof(a) != subnettypeof(b))
149 return 0;
150 if (a->maskbits < b->maskbits) /* a is bigger than b */
151 return 0;
152 if (!samenbits(&a->addr, &b->addr, b->maskbits))
153 return 0;
154 return 1;
155 }
156
157 /*
158 - samenbits - do two addresses have the same first n bits?
159 */
160 static int
161 samenbits(a, b, nbits)
162 const ip_address *a;
163 const ip_address *b;
164 int nbits;
165 {
166 const unsigned char *ap;
167 const unsigned char *bp;
168 size_t n;
169 int m;
170
171 if (addrtypeof(a) != addrtypeof(b))
172 return 0; /* arbitrary */
173 n = addrbytesptr(a, &ap);
174 if (n == 0)
175 return 0; /* arbitrary */
176 (void) addrbytesptr(b, &bp);
177 if (nbits > n*8)
178 return 0; /* "can't happen" */
179
180 for (; nbits >= 8 && *ap == *bp; nbits -= 8, ap++, bp++)
181 continue;
182 if (nbits >= 8)
183 return 0;
184 if (nbits > 0) { /* partial byte */
185 m = ~(0xff >> nbits);
186 if ((*ap & m) != (*bp & m))
187 return 0;
188 }
189 return 1;
190 }