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