Annotation of sys/netinet/if_atm.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: if_atm.c,v 1.13 2006/06/17 10:22:06 henning 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:
! 39: #if defined(INET) || defined(INET6)
! 40:
! 41: #include <sys/param.h>
! 42: #include <sys/systm.h>
! 43: #include <sys/malloc.h>
! 44: #include <sys/mbuf.h>
! 45: #include <sys/socket.h>
! 46: #include <sys/time.h>
! 47: #include <sys/kernel.h>
! 48: #include <sys/errno.h>
! 49: #include <sys/ioctl.h>
! 50: #include <sys/syslog.h>
! 51: #include <sys/proc.h>
! 52:
! 53: #include <net/if.h>
! 54: #include <net/if_dl.h>
! 55: #include <net/route.h>
! 56: #include <net/if_atm.h>
! 57:
! 58: #include <netinet/in.h>
! 59: #include <netinet/in_systm.h>
! 60: #include <netinet/in_var.h>
! 61: #include <netinet/ip.h>
! 62: #include <netinet/if_atm.h>
! 63:
! 64: #ifdef NATM
! 65: #include <netnatm/natm.h>
! 66: #endif
! 67:
! 68:
! 69: #define SDL(s) ((struct sockaddr_dl *)s)
! 70:
! 71: /*
! 72: * atm_rtrequest: handle ATM rt request (in support of generic code)
! 73: * inputs: "req" = request code
! 74: * "rt" = route entry
! 75: * "sa" = sockaddr
! 76: */
! 77:
! 78: void
! 79: atm_rtrequest(req, rt, info)
! 80: int req;
! 81: struct rtentry *rt;
! 82: struct rt_addrinfo *info;
! 83: {
! 84: struct sockaddr *gate = rt->rt_gateway;
! 85: struct atm_pseudoioctl api;
! 86: #ifdef NATM
! 87: struct sockaddr_in *sin;
! 88: struct natmpcb *npcb = NULL;
! 89: struct atm_pseudohdr *aph;
! 90: #endif
! 91: static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
! 92:
! 93: if (rt->rt_flags & RTF_GATEWAY) /* link level requests only */
! 94: return;
! 95:
! 96: switch (req) {
! 97:
! 98: case RTM_RESOLVE: /* resolve: only happens when cloning */
! 99: printf("atm_rtrequest: RTM_RESOLVE request detected?\n");
! 100: break;
! 101:
! 102: case RTM_ADD:
! 103:
! 104: /*
! 105: * route added by a command (e.g. ifconfig, route, arp...).
! 106: *
! 107: * first check to see if this is not a host route, in which
! 108: * case we are being called via "ifconfig" to set the address.
! 109: */
! 110:
! 111: if ((rt->rt_flags & RTF_HOST) == 0) {
! 112: rt_setgate(rt,rt_key(rt),(struct sockaddr *)&null_sdl, 0);
! 113: gate = rt->rt_gateway;
! 114: SDL(gate)->sdl_type = rt->rt_ifp->if_type;
! 115: SDL(gate)->sdl_index = rt->rt_ifp->if_index;
! 116: break;
! 117: }
! 118:
! 119: if ((rt->rt_flags & RTF_CLONING) != 0) {
! 120: printf("atm_rtrequest: cloning route detected?\n");
! 121: break;
! 122: }
! 123: if (gate->sa_family != AF_LINK ||
! 124: gate->sa_len < sizeof(null_sdl)) {
! 125: log(LOG_DEBUG, "atm_rtrequest: bad gateway value\n");
! 126: break;
! 127: }
! 128:
! 129: #ifdef DIAGNOSTIC
! 130: if (rt->rt_ifp->if_ioctl == NULL) panic("atm null ioctl");
! 131: #endif
! 132:
! 133: #ifdef NATM
! 134: /*
! 135: * let native ATM know we are using this VCI/VPI
! 136: * (i.e. reserve it)
! 137: */
! 138: sin = (struct sockaddr_in *) rt_key(rt);
! 139: if (sin->sin_family != AF_INET)
! 140: goto failed;
! 141: aph = (struct atm_pseudohdr *) LLADDR(SDL(gate));
! 142: npcb = npcb_add(NULL, rt->rt_ifp, ATM_PH_VCI(aph),
! 143: ATM_PH_VPI(aph));
! 144: if (npcb == NULL)
! 145: goto failed;
! 146: npcb->npcb_flags |= NPCB_IP;
! 147: npcb->ipaddr.s_addr = sin->sin_addr.s_addr;
! 148: /* XXX: move npcb to llinfo when ATM ARP is ready */
! 149: rt->rt_llinfo = (caddr_t) npcb;
! 150: rt->rt_flags |= RTF_LLINFO;
! 151: #endif
! 152: /*
! 153: * let the lower level know this circuit is active
! 154: */
! 155: bcopy(LLADDR(SDL(gate)), &api.aph, sizeof(api.aph));
! 156: api.rxhand = NULL;
! 157: if (rt->rt_ifp->if_ioctl(rt->rt_ifp, SIOCATMENA,
! 158: (caddr_t)&api) != 0) {
! 159: printf("atm: couldn't add VC\n");
! 160: goto failed;
! 161: }
! 162:
! 163: SDL(gate)->sdl_type = rt->rt_ifp->if_type;
! 164: SDL(gate)->sdl_index = rt->rt_ifp->if_index;
! 165:
! 166: break;
! 167:
! 168: failed:
! 169: #ifdef NATM
! 170: if (npcb) {
! 171: npcb_free(npcb, NPCB_DESTROY);
! 172: rt->rt_llinfo = NULL;
! 173: rt->rt_flags &= ~RTF_LLINFO;
! 174: }
! 175: #endif
! 176: rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
! 177: rt_mask(rt), 0, (struct rtentry **) 0, 0);
! 178: break;
! 179:
! 180: case RTM_DELETE:
! 181:
! 182: #ifdef NATM
! 183: /*
! 184: * tell native ATM we are done with this VC
! 185: */
! 186:
! 187: if (rt->rt_flags & RTF_LLINFO) {
! 188: npcb_free((struct natmpcb *)rt->rt_llinfo,
! 189: NPCB_DESTROY);
! 190: rt->rt_llinfo = NULL;
! 191: rt->rt_flags &= ~RTF_LLINFO;
! 192: }
! 193: #endif
! 194: /*
! 195: * tell the lower layer to disable this circuit
! 196: */
! 197:
! 198: bcopy(LLADDR(SDL(gate)), &api.aph, sizeof(api.aph));
! 199: api.rxhand = NULL;
! 200: (void)rt->rt_ifp->if_ioctl(rt->rt_ifp, SIOCATMDIS,
! 201: (caddr_t)&api);
! 202:
! 203: break;
! 204: }
! 205: }
! 206:
! 207: /*
! 208: * atmresolve:
! 209: * inputs:
! 210: * [1] "rt" = the link level route to use (or null if need to look one up)
! 211: * [2] "m" = mbuf containing the data to be sent
! 212: * [3] "dst" = sockaddr_in (IP) address of dest.
! 213: * output:
! 214: * [4] "desten" = ATM pseudo header which we will fill in VPI/VCI info
! 215: * return:
! 216: * 0 == resolve FAILED; note that "m" gets m_freem'd in this case
! 217: * 1 == resolve OK; desten contains result
! 218: *
! 219: * XXX: will need more work if we wish to support ATMARP in the kernel,
! 220: * but this is enough for PVCs entered via the "route" command.
! 221: */
! 222:
! 223: int
! 224: atmresolve(rt, m, dst, desten)
! 225: struct rtentry *rt;
! 226: struct mbuf *m;
! 227: struct sockaddr *dst;
! 228: struct atm_pseudohdr *desten; /* OUT */
! 229: {
! 230: struct sockaddr_dl *sdl;
! 231:
! 232: if (m->m_flags & (M_BCAST|M_MCAST)) {
! 233: log(LOG_INFO,
! 234: "atmresolve: BCAST/MCAST packet detected/dumped\n");
! 235: goto bad;
! 236: }
! 237:
! 238: if (rt == NULL) {
! 239: rt = RTALLOC1(dst, 0);
! 240: if (rt == NULL) goto bad; /* failed */
! 241: rt->rt_refcnt--; /* don't keep LL references */
! 242: if ((rt->rt_flags & RTF_GATEWAY) != 0 ||
! 243: (rt->rt_flags & RTF_LLINFO) == 0 ||
! 244: /* XXX: are we using LLINFO? */
! 245: rt->rt_gateway->sa_family != AF_LINK) {
! 246: goto bad;
! 247: }
! 248: }
! 249:
! 250: /*
! 251: * note that rt_gateway is a sockaddr_dl which contains the
! 252: * atm_pseudohdr data structure for this route. we currently
! 253: * don't need any rt_llinfo info (but will if we want to support
! 254: * ATM ARP [c.f. if_ether.c]).
! 255: */
! 256:
! 257: sdl = SDL(rt->rt_gateway);
! 258:
! 259: /*
! 260: * Check the address family and length is valid, the address
! 261: * is resolved; otherwise, try to resolve.
! 262: */
! 263:
! 264:
! 265: if (sdl->sdl_family == AF_LINK && sdl->sdl_alen == sizeof(*desten)) {
! 266: bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
! 267: return (1); /* ok, go for it! */
! 268: }
! 269:
! 270: /*
! 271: * we got an entry, but it doesn't have valid link address
! 272: * info in it (it is prob. the interface route, which has
! 273: * sdl_alen == 0). dump packet. (fall through to "bad").
! 274: */
! 275:
! 276: bad:
! 277: m_freem(m);
! 278: return (0);
! 279: }
! 280: #endif /* INET */
CVSweb