xref: /csrg-svn/sys/netns/ns.c (revision 21481)
1*21481Ssklower /*      ns.c     6.1     85/05/30     */
2*21481Ssklower 
3*21481Ssklower #include "param.h"
4*21481Ssklower #include "mbuf.h"
5*21481Ssklower #include "ioctl.h"
6*21481Ssklower #include "protosw.h"
7*21481Ssklower #include "socket.h"
8*21481Ssklower #include "socketvar.h"
9*21481Ssklower #include "uio.h"
10*21481Ssklower #include "dir.h"
11*21481Ssklower #include "user.h"
12*21481Ssklower 
13*21481Ssklower 
14*21481Ssklower #include "../net/if.h"
15*21481Ssklower #include "../net/route.h"
16*21481Ssklower #include "../net/af.h"
17*21481Ssklower 
18*21481Ssklower #include "ns.h"
19*21481Ssklower #include "ns_if.h"
20*21481Ssklower 
21*21481Ssklower #ifdef NS
22*21481Ssklower 
23*21481Ssklower struct ns_ifaddr *ns_ifaddr;
24*21481Ssklower 
25*21481Ssklower ns_hash(sns, hp)
26*21481Ssklower 	register struct sockaddr_ns *sns;
27*21481Ssklower 	struct afhash *hp;
28*21481Ssklower {
29*21481Ssklower 	register long hash = 0;
30*21481Ssklower 	register u_short *s =  sns->sns_addr.x_host.s_host;
31*21481Ssklower 
32*21481Ssklower 	hp->afh_nethash = ns_netof(sns->sns_addr);
33*21481Ssklower 	hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
34*21481Ssklower 	hp->afh_hosthash =  hash;
35*21481Ssklower }
36*21481Ssklower 
37*21481Ssklower 
38*21481Ssklower ns_netmatch(sns1, sns2)
39*21481Ssklower 	struct sockaddr_ns *sns1, *sns2;
40*21481Ssklower {
41*21481Ssklower 
42*21481Ssklower 	return (ns_netof(sns1->sns_addr) == ns_netof(sns2->sns_addr));
43*21481Ssklower }
44*21481Ssklower 
45*21481Ssklower /*
46*21481Ssklower  * Generic internet control operations (ioctl's).
47*21481Ssklower  */
48*21481Ssklower ns_control(so, cmd, data, ifp)
49*21481Ssklower 	struct socket *so;
50*21481Ssklower 	int cmd;
51*21481Ssklower 	caddr_t data;
52*21481Ssklower 	register struct ifnet *ifp;
53*21481Ssklower {
54*21481Ssklower 	register struct ifreq *ifr = (struct ifreq *)data;
55*21481Ssklower 	register struct ns_ifaddr *ia;
56*21481Ssklower 	struct ifaddr *ifa;
57*21481Ssklower 	struct mbuf *m;
58*21481Ssklower 	int error;
59*21481Ssklower 
60*21481Ssklower 	if (!suser())
61*21481Ssklower 		return (u.u_error);
62*21481Ssklower 
63*21481Ssklower 	/*
64*21481Ssklower 	 * Find address for this interface, if it exists.
65*21481Ssklower 	 */
66*21481Ssklower 	for (ia = ns_ifaddr; ia; ia = ia->ia_next)
67*21481Ssklower 		if (ia->ia_ifp == ifp)
68*21481Ssklower 			break;
69*21481Ssklower 
70*21481Ssklower 	switch (cmd) {
71*21481Ssklower 
72*21481Ssklower 	case SIOCGIFADDR:
73*21481Ssklower 	case SIOCGIFBRDADDR:
74*21481Ssklower 	case SIOCGIFDSTADDR:
75*21481Ssklower 		if (ia == (struct ns_ifaddr *)0)
76*21481Ssklower 			return (EADDRNOTAVAIL);
77*21481Ssklower 		break;
78*21481Ssklower 
79*21481Ssklower 	case SIOCSIFDSTADDR:
80*21481Ssklower 		return (EOPNOTSUPP);
81*21481Ssklower 
82*21481Ssklower 	case SIOCSIFADDR:
83*21481Ssklower 		if (ia == (struct ns_ifaddr *)0) {
84*21481Ssklower 			m = m_getclr(M_WAIT, MT_IFADDR);
85*21481Ssklower 			if (m == (struct mbuf *)NULL)
86*21481Ssklower 				return (ENOBUFS);
87*21481Ssklower 			if (ia = ns_ifaddr) {
88*21481Ssklower 				for ( ; ia->ia_next; ia = ia->ia_next)
89*21481Ssklower 					;
90*21481Ssklower 				ia->ia_next = mtod(m, struct ns_ifaddr *);
91*21481Ssklower 			} else
92*21481Ssklower 				ns_ifaddr = mtod(m, struct ns_ifaddr *);
93*21481Ssklower 			ia = mtod(m, struct ns_ifaddr *);
94*21481Ssklower 			if (ifa = ifp->if_addrlist) {
95*21481Ssklower 				for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
96*21481Ssklower 					;
97*21481Ssklower 				ifa->ifa_next = (struct ifaddr *) ia;
98*21481Ssklower 			} else
99*21481Ssklower 				ifp->if_addrlist = (struct ifaddr *) ia;
100*21481Ssklower 			ia->ia_ifp = ifp;
101*21481Ssklower 			IA_SNS(ia)->sns_family = AF_NS;
102*21481Ssklower 		}
103*21481Ssklower 		break;
104*21481Ssklower 	}
105*21481Ssklower 
106*21481Ssklower 	switch (cmd) {
107*21481Ssklower 
108*21481Ssklower 	case SIOCGIFADDR:
109*21481Ssklower 		ifr->ifr_addr = ia->ia_addr;
110*21481Ssklower 		break;
111*21481Ssklower 
112*21481Ssklower 	case SIOCGIFBRDADDR:
113*21481Ssklower 		if (ia == (struct ns_ifaddr *)0)
114*21481Ssklower 			return (EADDRNOTAVAIL);
115*21481Ssklower 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
116*21481Ssklower 			return (EINVAL);
117*21481Ssklower 		ifr->ifr_dstaddr = ia->ia_broadaddr;
118*21481Ssklower 		break;
119*21481Ssklower 
120*21481Ssklower 	case SIOCGIFDSTADDR:
121*21481Ssklower 		if (ia == (struct ns_ifaddr *)0)
122*21481Ssklower 			return (EADDRNOTAVAIL);
123*21481Ssklower 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
124*21481Ssklower 			return (EINVAL);
125*21481Ssklower 		ifr->ifr_dstaddr = ia->ia_dstaddr;
126*21481Ssklower 		break;
127*21481Ssklower 
128*21481Ssklower 	case SIOCSIFADDR:
129*21481Ssklower 		return
130*21481Ssklower 		    (ns_ifinit(ifp, ia, (struct sockaddr_ns *)&ifr->ifr_addr));
131*21481Ssklower 
132*21481Ssklower 	default:
133*21481Ssklower 		if (ifp->if_ioctl == 0)
134*21481Ssklower 			return (EOPNOTSUPP);
135*21481Ssklower 		return ((*ifp->if_ioctl)(ifp, cmd, data));
136*21481Ssklower 	}
137*21481Ssklower 	return (0);
138*21481Ssklower }
139*21481Ssklower 
140*21481Ssklower /*
141*21481Ssklower  * Initialize an interface's internet address
142*21481Ssklower  * and routing table entry.
143*21481Ssklower  */
144*21481Ssklower ns_ifinit(ifp, ia, sns)
145*21481Ssklower 	register struct ifnet *ifp;
146*21481Ssklower 	register struct ns_ifaddr *ia;
147*21481Ssklower 	struct sockaddr_ns *sns;
148*21481Ssklower {
149*21481Ssklower 	struct sockaddr_ns netaddr;
150*21481Ssklower 	register union ns_host *h = &(IA_SNS(ia)->sns_addr.x_host);
151*21481Ssklower 	int s = splimp(), error;
152*21481Ssklower 
153*21481Ssklower 	/*
154*21481Ssklower 	 * The convention we shall adopt for naming is that
155*21481Ssklower 	 * a supplied address of zero means that "we don't care".
156*21481Ssklower 	 * if there is a single interface, use the address of that
157*21481Ssklower 	 * interface as our 6 byte host address.
158*21481Ssklower 	 * if there are multiple interfaces, use any address already
159*21481Ssklower 	 * used.
160*21481Ssklower 	 *
161*21481Ssklower 	 * If we have gotten into trouble and want to reset back to
162*21481Ssklower 	 * virginity, we recognize a request of the broadcast address.
163*21481Ssklower 	 */
164*21481Ssklower 	if (ns_hosteqnh(sns->sns_addr.x_host, ns_broadhost)) {
165*21481Ssklower 		ns_thishost = ns_zerohost;
166*21481Ssklower 		splx(s);
167*21481Ssklower 		return(EINVAL);
168*21481Ssklower 	}
169*21481Ssklower 
170*21481Ssklower 	/*
171*21481Ssklower 	 * Delete any previous route for an old address.
172*21481Ssklower 	 */
173*21481Ssklower 
174*21481Ssklower 	bzero((caddr_t)&netaddr, sizeof (netaddr));
175*21481Ssklower 	netaddr.sns_family = AF_NS;
176*21481Ssklower 	netaddr.sns_addr.x_host = ns_broadhost;
177*21481Ssklower 	netaddr.sns_addr.x_net = ia->ia_net;
178*21481Ssklower 	if (ia->ia_flags & IFA_ROUTE) {
179*21481Ssklower 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
180*21481Ssklower 		    rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, -1);
181*21481Ssklower 		} else
182*21481Ssklower 		    rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr, -1);
183*21481Ssklower 	}
184*21481Ssklower 
185*21481Ssklower 	/*
186*21481Ssklower 	 * Set up new addresses.
187*21481Ssklower 	 */
188*21481Ssklower 	ia->ia_addr = *(struct sockaddr *)sns;
189*21481Ssklower 	ia->ia_net = sns->sns_addr.x_net;
190*21481Ssklower 	netaddr.sns_addr.x_net = ia->ia_net;
191*21481Ssklower 	if (ifp->if_flags & IFF_BROADCAST) {
192*21481Ssklower 		ia->ia_broadaddr = * (struct sockaddr *) &netaddr;
193*21481Ssklower 	}
194*21481Ssklower 	/*
195*21481Ssklower 	 * Point to point links are a little touchier --
196*21481Ssklower 	 * We have to have an address of our own first,
197*21481Ssklower 	 * and will use the supplied address as that of the other end.
198*21481Ssklower 	 */
199*21481Ssklower 	if (ifp->if_flags & IFF_POINTOPOINT) {
200*21481Ssklower 		struct sockaddr_ns *sns2 = IA_SNS(ia);
201*21481Ssklower 		if (ns_hosteqnh(ns_zerohost,ns_thishost))
202*21481Ssklower 			return(EINVAL);
203*21481Ssklower 		ia->ia_dstaddr = ia->ia_addr;
204*21481Ssklower 		sns2->sns_addr.x_host = ns_thishost;
205*21481Ssklower 		sns->sns_addr.x_host = ns_thishost;
206*21481Ssklower 	}
207*21481Ssklower 	/*
208*21481Ssklower 	 * Give the interface a chance to initialize
209*21481Ssklower 	 * if this is its first address,
210*21481Ssklower 	 * and to validate the address if necessary.
211*21481Ssklower 	 */
212*21481Ssklower 
213*21481Ssklower 	if (ns_hosteqnh(ns_thishost, ns_zerohost)) {
214*21481Ssklower 		if (ifp->if_ioctl &&
215*21481Ssklower 		     (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
216*21481Ssklower 			splx(s);
217*21481Ssklower 			return (error);
218*21481Ssklower 		}
219*21481Ssklower 		ns_thishost = *h;
220*21481Ssklower 	} else if (ns_hosteqnh(sns->sns_addr.x_host, ns_zerohost)
221*21481Ssklower 	    || ns_hosteqnh(sns->sns_addr.x_host, ns_thishost)) {
222*21481Ssklower 		*h = ns_thishost;
223*21481Ssklower 		if (ifp->if_ioctl &&
224*21481Ssklower 		     (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
225*21481Ssklower 			splx(s);
226*21481Ssklower 			return (error);
227*21481Ssklower 		}
228*21481Ssklower 		if(!ns_hosteqnh(ns_thishost,*h)) {
229*21481Ssklower 			splx(s);
230*21481Ssklower 			return (EINVAL);
231*21481Ssklower 		}
232*21481Ssklower 	} else {
233*21481Ssklower 		splx(s);
234*21481Ssklower 		return(EINVAL);
235*21481Ssklower 	}
236*21481Ssklower 	/*
237*21481Ssklower 	 * Add route for the network.
238*21481Ssklower 	 */
239*21481Ssklower 	if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
240*21481Ssklower 		rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, RTF_UP);
241*21481Ssklower 	} else
242*21481Ssklower 		rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr,
243*21481Ssklower 			RTF_HOST|RTF_UP);
244*21481Ssklower 	ia->ia_flags |= IFA_ROUTE;
245*21481Ssklower 	return(0);
246*21481Ssklower }
247*21481Ssklower 
248*21481Ssklower /*
249*21481Ssklower  * Return address info for specified internet network.
250*21481Ssklower  */
251*21481Ssklower struct ns_ifaddr *
252*21481Ssklower ns_iaonnetof(net)
253*21481Ssklower 	union ns_net net;
254*21481Ssklower {
255*21481Ssklower 	register struct ns_ifaddr *ia;
256*21481Ssklower 
257*21481Ssklower #define	NtoL(x)	(*(long *)(&(x)))
258*21481Ssklower 	for (ia = ns_ifaddr; ia; ia = ia->ia_next)
259*21481Ssklower 		if (NtoL(ia->ia_net) == NtoL(net))
260*21481Ssklower 			return (ia);
261*21481Ssklower 	return ((struct ns_ifaddr *)0);
262*21481Ssklower }
263*21481Ssklower #endif
264