bring up to revision 7 for tahoe release
[unix-history] / usr / src / sys / netns / ns.c
CommitLineData
8ae0e4b4 1/*
240edf1f
KS
2 * Copyright (c) 1984, 1985, 1986, 1987 Regents of the University of California.
3 * All rights reserved.
8ae0e4b4 4 *
240edf1f
KS
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of California at Berkeley. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific prior written permission. This software
10 * is provided ``as is'' without express or implied warranty.
11 *
12 * @(#)ns.c 7.2 (Berkeley) %G%
8ae0e4b4 13 */
de9bc7de
KS
14
15#include "param.h"
16#include "mbuf.h"
17#include "ioctl.h"
18#include "protosw.h"
19#include "socket.h"
20#include "socketvar.h"
21#include "uio.h"
22#include "dir.h"
23#include "user.h"
24
25
26#include "../net/if.h"
27#include "../net/route.h"
28#include "../net/af.h"
29
30#include "ns.h"
31#include "ns_if.h"
32
33#ifdef NS
34
35struct ns_ifaddr *ns_ifaddr;
36
37ns_hash(sns, hp)
38 register struct sockaddr_ns *sns;
39 struct afhash *hp;
40{
41 register long hash = 0;
42 register u_short *s = sns->sns_addr.x_host.s_host;
f1e269d4
KS
43 union {
44 union ns_net net_e;
45 long long_e;
46 } net;
de9bc7de 47
f1e269d4
KS
48 net.net_e = sns->sns_addr.x_net;
49 hp->afh_nethash = net.long_e;
de9bc7de
KS
50 hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
51 hp->afh_hosthash = hash;
52}
53
54
55ns_netmatch(sns1, sns2)
56 struct sockaddr_ns *sns1, *sns2;
57{
58
f1e269d4 59 return (ns_neteq(sns1->sns_addr, sns2->sns_addr));
de9bc7de
KS
60}
61
62/*
63 * Generic internet control operations (ioctl's).
64 */
f97be0c9 65/* ARGSUSED */
de9bc7de
KS
66ns_control(so, cmd, data, ifp)
67 struct socket *so;
68 int cmd;
69 caddr_t data;
70 register struct ifnet *ifp;
71{
72 register struct ifreq *ifr = (struct ifreq *)data;
73 register struct ns_ifaddr *ia;
74 struct ifaddr *ifa;
75 struct mbuf *m;
de9bc7de 76
de9bc7de
KS
77 /*
78 * Find address for this interface, if it exists.
79 */
8b659320 80 if (ifp == 0)
4353fa68 81 return (EADDRNOTAVAIL);
de9bc7de
KS
82 for (ia = ns_ifaddr; ia; ia = ia->ia_next)
83 if (ia->ia_ifp == ifp)
84 break;
85
86 switch (cmd) {
87
88 case SIOCGIFADDR:
4353fa68
KS
89 if (ia == (struct ns_ifaddr *)0)
90 return (EADDRNOTAVAIL);
91 ifr->ifr_addr = ia->ia_addr;
92 return (0);
93
94
de9bc7de 95 case SIOCGIFBRDADDR:
4353fa68
KS
96 if (ia == (struct ns_ifaddr *)0)
97 return (EADDRNOTAVAIL);
98 if ((ifp->if_flags & IFF_BROADCAST) == 0)
99 return (EINVAL);
100 ifr->ifr_dstaddr = ia->ia_broadaddr;
101 return (0);
102
de9bc7de
KS
103 case SIOCGIFDSTADDR:
104 if (ia == (struct ns_ifaddr *)0)
105 return (EADDRNOTAVAIL);
4353fa68
KS
106 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
107 return (EINVAL);
108 ifr->ifr_dstaddr = ia->ia_dstaddr;
109 return (0);
110 }
111
112 if (!suser())
113 return (u.u_error);
114
115 switch (cmd) {
de9bc7de 116
de9bc7de 117 case SIOCSIFADDR:
8b659320 118 case SIOCSIFDSTADDR:
de9bc7de
KS
119 if (ia == (struct ns_ifaddr *)0) {
120 m = m_getclr(M_WAIT, MT_IFADDR);
121 if (m == (struct mbuf *)NULL)
122 return (ENOBUFS);
123 if (ia = ns_ifaddr) {
124 for ( ; ia->ia_next; ia = ia->ia_next)
125 ;
126 ia->ia_next = mtod(m, struct ns_ifaddr *);
127 } else
128 ns_ifaddr = mtod(m, struct ns_ifaddr *);
129 ia = mtod(m, struct ns_ifaddr *);
130 if (ifa = ifp->if_addrlist) {
131 for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
132 ;
133 ifa->ifa_next = (struct ifaddr *) ia;
134 } else
135 ifp->if_addrlist = (struct ifaddr *) ia;
136 ia->ia_ifp = ifp;
137 IA_SNS(ia)->sns_family = AF_NS;
138 }
8b659320
KS
139 }
140
141 switch (cmd) {
142
143 case SIOCSIFDSTADDR:
144 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
145 return (EINVAL);
146 if (ia->ia_flags & IFA_ROUTE) {
147 rtinit(&ia->ia_dstaddr, &ia->ia_addr,
148 (int)SIOCDELRT, RTF_HOST);
149 ia->ia_flags &= ~IFA_ROUTE;
150 }
151 if (ifp->if_ioctl) {
152 int error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia);
153 if (error)
154 return (error);
155 }
156 ia->ia_dstaddr = ifr->ifr_dstaddr;
157 return (0);
158
159 case SIOCSIFADDR:
de9bc7de
KS
160 return
161 (ns_ifinit(ifp, ia, (struct sockaddr_ns *)&ifr->ifr_addr));
162
163 default:
164 if (ifp->if_ioctl == 0)
165 return (EOPNOTSUPP);
166 return ((*ifp->if_ioctl)(ifp, cmd, data));
167 }
de9bc7de
KS
168}
169
170/*
171 * Initialize an interface's internet address
172 * and routing table entry.
173 */
174ns_ifinit(ifp, ia, sns)
175 register struct ifnet *ifp;
176 register struct ns_ifaddr *ia;
177 struct sockaddr_ns *sns;
178{
179 struct sockaddr_ns netaddr;
180 register union ns_host *h = &(IA_SNS(ia)->sns_addr.x_host);
181 int s = splimp(), error;
182
183 /*
184 * The convention we shall adopt for naming is that
185 * a supplied address of zero means that "we don't care".
186 * if there is a single interface, use the address of that
187 * interface as our 6 byte host address.
188 * if there are multiple interfaces, use any address already
189 * used.
190 *
191 * If we have gotten into trouble and want to reset back to
192 * virginity, we recognize a request of the broadcast address.
193 */
194 if (ns_hosteqnh(sns->sns_addr.x_host, ns_broadhost)) {
195 ns_thishost = ns_zerohost;
196 splx(s);
8b659320 197 return (0);
de9bc7de
KS
198 }
199
200 /*
201 * Delete any previous route for an old address.
202 */
de9bc7de
KS
203 bzero((caddr_t)&netaddr, sizeof (netaddr));
204 netaddr.sns_family = AF_NS;
205 netaddr.sns_addr.x_host = ns_broadhost;
206 netaddr.sns_addr.x_net = ia->ia_net;
207 if (ia->ia_flags & IFA_ROUTE) {
208 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
8b659320
KS
209 rtinit((struct sockaddr *)&netaddr, &ia->ia_addr,
210 (int)SIOCDELRT, 0);
de9bc7de 211 } else
8b659320
KS
212 rtinit(&ia->ia_dstaddr, &ia->ia_addr,
213 (int)SIOCDELRT, RTF_HOST);
de9bc7de
KS
214 }
215
216 /*
217 * Set up new addresses.
218 */
219 ia->ia_addr = *(struct sockaddr *)sns;
220 ia->ia_net = sns->sns_addr.x_net;
221 netaddr.sns_addr.x_net = ia->ia_net;
222 if (ifp->if_flags & IFF_BROADCAST) {
223 ia->ia_broadaddr = * (struct sockaddr *) &netaddr;
224 }
8b659320 225
de9bc7de
KS
226 /*
227 * Give the interface a chance to initialize
228 * if this is its first address,
229 * and to validate the address if necessary.
230 */
de9bc7de
KS
231 if (ns_hosteqnh(ns_thishost, ns_zerohost)) {
232 if (ifp->if_ioctl &&
233 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
234 splx(s);
235 return (error);
236 }
237 ns_thishost = *h;
238 } else if (ns_hosteqnh(sns->sns_addr.x_host, ns_zerohost)
239 || ns_hosteqnh(sns->sns_addr.x_host, ns_thishost)) {
240 *h = ns_thishost;
241 if (ifp->if_ioctl &&
242 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
243 splx(s);
244 return (error);
245 }
8b659320 246 if (!ns_hosteqnh(ns_thishost,*h)) {
de9bc7de
KS
247 splx(s);
248 return (EINVAL);
249 }
250 } else {
251 splx(s);
8b659320 252 return (EINVAL);
de9bc7de 253 }
8b659320 254
de9bc7de
KS
255 /*
256 * Add route for the network.
257 */
8b659320
KS
258 if (ifp->if_flags & IFF_POINTOPOINT)
259 rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
de9bc7de 260 RTF_HOST|RTF_UP);
8b659320
KS
261 else
262 rtinit(&ia->ia_broadaddr, &ia->ia_addr, (int)SIOCADDRT,
263 RTF_UP);
de9bc7de 264 ia->ia_flags |= IFA_ROUTE;
8b659320 265 return (0);
de9bc7de
KS
266}
267
268/*
269 * Return address info for specified internet network.
270 */
271struct ns_ifaddr *
46aa06a9
KS
272ns_iaonnetof(dst)
273 register struct ns_addr *dst;
de9bc7de
KS
274{
275 register struct ns_ifaddr *ia;
46aa06a9 276 register struct ns_addr *compare;
8b659320
KS
277 register struct ifnet *ifp;
278 struct ns_ifaddr *ia_maybe = 0;
f1e269d4 279 union ns_net net = dst->x_net;
de9bc7de 280
46aa06a9 281 for (ia = ns_ifaddr; ia; ia = ia->ia_next) {
8b659320
KS
282 if (ifp = ia->ia_ifp) {
283 if (ifp->if_flags & IFF_POINTOPOINT) {
284 compare = &satons_addr(ia->ia_dstaddr);
285 if (ns_hosteq(*dst, *compare))
286 return (ia);
f1e269d4 287 if (ns_neteqnn(net, ia->ia_net))
8b659320
KS
288 ia_maybe = ia;
289 } else {
f1e269d4 290 if (ns_neteqnn(net, ia->ia_net))
46aa06a9
KS
291 return (ia);
292 }
293 }
294 }
295 return (ia_maybe);
de9bc7de
KS
296}
297#endif