|
|
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: /*
23: * Copyright (c) 1984, 1985, 1986, 1987, 1993
24: * The Regents of the University of California. All rights reserved.
25: *
26: * Redistribution and use in source and binary forms, with or without
27: * modification, are permitted provided that the following conditions
28: * are met:
29: * 1. Redistributions of source code must retain the above copyright
30: * notice, this list of conditions and the following disclaimer.
31: * 2. Redistributions in binary form must reproduce the above copyright
32: * notice, this list of conditions and the following disclaimer in the
33: * documentation and/or other materials provided with the distribution.
34: * 3. All advertising materials mentioning features or use of this software
35: * must display the following acknowledgement:
36: * This product includes software developed by the University of
37: * California, Berkeley and its contributors.
38: * 4. Neither the name of the University nor the names of its contributors
39: * may be used to endorse or promote products derived from this software
40: * without specific prior written permission.
41: *
42: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52: * SUCH DAMAGE.
53: *
54: * @(#)ns.c 8.2 (Berkeley) 11/15/93
55: */
56:
57: #include <sys/param.h>
58: #include <sys/mbuf.h>
59: #include <sys/ioctl.h>
60: #include <sys/protosw.h>
61: #include <sys/errno.h>
62: #include <sys/socket.h>
63: #include <sys/socketvar.h>
64:
65: #include <net/if.h>
66: #include <net/route.h>
67:
68: #include <netns/ns.h>
69: #include <netns/ns_if.h>
70:
71: #ifdef NS
72:
73: struct ns_ifaddr *ns_ifaddr;
74: int ns_interfaces;
75: extern struct sockaddr_ns ns_netmask, ns_hostmask;
76:
77: /*
78: * Generic internet control operations (ioctl's).
79: */
80: /* ARGSUSED */
81: ns_control(so, cmd, data, ifp)
82: struct socket *so;
83: int cmd;
84: caddr_t data;
85: register struct ifnet *ifp;
86: {
87: register struct ifreq *ifr = (struct ifreq *)data;
88: register struct ns_aliasreq *ifra = (struct ns_aliasreq *)data;
89: register struct ns_ifaddr *ia;
90: struct ifaddr *ifa;
91: struct ns_ifaddr *oia;
92: int error, dstIsNew, hostIsNew;
93:
94: /*
95: * Find address for this interface, if it exists.
96: */
97: if (ifp == 0)
98: return (EADDRNOTAVAIL);
99: for (ia = ns_ifaddr; ia; ia = ia->ia_next)
100: if (ia->ia_ifp == ifp)
101: break;
102:
103: switch (cmd) {
104:
105: case SIOCGIFADDR:
106: if (ia == (struct ns_ifaddr *)0)
107: return (EADDRNOTAVAIL);
108: *(struct sockaddr_ns *)&ifr->ifr_addr = ia->ia_addr;
109: return (0);
110:
111:
112: case SIOCGIFBRDADDR:
113: if (ia == (struct ns_ifaddr *)0)
114: return (EADDRNOTAVAIL);
115: if ((ifp->if_flags & IFF_BROADCAST) == 0)
116: return (EINVAL);
117: *(struct sockaddr_ns *)&ifr->ifr_dstaddr = ia->ia_broadaddr;
118: return (0);
119:
120: case SIOCGIFDSTADDR:
121: if (ia == (struct ns_ifaddr *)0)
122: return (EADDRNOTAVAIL);
123: if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
124: return (EINVAL);
125: *(struct sockaddr_ns *)&ifr->ifr_dstaddr = ia->ia_dstaddr;
126: return (0);
127: }
128:
129: if ((so->so_state & SS_PRIV) == 0)
130: return (EPERM);
131:
132: switch (cmd) {
133: case SIOCAIFADDR:
134: case SIOCDIFADDR:
135: if (ifra->ifra_addr.sns_family == AF_NS)
136: for (oia = ia; ia; ia = ia->ia_next) {
137: if (ia->ia_ifp == ifp &&
138: ns_neteq(ia->ia_addr.sns_addr,
139: ifra->ifra_addr.sns_addr))
140: break;
141: }
142: if (cmd == SIOCDIFADDR && ia == 0)
143: return (EADDRNOTAVAIL);
144: /* FALLTHROUGH */
145:
146: case SIOCSIFADDR:
147: case SIOCSIFDSTADDR:
148: if (ia == (struct ns_ifaddr *)0) {
149: // oia = (struct ns_ifaddr *)
150: // malloc(sizeof *ia, M_IFADDR, M_WAITOK);
151: MALLOC(oia, struct ns_ifaddr *, sizeof *ia, M_IFADDR, M_WAITOK);
152: if (oia == (struct ns_ifaddr *)NULL)
153: return (ENOBUFS);
154: bzero((caddr_t)oia, sizeof(*oia));
155: if (ia = ns_ifaddr) {
156: for ( ; ia->ia_next; ia = ia->ia_next)
157: ;
158: ia->ia_next = oia;
159: } else
160: ns_ifaddr = oia;
161: ia = oia;
162: if (ifa = ifp->if_addrlist) {
163: for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
164: ;
165: ifa->ifa_next = (struct ifaddr *) ia;
166: } else
167: ifp->if_addrlist = (struct ifaddr *) ia;
168: ia->ia_ifp = ifp;
169: ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
170:
171: ia->ia_ifa.ifa_netmask =
172: (struct sockaddr *)&ns_netmask;
173:
174: ia->ia_ifa.ifa_dstaddr =
175: (struct sockaddr *)&ia->ia_dstaddr;
176: if (ifp->if_flags & IFF_BROADCAST) {
177: ia->ia_broadaddr.sns_family = AF_NS;
178: ia->ia_broadaddr.sns_len = sizeof(ia->ia_addr);
179: ia->ia_broadaddr.sns_addr.x_host = ns_broadhost;
180: }
181: ns_interfaces++;
182: }
183: }
184:
185: switch (cmd) {
186: int error;
187:
188: case SIOCSIFDSTADDR:
189: if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
190: return (EINVAL);
191: if (ia->ia_flags & IFA_ROUTE) {
192: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
193: ia->ia_flags &= ~IFA_ROUTE;
194: }
195: if (ifp->if_ioctl) {
196: error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia);
197: if (error)
198: return (error);
199: }
200: *(struct sockaddr *)&ia->ia_dstaddr = ifr->ifr_dstaddr;
201: return (0);
202:
203: case SIOCSIFADDR:
204: return (ns_ifinit(ifp, ia,
205: (struct sockaddr_ns *)&ifr->ifr_addr, 1));
206:
207: case SIOCDIFADDR:
208: ns_ifscrub(ifp, ia);
209: if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
210: ifp->if_addrlist = ifa->ifa_next;
211: else {
212: while (ifa->ifa_next &&
213: (ifa->ifa_next != (struct ifaddr *)ia))
214: ifa = ifa->ifa_next;
215: if (ifa->ifa_next)
216: ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
217: else
218: printf("Couldn't unlink nsifaddr from ifp\n");
219: }
220: oia = ia;
221: if (oia == (ia = ns_ifaddr)) {
222: ns_ifaddr = ia->ia_next;
223: } else {
224: while (ia->ia_next && (ia->ia_next != oia)) {
225: ia = ia->ia_next;
226: }
227: if (ia->ia_next)
228: ia->ia_next = oia->ia_next;
229: else
230: printf("Didn't unlink nsifadr from list\n");
231: }
232: IFAFREE((&oia->ia_ifa));
233: if (0 == --ns_interfaces) {
234: /*
235: * We reset to virginity and start all over again
236: */
237: ns_thishost = ns_zerohost;
238: }
239: return (0);
240:
241: case SIOCAIFADDR:
242: dstIsNew = 0; hostIsNew = 1;
243: if (ia->ia_addr.sns_family == AF_NS) {
244: if (ifra->ifra_addr.sns_len == 0) {
245: ifra->ifra_addr = ia->ia_addr;
246: hostIsNew = 0;
247: } else if (ns_neteq(ifra->ifra_addr.sns_addr,
248: ia->ia_addr.sns_addr))
249: hostIsNew = 0;
250: }
251: if ((ifp->if_flags & IFF_POINTOPOINT) &&
252: (ifra->ifra_dstaddr.sns_family == AF_NS)) {
253: if (hostIsNew == 0)
254: ns_ifscrub(ifp, ia);
255: ia->ia_dstaddr = ifra->ifra_dstaddr;
256: dstIsNew = 1;
257: }
258: if (ifra->ifra_addr.sns_family == AF_NS &&
259: (hostIsNew || dstIsNew))
260: error = ns_ifinit(ifp, ia, &ifra->ifra_addr, 0);
261: return (error);
262:
263: default:
264: if (ifp->if_ioctl == 0)
265: return (EOPNOTSUPP);
266: return ((*ifp->if_ioctl)(ifp, cmd, data));
267: }
268: }
269:
270: /*
271: * Delete any previous route for an old address.
272: */
273: ns_ifscrub(ifp, ia)
274: register struct ifnet *ifp;
275: register struct ns_ifaddr *ia;
276: {
277: if (ia->ia_flags & IFA_ROUTE) {
278: if (ifp->if_flags & IFF_POINTOPOINT) {
279: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
280: } else
281: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
282: ia->ia_flags &= ~IFA_ROUTE;
283: }
284: }
285: /*
286: * Initialize an interface's internet address
287: * and routing table entry.
288: */
289: ns_ifinit(ifp, ia, sns, scrub)
290: register struct ifnet *ifp;
291: register struct ns_ifaddr *ia;
292: register struct sockaddr_ns *sns;
293: {
294: struct sockaddr_ns oldaddr;
295: register union ns_host *h = &ia->ia_addr.sns_addr.x_host;
296: int s = splimp(), error;
297:
298: /*
299: * Set up new addresses.
300: */
301: oldaddr = ia->ia_addr;
302: ia->ia_addr = *sns;
303: /*
304: * The convention we shall adopt for naming is that
305: * a supplied address of zero means that "we don't care".
306: * if there is a single interface, use the address of that
307: * interface as our 6 byte host address.
308: * if there are multiple interfaces, use any address already
309: * used.
310: *
311: * Give the interface a chance to initialize
312: * if this is its first address,
313: * and to validate the address if necessary.
314: */
315: if (ns_hosteqnh(ns_thishost, ns_zerohost)) {
316: if (ifp->if_ioctl &&
317: (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
318: ia->ia_addr = oldaddr;
319: splx(s);
320: return (error);
321: }
322: ns_thishost = *h;
323: } else if (ns_hosteqnh(sns->sns_addr.x_host, ns_zerohost)
324: || ns_hosteqnh(sns->sns_addr.x_host, ns_thishost)) {
325: *h = ns_thishost;
326: if (ifp->if_ioctl &&
327: (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
328: ia->ia_addr = oldaddr;
329: splx(s);
330: return (error);
331: }
332: if (!ns_hosteqnh(ns_thishost,*h)) {
333: ia->ia_addr = oldaddr;
334: splx(s);
335: return (EINVAL);
336: }
337: } else {
338: ia->ia_addr = oldaddr;
339: splx(s);
340: return (EINVAL);
341: }
342: ia->ia_ifa.ifa_metric = ifp->if_metric;
343: /*
344: * Add route for the network.
345: */
346: if (scrub) {
347: ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
348: ns_ifscrub(ifp, ia);
349: ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
350: }
351: if (ifp->if_flags & IFF_POINTOPOINT)
352: rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
353: else {
354: ia->ia_broadaddr.sns_addr.x_net = ia->ia_addr.sns_addr.x_net;
355: rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
356: }
357: ia->ia_flags |= IFA_ROUTE;
358: return (0);
359: }
360:
361: /*
362: * Return address info for specified internet network.
363: */
364: struct ns_ifaddr *
365: ns_iaonnetof(dst)
366: register struct ns_addr *dst;
367: {
368: register struct ns_ifaddr *ia;
369: register struct ns_addr *compare;
370: register struct ifnet *ifp;
371: struct ns_ifaddr *ia_maybe = 0;
372: union ns_net net = dst->x_net;
373:
374: for (ia = ns_ifaddr; ia; ia = ia->ia_next) {
375: if (ifp = ia->ia_ifp) {
376: if (ifp->if_flags & IFF_POINTOPOINT) {
377: compare = &satons_addr(ia->ia_dstaddr);
378: if (ns_hosteq(*dst, *compare))
379: return (ia);
380: if (ns_neteqnn(net, ia->ia_addr.sns_addr.x_net))
381: ia_maybe = ia;
382: } else {
383: if (ns_neteqnn(net, ia->ia_addr.sns_addr.x_net))
384: return (ia);
385: }
386: }
387: }
388: return (ia_maybe);
389: }
390: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.