af.c revision 133248
1109998Smarkm/* 2160814Ssimon * Copyright (c) 1985, 1993 3160814Ssimon * The Regents of the University of California. All rights reserved. 4160814Ssimon * 5109998Smarkm * Copyright (c) 1995 John Hay. All rights reserved. 6109998Smarkm * 7109998Smarkm * This file includes significant work done at Cornell University by 8109998Smarkm * Bill Nesheim. That work included by permission. 9109998Smarkm * 10109998Smarkm * Redistribution and use in source and binary forms, with or without 11109998Smarkm * modification, are permitted provided that the following conditions 12109998Smarkm * are met: 13280304Sjkim * 1. Redistributions of source code must retain the above copyright 14109998Smarkm * notice, this list of conditions and the following disclaimer. 15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 16109998Smarkm * notice, this list of conditions and the following disclaimer in the 17109998Smarkm * documentation and/or other materials provided with the distribution. 18109998Smarkm * 4. Neither the name of the University nor the names of its contributors 19109998Smarkm * may be used to endorse or promote products derived from this software 20109998Smarkm * without specific prior written permission. 21109998Smarkm * 22109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23109998Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25109998Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26109998Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27109998Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28109998Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30109998Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31109998Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32109998Smarkm * SUCH DAMAGE. 33109998Smarkm * 34109998Smarkm * $FreeBSD: head/usr.sbin/IPXrouted/af.c 133248 2004-08-07 04:19:37Z imp $ 35109998Smarkm */ 36109998Smarkm 37109998Smarkm#ifndef lint 38109998Smarkmstatic const char sccsid[] = "@(#)af.c 8.1 (Berkeley) 6/5/93"; 39109998Smarkm#endif /* not lint */ 40109998Smarkm 41109998Smarkm#include "defs.h" 42109998Smarkm 43109998Smarkm/* 44109998Smarkm * Address family support routines 45109998Smarkm */ 46109998Smarkmaf_hash_t null_hash; 47109998Smarkmaf_netmatch_t null_netmatch; 48109998Smarkmaf_output_t null_output; 49109998Smarkmaf_portmatch_t null_portmatch; 50109998Smarkmaf_portcheck_t null_portcheck; 51109998Smarkmaf_checkhost_t null_checkhost; 52109998Smarkmaf_ishost_t null_ishost; 53109998Smarkmaf_canon_t null_canon; 54109998Smarkm 55109998Smarkmvoid ipxnet_hash(struct sockaddr_ipx *, struct afhash *); 56109998Smarkmint ipxnet_netmatch(struct sockaddr_ipx *, struct sockaddr_ipx *); 57109998Smarkmvoid ipxnet_output(int, int, struct sockaddr_ipx *, int); 58160814Ssimonint ipxnet_portmatch(struct sockaddr_ipx *); 59160814Ssimonint ipxnet_checkhost(struct sockaddr_ipx *); 60160814Ssimonint ipxnet_ishost(struct sockaddr_ipx *); 61160814Ssimonvoid ipxnet_canon(struct sockaddr_ipx *); 62160814Ssimon 63109998Smarkm#define NIL \ 64109998Smarkm { null_hash, null_netmatch, null_output, \ 65109998Smarkm null_portmatch, null_portcheck, null_checkhost, \ 66238405Sjkim null_ishost, null_canon } 67280304Sjkim#define IPXNET \ 68238405Sjkim { (af_hash_t *)ipxnet_hash, \ 69238405Sjkim (af_netmatch_t *)ipxnet_netmatch, \ 70109998Smarkm (af_output_t *)ipxnet_output, \ 71109998Smarkm (af_portmatch_t *)ipxnet_portmatch, \ 72109998Smarkm (af_portcheck_t *)ipxnet_portmatch, \ 73280304Sjkim (af_checkhost_t *)ipxnet_checkhost, \ 74280304Sjkim (af_ishost_t *)ipxnet_ishost, \ 75280304Sjkim (af_canon_t *)ipxnet_canon } 76280304Sjkim 77280304Sjkimstruct afswitch afswitch[AF_MAX] = 78280304Sjkim { NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, 79280304Sjkim NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, 80280304Sjkim NIL, NIL, NIL, IPXNET, NIL, NIL }; 81280304Sjkim 82280304Sjkimstruct sockaddr_ipx ipxnet_default = { sizeof(struct sockaddr_ipx), AF_IPX }; 83280304Sjkim 84280304Sjkimunion ipx_net ipx_anynet; 85280304Sjkimunion ipx_net ipx_zeronet; 86280304Sjkim 87280304Sjkimvoid 88280304Sjkimipxnet_hash(sipx, hp) 89280304Sjkim register struct sockaddr_ipx *sipx; 90280304Sjkim struct afhash *hp; 91280304Sjkim{ 92280304Sjkim long hash; 93280304Sjkim#if 0 94280304Sjkim u_short *s = sipx->sipx_addr.x_host.s_host; 95280304Sjkim#endif 96280304Sjkim u_char *c; 97280304Sjkim 98280304Sjkim c = sipx->sipx_addr.x_net.c_net; 99280304Sjkim 100280304Sjkim#define IMVAL 33 101280304Sjkim hash = 0; 102280304Sjkim hash = hash * IMVAL + *c++; 103280304Sjkim hash = hash * IMVAL + *c++; 104280304Sjkim hash = hash * IMVAL + *c++; 105280304Sjkim hash = hash * IMVAL + *c++; 106280304Sjkim#undef IMVAL 107280304Sjkim 108280304Sjkim hp->afh_nethash = hash; 109280304Sjkim hp->afh_nethash ^= (hash >> 8); 110280304Sjkim hp->afh_nethash ^= (hash >> 16); 111280304Sjkim hp->afh_nethash ^= (hash >> 24); 112280304Sjkim 113109998Smarkm#if 0 114273149Sjkim hash = 0; 115280304Sjkim hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s; 116280304Sjkim hp->afh_hosthash = hash; 117273149Sjkim#endif 118273149Sjkim} 119280304Sjkim 120280304Sjkimint 121109998Smarkmipxnet_netmatch(sxn1, sxn2) 122109998Smarkm struct sockaddr_ipx *sxn1, *sxn2; 123280304Sjkim{ 124280304Sjkim return (ipx_neteq(sxn1->sipx_addr, sxn2->sipx_addr)); 125109998Smarkm} 126280304Sjkim 127280304Sjkim/* 128280304Sjkim * Verify the message is from the right port. 129280304Sjkim */ 130280304Sjkimint 131109998Smarkmipxnet_portmatch(sipx) 132109998Smarkm register struct sockaddr_ipx *sipx; 133280304Sjkim{ 134280304Sjkim 135280304Sjkim return (ntohs(sipx->sipx_addr.x_port) == IPXPORT_RIP ); 136280304Sjkim} 137280304Sjkim 138280304Sjkim 139280304Sjkim/* 140280304Sjkim * ipx output routine. 141280304Sjkim */ 142280304Sjkim#ifdef DEBUG 143280304Sjkimint do_output = 0; 144109998Smarkm#endif 145109998Smarkmvoid 146280304Sjkimipxnet_output(s, flags, sipx, size) 147280304Sjkim int s; 148280304Sjkim int flags; 149280304Sjkim struct sockaddr_ipx *sipx; 150280304Sjkim int size; 151280304Sjkim{ 152280304Sjkim struct sockaddr_ipx dst; 153280304Sjkim 154280304Sjkim dst = *sipx; 155280304Sjkim sipx = &dst; 156280304Sjkim if (sipx->sipx_addr.x_port == 0) 157109998Smarkm sipx->sipx_addr.x_port = htons(IPXPORT_RIP); 158109998Smarkm#ifdef DEBUG 159280304Sjkim if(do_output || ntohs(msg->rip_cmd) == RIPCMD_REQUEST) 160280304Sjkim#endif 161280304Sjkim /* 162280304Sjkim * Kludge to allow us to get routes out to machines that 163280304Sjkim * don't know their addresses yet; send to that address on 164280304Sjkim * ALL connected nets 165280304Sjkim */ 166280304Sjkim if (ipx_neteqnn(sipx->sipx_addr.x_net, ipx_zeronet)) { 167280304Sjkim extern struct interface *ifnet; 168109998Smarkm register struct interface *ifp; 169280304Sjkim 170280304Sjkim for (ifp = ifnet; ifp; ifp = ifp->int_next) { 171109998Smarkm sipx->sipx_addr.x_net = 172280304Sjkim satoipx_addr(ifp->int_addr).x_net; 173280304Sjkim (void) sendto(s, msg, size, flags, 174280304Sjkim (struct sockaddr *)sipx, sizeof (*sipx)); 175280304Sjkim } 176280304Sjkim return; 177280304Sjkim } 178280304Sjkim 179280304Sjkim (void) sendto(s, msg, size, flags, 180280304Sjkim (struct sockaddr *)sipx, sizeof (*sipx)); 181280304Sjkim} 182280304Sjkim 183280304Sjkim/* 184109998Smarkm * Return 1 if we want this route. 185280304Sjkim * We use this to disallow route net G entries for one for multiple 186109998Smarkm * point to point links. 187109998Smarkm */ 188280304Sjkimint 189280304Sjkimipxnet_checkhost(sipx) 190280304Sjkim struct sockaddr_ipx *sipx; 191280304Sjkim{ 192280304Sjkim register struct interface *ifp = if_ifwithnet((struct sockaddr *)sipx); 193280304Sjkim /* 194109998Smarkm * We want this route if there is no more than one 195280304Sjkim * point to point interface with this network. 196280304Sjkim */ 197280304Sjkim if (ifp == 0 || (ifp->int_flags & IFF_POINTOPOINT)==0) return (1); 198280304Sjkim return (ifp->int_sq.n == ifp->int_sq.p); 199280304Sjkim} 200280304Sjkim 201280304Sjkim/* 202109998Smarkm * Return 1 if the address is 203280304Sjkim * for a host, 0 for a network. 204280304Sjkim */ 205280304Sjkimint 206280304Sjkimipxnet_ishost(sipx) 207280304Sjkimstruct sockaddr_ipx *sipx; 208280304Sjkim{ 209280304Sjkim register u_short *s = sipx->sipx_addr.x_host.s_host; 210280304Sjkim 211160814Ssimon if ((s[0]==0x0000) && (s[1]==0x0000) && (s[2]==0x0000)) 212280304Sjkim return (0); 213280304Sjkim if ((s[0]==0xffff) && (s[1]==0xffff) && (s[2]==0xffff)) 214280304Sjkim return (0); 215280304Sjkim 216280304Sjkim return (1); 217160814Ssimon} 218280304Sjkim 219280304Sjkimvoid 220280304Sjkimipxnet_canon(sipx) 221280304Sjkim struct sockaddr_ipx *sipx; 222280304Sjkim{ 223280304Sjkim 224280304Sjkim sipx->sipx_addr.x_port = 0; 225280304Sjkim} 226280304Sjkim 227280304Sjkimvoid 228280304Sjkimnull_hash(addr, hp) 229280304Sjkim struct sockaddr *addr; 230160814Ssimon struct afhash *hp; 231280304Sjkim{ 232280304Sjkim 233280304Sjkim hp->afh_nethash = hp->afh_hosthash = 0; 234280304Sjkim} 235160814Ssimon 236280304Sjkimint 237160814Ssimonnull_netmatch(a1, a2) 238280304Sjkim struct sockaddr *a1, *a2; 239280304Sjkim{ 240280304Sjkim 241280304Sjkim return (0); 242280304Sjkim} 243280304Sjkim 244160814Ssimonvoid 245160814Ssimonnull_output(s, f, a1, n) 246280304Sjkim int s; 247280304Sjkim int f; 248280304Sjkim struct sockaddr *a1; 249280304Sjkim int n; 250280304Sjkim{ 251280304Sjkim 252160814Ssimon ; 253280304Sjkim} 254280304Sjkim 255280304Sjkimint 256280304Sjkimnull_portmatch(a1) 257280304Sjkim struct sockaddr *a1; 258280304Sjkim{ 259280304Sjkim 260160814Ssimon return (0); 261280304Sjkim} 262280304Sjkim 263109998Smarkmint 264280304Sjkimnull_portcheck(a1) 265280304Sjkim struct sockaddr *a1; 266280304Sjkim{ 267280304Sjkim 268280304Sjkim return (0); 269280304Sjkim} 270280304Sjkim 271109998Smarkmint 272280304Sjkimnull_ishost(a1) 273280304Sjkim struct sockaddr *a1; 274109998Smarkm{ 275280304Sjkim 276280304Sjkim return (0); 277280304Sjkim} 278280304Sjkim 279280304Sjkimint 280280304Sjkimnull_checkhost(a1) 281280304Sjkim struct sockaddr *a1; 282109998Smarkm{ 283280304Sjkim 284280304Sjkim return (0); 285109998Smarkm} 286280304Sjkim 287280304Sjkimvoid 288280304Sjkimnull_canon(a1) 289280304Sjkim struct sockaddr *a1; 290280304Sjkim{ 291280304Sjkim 292280304Sjkim ; 293109998Smarkm} 294280304Sjkim 295280304Sjkim