1/* $NetBSD: if_atm.c,v 1.6 1996/10/13 02:03:01 christos Exp $ */ 2 3/* 4 * 5 * Copyright (c) 1996 Charles D. Cranor and Washington University. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Charles D. Cranor and 19 * Washington University. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35/* 36 * IP <=> ATM address resolution. 37 */ 38
|
41#ifdef INET 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/mbuf.h> 46#include <sys/socket.h> 47#include <sys/sockio.h> 48#include <sys/syslog.h> 49 50#include <net/if.h> 51#include <net/if_dl.h> 52#include <net/route.h> 53#include <net/if_atm.h> 54 55#include <netinet/in.h> 56#include <netinet/if_atm.h> 57 58#ifdef NATM 59#include <netnatm/natm.h> 60#endif 61 62 63#define SDL(s) ((struct sockaddr_dl *)s) 64 65/* 66 * atm_rtrequest: handle ATM rt request (in support of generic code) 67 * inputs: "req" = request code 68 * "rt" = route entry 69 * "sa" = sockaddr 70 */ 71 72void 73atm_rtrequest(req, rt, sa) 74 int req; 75 register struct rtentry *rt; 76 struct sockaddr *sa; 77{ 78 register struct sockaddr *gate = rt->rt_gateway; 79 struct atm_pseudoioctl api; 80#ifdef NATM 81 struct sockaddr_in *sin; 82 struct natmpcb *npcb = NULL; 83 struct atm_pseudohdr *aph; 84#endif 85 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; 86 87 if (rt->rt_flags & RTF_GATEWAY) /* link level requests only */ 88 return; 89 90 switch (req) { 91 92 case RTM_RESOLVE: /* resolve: only happens when cloning */ 93 printf("atm_rtrequest: RTM_RESOLVE request detected?\n"); 94 break; 95 96 case RTM_ADD: 97 98 /* 99 * route added by a command (e.g. ifconfig, route, arp...). 100 * 101 * first check to see if this is not a host route, in which 102 * case we are being called via "ifconfig" to set the address. 103 */ 104 105 if ((rt->rt_flags & RTF_HOST) == 0) { 106 rt_setgate(rt,rt_key(rt),(struct sockaddr *)&null_sdl); 107 gate = rt->rt_gateway; 108 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 109 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 110 break; 111 } 112 113 if ((rt->rt_flags & RTF_CLONING) != 0) { 114 printf("atm_rtrequest: cloning route detected?\n"); 115 break; 116 } 117 if (gate->sa_family != AF_LINK || 118 gate->sa_len < sizeof(null_sdl)) { 119 log(LOG_DEBUG, "atm_rtrequest: bad gateway value"); 120 break; 121 } 122 123#ifdef DIAGNOSTIC 124 if (rt->rt_ifp->if_ioctl == NULL) panic("atm null ioctl"); 125#endif 126 127#ifdef NATM 128 /* 129 * let native ATM know we are using this VCI/VPI 130 * (i.e. reserve it) 131 */ 132 sin = (struct sockaddr_in *) rt_key(rt); 133 if (sin->sin_family != AF_INET) 134 goto failed; 135 aph = (struct atm_pseudohdr *) LLADDR(SDL(gate)); 136 npcb = npcb_add(NULL, rt->rt_ifp, ATM_PH_VCI(aph), 137 ATM_PH_VPI(aph)); 138 if (npcb == NULL) 139 goto failed; 140 npcb->npcb_flags |= NPCB_IP; 141 npcb->ipaddr.s_addr = sin->sin_addr.s_addr; 142 /* XXX: move npcb to llinfo when ATM ARP is ready */ 143 rt->rt_llinfo = (caddr_t) npcb; 144 rt->rt_flags |= RTF_LLINFO; 145#endif 146 /* 147 * let the lower level know this circuit is active 148 */ 149 bcopy(LLADDR(SDL(gate)), &api.aph, sizeof(api.aph)); 150 api.rxhand = NULL; 151 if (rt->rt_ifp->if_ioctl(rt->rt_ifp, SIOCATMENA, 152 (caddr_t)&api) != 0) { 153 printf("atm: couldn't add VC\n"); 154 goto failed; 155 } 156 157 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 158 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 159 160 break; 161 162failed: 163#ifdef NATM 164 if (npcb) { 165 npcb_free(npcb, NPCB_DESTROY); 166 rt->rt_llinfo = NULL; 167 rt->rt_flags &= ~RTF_LLINFO; 168 } 169#endif 170 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, 171 rt_mask(rt), 0, (struct rtentry **) 0); 172 break; 173 174 case RTM_DELETE: 175 176#ifdef NATM 177 /* 178 * tell native ATM we are done with this VC 179 */ 180 181 if (rt->rt_flags & RTF_LLINFO) { 182 npcb_free((struct natmpcb *)rt->rt_llinfo, 183 NPCB_DESTROY); 184 rt->rt_llinfo = NULL; 185 rt->rt_flags &= ~RTF_LLINFO; 186 } 187#endif 188 /* 189 * tell the lower layer to disable this circuit 190 */ 191 192 bcopy(LLADDR(SDL(gate)), &api.aph, sizeof(api.aph)); 193 api.rxhand = NULL; 194 (void)rt->rt_ifp->if_ioctl(rt->rt_ifp, SIOCATMDIS, 195 (caddr_t)&api); 196 197 break; 198 } 199} 200 201/* 202 * atmresolve: 203 * inputs: 204 * [1] "rt" = the link level route to use (or null if need to look one up) 205 * [2] "m" = mbuf containing the data to be sent 206 * [3] "dst" = sockaddr_in (IP) address of dest. 207 * output: 208 * [4] "desten" = ATM pseudo header which we will fill in VPI/VCI info 209 * return: 210 * 0 == resolve FAILED; note that "m" gets m_freem'd in this case 211 * 1 == resolve OK; desten contains result 212 * 213 * XXX: will need more work if we wish to support ATMARP in the kernel, 214 * but this is enough for PVCs entered via the "route" command. 215 */ 216 217int 218atmresolve(rt, m, dst, desten) 219 220register struct rtentry *rt; 221struct mbuf *m; 222register struct sockaddr *dst; 223register struct atm_pseudohdr *desten; /* OUT */ 224 225{ 226 struct sockaddr_dl *sdl; 227 228 if (m->m_flags & (M_BCAST|M_MCAST)) { 229 log(LOG_INFO, "atmresolve: BCAST/MCAST packet detected/dumped"); 230 goto bad; 231 } 232 233 if (rt == NULL) { 234 rt = RTALLOC1(dst, 0); 235 if (rt == NULL) goto bad; /* failed */ 236 rt->rt_refcnt--; /* don't keep LL references */ 237 if ((rt->rt_flags & RTF_GATEWAY) != 0 || 238 (rt->rt_flags & RTF_LLINFO) == 0 || 239 /* XXX: are we using LLINFO? */ 240 rt->rt_gateway->sa_family != AF_LINK) { 241 goto bad; 242 } 243 } 244 245 /* 246 * note that rt_gateway is a sockaddr_dl which contains the 247 * atm_pseudohdr data structure for this route. we currently 248 * don't need any rt_llinfo info (but will if we want to support 249 * ATM ARP [c.f. if_ether.c]). 250 */ 251 252 sdl = SDL(rt->rt_gateway); 253 254 /* 255 * Check the address family and length is valid, the address 256 * is resolved; otherwise, try to resolve. 257 */ 258 259 260 if (sdl->sdl_family == AF_LINK && sdl->sdl_alen == sizeof(*desten)) { 261 bcopy(LLADDR(sdl), desten, sdl->sdl_alen); 262 return(1); /* ok, go for it! */ 263 } 264 265 /* 266 * we got an entry, but it doesn't have valid link address 267 * info in it (it is prob. the interface route, which has 268 * sdl_alen == 0). dump packet. (fall through to "bad"). 269 */ 270 271bad: 272 m_freem(m); 273 return(0); 274} 275#endif /* INET */
|