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