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