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: releng/10.2/usr.sbin/IPXrouted/af.c 133248 2004-08-07 04:19:37Z imp $ 35 */ 36 37#ifndef lint 38static 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 */ 46af_hash_t null_hash; 47af_netmatch_t null_netmatch; 48af_output_t null_output; 49af_portmatch_t null_portmatch; 50af_portcheck_t null_portcheck; 51af_checkhost_t null_checkhost; 52af_ishost_t null_ishost; 53af_canon_t null_canon; 54 55void ipxnet_hash(struct sockaddr_ipx *, struct afhash *); 56int ipxnet_netmatch(struct sockaddr_ipx *, struct sockaddr_ipx *); 57void ipxnet_output(int, int, struct sockaddr_ipx *, int); 58int ipxnet_portmatch(struct sockaddr_ipx *); 59int ipxnet_checkhost(struct sockaddr_ipx *); 60int ipxnet_ishost(struct sockaddr_ipx *); 61void 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 77struct 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 82struct sockaddr_ipx ipxnet_default = { sizeof(struct sockaddr_ipx), AF_IPX }; 83 84union ipx_net ipx_anynet; 85union ipx_net ipx_zeronet; 86 87void 88ipxnet_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 120int 121ipxnet_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 */ 130int 131ipxnet_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 143int do_output = 0; 144#endif 145void 146ipxnet_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 */ 188int 189ipxnet_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 */ 205int 206ipxnet_ishost(sipx) 207struct 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 219void 220ipxnet_canon(sipx) 221 struct sockaddr_ipx *sipx; 222{ 223 224 sipx->sipx_addr.x_port = 0; 225} 226 227void 228null_hash(addr, hp) 229 struct sockaddr *addr; 230 struct afhash *hp; 231{ 232 233 hp->afh_nethash = hp->afh_hosthash = 0; 234} 235 236int 237null_netmatch(a1, a2) 238 struct sockaddr *a1, *a2; 239{ 240 241 return (0); 242} 243 244void 245null_output(s, f, a1, n) 246 int s; 247 int f; 248 struct sockaddr *a1; 249 int n; 250{ 251 252 ; 253} 254 255int 256null_portmatch(a1) 257 struct sockaddr *a1; 258{ 259 260 return (0); 261} 262 263int 264null_portcheck(a1) 265 struct sockaddr *a1; 266{ 267 268 return (0); 269} 270 271int 272null_ishost(a1) 273 struct sockaddr *a1; 274{ 275 276 return (0); 277} 278 279int 280null_checkhost(a1) 281 struct sockaddr *a1; 282{ 283 284 return (0); 285} 286 287void 288null_canon(a1) 289 struct sockaddr *a1; 290{ 291 292 ; 293} 294 295