]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/if_atm.c
xnu-201.42.3.tar.gz
[apple/xnu.git] / bsd / netinet / if_atm.c
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 */