| @@ -1,988 +1,988 @@ | | | @@ -1,988 +1,988 @@ |
1 | /* $NetBSD: iso.c,v 1.56 2009/04/18 14:58:06 tsutsui Exp $ */ | | 1 | /* $NetBSD: iso.c,v 1.57 2009/08/07 14:04:34 wiz Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2001 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2001 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * | | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. | | 26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | /*- | | 29 | /*- |
30 | * Copyright (c) 1991, 1993 | | 30 | * Copyright (c) 1991, 1993 |
31 | * The Regents of the University of California. All rights reserved. | | 31 | * The Regents of the University of California. All rights reserved. |
32 | * | | 32 | * |
33 | * Redistribution and use in source and binary forms, with or without | | 33 | * Redistribution and use in source and binary forms, with or without |
34 | * modification, are permitted provided that the following conditions | | 34 | * modification, are permitted provided that the following conditions |
35 | * are met: | | 35 | * are met: |
36 | * 1. Redistributions of source code must retain the above copyright | | 36 | * 1. Redistributions of source code must retain the above copyright |
37 | * notice, this list of conditions and the following disclaimer. | | 37 | * notice, this list of conditions and the following disclaimer. |
38 | * 2. Redistributions in binary form must reproduce the above copyright | | 38 | * 2. Redistributions in binary form must reproduce the above copyright |
39 | * notice, this list of conditions and the following disclaimer in the | | 39 | * notice, this list of conditions and the following disclaimer in the |
40 | * documentation and/or other materials provided with the distribution. | | 40 | * documentation and/or other materials provided with the distribution. |
41 | * 3. Neither the name of the University nor the names of its contributors | | 41 | * 3. Neither the name of the University nor the names of its contributors |
42 | * may be used to endorse or promote products derived from this software | | 42 | * may be used to endorse or promote products derived from this software |
43 | * without specific prior written permission. | | 43 | * without specific prior written permission. |
44 | * | | 44 | * |
45 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 45 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
55 | * SUCH DAMAGE. | | 55 | * SUCH DAMAGE. |
56 | * | | 56 | * |
57 | * @(#)iso.c 8.3 (Berkeley) 1/9/95 | | 57 | * @(#)iso.c 8.3 (Berkeley) 1/9/95 |
58 | */ | | 58 | */ |
59 | | | 59 | |
60 | /*********************************************************** | | 60 | /*********************************************************** |
61 | Copyright IBM Corporation 1987 | | 61 | Copyright IBM Corporation 1987 |
62 | | | 62 | |
63 | All Rights Reserved | | 63 | All Rights Reserved |
64 | | | 64 | |
65 | Permission to use, copy, modify, and distribute this software and its | | 65 | Permission to use, copy, modify, and distribute this software and its |
66 | documentation for any purpose and without fee is hereby granted, | | 66 | documentation for any purpose and without fee is hereby granted, |
67 | provided that the above copyright notice appear in all copies and that | | 67 | provided that the above copyright notice appear in all copies and that |
68 | both that copyright notice and this permission notice appear in | | 68 | both that copyright notice and this permission notice appear in |
69 | supporting documentation, and that the name of IBM not be | | 69 | supporting documentation, and that the name of IBM not be |
70 | used in advertising or publicity pertaining to distribution of the | | 70 | used in advertising or publicity pertaining to distribution of the |
71 | software without specific, written prior permission. | | 71 | software without specific, written prior permission. |
72 | | | 72 | |
73 | IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | | 73 | IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
74 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | | 74 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL |
75 | IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | | 75 | IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR |
76 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | | 76 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
77 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | | 77 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
78 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | | 78 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
79 | SOFTWARE. | | 79 | SOFTWARE. |
80 | | | 80 | |
81 | ******************************************************************/ | | 81 | ******************************************************************/ |
82 | | | 82 | |
83 | /* | | 83 | /* |
84 | * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison | | 84 | * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison |
85 | */ | | 85 | */ |
86 | /* | | 86 | /* |
87 | * iso.c: miscellaneous routines to support the iso address family | | 87 | * iso.c: miscellaneous routines to support the iso address family |
88 | */ | | 88 | */ |
89 | | | 89 | |
90 | #include <sys/cdefs.h> | | 90 | #include <sys/cdefs.h> |
91 | __KERNEL_RCSID(0, "$NetBSD: iso.c,v 1.56 2009/04/18 14:58:06 tsutsui Exp $"); | | 91 | __KERNEL_RCSID(0, "$NetBSD: iso.c,v 1.57 2009/08/07 14:04:34 wiz Exp $"); |
92 | | | 92 | |
93 | #include <sys/param.h> | | 93 | #include <sys/param.h> |
94 | #include <sys/systm.h> | | 94 | #include <sys/systm.h> |
95 | #include <sys/ioctl.h> | | 95 | #include <sys/ioctl.h> |
96 | #include <sys/mbuf.h> | | 96 | #include <sys/mbuf.h> |
97 | #include <sys/domain.h> | | 97 | #include <sys/domain.h> |
98 | #include <sys/protosw.h> | | 98 | #include <sys/protosw.h> |
99 | #include <sys/socket.h> | | 99 | #include <sys/socket.h> |
100 | #include <sys/socketvar.h> | | 100 | #include <sys/socketvar.h> |
101 | #include <sys/errno.h> | | 101 | #include <sys/errno.h> |
102 | #include <sys/proc.h> | | 102 | #include <sys/proc.h> |
103 | #include <sys/kauth.h> | | 103 | #include <sys/kauth.h> |
104 | | | 104 | |
105 | #include <net/if.h> | | 105 | #include <net/if.h> |
106 | #include <net/if_types.h> | | 106 | #include <net/if_types.h> |
107 | #include <net/route.h> | | 107 | #include <net/route.h> |
108 | | | 108 | |
109 | #include <netiso/iso.h> | | 109 | #include <netiso/iso.h> |
110 | #include <netiso/iso_var.h> | | 110 | #include <netiso/iso_var.h> |
111 | #include <netiso/iso_snpac.h> | | 111 | #include <netiso/iso_snpac.h> |
112 | #include <netiso/iso_pcb.h> | | 112 | #include <netiso/iso_pcb.h> |
113 | #include <netiso/clnp.h> | | 113 | #include <netiso/clnp.h> |
114 | #include <netiso/argo_debug.h> | | 114 | #include <netiso/argo_debug.h> |
115 | | | 115 | |
116 | #include "opt_iso.h" | | 116 | #include "opt_iso.h" |
117 | #ifdef ISO | | 117 | #ifdef ISO |
118 | | | 118 | |
119 | int iso_interfaces = 0; /* number of external interfaces */ | | 119 | int iso_interfaces = 0; /* number of external interfaces */ |
120 | | | 120 | |
121 | /* | | 121 | /* |
122 | * FUNCTION: iso_addrmatch1 | | 122 | * FUNCTION: iso_addrmatch1 |
123 | * | | 123 | * |
124 | * PURPOSE: decide if the two iso_addrs passed are equal | | 124 | * PURPOSE: decide if the two iso_addrs passed are equal |
125 | * | | 125 | * |
126 | * RETURNS: true if the addrs match, false if they do not | | 126 | * RETURNS: true if the addrs match, false if they do not |
127 | * | | 127 | * |
128 | * SIDE EFFECTS: | | 128 | * SIDE EFFECTS: |
129 | * | | 129 | * |
130 | * NOTES: | | 130 | * NOTES: |
131 | */ | | 131 | */ |
132 | int | | 132 | int |
133 | iso_addrmatch1(const struct iso_addr *isoaa, const struct iso_addr *isoab) | | 133 | iso_addrmatch1(const struct iso_addr *isoaa, const struct iso_addr *isoab) |
134 | { | | 134 | { |
135 | u_int compare_len; | | 135 | u_int compare_len; |
136 | | | 136 | |
137 | #ifdef ARGO_DEBUG | | 137 | #ifdef ARGO_DEBUG |
138 | if (argo_debug[D_ROUTE]) { | | 138 | if (argo_debug[D_ROUTE]) { |
139 | printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len, | | 139 | printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len, |
140 | isoab->isoa_len); | | 140 | isoab->isoa_len); |
141 | printf("a:\n"); | | 141 | printf("a:\n"); |
142 | dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len); | | 142 | dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len); |
143 | printf("b:\n"); | | 143 | printf("b:\n"); |
144 | dump_buf(isoab->isoa_genaddr, isoab->isoa_len); | | 144 | dump_buf(isoab->isoa_genaddr, isoab->isoa_len); |
145 | } | | 145 | } |
146 | #endif | | 146 | #endif |
147 | | | 147 | |
148 | if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) { | | 148 | if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) { |
149 | #ifdef ARGO_DEBUG | | 149 | #ifdef ARGO_DEBUG |
150 | if (argo_debug[D_ROUTE]) { | | 150 | if (argo_debug[D_ROUTE]) { |
151 | printf("iso_addrmatch1: returning false because of lengths\n"); | | 151 | printf("iso_addrmatch1: returning false because of lengths\n"); |
152 | } | | 152 | } |
153 | #endif | | 153 | #endif |
154 | return 0; | | 154 | return 0; |
155 | } | | 155 | } |
156 | #ifdef notdef | | 156 | #ifdef notdef |
157 | /* TODO : generalize this to all afis with masks */ | | 157 | /* TODO : generalize this to all afis with masks */ |
158 | if (isoaa->isoa_afi == AFI_37) { | | 158 | if (isoaa->isoa_afi == AFI_37) { |
159 | /* | | 159 | /* |
160 | * must not compare 2 least significant digits, or for that | | 160 | * must not compare 2 least significant digits, or for that |
161 | * matter, the DSP | | 161 | * matter, the DSP |
162 | */ | | 162 | */ |
163 | compare_len = ADDR37_IDI_LEN - 1; | | 163 | compare_len = ADDR37_IDI_LEN - 1; |
164 | } | | 164 | } |
165 | #endif | | 165 | #endif |
166 | | | 166 | |
167 | #ifdef ARGO_DEBUG | | 167 | #ifdef ARGO_DEBUG |
168 | if (argo_debug[D_ROUTE]) { | | 168 | if (argo_debug[D_ROUTE]) { |
169 | int i; | | 169 | int i; |
170 | const char *a, *b; | | 170 | const char *a, *b; |
171 | | | 171 | |
172 | a = isoaa->isoa_genaddr; | | 172 | a = isoaa->isoa_genaddr; |
173 | b = isoab->isoa_genaddr; | | 173 | b = isoab->isoa_genaddr; |
174 | | | 174 | |
175 | for (i = 0; i < compare_len; i++) { | | 175 | for (i = 0; i < compare_len; i++) { |
176 | printf("<%x=%x>", a[i] & 0xff, b[i] & 0xff); | | 176 | printf("<%x=%x>", a[i] & 0xff, b[i] & 0xff); |
177 | if (a[i] != b[i]) { | | 177 | if (a[i] != b[i]) { |
178 | printf("\naddrs are not equal at byte %d\n", i); | | 178 | printf("\naddrs are not equal at byte %d\n", i); |
179 | return (0); | | 179 | return (0); |
180 | } | | 180 | } |
181 | } | | 181 | } |
182 | printf("\n"); | | 182 | printf("\n"); |
183 | printf("addrs are equal\n"); | | 183 | printf("addrs are equal\n"); |
184 | return (1); | | 184 | return (1); |
185 | } | | 185 | } |
186 | #endif | | 186 | #endif |
187 | return (!memcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len)); | | 187 | return (!memcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len)); |
188 | } | | 188 | } |
189 | | | 189 | |
190 | /* | | 190 | /* |
191 | * FUNCTION: iso_addrmatch | | 191 | * FUNCTION: iso_addrmatch |
192 | * | | 192 | * |
193 | * PURPOSE: decide if the two sockadrr_isos passed are equal | | 193 | * PURPOSE: decide if the two sockadrr_isos passed are equal |
194 | * | | 194 | * |
195 | * RETURNS: true if the addrs match, false if they do not | | 195 | * RETURNS: true if the addrs match, false if they do not |
196 | * | | 196 | * |
197 | * SIDE EFFECTS: | | 197 | * SIDE EFFECTS: |
198 | * | | 198 | * |
199 | * NOTES: | | 199 | * NOTES: |
200 | */ | | 200 | */ |
201 | int | | 201 | int |
202 | iso_addrmatch(const struct sockaddr_iso *sisoa, | | 202 | iso_addrmatch(const struct sockaddr_iso *sisoa, |
203 | const struct sockaddr_iso *sisob) | | 203 | const struct sockaddr_iso *sisob) |
204 | { | | 204 | { |
205 | return (iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr)); | | 205 | return (iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr)); |
206 | } | | 206 | } |
207 | #ifdef notdef | | 207 | #ifdef notdef |
208 | /* | | 208 | /* |
209 | * FUNCTION: iso_netmatch | | 209 | * FUNCTION: iso_netmatch |
210 | * | | 210 | * |
211 | * PURPOSE: similar to iso_addrmatch but takes sockaddr_iso | | 211 | * PURPOSE: similar to iso_addrmatch but takes sockaddr_iso |
212 | * as argument. | | 212 | * as argument. |
213 | * | | 213 | * |
214 | * RETURNS: true if same net, false if not | | 214 | * RETURNS: true if same net, false if not |
215 | * | | 215 | * |
216 | * SIDE EFFECTS: | | 216 | * SIDE EFFECTS: |
217 | * | | 217 | * |
218 | * NOTES: | | 218 | * NOTES: |
219 | */ | | 219 | */ |
220 | int | | 220 | int |
221 | iso_netmatch(const struct sockaddr_iso *sisoa, | | 221 | iso_netmatch(const struct sockaddr_iso *sisoa, |
222 | const struct sockaddr_iso *sisob) | | 222 | const struct sockaddr_iso *sisob) |
223 | { | | 223 | { |
224 | u_char bufa[sizeof(struct sockaddr_iso)]; | | 224 | u_char bufa[sizeof(struct sockaddr_iso)]; |
225 | u_char bufb[sizeof(struct sockaddr_iso)]; | | 225 | u_char bufb[sizeof(struct sockaddr_iso)]; |
226 | int lena, lenb; | | 226 | int lena, lenb; |
227 | | | 227 | |
228 | lena = iso_netof(&sisoa->siso_addr, bufa); | | 228 | lena = iso_netof(&sisoa->siso_addr, bufa); |
229 | lenb = iso_netof(&sisob->siso_addr, bufb); | | 229 | lenb = iso_netof(&sisob->siso_addr, bufb); |
230 | | | 230 | |
231 | #ifdef ARGO_DEBUG | | 231 | #ifdef ARGO_DEBUG |
232 | if (argo_debug[D_ROUTE]) { | | 232 | if (argo_debug[D_ROUTE]) { |
233 | printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb); | | 233 | printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb); |
234 | printf("a:\n"); | | 234 | printf("a:\n"); |
235 | dump_buf(bufa, lena); | | 235 | dump_buf(bufa, lena); |
236 | printf("b:\n"); | | 236 | printf("b:\n"); |
237 | dump_buf(bufb, lenb); | | 237 | dump_buf(bufb, lenb); |
238 | } | | 238 | } |
239 | #endif | | 239 | #endif |
240 | | | 240 | |
241 | return ((lena == lenb) && (!memcmp(bufa, bufb, lena))); | | 241 | return ((lena == lenb) && (!memcmp(bufa, bufb, lena))); |
242 | } | | 242 | } |
243 | #endif /* notdef */ | | 243 | #endif /* notdef */ |
244 | | | 244 | |
245 | /* | | 245 | /* |
246 | * FUNCTION: iso_hashchar | | 246 | * FUNCTION: iso_hashchar |
247 | * | | 247 | * |
248 | * PURPOSE: Hash all character in the buffer specified into | | 248 | * PURPOSE: Hash all character in the buffer specified into |
249 | * a long. Return the long. | | 249 | * a long. Return the long. |
250 | * | | 250 | * |
251 | * RETURNS: The hash value. | | 251 | * RETURNS: The hash value. |
252 | * | | 252 | * |
253 | * SIDE EFFECTS: | | 253 | * SIDE EFFECTS: |
254 | * | | 254 | * |
255 | * NOTES: The hash is achieved by exclusive ORing 4 byte | | 255 | * NOTES: The hash is achieved by exclusive ORing 4 byte |
256 | * quantities. | | 256 | * quantities. |
257 | */ | | 257 | */ |
258 | u_long | | 258 | u_long |
259 | iso_hashchar(void *bufv, int len) | | 259 | iso_hashchar(void *bufv, int len) |
260 | { | | 260 | { |
261 | char *buf = bufv; | | 261 | char *buf = bufv; |
262 | u_long h = 0; | | 262 | u_long h = 0; |
263 | int i; | | 263 | int i; |
264 | | | 264 | |
265 | for (i = 0; i < len; i += 4) { | | 265 | for (i = 0; i < len; i += 4) { |
266 | u_long l = 0; | | 266 | u_long l = 0; |
267 | | | 267 | |
268 | if ((len - i) < 4) { | | 268 | if ((len - i) < 4) { |
269 | /* buffer not multiple of 4 */ | | 269 | /* buffer not multiple of 4 */ |
270 | switch (len - i) { | | 270 | switch (len - i) { |
271 | case 3: | | 271 | case 3: |
272 | l |= buf[i + 2] << 8; | | 272 | l |= buf[i + 2] << 8; |
273 | case 2: | | 273 | case 2: |
274 | l |= buf[i + 1] << 16; | | 274 | l |= buf[i + 1] << 16; |
275 | case 1: | | 275 | case 1: |
276 | l |= buf[i] << 24; | | 276 | l |= buf[i] << 24; |
277 | break; | | 277 | break; |
278 | default: | | 278 | default: |
279 | printf("iso_hashchar: unexpected value x%x\n", len - i); | | 279 | printf("iso_hashchar: unexpected value x%x\n", len - i); |
280 | break; | | 280 | break; |
281 | } | | 281 | } |
282 | } else { | | 282 | } else { |
283 | l |= buf[i] << 24; | | 283 | l |= buf[i] << 24; |
284 | l |= buf[i + 1] << 16; | | 284 | l |= buf[i + 1] << 16; |
285 | l |= buf[i + 2] << 8; | | 285 | l |= buf[i + 2] << 8; |
286 | l |= buf[i + 3]; | | 286 | l |= buf[i + 3]; |
287 | } | | 287 | } |
288 | | | 288 | |
289 | h ^= l; | | 289 | h ^= l; |
290 | } | | 290 | } |
291 | | | 291 | |
292 | h ^= (u_long) (len % 4); | | 292 | h ^= (u_long) (len % 4); |
293 | | | 293 | |
294 | return (h); | | 294 | return (h); |
295 | } | | 295 | } |
296 | | | 296 | |
297 | #ifdef notdef | | 297 | #ifdef notdef |
298 | /* | | 298 | /* |
299 | * FUNCTION: iso_hash | | 299 | * FUNCTION: iso_hash |
300 | * | | 300 | * |
301 | * PURPOSE: Fill in fields of afhash structure based upon addr | | 301 | * PURPOSE: Fill in fields of afhash structure based upon addr |
302 | * passed. | | 302 | * passed. |
303 | * | | 303 | * |
304 | * RETURNS: none | | 304 | * RETURNS: none |
305 | * | | 305 | * |
306 | * SIDE EFFECTS: | | 306 | * SIDE EFFECTS: |
307 | * | | 307 | * |
308 | * NOTES: | | 308 | * NOTES: |
309 | */ | | 309 | */ |
310 | void | | 310 | void |
311 | iso_hash( | | 311 | iso_hash( |
312 | struct sockaddr_iso *siso, /* address to perform hash on */ | | 312 | struct sockaddr_iso *siso, /* address to perform hash on */ |
313 | struct afhash *hp) /* RETURN: hash info here */ | | 313 | struct afhash *hp) /* RETURN: hash info here */ |
314 | { | | 314 | { |
315 | u_long buf[sizeof(struct sockaddr_iso) / 4 + 1]; | | 315 | u_long buf[sizeof(struct sockaddr_iso) / 4 + 1]; |
316 | int bufsize; | | 316 | int bufsize; |
317 | | | 317 | |
318 | | | 318 | |
319 | memset(buf, 0, sizeof(buf)); | | 319 | memset(buf, 0, sizeof(buf)); |
320 | | | 320 | |
321 | bufsize = iso_netof(&siso->siso_addr, buf); | | 321 | bufsize = iso_netof(&siso->siso_addr, buf); |
322 | hp->afh_nethash = iso_hashchar((void *) buf, bufsize); | | 322 | hp->afh_nethash = iso_hashchar((void *) buf, bufsize); |
323 | | | 323 | |
324 | #ifdef ARGO_DEBUG | | 324 | #ifdef ARGO_DEBUG |
325 | if (argo_debug[D_ROUTE]) { | | 325 | if (argo_debug[D_ROUTE]) { |
326 | printf("iso_hash: iso_netof: bufsize = %d\n", bufsize); | | 326 | printf("iso_hash: iso_netof: bufsize = %d\n", bufsize); |
327 | } | | 327 | } |
328 | #endif | | 328 | #endif |
329 | | | 329 | |
330 | hp->afh_hosthash = iso_hashchar((void *) & siso->siso_addr, | | 330 | hp->afh_hosthash = iso_hashchar((void *) & siso->siso_addr, |
331 | siso->siso_addr.isoa_len); | | 331 | siso->siso_addr.isoa_len); |
332 | | | 332 | |
333 | #ifdef ARGO_DEBUG | | 333 | #ifdef ARGO_DEBUG |
334 | if (argo_debug[D_ROUTE]) { | | 334 | if (argo_debug[D_ROUTE]) { |
335 | printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n", | | 335 | printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n", |
336 | clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash, | | 336 | clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash, |
337 | hp->afh_hosthash); | | 337 | hp->afh_hosthash); |
338 | } | | 338 | } |
339 | #endif | | 339 | #endif |
340 | } | | 340 | } |
341 | /* | | 341 | /* |
342 | * FUNCTION: iso_netof | | 342 | * FUNCTION: iso_netof |
343 | * | | 343 | * |
344 | * PURPOSE: Extract the network portion of the iso address. | | 344 | * PURPOSE: Extract the network portion of the iso address. |
345 | * The network portion of the iso address varies depending | | 345 | * The network portion of the iso address varies depending |
346 | * on the type of address. The network portion of the | | 346 | * on the type of address. The network portion of the |
347 | * address will include the IDP. The network portion is: | | 347 | * address will include the IDP. The network portion is: |
348 | * | | 348 | * |
349 | * TYPE DESC | | 349 | * TYPE DESC |
350 | * t37 The AFI and x.121 (IDI) | | 350 | * t37 The AFI and x.121 (IDI) |
351 | * osinet The AFI, orgid, snetid | | 351 | * osinet The AFI, orgid, snetid |
352 | * rfc986 The AFI, vers and network part | | 352 | * rfc986 The AFI, vers and network part |
353 | * of internet address. | | 353 | * of internet address. |
354 | * | | 354 | * |
355 | * RETURNS: number of bytes placed into buf. | | 355 | * RETURNS: number of bytes placed into buf. |
356 | * | | 356 | * |
357 | * SIDE EFFECTS: | | 357 | * SIDE EFFECTS: |
358 | * | | 358 | * |
359 | * NOTES: Buf is assumed to be big enough | | 359 | * NOTES: Buf is assumed to be big enough |
360 | */ | | 360 | */ |
361 | u_int | | 361 | u_int |
362 | iso_netof( | | 362 | iso_netof( |
363 | struct iso_addr *isoa, /* address */ | | 363 | struct iso_addr *isoa, /* address */ |
364 | void * buf) /* RESULT: network portion of address here */ | | 364 | void * buf) /* RESULT: network portion of address here */ |
365 | { | | 365 | { |
366 | u_int len = 1;/* length of afi */ | | 366 | u_int len = 1;/* length of afi */ |
367 | | | 367 | |
368 | switch (isoa->isoa_afi) { | | 368 | switch (isoa->isoa_afi) { |
369 | case AFI_37: | | 369 | case AFI_37: |
370 | /* | | 370 | /* |
371 | * Due to classic x.25 tunnel vision, there is no | | 371 | * Due to classic x.25 tunnel vision, there is no |
372 | * net portion of an x.121 address. For our purposes | | 372 | * net portion of an x.121 address. For our purposes |
373 | * the AFI will do, so that all x.25 -type addresses | | 373 | * the AFI will do, so that all x.25 -type addresses |
374 | * map to the single x.25 SNPA. (Cannot have more than | | 374 | * map to the single x.25 SNPA. (Cannot have more than |
375 | * one, obviously). | | 375 | * one, obviously). |
376 | */ | | 376 | */ |
377 | | | 377 | |
378 | break; | | 378 | break; |
379 | | | 379 | |
380 | /* case AFI_OSINET: */ | | 380 | /* case AFI_OSINET: */ |
381 | case AFI_RFC986:{ | | 381 | case AFI_RFC986:{ |
382 | u_short idi; /* value of idi */ | | 382 | u_short idi; /* value of idi */ |
383 | | | 383 | |
384 | /* osinet and rfc986 have idi in the same place */ | | 384 | /* osinet and rfc986 have idi in the same place */ |
385 | CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi); | | 385 | CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi); |
386 | | | 386 | |
387 | if (idi == IDI_OSINET) | | 387 | if (idi == IDI_OSINET) |
388 | /* | | 388 | /* |
389 | * Network portion of OSINET address can only | | 389 | * Network portion of OSINET address can only |
390 | * be the IDI. Clearly, with one x25 interface, | | 390 | * be the IDI. Clearly, with one x25 interface, |
391 | * one could get to several orgids, and | | 391 | * one could get to several orgids, and |
392 | * several snetids. | | 392 | * several snetids. |
393 | */ | | 393 | */ |
394 | #if 0 | | 394 | #if 0 |
395 | len += (ADDROSINET_IDI_LEN + | | 395 | len += (ADDROSINET_IDI_LEN + |
396 | OVLOSINET_ORGID_LEN + | | 396 | OVLOSINET_ORGID_LEN + |
397 | OVLOSINET_SNETID_LEN); | | 397 | OVLOSINET_SNETID_LEN); |
398 | #endif | | 398 | #endif |
399 | len += ADDROSINET_IDI_LEN; | | 399 | len += ADDROSINET_IDI_LEN; |
400 | else if (idi == IDI_RFC986) { | | 400 | else if (idi == IDI_RFC986) { |
401 | struct ovl_rfc986 *o986 = | | 401 | struct ovl_rfc986 *o986 = |
402 | (struct ovl_rfc986 *) isoa; | | 402 | (struct ovl_rfc986 *) isoa; |
403 | | | 403 | |
404 | /* | | 404 | /* |
405 | * bump len to include idi and version (1 | | 405 | * bump len to include idi and version (1 |
406 | * byte) | | 406 | * byte) |
407 | */ | | 407 | */ |
408 | len += ADDRRFC986_IDI_LEN + 1; | | 408 | len += ADDRRFC986_IDI_LEN + 1; |
409 | | | 409 | |
410 | #ifdef ARGO_DEBUG | | 410 | #ifdef ARGO_DEBUG |
411 | if (argo_debug[D_ROUTE]) { | | 411 | if (argo_debug[D_ROUTE]) { |
412 | printf("iso_netof: isoa "); | | 412 | printf("iso_netof: isoa "); |
413 | dump_buf(isoa, sizeof(*isoa)); | | 413 | dump_buf(isoa, sizeof(*isoa)); |
414 | printf("iso_netof: inetaddr 0x%x ", | | 414 | printf("iso_netof: inetaddr 0x%x ", |
415 | inetaddr); | | 415 | inetaddr); |
416 | } | | 416 | } |
417 | #endif | | 417 | #endif |
418 | | | 418 | |
419 | /* | | 419 | /* |
420 | * bump len by size of network portion of | | 420 | * bump len by size of network portion of |
421 | * inet address | | 421 | * inet address |
422 | */ | | 422 | */ |
423 | if (IN_CLASSA(o986->o986_inetaddr)) { | | 423 | if (IN_CLASSA(o986->o986_inetaddr)) { |
424 | len += 4 - IN_CLASSA_NSHIFT / 8; | | 424 | len += 4 - IN_CLASSA_NSHIFT / 8; |
425 | #ifdef ARGO_DEBUG | | 425 | #ifdef ARGO_DEBUG |
426 | if (argo_debug[D_ROUTE]) { | | 426 | if (argo_debug[D_ROUTE]) { |
427 | printf("iso_netof: class A net len is now %d\n", len); | | 427 | printf("iso_netof: class A net len is now %d\n", len); |
428 | } | | 428 | } |
429 | #endif | | 429 | #endif |
430 | } else if (IN_CLASSB(o986->o986_inetaddr)) { | | 430 | } else if (IN_CLASSB(o986->o986_inetaddr)) { |
431 | len += 4 - IN_CLASSB_NSHIFT / 8; | | 431 | len += 4 - IN_CLASSB_NSHIFT / 8; |
432 | #ifdef ARGO_DEBUG | | 432 | #ifdef ARGO_DEBUG |
433 | if (argo_debug[D_ROUTE]) { | | 433 | if (argo_debug[D_ROUTE]) { |
434 | printf("iso_netof: class B net len is now %d\n", len); | | 434 | printf("iso_netof: class B net len is now %d\n", len); |
435 | } | | 435 | } |
436 | #endif | | 436 | #endif |
437 | } else { | | 437 | } else { |
438 | len += 4 - IN_CLASSC_NSHIFT / 8; | | 438 | len += 4 - IN_CLASSC_NSHIFT / 8; |
439 | #ifdef ARGO_DEBUG | | 439 | #ifdef ARGO_DEBUG |
440 | if (argo_debug[D_ROUTE]) { | | 440 | if (argo_debug[D_ROUTE]) { |
441 | printf("iso_netof: class C net len is now %d\n", len); | | 441 | printf("iso_netof: class C net len is now %d\n", len); |
442 | } | | 442 | } |
443 | #endif | | 443 | #endif |
444 | } | | 444 | } |
445 | } else | | 445 | } else |
446 | len = 0; | | 446 | len = 0; |
447 | } break; | | 447 | } break; |
448 | | | 448 | |
449 | default: | | 449 | default: |
450 | len = 0; | | 450 | len = 0; |
451 | } | | 451 | } |
452 | | | 452 | |
453 | memcpy(buf, (void *) isoa, len); | | 453 | memcpy(buf, (void *) isoa, len); |
454 | #ifdef ARGO_DEBUG | | 454 | #ifdef ARGO_DEBUG |
455 | if (argo_debug[D_ROUTE]) { | | 455 | if (argo_debug[D_ROUTE]) { |
456 | printf("iso_netof: isoa "); | | 456 | printf("iso_netof: isoa "); |
457 | dump_buf(isoa, len); | | 457 | dump_buf(isoa, len); |
458 | printf("iso_netof: net "); | | 458 | printf("iso_netof: net "); |
459 | dump_buf(buf, len); | | 459 | dump_buf(buf, len); |
460 | } | | 460 | } |
461 | #endif | | 461 | #endif |
462 | return len; | | 462 | return len; |
463 | } | | 463 | } |
464 | #endif /* notdef */ | | 464 | #endif /* notdef */ |
465 | /* | | 465 | /* |
466 | * Generic iso control operations (ioctl's). | | 466 | * Generic iso control operations (ioctl's). |
467 | * Ifp is 0 if not an interface-specific ioctl. | | 467 | * Ifp is 0 if not an interface-specific ioctl. |
468 | */ | | 468 | */ |
469 | /* ARGSUSED */ | | 469 | /* ARGSUSED */ |
470 | int | | 470 | int |
471 | iso_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp, | | 471 | iso_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp, |
472 | struct lwp *l) | | 472 | struct lwp *l) |
473 | { | | 473 | { |
474 | struct iso_ifreq *ifr = (struct iso_ifreq *) data; | | 474 | struct iso_ifreq *ifr = (struct iso_ifreq *) data; |
475 | struct iso_ifaddr *ia = 0; | | 475 | struct iso_ifaddr *ia = 0; |
476 | struct iso_aliasreq *ifra = (struct iso_aliasreq *) data; | | 476 | struct iso_aliasreq *ifra = (struct iso_aliasreq *) data; |
477 | int error, hostIsNew, maskIsNew; | | 477 | int error, hostIsNew, maskIsNew; |
478 | | | 478 | |
479 | /* | | 479 | /* |
480 | * Find address for this interface, if it exists. | | 480 | * Find address for this interface, if it exists. |
481 | */ | | 481 | */ |
482 | if (ifp) | | 482 | if (ifp) |
483 | TAILQ_FOREACH(ia, &iso_ifaddr, ia_list) | | 483 | TAILQ_FOREACH(ia, &iso_ifaddr, ia_list) |
484 | if (ia->ia_ifp == ifp) | | 484 | if (ia->ia_ifp == ifp) |
485 | break; | | 485 | break; |
486 | | | 486 | |
487 | switch (cmd) { | | 487 | switch (cmd) { |
488 | | | 488 | |
489 | case SIOCAIFADDR_ISO: | | 489 | case SIOCAIFADDR_ISO: |
490 | case SIOCDIFADDR_ISO: | | 490 | case SIOCDIFADDR_ISO: |
491 | if (ifra->ifra_addr.siso_family == AF_ISO) | | 491 | if (ifra->ifra_addr.siso_family == AF_ISO) |
492 | for (; ia != 0; ia = ia->ia_list.tqe_next) { | | 492 | for (; ia != 0; ia = ia->ia_list.tqe_next) { |
493 | if (ia->ia_ifp == ifp && | | 493 | if (ia->ia_ifp == ifp && |
494 | SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) | | 494 | SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) |
495 | break; | | 495 | break; |
496 | } | | 496 | } |
497 | if (cmd == SIOCDIFADDR_ISO && ia == 0) | | 497 | if (cmd == SIOCDIFADDR_ISO && ia == 0) |
498 | return (EADDRNOTAVAIL); | | 498 | return (EADDRNOTAVAIL); |
499 | /* FALLTHROUGH */ | | 499 | /* FALLTHROUGH */ |
500 | #if 0 | | 500 | #if 0 |
501 | case SIOCSIFADDR: | | 501 | case SIOCSIFADDR: |
502 | case SIOCSIFNETMASK: | | 502 | case SIOCSIFNETMASK: |
503 | case SIOCSIFDSTADDR: | | 503 | case SIOCSIFDSTADDR: |
504 | #endif | | 504 | #endif |
505 | if (l == 0 || kauth_authorize_network(l->l_cred, | | 505 | if (l == 0 || kauth_authorize_network(l->l_cred, |
506 | KAUTH_NETWORK_INTERFACE, | | 506 | KAUTH_NETWORK_INTERFACE, |
507 | KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, | | 507 | KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, |
508 | NULL)) | | 508 | NULL)) |
509 | return (EPERM); | | 509 | return (EPERM); |
510 | | | 510 | |
511 | if (ifp == 0) | | 511 | if (ifp == 0) |
512 | panic("iso_control"); | | 512 | panic("iso_control"); |
513 | if (ia == 0) { | | 513 | if (ia == 0) { |
514 | ia = malloc(sizeof(*ia), | | 514 | ia = malloc(sizeof(*ia), |
515 | M_IFADDR, M_WAITOK|M_ZERO); | | 515 | M_IFADDR, M_WAITOK|M_ZERO); |
516 | if (ia == 0) | | 516 | if (ia == 0) |
517 | return (ENOBUFS); | | 517 | return (ENOBUFS); |
518 | TAILQ_INSERT_TAIL(&iso_ifaddr, ia, ia_list); | | 518 | TAILQ_INSERT_TAIL(&iso_ifaddr, ia, ia_list); |
519 | IFAREF(&ia->ia_ifa); | | 519 | IFAREF(&ia->ia_ifa); |
520 | ifa_insert(ifp, &ia->ia_ifa); | | 520 | ifa_insert(ifp, &ia->ia_ifa); |
521 | ia->ia_ifa.ifa_addr = sisotosa(&ia->ia_addr); | | 521 | ia->ia_ifa.ifa_addr = sisotosa(&ia->ia_addr); |
522 | ia->ia_ifa.ifa_dstaddr = sisotosa(&ia->ia_dstaddr); | | 522 | ia->ia_ifa.ifa_dstaddr = sisotosa(&ia->ia_dstaddr); |
523 | ia->ia_ifa.ifa_netmask = sisotosa(&ia->ia_sockmask); | | 523 | ia->ia_ifa.ifa_netmask = sisotosa(&ia->ia_sockmask); |
524 | ia->ia_ifp = ifp; | | 524 | ia->ia_ifp = ifp; |
525 | if ((ifp->if_flags & IFF_LOOPBACK) == 0) | | 525 | if ((ifp->if_flags & IFF_LOOPBACK) == 0) |
526 | iso_interfaces++; | | 526 | iso_interfaces++; |
527 | } | | 527 | } |
528 | break; | | 528 | break; |
529 | | | 529 | |
530 | case SIOCGIFADDR_ISO: | | 530 | case SIOCGIFADDR_ISO: |
531 | case SIOCGIFNETMASK_ISO: | | 531 | case SIOCGIFNETMASK_ISO: |
532 | case SIOCGIFDSTADDR_ISO: | | 532 | case SIOCGIFDSTADDR_ISO: |
533 | if (ia == 0) | | 533 | if (ia == 0) |
534 | return (EADDRNOTAVAIL); | | 534 | return (EADDRNOTAVAIL); |
535 | break; | | 535 | break; |
536 | } | | 536 | } |
537 | switch (cmd) { | | 537 | switch (cmd) { |
538 | | | 538 | |
539 | case SIOCGIFADDR_ISO: | | 539 | case SIOCGIFADDR_ISO: |
540 | ifr->ifr_Addr = ia->ia_addr; | | 540 | ifr->ifr_Addr = ia->ia_addr; |
541 | break; | | 541 | break; |
542 | | | 542 | |
543 | case SIOCGIFDSTADDR_ISO: | | 543 | case SIOCGIFDSTADDR_ISO: |
544 | if ((ifp->if_flags & IFF_POINTOPOINT) == 0) | | 544 | if ((ifp->if_flags & IFF_POINTOPOINT) == 0) |
545 | return (EINVAL); | | 545 | return (EINVAL); |
546 | ifr->ifr_Addr = ia->ia_dstaddr; | | 546 | ifr->ifr_Addr = ia->ia_dstaddr; |
547 | break; | | 547 | break; |
548 | | | 548 | |
549 | case SIOCGIFNETMASK_ISO: | | 549 | case SIOCGIFNETMASK_ISO: |
550 | ifr->ifr_Addr = ia->ia_sockmask; | | 550 | ifr->ifr_Addr = ia->ia_sockmask; |
551 | break; | | 551 | break; |
552 | | | 552 | |
553 | case SIOCAIFADDR_ISO: | | 553 | case SIOCAIFADDR_ISO: |
554 | maskIsNew = 0; | | 554 | maskIsNew = 0; |
555 | hostIsNew = 1; | | 555 | hostIsNew = 1; |
556 | error = 0; | | 556 | error = 0; |
557 | if (ia->ia_addr.siso_family == AF_ISO) { | | 557 | if (ia->ia_addr.siso_family == AF_ISO) { |
558 | if (ifra->ifra_addr.siso_len == 0) { | | 558 | if (ifra->ifra_addr.siso_len == 0) { |
559 | ifra->ifra_addr = ia->ia_addr; | | 559 | ifra->ifra_addr = ia->ia_addr; |
560 | hostIsNew = 0; | | 560 | hostIsNew = 0; |
561 | } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) | | 561 | } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) |
562 | hostIsNew = 0; | | 562 | hostIsNew = 0; |
563 | } | | 563 | } |
564 | if (ifra->ifra_mask.siso_len) { | | 564 | if (ifra->ifra_mask.siso_len) { |
565 | iso_ifscrub(ifp, ia); | | 565 | iso_ifscrub(ifp, ia); |
566 | ia->ia_sockmask = ifra->ifra_mask; | | 566 | ia->ia_sockmask = ifra->ifra_mask; |
567 | maskIsNew = 1; | | 567 | maskIsNew = 1; |
568 | } | | 568 | } |
569 | if ((ifp->if_flags & IFF_POINTOPOINT) && | | 569 | if ((ifp->if_flags & IFF_POINTOPOINT) && |
570 | (ifra->ifra_dstaddr.siso_family == AF_ISO)) { | | 570 | (ifra->ifra_dstaddr.siso_family == AF_ISO)) { |
571 | iso_ifscrub(ifp, ia); | | 571 | iso_ifscrub(ifp, ia); |
572 | ia->ia_dstaddr = ifra->ifra_dstaddr; | | 572 | ia->ia_dstaddr = ifra->ifra_dstaddr; |
573 | maskIsNew = 1; /* We lie; but the effect's the same */ | | 573 | maskIsNew = 1; /* We lie; but the effect's the same */ |
574 | } | | 574 | } |
575 | if (ifra->ifra_addr.siso_family == AF_ISO && | | 575 | if (ifra->ifra_addr.siso_family == AF_ISO && |
576 | (hostIsNew || maskIsNew)) | | 576 | (hostIsNew || maskIsNew)) |
577 | error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0); | | 577 | error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0); |
578 | if (ifra->ifra_snpaoffset) | | 578 | if (ifra->ifra_snpaoffset) |
579 | ia->ia_snpaoffset = ifra->ifra_snpaoffset; | | 579 | ia->ia_snpaoffset = ifra->ifra_snpaoffset; |
580 | return (error); | | 580 | return (error); |
581 | | | 581 | |
582 | case SIOCDIFADDR_ISO: | | 582 | case SIOCDIFADDR_ISO: |
583 | iso_purgeaddr(&ia->ia_ifa); | | 583 | iso_purgeaddr(&ia->ia_ifa); |
584 | break; | | 584 | break; |
585 | | | 585 | |
586 | #define cmdbyte(x) (((x) >> 8) & 0xff) | | 586 | #define cmdbyte(x) (((x) >> 8) & 0xff) |
587 | default: | | 587 | default: |
588 | if (cmdbyte(cmd) == 'a') | | 588 | if (cmdbyte(cmd) == 'a') |
589 | return (snpac_ioctl(so, cmd, data, l)); | | 589 | return (snpac_ioctl(so, cmd, data, l)); |
590 | return ENOTTY; | | 590 | return ENOTTY; |
591 | } | | 591 | } |
592 | return (0); | | 592 | return (0); |
593 | } | | 593 | } |
594 | | | 594 | |
595 | void | | 595 | void |
596 | iso_purgeaddr(struct ifaddr *ifa) | | 596 | iso_purgeaddr(struct ifaddr *ifa) |
597 | { | | 597 | { |
598 | struct ifnet *ifp = ifa->ifa_ifp; | | 598 | struct ifnet *ifp = ifa->ifa_ifp; |
599 | struct iso_ifaddr *ia = (void *) ifa; | | 599 | struct iso_ifaddr *ia = (void *) ifa; |
600 | | | 600 | |
601 | iso_ifscrub(ifp, ia); | | 601 | iso_ifscrub(ifp, ia); |
602 | ifa_remove(ifp, &ia->ia_ifa); | | 602 | ifa_remove(ifp, &ia->ia_ifa); |
603 | TAILQ_REMOVE(&iso_ifaddr, ia, ia_list); | | 603 | TAILQ_REMOVE(&iso_ifaddr, ia, ia_list); |
604 | IFAFREE(&ia->ia_ifa); | | 604 | IFAFREE(&ia->ia_ifa); |
605 | } | | 605 | } |
606 | | | 606 | |
607 | void | | 607 | void |
608 | iso_purgeif(struct ifnet *ifp) | | 608 | iso_purgeif(struct ifnet *ifp) |
609 | { | | 609 | { |
610 | if_purgeaddrs(ifp, AF_ISO, iso_purgeaddr); | | 610 | if_purgeaddrs(ifp, AF_ISO, iso_purgeaddr); |
611 | } | | 611 | } |
612 | | | 612 | |
613 | /* | | 613 | /* |
614 | * Delete any existing route for an interface. | | 614 | * Delete any existing route for an interface. |
615 | */ | | 615 | */ |
616 | void | | 616 | void |
617 | iso_ifscrub(struct ifnet *ifp, struct iso_ifaddr *ia) | | 617 | iso_ifscrub(struct ifnet *ifp, struct iso_ifaddr *ia) |
618 | { | | 618 | { |
619 | int nsellength = ia->ia_addr.siso_tlen; | | 619 | int nsellength = ia->ia_addr.siso_tlen; |
620 | if ((ia->ia_flags & IFA_ROUTE) == 0) | | 620 | if ((ia->ia_flags & IFA_ROUTE) == 0) |
621 | return; | | 621 | return; |
622 | ia->ia_addr.siso_tlen = 0; | | 622 | ia->ia_addr.siso_tlen = 0; |
623 | if (ifp->if_flags & IFF_LOOPBACK) | | 623 | if (ifp->if_flags & IFF_LOOPBACK) |
624 | rtinit(&(ia->ia_ifa), (int) RTM_DELETE, RTF_HOST); | | 624 | rtinit(&(ia->ia_ifa), (int) RTM_DELETE, RTF_HOST); |
625 | else if (ifp->if_flags & IFF_POINTOPOINT) | | 625 | else if (ifp->if_flags & IFF_POINTOPOINT) |
626 | rtinit(&(ia->ia_ifa), (int) RTM_DELETE, RTF_HOST); | | 626 | rtinit(&(ia->ia_ifa), (int) RTM_DELETE, RTF_HOST); |
627 | else { | | 627 | else { |
628 | rtinit(&(ia->ia_ifa), (int) RTM_DELETE, 0); | | 628 | rtinit(&(ia->ia_ifa), (int) RTM_DELETE, 0); |
629 | } | | 629 | } |
630 | ia->ia_addr.siso_tlen = nsellength; | | 630 | ia->ia_addr.siso_tlen = nsellength; |
631 | ia->ia_flags &= ~IFA_ROUTE; | | 631 | ia->ia_flags &= ~IFA_ROUTE; |
632 | } | | 632 | } |
633 | | | 633 | |
634 | /* | | 634 | /* |
635 | * Initialize an interface's internet address | | 635 | * Initialize an interface's internet address |
636 | * and routing table entry. | | 636 | * and routing table entry. |
637 | */ | | 637 | */ |
638 | int | | 638 | int |
639 | iso_ifinit(struct ifnet *ifp, struct iso_ifaddr *ia, struct sockaddr_iso *siso, | | 639 | iso_ifinit(struct ifnet *ifp, struct iso_ifaddr *ia, struct sockaddr_iso *siso, |
640 | int scrub) | | 640 | int scrub) |
641 | { | | 641 | { |
642 | struct sockaddr_iso oldaddr; | | 642 | struct sockaddr_iso oldaddr; |
643 | int s = splnet(), error, nsellength; | | 643 | int s = splnet(), error, nsellength; |
644 | | | 644 | |
645 | oldaddr = ia->ia_addr; | | 645 | oldaddr = ia->ia_addr; |
646 | ia->ia_addr = *siso; | | 646 | ia->ia_addr = *siso; |
647 | /* | | 647 | /* |
648 | * Give the interface a chance to initialize | | 648 | * Give the interface a chance to initialize |
649 | * if this is its first address, | | 649 | * if this is its first address, |
650 | * and to validate the address if necessary. | | 650 | * and to validate the address if necessary. |
651 | */ | | 651 | */ |
652 | if ((error = (*ifp->if_ioctl)(ifp, SIOCINITIFADDR, ia)) != 0) { | | 652 | if ((error = (*ifp->if_ioctl)(ifp, SIOCINITIFADDR, ia)) != 0) { |
653 | splx(s); | | 653 | splx(s); |
654 | ia->ia_addr = oldaddr; | | 654 | ia->ia_addr = oldaddr; |
655 | return (error); | | 655 | return (error); |
656 | } | | 656 | } |
657 | if (scrub) { | | 657 | if (scrub) { |
658 | ia->ia_ifa.ifa_addr = sisotosa(&oldaddr); | | 658 | ia->ia_ifa.ifa_addr = sisotosa(&oldaddr); |
659 | iso_ifscrub(ifp, ia); | | 659 | iso_ifscrub(ifp, ia); |
660 | ia->ia_ifa.ifa_addr = sisotosa(&ia->ia_addr); | | 660 | ia->ia_ifa.ifa_addr = sisotosa(&ia->ia_addr); |
661 | } | | 661 | } |
662 | /* | | 662 | /* |
663 | * XXX -- The following is here temporarily out of laziness in not | | 663 | * XXX -- The following is here temporarily out of laziness in not |
664 | * changing every ethernet driver's if_ioctl routine | | 664 | * changing every ethernet driver's if_ioctl routine |
665 | * | | 665 | * |
666 | * XXX extract llc_ifinit() and call from ether_ioctl(), | | 666 | * XXX extract llc_ifinit() and call from ether_ioctl(), |
667 | * XXX fddi_ioctl(). --dyoung | | 667 | * XXX fddi_ioctl(). --dyoung |
668 | * | | 668 | * |
669 | */ | | 669 | */ |
670 | if (ifp->if_type == IFT_ETHER || ifp->if_type == IFT_FDDI) { | | 670 | if (ifp->if_type == IFT_ETHER || ifp->if_type == IFT_FDDI) { |
671 | ia->ia_ifa.ifa_rtrequest = llc_rtrequest; | | 671 | ia->ia_ifa.ifa_rtrequest = llc_rtrequest; |
672 | ia->ia_ifa.ifa_flags |= RTF_CLONING; | | 672 | ia->ia_ifa.ifa_flags |= RTF_CLONING; |
673 | } | | 673 | } |
674 | /* | | 674 | /* |
675 | * Add route for the network. | | 675 | * Add route for the network. |
676 | */ | | 676 | */ |
677 | nsellength = ia->ia_addr.siso_tlen; | | 677 | nsellength = ia->ia_addr.siso_tlen; |
678 | ia->ia_addr.siso_tlen = 0; | | 678 | ia->ia_addr.siso_tlen = 0; |
679 | if (ifp->if_flags & IFF_LOOPBACK) { | | 679 | if (ifp->if_flags & IFF_LOOPBACK) { |
680 | ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; | | 680 | ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; |
681 | error = rtinit(&(ia->ia_ifa), (int) RTM_ADD, RTF_HOST | RTF_UP); | | 681 | error = rtinit(&(ia->ia_ifa), (int) RTM_ADD, RTF_HOST | RTF_UP); |
682 | } else if (ifp->if_flags & IFF_POINTOPOINT && | | 682 | } else if (ifp->if_flags & IFF_POINTOPOINT && |
683 | ia->ia_dstaddr.siso_family == AF_ISO) | | 683 | ia->ia_dstaddr.siso_family == AF_ISO) |
684 | error = rtinit(&(ia->ia_ifa), (int) RTM_ADD, RTF_HOST | RTF_UP); | | 684 | error = rtinit(&(ia->ia_ifa), (int) RTM_ADD, RTF_HOST | RTF_UP); |
685 | else { | | 685 | else { |
686 | rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr, | | 686 | rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr, |
687 | ia->ia_ifa.ifa_netmask); | | 687 | ia->ia_ifa.ifa_netmask); |
688 | ia->ia_dstaddr.siso_nlen = | | 688 | ia->ia_dstaddr.siso_nlen = |
689 | min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6)); | | 689 | min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6)); |
690 | error = rtinit(&(ia->ia_ifa), (int) RTM_ADD, RTF_UP); | | 690 | error = rtinit(&(ia->ia_ifa), (int) RTM_ADD, RTF_UP); |
691 | } | | 691 | } |
692 | ia->ia_addr.siso_tlen = nsellength; | | 692 | ia->ia_addr.siso_tlen = nsellength; |
693 | ia->ia_flags |= IFA_ROUTE; | | 693 | ia->ia_flags |= IFA_ROUTE; |
694 | splx(s); | | 694 | splx(s); |
695 | return (error); | | 695 | return (error); |
696 | } | | 696 | } |
697 | #ifdef notdef | | 697 | #ifdef notdef |
698 | | | 698 | |
699 | struct ifaddr * | | 699 | struct ifaddr * |
700 | iso_ifwithidi(struct sockaddr *addr) | | 700 | iso_ifwithidi(struct sockaddr *addr) |
701 | { | | 701 | { |
702 | struct ifnet *ifp; | | 702 | struct ifnet *ifp; |
703 | struct ifaddr *ifa; | | 703 | struct ifaddr *ifa; |
704 | u_int af = addr->sa_family; | | 704 | u_int af = addr->sa_family; |
705 | | | 705 | |
706 | if (af != AF_ISO) | | 706 | if (af != AF_ISO) |
707 | return (0); | | 707 | return (0); |
708 | #ifdef ARGO_DEBUG | | 708 | #ifdef ARGO_DEBUG |
709 | if (argo_debug[D_ROUTE]) { | | 709 | if (argo_debug[D_ROUTE]) { |
710 | printf(">>> iso_ifwithidi addr\n"); | | 710 | printf(">>> iso_ifwithidi addr\n"); |
711 | dump_isoaddr(satosiso(addr)); | | 711 | dump_isoaddr(satosiso(addr)); |
712 | printf("\n"); | | 712 | printf("\n"); |
713 | } | | 713 | } |
714 | #endif | | 714 | #endif |
715 | TAILQ_FOREACH(ifp, &ifnet, if_list) { | | 715 | TAILQ_FOREACH(ifp, &ifnet, if_list) { |
716 | #ifdef ARGO_DEBUG | | 716 | #ifdef ARGO_DEBUG |
717 | if (argo_debug[D_ROUTE]) { | | 717 | if (argo_debug[D_ROUTE]) { |
718 | printf("iso_ifwithidi ifnet %s\n", ifp->if_name); | | 718 | printf("iso_ifwithidi ifnet %s\n", ifp->if_name); |
719 | } | | 719 | } |
720 | #endif | | 720 | #endif |
721 | IFADDR_FOREACH(ifa, ifp) { | | 721 | IFADDR_FOREACH(ifa, ifp) { |
722 | #ifdef ARGO_DEBUG | | 722 | #ifdef ARGO_DEBUG |
723 | if (argo_debug[D_ROUTE]) { | | 723 | if (argo_debug[D_ROUTE]) { |
724 | printf("iso_ifwithidi address "); | | 724 | printf("iso_ifwithidi address "); |
725 | dump_isoaddr(satosiso(ifa->ifa_addr)); | | 725 | dump_isoaddr(satosiso(ifa->ifa_addr)); |
726 | } | | 726 | } |
727 | #endif | | 727 | #endif |
728 | if (ifa->ifa_addr->sa_family != addr->sa_family) | | 728 | if (ifa->ifa_addr->sa_family != addr->sa_family) |
729 | continue; | | 729 | continue; |
730 | | | 730 | |
731 | #ifdef ARGO_DEBUG | | 731 | #ifdef ARGO_DEBUG |
732 | if (argo_debug[D_ROUTE]) { | | 732 | if (argo_debug[D_ROUTE]) { |
733 | printf(" af same, args to iso_eqtype:\n"); | | 733 | printf(" af same, args to iso_eqtype:\n"); |
734 | printf("0x%x ", satosiso(ifa->ifa_addr)->siso_addr); | | 734 | printf("0x%x ", satosiso(ifa->ifa_addr)->siso_addr); |
735 | printf(" 0x%x\n", | | 735 | printf(" 0x%x\n", |
736 | &satosiso(addr)->siso_addr)); | | 736 | &satosiso(addr)->siso_addr); |
737 | } | | 737 | } |
738 | #endif | | 738 | #endif |
739 | | | 739 | |
740 | if (iso_eqtype(&satosiso(ifa->ifa_addr)->siso_addr, | | 740 | if (iso_eqtype(&satosiso(ifa->ifa_addr)->siso_addr, |
741 | &satosiso(addr)->siso_addr)) { | | 741 | &satosiso(addr)->siso_addr)) { |
742 | #ifdef ARGO_DEBUG | | 742 | #ifdef ARGO_DEBUG |
743 | if (argo_debug[D_ROUTE]) { | | 743 | if (argo_debug[D_ROUTE]) { |
744 | printf("ifa_ifwithidi: ifa found\n"); | | 744 | printf("ifa_ifwithidi: ifa found\n"); |
745 | } | | 745 | } |
746 | #endif | | 746 | #endif |
747 | return (ifa); | | 747 | return (ifa); |
748 | } | | 748 | } |
749 | #ifdef ARGO_DEBUG | | 749 | #ifdef ARGO_DEBUG |
750 | if (argo_debug[D_ROUTE]) { | | 750 | if (argo_debug[D_ROUTE]) { |
751 | printf(" iso_eqtype failed\n"); | | 751 | printf(" iso_eqtype failed\n"); |
752 | } | | 752 | } |
753 | #endif | | 753 | #endif |
754 | } | | 754 | } |
755 | } | | 755 | } |
756 | return ((struct ifaddr *) 0); | | 756 | return ((struct ifaddr *) 0); |
757 | } | | 757 | } |
758 | | | 758 | |
759 | #endif /* notdef */ | | 759 | #endif /* notdef */ |
760 | /* | | 760 | /* |
761 | * FUNCTION: iso_ck_addr | | 761 | * FUNCTION: iso_ck_addr |
762 | * | | 762 | * |
763 | * PURPOSE: return true if the iso_addr passed is | | 763 | * PURPOSE: return true if the iso_addr passed is |
764 | * within the legal size limit for an iso address. | | 764 | * within the legal size limit for an iso address. |
765 | * | | 765 | * |
766 | * RETURNS: true or false | | 766 | * RETURNS: true or false |
767 | * | | 767 | * |
768 | * SIDE EFFECTS: | | 768 | * SIDE EFFECTS: |
769 | * | | 769 | * |
770 | */ | | 770 | */ |
771 | int | | 771 | int |
772 | iso_ck_addr(struct iso_addr *isoa) | | 772 | iso_ck_addr(struct iso_addr *isoa) |
773 | { | | 773 | { |
774 | return (isoa->isoa_len <= 20); | | 774 | return (isoa->isoa_len <= 20); |
775 | | | 775 | |
776 | } | | 776 | } |
777 | | | 777 | |
778 | #ifdef notdef | | 778 | #ifdef notdef |
779 | /* | | 779 | /* |
780 | * FUNCTION: iso_eqtype | | 780 | * FUNCTION: iso_eqtype |
781 | * | | 781 | * |
782 | * PURPOSE: Determine if two iso addresses are of the same type. | | 782 | * PURPOSE: Determine if two iso addresses are of the same type. |
783 | * This is flaky. Really we should consider all type | | 783 | * This is flaky. Really we should consider all type |
784 | * 47 addrs to be the same - but there do exist different | | 784 | * 47 addrs to be the same - but there do exist different |
785 | * structures for 47 addrs. Gosip adds a 3rd. | | 785 | * structures for 47 addrs. Gosip adds a 3rd. |
786 | * | | 786 | * |
787 | * RETURNS: true if the addresses are the same type | | 787 | * RETURNS: true if the addresses are the same type |
788 | * | | 788 | * |
789 | * SIDE EFFECTS: | | 789 | * SIDE EFFECTS: |
790 | * | | 790 | * |
791 | * NOTES: By type, I mean rfc986, t37, or osinet | | 791 | * NOTES: By type, I mean rfc986, t37, or osinet |
792 | * | | 792 | * |
793 | * This will first compare afis. If they match, then | | 793 | * This will first compare afis. If they match, then |
794 | * if the addr is not t37, the idis must be compared. | | 794 | * if the addr is not t37, the idis must be compared. |
795 | */ | | 795 | */ |
796 | int | | 796 | int |
797 | iso_eqtype( | | 797 | iso_eqtype( |
798 | struct iso_addr *isoaa, /* first addr to check */ | | 798 | struct iso_addr *isoaa, /* first addr to check */ |
799 | struct iso_addr *isoab) /* other addr to check */ | | 799 | struct iso_addr *isoab) /* other addr to check */ |
800 | { | | 800 | { |
801 | if (isoaa->isoa_afi == isoab->isoa_afi) { | | 801 | if (isoaa->isoa_afi == isoab->isoa_afi) { |
802 | if (isoaa->isoa_afi == AFI_37) | | 802 | if (isoaa->isoa_afi == AFI_37) |
803 | return (1); | | 803 | return (1); |
804 | else | | 804 | else |
805 | return (!memcmp(&isoaa->isoa_u, &isoab->isoa_u, 2)); | | 805 | return (!memcmp(&isoaa->isoa_u, &isoab->isoa_u, 2)); |
806 | } | | 806 | } |
807 | return (0); | | 807 | return (0); |
808 | } | | 808 | } |
809 | #endif /* notdef */ | | 809 | #endif /* notdef */ |
810 | /* | | 810 | /* |
811 | * FUNCTION: iso_localifa() | | 811 | * FUNCTION: iso_localifa() |
812 | * | | 812 | * |
813 | * PURPOSE: Find an interface addresss having a given destination | | 813 | * PURPOSE: Find an interface addresss having a given destination |
814 | * or at least matching the net. | | 814 | * or at least matching the net. |
815 | * | | 815 | * |
816 | * RETURNS: ptr to an interface address | | 816 | * RETURNS: ptr to an interface address |
817 | * | | 817 | * |
818 | * SIDE EFFECTS: | | 818 | * SIDE EFFECTS: |
819 | * | | 819 | * |
820 | * NOTES: | | 820 | * NOTES: |
821 | */ | | 821 | */ |
822 | struct iso_ifaddr * | | 822 | struct iso_ifaddr * |
823 | iso_localifa(const struct sockaddr_iso *siso) | | 823 | iso_localifa(const struct sockaddr_iso *siso) |
824 | { | | 824 | { |
825 | struct iso_ifaddr *ia; | | 825 | struct iso_ifaddr *ia; |
826 | const char *cp1, *cp2, *cp3; | | 826 | const char *cp1, *cp2, *cp3; |
827 | struct ifnet *ifp; | | 827 | struct ifnet *ifp; |
828 | struct iso_ifaddr *ia_maybe = 0; | | 828 | struct iso_ifaddr *ia_maybe = 0; |
829 | /* | | 829 | /* |
830 | * We make one pass looking for both net matches and an exact | | 830 | * We make one pass looking for both net matches and an exact |
831 | * dst addr. | | 831 | * dst addr. |
832 | */ | | 832 | */ |
833 | TAILQ_FOREACH(ia, &iso_ifaddr, ia_list) { | | 833 | TAILQ_FOREACH(ia, &iso_ifaddr, ia_list) { |
834 | if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0)) | | 834 | if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0)) |
835 | continue; | | 835 | continue; |
836 | if (ifp->if_flags & IFF_POINTOPOINT) { | | 836 | if (ifp->if_flags & IFF_POINTOPOINT) { |
837 | if ((ia->ia_dstaddr.siso_family == AF_ISO) && | | 837 | if ((ia->ia_dstaddr.siso_family == AF_ISO) && |
838 | SAME_ISOADDR(&ia->ia_dstaddr, siso)) | | 838 | SAME_ISOADDR(&ia->ia_dstaddr, siso)) |
839 | return (ia); | | 839 | return (ia); |
840 | else if (SAME_ISOADDR(&ia->ia_addr, siso)) | | 840 | else if (SAME_ISOADDR(&ia->ia_addr, siso)) |
841 | ia_maybe = ia; | | 841 | ia_maybe = ia; |
842 | continue; | | 842 | continue; |
843 | } | | 843 | } |
844 | if (ia->ia_sockmask.siso_len) { | | 844 | if (ia->ia_sockmask.siso_len) { |
845 | char *cplim = ia->ia_sockmask.siso_len + | | 845 | char *cplim = ia->ia_sockmask.siso_len + |
846 | (char *) &ia->ia_sockmask; | | 846 | (char *) &ia->ia_sockmask; |
847 | cp1 = ia->ia_sockmask.siso_data; | | 847 | cp1 = ia->ia_sockmask.siso_data; |
848 | cp2 = siso->siso_data; | | 848 | cp2 = siso->siso_data; |
849 | cp3 = ia->ia_addr.siso_data; | | 849 | cp3 = ia->ia_addr.siso_data; |
850 | while (cp1 < cplim) | | 850 | while (cp1 < cplim) |
851 | if (*cp1++ & (*cp2++ ^ *cp3++)) | | 851 | if (*cp1++ & (*cp2++ ^ *cp3++)) |
852 | goto next; | | 852 | goto next; |
853 | ia_maybe = ia; | | 853 | ia_maybe = ia; |
854 | } | | 854 | } |
855 | if (SAME_ISOADDR(&ia->ia_addr, siso)) | | 855 | if (SAME_ISOADDR(&ia->ia_addr, siso)) |
856 | return ia; | | 856 | return ia; |
857 | next: ; | | 857 | next: ; |
858 | } | | 858 | } |
859 | return ia_maybe; | | 859 | return ia_maybe; |
860 | } | | 860 | } |
861 | | | 861 | |
862 | /* | | 862 | /* |
863 | * FUNCTION: iso_nlctloutput | | 863 | * FUNCTION: iso_nlctloutput |
864 | * | | 864 | * |
865 | * PURPOSE: Set options at the network level | | 865 | * PURPOSE: Set options at the network level |
866 | * | | 866 | * |
867 | * RETURNS: E* | | 867 | * RETURNS: E* |
868 | * | | 868 | * |
869 | * SIDE EFFECTS: | | 869 | * SIDE EFFECTS: |
870 | * | | 870 | * |
871 | * NOTES: This could embody some of the functions of | | 871 | * NOTES: This could embody some of the functions of |
872 | * rclnp_ctloutput and cons_ctloutput. | | 872 | * rclnp_ctloutput and cons_ctloutput. |
873 | */ | | 873 | */ |
874 | int | | 874 | int |
875 | iso_nlctloutput( | | 875 | iso_nlctloutput( |
876 | int cmd, /* command:set or get */ | | 876 | int cmd, /* command:set or get */ |
877 | int optname, /* option of interest */ | | 877 | int optname, /* option of interest */ |
878 | void * pcb, /* nl pcb */ | | 878 | void * pcb, /* nl pcb */ |
879 | struct mbuf *m) /* data for set, buffer for get */ | | 879 | struct mbuf *m) /* data for set, buffer for get */ |
880 | { | | 880 | { |
881 | int error = 0; /* return value */ | | 881 | int error = 0; /* return value */ |
882 | void * data; /* data for option */ | | 882 | void * data; /* data for option */ |
883 | int data_len; /* data's length */ | | 883 | int data_len; /* data's length */ |
884 | | | 884 | |
885 | #ifdef ARGO_DEBUG | | 885 | #ifdef ARGO_DEBUG |
886 | if (argo_debug[D_ISO]) { | | 886 | if (argo_debug[D_ISO]) { |
887 | printf("iso_nlctloutput: cmd %x, opt %x, pcb %p, m %p\n", | | 887 | printf("iso_nlctloutput: cmd %x, opt %x, pcb %p, m %p\n", |
888 | cmd, optname, pcb, m); | | 888 | cmd, optname, pcb, m); |
889 | } | | 889 | } |
890 | #endif | | 890 | #endif |
891 | | | 891 | |
892 | if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT)) | | 892 | if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT)) |
893 | return (EOPNOTSUPP); | | 893 | return (EOPNOTSUPP); |
894 | | | 894 | |
895 | data = mtod(m, void *); | | 895 | data = mtod(m, void *); |
896 | data_len = (m)->m_len; | | 896 | data_len = (m)->m_len; |
897 | | | 897 | |
898 | #ifdef ARGO_DEBUG | | 898 | #ifdef ARGO_DEBUG |
899 | if (argo_debug[D_ISO]) { | | 899 | if (argo_debug[D_ISO]) { |
900 | printf("iso_nlctloutput: data is:\n"); | | 900 | printf("iso_nlctloutput: data is:\n"); |
901 | dump_buf(data, data_len); | | 901 | dump_buf(data, data_len); |
902 | } | | 902 | } |
903 | #endif | | 903 | #endif |
904 | | | 904 | |
905 | switch (optname) { | | 905 | switch (optname) { |
906 | default: | | 906 | default: |
907 | error = EOPNOTSUPP; | | 907 | error = EOPNOTSUPP; |
908 | } | | 908 | } |
909 | if (cmd == PRCO_SETOPT) | | 909 | if (cmd == PRCO_SETOPT) |
910 | m_freem(m); | | 910 | m_freem(m); |
911 | return error; | | 911 | return error; |
912 | } | | 912 | } |
913 | #endif /* ISO */ | | 913 | #endif /* ISO */ |
914 | | | 914 | |
915 | #ifdef ARGO_DEBUG | | 915 | #ifdef ARGO_DEBUG |
916 | | | 916 | |
917 | /* | | 917 | /* |
918 | * FUNCTION: dump_isoaddr | | 918 | * FUNCTION: dump_isoaddr |
919 | * | | 919 | * |
920 | * PURPOSE: debugging | | 920 | * PURPOSE: debugging |
921 | * | | 921 | * |
922 | * RETURNS: nada | | 922 | * RETURNS: nada |
923 | * | | 923 | * |
924 | */ | | 924 | */ |
925 | void | | 925 | void |
926 | dump_isoaddr(const struct sockaddr_iso *s) | | 926 | dump_isoaddr(const struct sockaddr_iso *s) |
927 | { | | 927 | { |
928 | if (s->siso_family == AF_ISO) { | | 928 | if (s->siso_family == AF_ISO) { |
929 | printf("ISO address: suffixlen %d, %s\n", | | 929 | printf("ISO address: suffixlen %d, %s\n", |
930 | s->siso_tlen, clnp_saddr_isop(s)); | | 930 | s->siso_tlen, clnp_saddr_isop(s)); |
931 | } else if (s->siso_family == AF_INET) { | | 931 | } else if (s->siso_family == AF_INET) { |
932 | /* hack */ | | 932 | /* hack */ |
933 | const struct sockaddr_in *sin = satocsin(s); | | 933 | const struct sockaddr_in *sin = satocsin(s); |
934 | | | 934 | |
935 | printf("%d.%d.%d.%d: %d", | | 935 | printf("%d.%d.%d.%d: %d", |
936 | (sin->sin_addr.s_addr >> 24) & 0xff, | | 936 | (sin->sin_addr.s_addr >> 24) & 0xff, |
937 | (sin->sin_addr.s_addr >> 16) & 0xff, | | 937 | (sin->sin_addr.s_addr >> 16) & 0xff, |
938 | (sin->sin_addr.s_addr >> 8) & 0xff, | | 938 | (sin->sin_addr.s_addr >> 8) & 0xff, |
939 | (sin->sin_addr.s_addr) & 0xff, | | 939 | (sin->sin_addr.s_addr) & 0xff, |
940 | sin->sin_port); | | 940 | sin->sin_port); |
941 | } | | 941 | } |
942 | } | | 942 | } |
943 | | | 943 | |
944 | #endif /* ARGO_DEBUG */ | | 944 | #endif /* ARGO_DEBUG */ |
945 | | | 945 | |
946 | struct queue { | | 946 | struct queue { |
947 | struct queue *q_next, *q_prev; | | 947 | struct queue *q_next, *q_prev; |
948 | }; | | 948 | }; |
949 | | | 949 | |
950 | /* | | 950 | /* |
951 | * FUNCTION: iso_insque | | 951 | * FUNCTION: iso_insque |
952 | * | | 952 | * |
953 | * PURPOSE: insert an element into a queue | | 953 | * PURPOSE: insert an element into a queue |
954 | * | | 954 | * |
955 | * RETURNS: | | 955 | * RETURNS: |
956 | */ | | 956 | */ |
957 | void | | 957 | void |
958 | iso_insque(void *v1, void *v2) | | 958 | iso_insque(void *v1, void *v2) |
959 | { | | 959 | { |
960 | struct queue *elem = v1, *head = v2; | | 960 | struct queue *elem = v1, *head = v2; |
961 | struct queue *next; | | 961 | struct queue *next; |
962 | | | 962 | |
963 | next = head->q_next; | | 963 | next = head->q_next; |
964 | elem->q_next = next; | | 964 | elem->q_next = next; |
965 | head->q_next = elem; | | 965 | head->q_next = elem; |
966 | elem->q_prev = head; | | 966 | elem->q_prev = head; |
967 | next->q_prev = elem; | | 967 | next->q_prev = elem; |
968 | } | | 968 | } |
969 | | | 969 | |
970 | /* | | 970 | /* |
971 | * FUNCTION: iso_remque | | 971 | * FUNCTION: iso_remque |
972 | * | | 972 | * |
973 | * PURPOSE: remove an element from a queue | | 973 | * PURPOSE: remove an element from a queue |
974 | * | | 974 | * |
975 | * RETURNS: | | 975 | * RETURNS: |
976 | */ | | 976 | */ |
977 | void | | 977 | void |
978 | iso_remque(void *v) | | 978 | iso_remque(void *v) |
979 | { | | 979 | { |
980 | struct queue *elem = v; | | 980 | struct queue *elem = v; |
981 | struct queue *next, *prev; | | 981 | struct queue *next, *prev; |
982 | | | 982 | |
983 | next = elem->q_next; | | 983 | next = elem->q_next; |
984 | prev = elem->q_prev; | | 984 | prev = elem->q_prev; |
985 | next->q_prev = prev; | | 985 | next->q_prev = prev; |
986 | prev->q_next = next; | | 986 | prev->q_next = next; |
987 | elem->q_prev = NULL; | | 987 | elem->q_prev = NULL; |
988 | } | | 988 | } |