split out descend and inherit attributes; add signal tracing
[unix-history] / usr / src / sys / netiso / iso_snpac.c
CommitLineData
600d71da
KS
1/***********************************************************
2 Copyright IBM Corporation 1987
3
4 All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of IBM not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
21
22******************************************************************/
23
24/*
25 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
26 */
27/* $Header: iso_snpac.c,v 1.8 88/09/19 13:51:36 hagens Exp $ */
28/* $Source: /usr/argo/sys/netiso/RCS/iso_snpac.c,v $ */
d12b96b5 29/* @(#)iso_snpac.c 7.9 (Berkeley) %G% */
600d71da
KS
30
31#ifndef lint
32static char *rcsid = "$Header: iso_snpac.c,v 1.8 88/09/19 13:51:36 hagens Exp $";
33#endif lint
34
35#ifdef ISO
36
a50e2bc0
KS
37#include "types.h"
38#include "param.h"
d910a5d6 39#include "systm.h"
849cbd39 40#include "user.h"
a50e2bc0
KS
41#include "mbuf.h"
42#include "domain.h"
43#include "protosw.h"
44#include "socket.h"
45#include "socketvar.h"
46#include "errno.h"
47#include "ioctl.h"
a50e2bc0 48#include "kernel.h"
600d71da
KS
49
50#include "../net/if.h"
d910a5d6 51#include "../net/if_dl.h"
600d71da
KS
52#include "../net/route.h"
53
a50e2bc0
KS
54#include "iso.h"
55#include "iso_var.h"
56#include "iso_snpac.h"
57#include "clnp.h"
58#include "clnp_stat.h"
a50e2bc0 59#include "esis.h"
44f52ea5 60#include "argo_debug.h"
600d71da 61
600d71da 62int iso_systype = SNPA_ES; /* default to be an ES */
d12b96b5
KS
63extern short esis_holding_time, esis_config_time, esis_esconfig_time;
64extern int esis_config();
a50e2bc0
KS
65
66struct sockaddr_iso blank_siso = {sizeof(blank_siso), AF_ISO};
67extern u_long iso_hashchar();
68static struct sockaddr_iso
69 dst = {sizeof(dst), AF_ISO},
70 gte = {sizeof(dst), AF_ISO},
71 src = {sizeof(dst), AF_ISO},
72 msk = {sizeof(dst), AF_ISO},
73 zmk = {1};
74#define zsi blank_siso
75#define zero_isoa zsi.siso_addr
76#define zap_isoaddr(a, b) (bzero((caddr_t)&a.siso_addr, sizeof(*r)), \
77 ((r = b) && bcopy((caddr_t)r, (caddr_t)&a.siso_addr, 1 + (r)->isoa_len)))
78#define S(x) ((struct sockaddr *)&(x))
600d71da 79
d910a5d6
KS
80static struct sockaddr_dl blank_dl = {sizeof(blank_dl), AF_LINK};
81static struct sockaddr_dl gte_dl;
82#define zap_linkaddr(a, b, c, i) \
83 (*a = blank_dl, bcopy(b, a->sdl_data, a->sdl_alen = c), a->sdl_index = i)
600d71da
KS
84
85/*
86 * We only keep track of a single IS at a time.
87 */
d910a5d6 88struct rtentry *known_is;
600d71da
KS
89
90/*
91 * Addresses taken from NBS agreements, December 1987.
92 *
93 * These addresses assume on-the-wire transmission of least significant
94 * bit first. This is the method used by 802.3. When these
95 * addresses are passed to the token ring driver, (802.5), they
96 * must be bit-swaped because 802.5 transmission order is MSb first.
97 *
98 * Furthermore, according to IBM Austin, these addresses are not
99 * true token ring multicast addresses. More work is necessary
100 * to get multicast to work right on token ring.
101 *
102 * Currently, the token ring driver does not handle multicast, so
103 * these addresses are converted into the broadcast address in
104 * lan_output() That means that if these multicast addresses change
105 * the token ring driver must be altered.
106 */
c2bb180a
KS
107char all_es_snpa[] = { 0x09, 0x00, 0x2b, 0x00, 0x00, 0x04 };
108char all_is_snpa[] = { 0x09, 0x00, 0x2b, 0x00, 0x00, 0x05 };
600d71da 109
d910a5d6
KS
110union sockunion {
111 struct sockaddr_iso siso;
112 struct sockaddr_dl sdl;
113 struct sockaddr sa;
114};
600d71da 115
d910a5d6
KS
116/*
117 * FUNCTION: llc_rtrequest
118 *
119 * PURPOSE: Manage routing table entries specific to LLC for ISO.
120 *
121 * NOTES: This does a lot of obscure magic;
122 */
123llc_rtrequest(req, rt, sa)
124int req;
125register struct rtentry *rt;
126struct sockaddr *sa;
127{
128 register union sockunion *gate = (union sockunion *)rt->rt_gateway;
129 register struct llinfo_llc *lc = (struct llinfo_llc *)rt->rt_llinfo, *lc2;
130 struct rtentry *rt2;
131 struct ifnet *ifp = rt->rt_ifp;
132 int addrlen = ifp->if_addrlen;
c2bb180a 133 static struct rtentry *recursing = 0;
d910a5d6 134
c2bb180a
KS
135 IFDEBUG (D_SNPA)
136 printf("llc_rtrequest(%d, %x, %x)\n", req, rt, sa);
137 ENDDEBUG
138 if (rt->rt_flags & RTF_GATEWAY) {
139 if (recursing) {
140 log("llc_rtrequest: gateway route points to same type %x %x\n",
141 recursing, rt);
142 } else switch (req) {
143 case RTM_RESOLVE:
144 case RTM_ADD:
145 recursing = rt;
146 rt->rt_llinfo = (caddr_t)rtalloc1(&gate->sa, 1);
147 recursing = 0;
148 return;
149
150 case RTM_DELETE:
151 if (lc)
152 RTFREE((struct rtentry *)lc);
153 rt->rt_llinfo = 0;
d910a5d6 154 }
c2bb180a 155 } else switch (req) {
d910a5d6 156 case RTM_ADD:
c2bb180a
KS
157 /*
158 * Case 1: This route may come from a route to iface with mask
159 * or from a default route.
160 */
d910a5d6 161 if (rt->rt_flags & RTF_CLONING) {
c2bb180a
KS
162 register struct ifaddr *ifa;
163 register struct sockaddr *sa;
164 for (ifa = ifp->if_addrlist; ifa; ifa->ifa_next)
165 if ((sa = ifa->ifa_addr)->sa_family == AF_LINK) {
166 if (sa->sa_len > gate->sa.sa_len)
167 log("llc_rtrequest: cloning address too small\n");
168 else {
169 Bcopy(sa, gate, gate->sa.sa_len);
170 gate->sdl.sdl_alen = 0;
171 }
172 return;
d910a5d6 173 }
c2bb180a
KS
174 if (ifa == 0)
175 log("llc_rtrequest: can't find LL ifaddr for iface\n");
176 return;
177 }
178 /* FALLTHROUGH */
179 case RTM_RESOLVE:
180 /*
181 * Case 2: This route may come from cloning, or a manual route
182 * add with a LL address.
183 */
184 if (gate->sdl.sdl_family != AF_LINK) {
185 log("llc_rtrequest: got non-link non-gateway route\n");
186 return;
d910a5d6 187 }
c2bb180a
KS
188 if (lc != 0)
189 log("llc_rtrequest: losing old rt_llinfo\n");
190 R_Malloc(lc, struct llinfo_llc *, sizeof (*lc));
191 rt->rt_llinfo = (caddr_t)lc;
192 if (lc == 0) {
193 log("llc_rtrequest: malloc failed\n");
194 return;
195 }
196 Bzero(lc, sizeof(*lc));
197 lc->lc_rt = rt;
198 rt->rt_flags |= RTF_LLINFO;
199 insque(lc, &llinfo_llc);
200 if (gate->sdl.sdl_alen == sizeof(struct esis_req) + addrlen) {
201 gate->sdl.sdl_alen -= sizeof(struct esis_req);
202 bcopy(addrlen + LLADDR(&gate->sdl),
203 (caddr_t)&lc->lc_er, sizeof(lc->lc_er));
204 } else if (gate->sdl.sdl_alen == addrlen)
205 lc->lc_flags = (SNPA_ES | SNPA_VALID | SNPA_PERM);
d910a5d6
KS
206 break;
207 case RTM_DELETE:
c2bb180a
KS
208 if (lc == 0 || (rt->rt_flags & RTF_CLONING))
209 return;
210 remque(lc);
211 Free(lc);
212 rt->rt_llinfo = 0;
213 rt->rt_flags &= ~RTF_LLINFO;
d910a5d6
KS
214 break;
215 }
216}
600d71da
KS
217/*
218 * FUNCTION: iso_snparesolve
219 *
220 * PURPOSE: Resolve an iso address into snpa address
221 *
222 * RETURNS: 0 if addr is resolved
223 * errno if addr is unknown
224 *
225 * SIDE EFFECTS:
226 *
d910a5d6
KS
227 * NOTES: Now that we have folded the snpa cache into the routing
228 * table, we know there is no snpa address known for this
229 * destination. If we know of a default IS, then the address
230 * of the IS is returned. If no IS is known, then return the
231 * multi-cast address for "all ES" for this interface.
600d71da
KS
232 *
233 * NB: the last case described above constitutes the
234 * query configuration function 9542, sec 6.5
235 * A mechanism is needed to prevent this function from
236 * being invoked if the system is an IS.
237 */
a50e2bc0 238iso_snparesolve(ifp, dest, snpa, snpa_len)
d910a5d6
KS
239struct ifnet *ifp; /* outgoing interface */
240struct sockaddr_iso *dest; /* destination */
241caddr_t snpa; /* RESULT: snpa to be used */
242int *snpa_len; /* RESULT: length of snpa */
600d71da 243{
d910a5d6
KS
244 struct llinfo_llc *sc; /* ptr to snpa table entry */
245 caddr_t found_snpa;
246 int addrlen;
600d71da
KS
247
248 /*
249 * This hack allows us to send esis packets that have the destination snpa
250 * addresss embedded in the destination nsap address
251 */
d910a5d6 252 if (dest->siso_data[0] == AFI_SNA) {
600d71da
KS
253 /*
254 * This is a subnetwork address. Return it immediately
255 */
256 IFDEBUG(D_SNPA)
257 printf("iso_snparesolve: return SN address\n");
258 ENDDEBUG
d910a5d6
KS
259 addrlen = dest->siso_nlen - 1; /* subtract size of AFI */
260 found_snpa = (caddr_t) dest->siso_data + 1;
600d71da 261 /*
d910a5d6
KS
262 * If we are an IS, we can't do much with the packet;
263 * Check if we know about an IS.
600d71da 264 */
d910a5d6
KS
265 } else if (iso_systype != SNPA_IS && known_is != 0 &&
266 (sc = (struct llinfo_llc *)known_is->rt_llinfo) &&
267 (sc->lc_flags & SNPA_VALID)) {
268 register struct sockaddr_dl *sdl =
269 (struct sockaddr_dl *)(known_is->rt_gateway);
270 found_snpa = LLADDR(sdl);
271 addrlen = sdl->sdl_alen;
272 } else if (ifp->if_flags & IFF_BROADCAST) {
273 /*
274 * no IS, no match. Return "all es" multicast address for this
275 * interface, as per Query Configuration Function (9542 sec 6.5)
276 *
277 * Note: there is a potential problem here. If the destination
278 * is on the subnet and it does not respond with a ESH, but
279 * does send back a TP CC, a connection could be established
280 * where we always transmit the CLNP packet to "all es"
600d71da 281 */
d910a5d6
KS
282 addrlen = ifp->if_addrlen;
283 found_snpa = (caddr_t)all_es_snpa;
284 } else
285 return (ENETUNREACH);
286 bcopy(found_snpa, snpa, *snpa_len = addrlen);
600d71da 287 return (0);
600d71da
KS
288}
289
600d71da 290
600d71da
KS
291/*
292 * FUNCTION: snpac_free
293 *
294 * PURPOSE: free an entry in the iso address map table
295 *
296 * RETURNS: nothing
297 *
298 * SIDE EFFECTS:
299 *
300 * NOTES: If there is a route entry associated with cache
301 * entry, then delete that as well
302 */
d910a5d6
KS
303snpac_free(lc)
304register struct llinfo_llc *lc; /* entry to free */
600d71da 305{
d910a5d6 306 register struct rtentry *rt = lc->lc_rt;
a50e2bc0 307 register struct iso_addr *r;
600d71da 308
d910a5d6
KS
309 if (known_is == rt)
310 known_is = 0;
311 if (rt && (rt->rt_flags & RTF_UP) &&
312 (rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED))) {
a50e2bc0
KS
313 RTFREE(rt);
314 rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
315 rt->rt_flags, (struct rtentry **)0);
a50e2bc0 316 RTFREE(rt);
600d71da 317 }
600d71da
KS
318}
319
320/*
321 * FUNCTION: snpac_add
322 *
323 * PURPOSE: Add an entry to the snpa cache
324 *
325 * RETURNS:
326 *
327 * SIDE EFFECTS:
328 *
329 * NOTES: If entry already exists, then update holding time.
330 */
c2bb180a 331snpac_add(ifp, nsap, snpa, type, ht, nsellength)
600d71da
KS
332struct ifnet *ifp; /* interface info is related to */
333struct iso_addr *nsap; /* nsap to add */
334caddr_t snpa; /* translation */
600d71da 335char type; /* SNPA_IS or SNPA_ES */
a50e2bc0 336u_short ht; /* holding time (in seconds) */
c2bb180a 337int nsellength; /* nsaps may differ only in trailing bytes */
600d71da 338{
d910a5d6 339 register struct llinfo_llc *lc;
c2bb180a
KS
340 register struct rtentry *rt;
341 struct rtentry *mrt = 0;
d910a5d6
KS
342 register struct iso_addr *r; /* for zap_isoaddr macro */
343 int snpalen = min(ifp->if_addrlen, MAX_SNPALEN);
344 int new_entry = 0, index = ifp->if_index;
345
c2bb180a
KS
346 IFDEBUG(D_SNPA)
347 printf("snpac_add(%x, %x, %x, %x, %x, %x)\n",
348 ifp, nsap, snpa, type, ht, nsellength);
349 ENDDEBUG
d910a5d6
KS
350 zap_isoaddr(dst, nsap);
351 rt = rtalloc1(S(dst), 0);
c2bb180a
KS
352 IFDEBUG(D_SNPA)
353 printf("snpac_add: rtalloc1 returns %x\n", rt);
354 ENDDEBUG
d910a5d6 355 if (rt == 0) {
c2bb180a
KS
356 struct sockaddr *netmask;
357 int flags;
358 add:
359 if (nsellength) {
360 netmask = S(msk); flags = RTF_UP;
361 snpac_fixdstandmask(nsellength);
362 } else {
363 netmask = 0; flags = RTF_UP | RTF_HOST;
364 }
d910a5d6
KS
365 new_entry = 1;
366 zap_linkaddr((&gte_dl), snpa, snpalen, index);
c2bb180a
KS
367 if (rtrequest(RTM_ADD, S(dst), S(gte_dl), netmask, flags, &mrt) ||
368 mrt == 0)
d910a5d6 369 return (0);
c2bb180a
KS
370 rt = mrt;
371 rt->rt_refcnt--;
d910a5d6
KS
372 } else {
373 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)rt->rt_gateway;
c2bb180a
KS
374 rt->rt_refcnt--;
375 if ((rt->rt_flags & RTF_LLINFO) == 0)
376 goto add;
377 if (nsellength && (rt->rt_flags & RTF_HOST)) {
378 if (rt->rt_refcnt == 0) {
379 rtrequest(RTM_DELETE, S(dst), (struct sockaddr *)0,
380 (struct sockaddr *)0, 0, (struct rtentry *)0);
381 rt = 0;
382 goto add;
383 } else {
384 static struct iso_addr nsap2; register char *cp;
385 nsap2 = *nsap;
386 cp = nsap2.isoa_genaddr + nsap->isoa_len - nsellength;
387 while (cp < (char *)(1 + &nsap2))
388 *cp++ = 0;
389 (void) snpac_add(ifp, &nsap2, snpa, type, ht, nsellength);
390 }
391 }
d910a5d6
KS
392 if (sdl->sdl_family != AF_LINK || sdl->sdl_alen == 0) {
393 int old_sdl_len = sdl->sdl_len;
c2bb180a
KS
394 if (old_sdl_len < sizeof(*sdl)) {
395 log("snpac_add: cant make room for lladdr\n");
d910a5d6 396 return (0);
c2bb180a 397 }
d910a5d6
KS
398 zap_linkaddr(sdl, snpa, snpalen, index);
399 sdl->sdl_len = old_sdl_len;
400 new_entry = 1;
401 }
600d71da 402 }
c2bb180a
KS
403 if ((lc = (struct llinfo_llc *)rt->rt_llinfo) == 0)
404 panic("snpac_rtrequest");
405 rt->rt_idle = ht;
d910a5d6 406 lc->lc_flags = SNPA_VALID | type;
600d71da 407 if (type & SNPA_IS)
d910a5d6 408 snpac_logdefis(rt);
c2bb180a
KS
409 return (new_entry);
410}
411
412static snpac_fixdstandmask(nsellength)
413{
414 register char *cp = msk.siso_data, *cplim;
415
416 cplim = cp + (dst.siso_nlen -= nsellength);
417 msk.siso_len = cplim - (char *)&msk;
418 msk.siso_nlen = 0;
419 while (cp < cplim)
420 *cp++ = -1;
421 while (cp < (char *)msk.siso_pad)
422 *cp++ = 0;
423 for (cp = dst.siso_data + dst.siso_nlen; cp < (char *)dst.siso_pad; )
424 *cp++ = 0;
600d71da
KS
425}
426
427/*
428 * FUNCTION: snpac_ioctl
429 *
600d71da
KS
430 * PURPOSE: Set/Get the system type and esis parameters
431 *
432 * RETURNS: 0 on success, or unix error code
433 *
434 * SIDE EFFECTS:
435 *
436 * NOTES:
437 */
d910a5d6 438snpac_ioctl (cmd, data)
600d71da
KS
439int cmd; /* ioctl to process */
440caddr_t data; /* data for the cmd */
441{
442 register struct systype_req *rq = (struct systype_req *)data;
600d71da 443
c2bb180a 444 IFDEBUG(D_IOCTL)
600d71da 445 if (cmd == SIOCSSTYPE)
d910a5d6 446 printf("snpac_ioctl: cmd set, type x%x, ht %d, ct %d\n",
600d71da
KS
447 rq->sr_type, rq->sr_holdt, rq->sr_configt);
448 else
d910a5d6 449 printf("snpac_ioctl: cmd get\n");
600d71da
KS
450 ENDDEBUG
451
452 if (cmd == SIOCSSTYPE) {
849cbd39 453 if (suser(u.u_cred, &u.u_acflag))
600d71da
KS
454 return(EACCES);
455 if ((rq->sr_type & (SNPA_ES|SNPA_IS)) == (SNPA_ES|SNPA_IS))
456 return(EINVAL);
457 if (rq->sr_type & SNPA_ES) {
458 iso_systype = SNPA_ES;
459 } else if (rq->sr_type & SNPA_IS) {
460 iso_systype = SNPA_IS;
461 } else {
462 return(EINVAL);
463 }
464 esis_holding_time = rq->sr_holdt;
465 esis_config_time = rq->sr_configt;
d12b96b5
KS
466 if (esis_esconfig_time != rq->sr_esconfigt) {
467 untimeout(esis_config, (caddr_t)0);
468 esis_esconfig_time = rq->sr_esconfigt;
469 esis_config();
470 }
600d71da
KS
471 } else if (cmd == SIOCGSTYPE) {
472 rq->sr_type = iso_systype;
473 rq->sr_holdt = esis_holding_time;
474 rq->sr_configt = esis_config_time;
d12b96b5 475 rq->sr_esconfigt = esis_esconfig_time;
600d71da 476 } else {
d910a5d6 477 return (EINVAL);
600d71da 478 }
d910a5d6 479 return (0);
600d71da
KS
480}
481
482/*
483 * FUNCTION: snpac_logdefis
484 *
485 * PURPOSE: Mark the IS passed as the default IS
486 *
487 * RETURNS: nothing
488 *
489 * SIDE EFFECTS:
490 *
491 * NOTES:
492 */
493snpac_logdefis(sc)
d910a5d6 494register struct rtentry *sc;
600d71da 495{
a50e2bc0 496 register struct iso_addr *r;
d910a5d6 497 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sc->rt_gateway;
a50e2bc0 498 register struct rtentry *rt = rtalloc1((struct sockaddr *)&zsi, 0);
d910a5d6
KS
499
500 zap_linkaddr((&gte_dl), LLADDR(sdl), sdl->sdl_alen, sdl->sdl_index);
a50e2bc0
KS
501 if (known_is == 0)
502 known_is = sc;
503 if (known_is != sc) {
d910a5d6 504 rtfree(known_is);
a50e2bc0
KS
505 known_is = sc;
506 }
507 if (rt == 0) {
d910a5d6
KS
508 rtrequest(RTM_ADD, S(zsi), S(gte_dl), S(zmk),
509 RTF_DYNAMIC|RTF_GATEWAY|RTF_CLONING, 0);
a50e2bc0
KS
510 return;
511 }
c2bb180a 512 rt->rt_refcnt--;
a50e2bc0 513 if (rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED)) {
d910a5d6 514 *((struct sockaddr_dl *)rt->rt_gateway) = gte_dl;
600d71da 515 }
600d71da
KS
516}
517
518/*
519 * FUNCTION: snpac_age
520 *
521 * PURPOSE: Time out snpac entries
522 *
523 * RETURNS:
524 *
525 * SIDE EFFECTS:
526 *
527 * NOTES: When encountering an entry for the first time, snpac_age
528 * may delete up to SNPAC_AGE too many seconds. Ie.
529 * if the entry is added a moment before snpac_age is
530 * called, the entry will immediately have SNPAC_AGE
531 * seconds taken off the holding time, even though
532 * it has only been held a brief moment.
533 *
534 * The proper way to do this is set an expiry timeval
535 * equal to current time + holding time. Then snpac_age
536 * would time out entries where expiry date is older
537 * than the current time.
538 */
539snpac_age()
540{
d910a5d6 541 register struct llinfo_llc *lc;
600d71da
KS
542
543 timeout(snpac_age, (caddr_t)0, SNPAC_AGE * hz);
544
d910a5d6
KS
545 for (lc = llinfo_llc.lc_next; lc != & llinfo_llc; lc = lc->lc_next) {
546 if (((lc->lc_flags & SNPA_PERM) == 0) && (lc->lc_flags & SNPA_VALID)) {
c2bb180a
KS
547 lc->lc_rt->rt_idle -= SNPAC_AGE;
548 if (lc->lc_rt->rt_idle > 0)
600d71da
KS
549 continue;
550 else
d910a5d6 551 snpac_free(lc);
600d71da
KS
552 }
553 }
554}
555
556/*
557 * FUNCTION: snpac_ownmulti
558 *
559 * PURPOSE: Determine if the snpa address is a multicast address
560 * of the same type as the system.
561 *
562 * RETURNS: true or false
563 *
564 * SIDE EFFECTS:
565 *
566 * NOTES: Used by interface drivers when not in eavesdrop mode
567 * as interm kludge until
568 * real multicast addresses can be configured
569 */
570snpac_ownmulti(snpa, len)
d910a5d6
KS
571caddr_t snpa;
572u_int len;
600d71da 573{
a50e2bc0 574 return (((iso_systype & SNPA_ES) &&
d910a5d6 575 (!bcmp(snpa, (caddr_t)all_es_snpa, len))) ||
a50e2bc0 576 ((iso_systype & SNPA_IS) &&
d910a5d6 577 (!bcmp(snpa, (caddr_t)all_is_snpa, len))));
600d71da
KS
578}
579
580/*
581 * FUNCTION: snpac_flushifp
582 *
583 * PURPOSE: Flush entries associated with specific ifp
584 *
585 * RETURNS: nothing
586 *
587 * SIDE EFFECTS:
588 *
589 * NOTES:
590 */
591snpac_flushifp(ifp)
592struct ifnet *ifp;
593{
d910a5d6 594 register struct llinfo_llc *lc;
600d71da 595
d910a5d6
KS
596 for (lc = llinfo_llc.lc_next; lc != & llinfo_llc; lc = lc->lc_next) {
597 if (lc->lc_rt->rt_ifp == ifp && (lc->lc_flags & SNPA_VALID))
598 snpac_free(lc);
600d71da
KS
599 }
600}
601
602/*
603 * FUNCTION: snpac_rtrequest
604 *
605 * PURPOSE: Make a routing request
606 *
607 * RETURNS: nothing
608 *
609 * SIDE EFFECTS:
610 *
611 * NOTES: In the future, this should make a request of a user
612 * level routing daemon.
613 */
a50e2bc0 614snpac_rtrequest(req, host, gateway, netmask, flags, ret_nrt)
600d71da 615int req;
a50e2bc0 616struct iso_addr *host;
600d71da 617struct iso_addr *gateway;
a50e2bc0 618struct iso_addr *netmask;
600d71da 619short flags;
a50e2bc0 620struct rtentry **ret_nrt;
600d71da 621{
a50e2bc0 622 register struct iso_addr *r;
600d71da
KS
623
624 IFDEBUG(D_SNPA)
625 printf("snpac_rtrequest: ");
a50e2bc0 626 if (req == RTM_ADD)
600d71da 627 printf("add");
a50e2bc0 628 else if (req == RTM_DELETE)
600d71da
KS
629 printf("delete");
630 else
631 printf("unknown command");
a50e2bc0 632 printf(" dst: %s\n", clnp_iso_addrp(host));
600d71da
KS
633 printf("\tgateway: %s\n", clnp_iso_addrp(gateway));
634 ENDDEBUG
635
600d71da 636
a50e2bc0
KS
637 zap_isoaddr(dst, host);
638 zap_isoaddr(gte, gateway);
c2bb180a
KS
639 if (netmask) {
640 zap_isoaddr(msk, netmask);
641 msk.siso_nlen = 0;
642 msk.siso_len = msk.siso_pad - (u_char *)&msk;
643 }
600d71da 644
a50e2bc0
KS
645 rtrequest(req, S(dst), S(gte), (netmask ? S(msk) : (struct sockaddr *)0),
646 flags, ret_nrt);
647}
600d71da
KS
648
649/*
650 * FUNCTION: snpac_addrt
651 *
652 * PURPOSE: Associate a routing entry with an snpac entry
653 *
654 * RETURNS: nothing
655 *
656 * SIDE EFFECTS:
657 *
658 * NOTES: If a cache entry exists for gateway, then
659 * make a routing entry (host, gateway) and associate
660 * with gateway.
661 *
662 * If a route already exists and is different, first delete
663 * it.
664 *
665 * This could be made more efficient by checking
666 * the existing route before adding a new one.
667 */
af8f5eff
KS
668snpac_addrt(ifp, host, gateway, netmask)
669struct ifnet *ifp;
670struct iso_addr *host, *gateway, *netmask;
600d71da 671{
a50e2bc0 672 register struct iso_addr *r;
600d71da 673
d910a5d6
KS
674 zap_isoaddr(dst, host);
675 zap_isoaddr(gte, gateway);
d910a5d6 676 if (netmask) {
c2bb180a
KS
677 zap_isoaddr(msk, netmask);
678 msk.siso_nlen = 0;
679 msk.siso_len = msk.siso_pad - (u_char *)&msk;
d910a5d6
KS
680 rtredirect(S(dst), S(gte), S(msk), RTF_DONE, S(gte), 0);
681 } else
682 rtredirect(S(dst), S(gte), (struct sockaddr *)0,
683 RTF_DONE | RTF_HOST, S(gte), 0);
600d71da
KS
684}
685#endif ISO