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