1 /* 2 * Copyright (c) 1985 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This file includes significant work done at Cornell University by 6 * Bill Nesheim. That work included by permission. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the University of California, Berkeley. The name of the 14 * University may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 */ 20 21 #ifndef lint 22 static char sccsid[] = "@(#)af.c 5.8 (Berkeley) 09/19/88"; 23 #endif /* not lint */ 24 25 #include "defs.h" 26 27 /* 28 * Address family support routines 29 */ 30 int null_hash(), null_netmatch(), null_output(), 31 null_portmatch(), null_portcheck(), 32 null_checkhost(), null_ishost(), null_canon(); 33 int xnnet_hash(), xnnet_netmatch(), xnnet_output(), 34 xnnet_portmatch(), 35 xnnet_checkhost(), xnnet_ishost(), xnnet_canon(); 36 #define NIL \ 37 { null_hash, null_netmatch, null_output, \ 38 null_portmatch, null_portcheck, null_checkhost, \ 39 null_ishost, null_canon } 40 #define XNSNET \ 41 { xnnet_hash, xnnet_netmatch, xnnet_output, \ 42 xnnet_portmatch, xnnet_portmatch, xnnet_checkhost, \ 43 xnnet_ishost, xnnet_canon } 44 45 struct afswitch afswitch[AF_MAX] = 46 { NIL, NIL, NIL, NIL, NIL, NIL, XNSNET, NIL, NIL, NIL, NIL }; 47 48 struct sockaddr_ns xnnet_default = { AF_NS }; 49 50 union ns_net ns_anynet; 51 union ns_net ns_zeronet; 52 53 xnnet_hash(sns, hp) 54 register struct sockaddr_ns *sns; 55 struct afhash *hp; 56 { 57 register long hash = 0; 58 register u_short *s = sns->sns_addr.x_host.s_host; 59 union ns_net_u net; 60 61 net.net_e = sns->sns_addr.x_net; 62 hp->afh_nethash = net.long_e; 63 hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s; 64 hp->afh_hosthash = hash; 65 } 66 67 xnnet_netmatch(sxn1, sxn2) 68 struct sockaddr_ns *sxn1, *sxn2; 69 { 70 return (ns_neteq(sxn1->sns_addr, sxn2->sns_addr)); 71 } 72 73 /* 74 * Verify the message is from the right port. 75 */ 76 xnnet_portmatch(sns) 77 register struct sockaddr_ns *sns; 78 { 79 80 return (ntohs(sns->sns_addr.x_port) == IDPPORT_RIF ); 81 } 82 83 84 /* 85 * xns output routine. 86 */ 87 #ifdef DEBUG 88 int do_output = 0; 89 #endif 90 xnnet_output(flags, sns, size) 91 int flags; 92 struct sockaddr_ns *sns; 93 int size; 94 { 95 struct sockaddr_ns dst; 96 97 dst = *sns; 98 sns = &dst; 99 if (sns->sns_addr.x_port == 0) 100 sns->sns_addr.x_port = htons(IDPPORT_RIF); 101 #ifdef DEBUG 102 if(do_output || ntohs(msg->rip_cmd) == RIPCMD_REQUEST) 103 #endif 104 /* 105 * Kludge to allow us to get routes out to machines that 106 * don't know their addresses yet; send to that address on 107 * ALL connected nets 108 */ 109 if (ns_neteqnn(sns->sns_addr.x_net, ns_zeronet)) { 110 extern struct interface *ifnet; 111 register struct interface *ifp; 112 113 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 114 sns->sns_addr.x_net = 115 satons_addr(ifp->int_addr).x_net; 116 (void) sendto(s, msg, size, flags, sns, sizeof (*sns)); 117 } 118 return; 119 } 120 121 (void) sendto(s, msg, size, flags, sns, sizeof (*sns)); 122 } 123 124 /* 125 * Return 1 if we want this route. 126 * We use this to disallow route net G entries for one for multiple 127 * point to point links. 128 */ 129 xnnet_checkhost(sns) 130 struct sockaddr_ns *sns; 131 { 132 register struct interface *ifp = if_ifwithnet(sns); 133 /* 134 * We want this route if there is no more than one 135 * point to point interface with this network. 136 */ 137 if (ifp == 0 || (ifp->int_flags & IFF_POINTOPOINT)==0) return (1); 138 return (ifp->int_sq.n == ifp->int_sq.p); 139 } 140 141 /* 142 * Return 1 if the address is 143 * for a host, 0 for a network. 144 */ 145 xnnet_ishost(sns) 146 struct sockaddr_ns *sns; 147 { 148 register u_short *s = sns->sns_addr.x_host.s_host; 149 150 if ((s[0]==0xffff) && (s[1]==0xffff) && (s[2]==0xffff)) 151 return (0); 152 else 153 return (1); 154 } 155 156 xnnet_canon(sns) 157 struct sockaddr_ns *sns; 158 { 159 160 sns->sns_addr.x_port = 0; 161 } 162 163 /*ARGSUSED*/ 164 null_hash(addr, hp) 165 struct sockaddr *addr; 166 struct afhash *hp; 167 { 168 169 hp->afh_nethash = hp->afh_hosthash = 0; 170 } 171 172 /*ARGSUSED*/ 173 null_netmatch(a1, a2) 174 struct sockaddr *a1, *a2; 175 { 176 177 return (0); 178 } 179 180 /*ARGSUSED*/ 181 null_output(s, f, a1, n) 182 int s, f; 183 struct sockaddr *a1; 184 int n; 185 { 186 187 ; 188 } 189 190 /*ARGSUSED*/ 191 null_portmatch(a1) 192 struct sockaddr *a1; 193 { 194 195 return (0); 196 } 197 198 /*ARGSUSED*/ 199 null_portcheck(a1) 200 struct sockaddr *a1; 201 { 202 203 return (0); 204 } 205 206 /*ARGSUSED*/ 207 null_ishost(a1) 208 struct sockaddr *a1; 209 { 210 211 return (0); 212 } 213 214 /*ARGSUSED*/ 215 null_checkhost(a1) 216 struct sockaddr *a1; 217 { 218 219 return (0); 220 } 221 222 /*ARGSUSED*/ 223 null_canon(a1) 224 struct sockaddr *a1; 225 { 226 227 ; 228 } 229