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