]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.sbin/IPXrouted/af.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.sbin / IPXrouted / af.c
1 /*
2  * Copyright (c) 1985, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Copyright (c) 1995 John Hay.  All rights reserved.
6  *
7  * This file includes significant work done at Cornell University by
8  * Bill Nesheim.  That work included by permission.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 4. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * $FreeBSD$
35  */
36
37 #ifndef lint
38 static const char sccsid[] = "@(#)af.c  8.1 (Berkeley) 6/5/93";
39 #endif /* not lint */
40
41 #include "defs.h"
42
43 /*
44  * Address family support routines
45  */
46 af_hash_t       null_hash;
47 af_netmatch_t   null_netmatch;
48 af_output_t     null_output;
49 af_portmatch_t  null_portmatch;
50 af_portcheck_t  null_portcheck;
51 af_checkhost_t  null_checkhost;
52 af_ishost_t     null_ishost;
53 af_canon_t      null_canon;
54
55 void    ipxnet_hash(struct sockaddr_ipx *, struct afhash *);
56 int     ipxnet_netmatch(struct sockaddr_ipx *, struct sockaddr_ipx *);
57 void    ipxnet_output(int, int, struct sockaddr_ipx *, int);
58 int     ipxnet_portmatch(struct sockaddr_ipx *);
59 int     ipxnet_checkhost(struct sockaddr_ipx *);
60 int     ipxnet_ishost(struct sockaddr_ipx *);
61 void    ipxnet_canon(struct sockaddr_ipx *);
62
63 #define NIL \
64         { null_hash,            null_netmatch,          null_output, \
65           null_portmatch,       null_portcheck,         null_checkhost, \
66           null_ishost,          null_canon }
67 #define IPXNET \
68         { (af_hash_t *)ipxnet_hash, \
69           (af_netmatch_t *)ipxnet_netmatch, \
70           (af_output_t *)ipxnet_output, \
71           (af_portmatch_t *)ipxnet_portmatch, \
72           (af_portcheck_t *)ipxnet_portmatch, \
73           (af_checkhost_t *)ipxnet_checkhost, \
74           (af_ishost_t *)ipxnet_ishost, \
75           (af_canon_t *)ipxnet_canon }
76
77 struct afswitch afswitch[AF_MAX] =
78         { NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
79           NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
80           NIL, NIL, NIL, IPXNET, NIL, NIL };
81
82 struct sockaddr_ipx ipxnet_default = { sizeof(struct sockaddr_ipx), AF_IPX };
83
84 union ipx_net ipx_anynet;
85 union ipx_net ipx_zeronet;
86
87 void
88 ipxnet_hash(sipx, hp)
89         register struct sockaddr_ipx *sipx;
90         struct afhash *hp;
91 {
92         long hash;
93 #if 0
94         u_short *s = sipx->sipx_addr.x_host.s_host;
95 #endif
96         u_char *c;
97
98         c = sipx->sipx_addr.x_net.c_net;
99
100 #define IMVAL   33
101         hash = 0;
102         hash = hash * IMVAL + *c++;
103         hash = hash * IMVAL + *c++;
104         hash = hash * IMVAL + *c++;
105         hash = hash * IMVAL + *c++;
106 #undef IMVAL
107
108         hp->afh_nethash = hash;
109         hp->afh_nethash ^= (hash >> 8);
110         hp->afh_nethash ^= (hash >> 16);
111         hp->afh_nethash ^= (hash >> 24);
112
113 #if 0
114         hash = 0;
115         hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
116         hp->afh_hosthash = hash;
117 #endif
118 }
119
120 int
121 ipxnet_netmatch(sxn1, sxn2)
122         struct sockaddr_ipx *sxn1, *sxn2;
123 {
124         return (ipx_neteq(sxn1->sipx_addr, sxn2->sipx_addr));
125 }
126
127 /*
128  * Verify the message is from the right port.
129  */
130 int
131 ipxnet_portmatch(sipx)
132         register struct sockaddr_ipx *sipx;
133 {
134         
135         return (ntohs(sipx->sipx_addr.x_port) == IPXPORT_RIP );
136 }
137
138
139 /*
140  * ipx output routine.
141  */
142 #ifdef DEBUG
143 int do_output = 0;
144 #endif
145 void
146 ipxnet_output(s, flags, sipx, size)
147         int s;
148         int flags;
149         struct sockaddr_ipx *sipx;
150         int size;
151 {
152         struct sockaddr_ipx dst;
153
154         dst = *sipx;
155         sipx = &dst;
156         if (sipx->sipx_addr.x_port == 0)
157                 sipx->sipx_addr.x_port = htons(IPXPORT_RIP);
158 #ifdef DEBUG
159         if(do_output || ntohs(msg->rip_cmd) == RIPCMD_REQUEST)
160 #endif  
161         /*
162          * Kludge to allow us to get routes out to machines that
163          * don't know their addresses yet; send to that address on
164          * ALL connected nets
165          */
166          if (ipx_neteqnn(sipx->sipx_addr.x_net, ipx_zeronet)) {
167                 extern  struct interface *ifnet;
168                 register struct interface *ifp;
169                 
170                 for (ifp = ifnet; ifp; ifp = ifp->int_next) {
171                         sipx->sipx_addr.x_net = 
172                                 satoipx_addr(ifp->int_addr).x_net;
173                         (void) sendto(s, msg, size, flags,
174                             (struct sockaddr *)sipx, sizeof (*sipx));
175                 }
176                 return;
177         }
178         
179         (void) sendto(s, msg, size, flags,
180             (struct sockaddr *)sipx, sizeof (*sipx));
181 }
182
183 /*
184  * Return 1 if we want this route.
185  * We use this to disallow route net G entries for one for multiple
186  * point to point links.
187  */
188 int
189 ipxnet_checkhost(sipx)
190         struct sockaddr_ipx *sipx;
191 {
192         register struct interface *ifp = if_ifwithnet((struct sockaddr *)sipx);
193         /*
194          * We want this route if there is no more than one 
195          * point to point interface with this network.
196          */
197         if (ifp == 0 || (ifp->int_flags & IFF_POINTOPOINT)==0) return (1);
198         return (ifp->int_sq.n == ifp->int_sq.p);
199 }
200
201 /*
202  * Return 1 if the address is
203  * for a host, 0 for a network.
204  */
205 int
206 ipxnet_ishost(sipx)
207 struct sockaddr_ipx *sipx;
208 {
209         register u_short *s = sipx->sipx_addr.x_host.s_host;
210
211         if ((s[0]==0x0000) && (s[1]==0x0000) && (s[2]==0x0000))
212                 return (0);
213         if ((s[0]==0xffff) && (s[1]==0xffff) && (s[2]==0xffff))
214                 return (0);
215
216         return (1);
217 }
218
219 void
220 ipxnet_canon(sipx)
221         struct sockaddr_ipx *sipx;
222 {
223
224         sipx->sipx_addr.x_port = 0;
225 }
226
227 void
228 null_hash(addr, hp)
229         struct sockaddr *addr;
230         struct afhash *hp;
231 {
232
233         hp->afh_nethash = hp->afh_hosthash = 0;
234 }
235
236 int
237 null_netmatch(a1, a2)
238         struct sockaddr *a1, *a2;
239 {
240
241         return (0);
242 }
243
244 void
245 null_output(s, f, a1, n)
246         int s;
247         int f;
248         struct sockaddr *a1;
249         int n;
250 {
251
252         ;
253 }
254
255 int
256 null_portmatch(a1)
257         struct sockaddr *a1;
258 {
259
260         return (0);
261 }
262
263 int
264 null_portcheck(a1)
265         struct sockaddr *a1;
266 {
267
268         return (0);
269 }
270
271 int
272 null_ishost(a1)
273         struct sockaddr *a1;
274 {
275
276         return (0);
277 }
278
279 int
280 null_checkhost(a1)
281         struct sockaddr *a1;
282 {
283
284         return (0);
285 }
286
287 void
288 null_canon(a1)
289         struct sockaddr *a1;
290 {
291
292         ;
293 }
294