manual page from Sam Leffler
[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 $ */
dbed88af 29/* @(#)iso_snpac.c 7.10 (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 };
dbed88af
KS
109char all_l1is_snpa[] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x14};
110char all_l2is_snpa[] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x15};
600d71da 111
d910a5d6
KS
112union sockunion {
113 struct sockaddr_iso siso;
114 struct sockaddr_dl sdl;
115 struct sockaddr sa;
116};
600d71da 117
d910a5d6
KS
118/*
119 * FUNCTION: llc_rtrequest
120 *
121 * PURPOSE: Manage routing table entries specific to LLC for ISO.
122 *
123 * NOTES: This does a lot of obscure magic;
124 */
125llc_rtrequest(req, rt, sa)
126int req;
127register struct rtentry *rt;
128struct sockaddr *sa;
129{
130 register union sockunion *gate = (union sockunion *)rt->rt_gateway;
131 register struct llinfo_llc *lc = (struct llinfo_llc *)rt->rt_llinfo, *lc2;
132 struct rtentry *rt2;
133 struct ifnet *ifp = rt->rt_ifp;
134 int addrlen = ifp->if_addrlen;
c2bb180a 135 static struct rtentry *recursing = 0;
d910a5d6 136
c2bb180a
KS
137 IFDEBUG (D_SNPA)
138 printf("llc_rtrequest(%d, %x, %x)\n", req, rt, sa);
139 ENDDEBUG
140 if (rt->rt_flags & RTF_GATEWAY) {
141 if (recursing) {
142 log("llc_rtrequest: gateway route points to same type %x %x\n",
143 recursing, rt);
144 } else switch (req) {
145 case RTM_RESOLVE:
146 case RTM_ADD:
147 recursing = rt;
148 rt->rt_llinfo = (caddr_t)rtalloc1(&gate->sa, 1);
149 recursing = 0;
150 return;
151
152 case RTM_DELETE:
153 if (lc)
154 RTFREE((struct rtentry *)lc);
155 rt->rt_llinfo = 0;
d910a5d6 156 }
c2bb180a 157 } else switch (req) {
d910a5d6 158 case RTM_ADD:
c2bb180a
KS
159 /*
160 * Case 1: This route may come from a route to iface with mask
161 * or from a default route.
162 */
d910a5d6 163 if (rt->rt_flags & RTF_CLONING) {
c2bb180a
KS
164 register struct ifaddr *ifa;
165 register struct sockaddr *sa;
166 for (ifa = ifp->if_addrlist; ifa; ifa->ifa_next)
167 if ((sa = ifa->ifa_addr)->sa_family == AF_LINK) {
168 if (sa->sa_len > gate->sa.sa_len)
169 log("llc_rtrequest: cloning address too small\n");
170 else {
171 Bcopy(sa, gate, gate->sa.sa_len);
172 gate->sdl.sdl_alen = 0;
173 }
174 return;
d910a5d6 175 }
c2bb180a
KS
176 if (ifa == 0)
177 log("llc_rtrequest: can't find LL ifaddr for iface\n");
178 return;
179 }
180 /* FALLTHROUGH */
181 case RTM_RESOLVE:
182 /*
183 * Case 2: This route may come from cloning, or a manual route
184 * add with a LL address.
185 */
186 if (gate->sdl.sdl_family != AF_LINK) {
187 log("llc_rtrequest: got non-link non-gateway route\n");
188 return;
d910a5d6 189 }
c2bb180a
KS
190 if (lc != 0)
191 log("llc_rtrequest: losing old rt_llinfo\n");
192 R_Malloc(lc, struct llinfo_llc *, sizeof (*lc));
193 rt->rt_llinfo = (caddr_t)lc;
194 if (lc == 0) {
195 log("llc_rtrequest: malloc failed\n");
196 return;
197 }
198 Bzero(lc, sizeof(*lc));
199 lc->lc_rt = rt;
200 rt->rt_flags |= RTF_LLINFO;
201 insque(lc, &llinfo_llc);
202 if (gate->sdl.sdl_alen == sizeof(struct esis_req) + addrlen) {
203 gate->sdl.sdl_alen -= sizeof(struct esis_req);
204 bcopy(addrlen + LLADDR(&gate->sdl),
205 (caddr_t)&lc->lc_er, sizeof(lc->lc_er));
206 } else if (gate->sdl.sdl_alen == addrlen)
207 lc->lc_flags = (SNPA_ES | SNPA_VALID | SNPA_PERM);
d910a5d6
KS
208 break;
209 case RTM_DELETE:
c2bb180a
KS
210 if (lc == 0 || (rt->rt_flags & RTF_CLONING))
211 return;
212 remque(lc);
213 Free(lc);
214 rt->rt_llinfo = 0;
215 rt->rt_flags &= ~RTF_LLINFO;
d910a5d6
KS
216 break;
217 }
218}
600d71da
KS
219/*
220 * FUNCTION: iso_snparesolve
221 *
222 * PURPOSE: Resolve an iso address into snpa address
223 *
224 * RETURNS: 0 if addr is resolved
225 * errno if addr is unknown
226 *
227 * SIDE EFFECTS:
228 *
d910a5d6
KS
229 * NOTES: Now that we have folded the snpa cache into the routing
230 * table, we know there is no snpa address known for this
231 * destination. If we know of a default IS, then the address
232 * of the IS is returned. If no IS is known, then return the
233 * multi-cast address for "all ES" for this interface.
600d71da
KS
234 *
235 * NB: the last case described above constitutes the
236 * query configuration function 9542, sec 6.5
237 * A mechanism is needed to prevent this function from
238 * being invoked if the system is an IS.
239 */
a50e2bc0 240iso_snparesolve(ifp, dest, snpa, snpa_len)
d910a5d6
KS
241struct ifnet *ifp; /* outgoing interface */
242struct sockaddr_iso *dest; /* destination */
243caddr_t snpa; /* RESULT: snpa to be used */
244int *snpa_len; /* RESULT: length of snpa */
600d71da 245{
d910a5d6
KS
246 struct llinfo_llc *sc; /* ptr to snpa table entry */
247 caddr_t found_snpa;
248 int addrlen;
600d71da
KS
249
250 /*
251 * This hack allows us to send esis packets that have the destination snpa
252 * addresss embedded in the destination nsap address
253 */
d910a5d6 254 if (dest->siso_data[0] == AFI_SNA) {
600d71da
KS
255 /*
256 * This is a subnetwork address. Return it immediately
257 */
258 IFDEBUG(D_SNPA)
259 printf("iso_snparesolve: return SN address\n");
260 ENDDEBUG
d910a5d6
KS
261 addrlen = dest->siso_nlen - 1; /* subtract size of AFI */
262 found_snpa = (caddr_t) dest->siso_data + 1;
600d71da 263 /*
d910a5d6
KS
264 * If we are an IS, we can't do much with the packet;
265 * Check if we know about an IS.
600d71da 266 */
d910a5d6
KS
267 } else if (iso_systype != SNPA_IS && known_is != 0 &&
268 (sc = (struct llinfo_llc *)known_is->rt_llinfo) &&
269 (sc->lc_flags & SNPA_VALID)) {
270 register struct sockaddr_dl *sdl =
271 (struct sockaddr_dl *)(known_is->rt_gateway);
272 found_snpa = LLADDR(sdl);
273 addrlen = sdl->sdl_alen;
274 } else if (ifp->if_flags & IFF_BROADCAST) {
275 /*
276 * no IS, no match. Return "all es" multicast address for this
277 * interface, as per Query Configuration Function (9542 sec 6.5)
278 *
279 * Note: there is a potential problem here. If the destination
280 * is on the subnet and it does not respond with a ESH, but
281 * does send back a TP CC, a connection could be established
282 * where we always transmit the CLNP packet to "all es"
600d71da 283 */
d910a5d6
KS
284 addrlen = ifp->if_addrlen;
285 found_snpa = (caddr_t)all_es_snpa;
286 } else
287 return (ENETUNREACH);
288 bcopy(found_snpa, snpa, *snpa_len = addrlen);
600d71da 289 return (0);
600d71da
KS
290}
291
600d71da 292
600d71da
KS
293/*
294 * FUNCTION: snpac_free
295 *
296 * PURPOSE: free an entry in the iso address map table
297 *
298 * RETURNS: nothing
299 *
300 * SIDE EFFECTS:
301 *
302 * NOTES: If there is a route entry associated with cache
303 * entry, then delete that as well
304 */
d910a5d6
KS
305snpac_free(lc)
306register struct llinfo_llc *lc; /* entry to free */
600d71da 307{
d910a5d6 308 register struct rtentry *rt = lc->lc_rt;
a50e2bc0 309 register struct iso_addr *r;
600d71da 310
d910a5d6
KS
311 if (known_is == rt)
312 known_is = 0;
313 if (rt && (rt->rt_flags & RTF_UP) &&
314 (rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED))) {
a50e2bc0
KS
315 RTFREE(rt);
316 rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
317 rt->rt_flags, (struct rtentry **)0);
a50e2bc0 318 RTFREE(rt);
600d71da 319 }
600d71da
KS
320}
321
322/*
323 * FUNCTION: snpac_add
324 *
325 * PURPOSE: Add an entry to the snpa cache
326 *
327 * RETURNS:
328 *
329 * SIDE EFFECTS:
330 *
331 * NOTES: If entry already exists, then update holding time.
332 */
c2bb180a 333snpac_add(ifp, nsap, snpa, type, ht, nsellength)
600d71da
KS
334struct ifnet *ifp; /* interface info is related to */
335struct iso_addr *nsap; /* nsap to add */
336caddr_t snpa; /* translation */
600d71da 337char type; /* SNPA_IS or SNPA_ES */
a50e2bc0 338u_short ht; /* holding time (in seconds) */
c2bb180a 339int nsellength; /* nsaps may differ only in trailing bytes */
600d71da 340{
d910a5d6 341 register struct llinfo_llc *lc;
c2bb180a
KS
342 register struct rtentry *rt;
343 struct rtentry *mrt = 0;
d910a5d6
KS
344 register struct iso_addr *r; /* for zap_isoaddr macro */
345 int snpalen = min(ifp->if_addrlen, MAX_SNPALEN);
346 int new_entry = 0, index = ifp->if_index;
347
c2bb180a
KS
348 IFDEBUG(D_SNPA)
349 printf("snpac_add(%x, %x, %x, %x, %x, %x)\n",
350 ifp, nsap, snpa, type, ht, nsellength);
351 ENDDEBUG
d910a5d6
KS
352 zap_isoaddr(dst, nsap);
353 rt = rtalloc1(S(dst), 0);
c2bb180a
KS
354 IFDEBUG(D_SNPA)
355 printf("snpac_add: rtalloc1 returns %x\n", rt);
356 ENDDEBUG
d910a5d6 357 if (rt == 0) {
c2bb180a
KS
358 struct sockaddr *netmask;
359 int flags;
360 add:
361 if (nsellength) {
362 netmask = S(msk); flags = RTF_UP;
363 snpac_fixdstandmask(nsellength);
364 } else {
365 netmask = 0; flags = RTF_UP | RTF_HOST;
366 }
d910a5d6
KS
367 new_entry = 1;
368 zap_linkaddr((&gte_dl), snpa, snpalen, index);
c2bb180a
KS
369 if (rtrequest(RTM_ADD, S(dst), S(gte_dl), netmask, flags, &mrt) ||
370 mrt == 0)
d910a5d6 371 return (0);
c2bb180a
KS
372 rt = mrt;
373 rt->rt_refcnt--;
d910a5d6
KS
374 } else {
375 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)rt->rt_gateway;
c2bb180a
KS
376 rt->rt_refcnt--;
377 if ((rt->rt_flags & RTF_LLINFO) == 0)
378 goto add;
379 if (nsellength && (rt->rt_flags & RTF_HOST)) {
380 if (rt->rt_refcnt == 0) {
381 rtrequest(RTM_DELETE, S(dst), (struct sockaddr *)0,
382 (struct sockaddr *)0, 0, (struct rtentry *)0);
383 rt = 0;
384 goto add;
385 } else {
386 static struct iso_addr nsap2; register char *cp;
387 nsap2 = *nsap;
388 cp = nsap2.isoa_genaddr + nsap->isoa_len - nsellength;
389 while (cp < (char *)(1 + &nsap2))
390 *cp++ = 0;
391 (void) snpac_add(ifp, &nsap2, snpa, type, ht, nsellength);
392 }
393 }
d910a5d6
KS
394 if (sdl->sdl_family != AF_LINK || sdl->sdl_alen == 0) {
395 int old_sdl_len = sdl->sdl_len;
c2bb180a
KS
396 if (old_sdl_len < sizeof(*sdl)) {
397 log("snpac_add: cant make room for lladdr\n");
d910a5d6 398 return (0);
c2bb180a 399 }
d910a5d6
KS
400 zap_linkaddr(sdl, snpa, snpalen, index);
401 sdl->sdl_len = old_sdl_len;
402 new_entry = 1;
403 }
600d71da 404 }
c2bb180a
KS
405 if ((lc = (struct llinfo_llc *)rt->rt_llinfo) == 0)
406 panic("snpac_rtrequest");
407 rt->rt_idle = ht;
d910a5d6 408 lc->lc_flags = SNPA_VALID | type;
600d71da 409 if (type & SNPA_IS)
d910a5d6 410 snpac_logdefis(rt);
c2bb180a
KS
411 return (new_entry);
412}
413
414static snpac_fixdstandmask(nsellength)
415{
416 register char *cp = msk.siso_data, *cplim;
417
418 cplim = cp + (dst.siso_nlen -= nsellength);
419 msk.siso_len = cplim - (char *)&msk;
420 msk.siso_nlen = 0;
421 while (cp < cplim)
422 *cp++ = -1;
423 while (cp < (char *)msk.siso_pad)
424 *cp++ = 0;
425 for (cp = dst.siso_data + dst.siso_nlen; cp < (char *)dst.siso_pad; )
426 *cp++ = 0;
600d71da
KS
427}
428
429/*
430 * FUNCTION: snpac_ioctl
431 *
600d71da
KS
432 * PURPOSE: Set/Get the system type and esis parameters
433 *
434 * RETURNS: 0 on success, or unix error code
435 *
436 * SIDE EFFECTS:
437 *
438 * NOTES:
439 */
d910a5d6 440snpac_ioctl (cmd, data)
600d71da
KS
441int cmd; /* ioctl to process */
442caddr_t data; /* data for the cmd */
443{
444 register struct systype_req *rq = (struct systype_req *)data;
600d71da 445
c2bb180a 446 IFDEBUG(D_IOCTL)
600d71da 447 if (cmd == SIOCSSTYPE)
d910a5d6 448 printf("snpac_ioctl: cmd set, type x%x, ht %d, ct %d\n",
600d71da
KS
449 rq->sr_type, rq->sr_holdt, rq->sr_configt);
450 else
d910a5d6 451 printf("snpac_ioctl: cmd get\n");
600d71da
KS
452 ENDDEBUG
453
454 if (cmd == SIOCSSTYPE) {
849cbd39 455 if (suser(u.u_cred, &u.u_acflag))
600d71da
KS
456 return(EACCES);
457 if ((rq->sr_type & (SNPA_ES|SNPA_IS)) == (SNPA_ES|SNPA_IS))
458 return(EINVAL);
459 if (rq->sr_type & SNPA_ES) {
460 iso_systype = SNPA_ES;
461 } else if (rq->sr_type & SNPA_IS) {
462 iso_systype = SNPA_IS;
463 } else {
464 return(EINVAL);
465 }
466 esis_holding_time = rq->sr_holdt;
467 esis_config_time = rq->sr_configt;
d12b96b5
KS
468 if (esis_esconfig_time != rq->sr_esconfigt) {
469 untimeout(esis_config, (caddr_t)0);
470 esis_esconfig_time = rq->sr_esconfigt;
471 esis_config();
472 }
600d71da
KS
473 } else if (cmd == SIOCGSTYPE) {
474 rq->sr_type = iso_systype;
475 rq->sr_holdt = esis_holding_time;
476 rq->sr_configt = esis_config_time;
d12b96b5 477 rq->sr_esconfigt = esis_esconfig_time;
600d71da 478 } else {
d910a5d6 479 return (EINVAL);
600d71da 480 }
d910a5d6 481 return (0);
600d71da
KS
482}
483
484/*
485 * FUNCTION: snpac_logdefis
486 *
487 * PURPOSE: Mark the IS passed as the default IS
488 *
489 * RETURNS: nothing
490 *
491 * SIDE EFFECTS:
492 *
493 * NOTES:
494 */
495snpac_logdefis(sc)
d910a5d6 496register struct rtentry *sc;
600d71da 497{
a50e2bc0 498 register struct iso_addr *r;
d910a5d6 499 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sc->rt_gateway;
a50e2bc0 500 register struct rtentry *rt = rtalloc1((struct sockaddr *)&zsi, 0);
d910a5d6
KS
501
502 zap_linkaddr((&gte_dl), LLADDR(sdl), sdl->sdl_alen, sdl->sdl_index);
a50e2bc0
KS
503 if (known_is == 0)
504 known_is = sc;
505 if (known_is != sc) {
d910a5d6 506 rtfree(known_is);
a50e2bc0
KS
507 known_is = sc;
508 }
509 if (rt == 0) {
d910a5d6
KS
510 rtrequest(RTM_ADD, S(zsi), S(gte_dl), S(zmk),
511 RTF_DYNAMIC|RTF_GATEWAY|RTF_CLONING, 0);
a50e2bc0
KS
512 return;
513 }
c2bb180a 514 rt->rt_refcnt--;
a50e2bc0 515 if (rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED)) {
d910a5d6 516 *((struct sockaddr_dl *)rt->rt_gateway) = gte_dl;
600d71da 517 }
600d71da
KS
518}
519
520/*
521 * FUNCTION: snpac_age
522 *
523 * PURPOSE: Time out snpac entries
524 *
525 * RETURNS:
526 *
527 * SIDE EFFECTS:
528 *
529 * NOTES: When encountering an entry for the first time, snpac_age
530 * may delete up to SNPAC_AGE too many seconds. Ie.
531 * if the entry is added a moment before snpac_age is
532 * called, the entry will immediately have SNPAC_AGE
533 * seconds taken off the holding time, even though
534 * it has only been held a brief moment.
535 *
536 * The proper way to do this is set an expiry timeval
537 * equal to current time + holding time. Then snpac_age
538 * would time out entries where expiry date is older
539 * than the current time.
540 */
541snpac_age()
542{
d910a5d6 543 register struct llinfo_llc *lc;
600d71da
KS
544
545 timeout(snpac_age, (caddr_t)0, SNPAC_AGE * hz);
546
d910a5d6
KS
547 for (lc = llinfo_llc.lc_next; lc != & llinfo_llc; lc = lc->lc_next) {
548 if (((lc->lc_flags & SNPA_PERM) == 0) && (lc->lc_flags & SNPA_VALID)) {
c2bb180a
KS
549 lc->lc_rt->rt_idle -= SNPAC_AGE;
550 if (lc->lc_rt->rt_idle > 0)
600d71da
KS
551 continue;
552 else
d910a5d6 553 snpac_free(lc);
600d71da
KS
554 }
555 }
556}
557
558/*
559 * FUNCTION: snpac_ownmulti
560 *
561 * PURPOSE: Determine if the snpa address is a multicast address
562 * of the same type as the system.
563 *
564 * RETURNS: true or false
565 *
566 * SIDE EFFECTS:
567 *
568 * NOTES: Used by interface drivers when not in eavesdrop mode
569 * as interm kludge until
570 * real multicast addresses can be configured
571 */
572snpac_ownmulti(snpa, len)
d910a5d6
KS
573caddr_t snpa;
574u_int len;
600d71da 575{
a50e2bc0 576 return (((iso_systype & SNPA_ES) &&
d910a5d6 577 (!bcmp(snpa, (caddr_t)all_es_snpa, len))) ||
a50e2bc0 578 ((iso_systype & SNPA_IS) &&
d910a5d6 579 (!bcmp(snpa, (caddr_t)all_is_snpa, len))));
600d71da
KS
580}
581
582/*
583 * FUNCTION: snpac_flushifp
584 *
585 * PURPOSE: Flush entries associated with specific ifp
586 *
587 * RETURNS: nothing
588 *
589 * SIDE EFFECTS:
590 *
591 * NOTES:
592 */
593snpac_flushifp(ifp)
594struct ifnet *ifp;
595{
d910a5d6 596 register struct llinfo_llc *lc;
600d71da 597
d910a5d6
KS
598 for (lc = llinfo_llc.lc_next; lc != & llinfo_llc; lc = lc->lc_next) {
599 if (lc->lc_rt->rt_ifp == ifp && (lc->lc_flags & SNPA_VALID))
600 snpac_free(lc);
600d71da
KS
601 }
602}
603
604/*
605 * FUNCTION: snpac_rtrequest
606 *
607 * PURPOSE: Make a routing request
608 *
609 * RETURNS: nothing
610 *
611 * SIDE EFFECTS:
612 *
613 * NOTES: In the future, this should make a request of a user
614 * level routing daemon.
615 */
a50e2bc0 616snpac_rtrequest(req, host, gateway, netmask, flags, ret_nrt)
600d71da 617int req;
a50e2bc0 618struct iso_addr *host;
600d71da 619struct iso_addr *gateway;
a50e2bc0 620struct iso_addr *netmask;
600d71da 621short flags;
a50e2bc0 622struct rtentry **ret_nrt;
600d71da 623{
a50e2bc0 624 register struct iso_addr *r;
600d71da
KS
625
626 IFDEBUG(D_SNPA)
627 printf("snpac_rtrequest: ");
a50e2bc0 628 if (req == RTM_ADD)
600d71da 629 printf("add");
a50e2bc0 630 else if (req == RTM_DELETE)
600d71da
KS
631 printf("delete");
632 else
633 printf("unknown command");
a50e2bc0 634 printf(" dst: %s\n", clnp_iso_addrp(host));
600d71da
KS
635 printf("\tgateway: %s\n", clnp_iso_addrp(gateway));
636 ENDDEBUG
637
600d71da 638
a50e2bc0
KS
639 zap_isoaddr(dst, host);
640 zap_isoaddr(gte, gateway);
c2bb180a
KS
641 if (netmask) {
642 zap_isoaddr(msk, netmask);
643 msk.siso_nlen = 0;
644 msk.siso_len = msk.siso_pad - (u_char *)&msk;
645 }
600d71da 646
a50e2bc0
KS
647 rtrequest(req, S(dst), S(gte), (netmask ? S(msk) : (struct sockaddr *)0),
648 flags, ret_nrt);
649}
600d71da
KS
650
651/*
652 * FUNCTION: snpac_addrt
653 *
654 * PURPOSE: Associate a routing entry with an snpac entry
655 *
656 * RETURNS: nothing
657 *
658 * SIDE EFFECTS:
659 *
660 * NOTES: If a cache entry exists for gateway, then
661 * make a routing entry (host, gateway) and associate
662 * with gateway.
663 *
664 * If a route already exists and is different, first delete
665 * it.
666 *
667 * This could be made more efficient by checking
668 * the existing route before adding a new one.
669 */
af8f5eff
KS
670snpac_addrt(ifp, host, gateway, netmask)
671struct ifnet *ifp;
672struct iso_addr *host, *gateway, *netmask;
600d71da 673{
a50e2bc0 674 register struct iso_addr *r;
600d71da 675
d910a5d6
KS
676 zap_isoaddr(dst, host);
677 zap_isoaddr(gte, gateway);
d910a5d6 678 if (netmask) {
c2bb180a
KS
679 zap_isoaddr(msk, netmask);
680 msk.siso_nlen = 0;
681 msk.siso_len = msk.siso_pad - (u_char *)&msk;
d910a5d6
KS
682 rtredirect(S(dst), S(gte), S(msk), RTF_DONE, S(gte), 0);
683 } else
684 rtredirect(S(dst), S(gte), (struct sockaddr *)0,
685 RTF_DONE | RTF_HOST, S(gte), 0);
600d71da
KS
686}
687#endif ISO