Annotation of sys/netinet/if_atm.c, Revision 1.1.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