OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / lib / 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.7 2000/11/29 16:34:01 henry 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 }