|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright IBM Corporation 1987 ! 3: ! 4: All Rights Reserved ! 5: ! 6: Permission to use, copy, modify, and distribute this software and its ! 7: documentation for any purpose and without fee is hereby granted, ! 8: provided that the above copyright notice appear in all copies and that ! 9: both that copyright notice and this permission notice appear in ! 10: supporting documentation, and that the name of IBM not be ! 11: used in advertising or publicity pertaining to distribution of the ! 12: software without specific, written prior permission. ! 13: ! 14: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 15: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 16: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 17: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 18: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 19: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 20: SOFTWARE. ! 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 $ */ ! 29: /* @(#)iso_snpac.c 7.9 (Berkeley) 6/22/90 */ ! 30: ! 31: #ifndef lint ! 32: static 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: ! 37: #include "types.h" ! 38: #include "param.h" ! 39: #include "systm.h" ! 40: #include "user.h" ! 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" ! 48: #include "kernel.h" ! 49: ! 50: #include "../net/if.h" ! 51: #include "../net/if_dl.h" ! 52: #include "../net/route.h" ! 53: ! 54: #include "iso.h" ! 55: #include "iso_var.h" ! 56: #include "iso_snpac.h" ! 57: #include "clnp.h" ! 58: #include "clnp_stat.h" ! 59: #include "esis.h" ! 60: #include "argo_debug.h" ! 61: ! 62: int iso_systype = SNPA_ES; /* default to be an ES */ ! 63: extern short esis_holding_time, esis_config_time, esis_esconfig_time; ! 64: extern int esis_config(); ! 65: ! 66: struct sockaddr_iso blank_siso = {sizeof(blank_siso), AF_ISO}; ! 67: extern u_long iso_hashchar(); ! 68: static 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)) ! 79: ! 80: static struct sockaddr_dl blank_dl = {sizeof(blank_dl), AF_LINK}; ! 81: static 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) ! 84: ! 85: /* ! 86: * We only keep track of a single IS at a time. ! 87: */ ! 88: struct rtentry *known_is; ! 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: */ ! 107: char all_es_snpa[] = { 0x09, 0x00, 0x2b, 0x00, 0x00, 0x04 }; ! 108: char all_is_snpa[] = { 0x09, 0x00, 0x2b, 0x00, 0x00, 0x05 }; ! 109: ! 110: union sockunion { ! 111: struct sockaddr_iso siso; ! 112: struct sockaddr_dl sdl; ! 113: struct sockaddr sa; ! 114: }; ! 115: ! 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: */ ! 123: llc_rtrequest(req, rt, sa) ! 124: int req; ! 125: register struct rtentry *rt; ! 126: struct 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; ! 133: static struct rtentry *recursing = 0; ! 134: ! 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; ! 154: } ! 155: } else switch (req) { ! 156: case RTM_ADD: ! 157: /* ! 158: * Case 1: This route may come from a route to iface with mask ! 159: * or from a default route. ! 160: */ ! 161: if (rt->rt_flags & RTF_CLONING) { ! 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; ! 173: } ! 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; ! 187: } ! 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); ! 206: break; ! 207: case RTM_DELETE: ! 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; ! 214: break; ! 215: } ! 216: } ! 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: * ! 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. ! 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: */ ! 238: iso_snparesolve(ifp, dest, snpa, snpa_len) ! 239: struct ifnet *ifp; /* outgoing interface */ ! 240: struct sockaddr_iso *dest; /* destination */ ! 241: caddr_t snpa; /* RESULT: snpa to be used */ ! 242: int *snpa_len; /* RESULT: length of snpa */ ! 243: { ! 244: struct llinfo_llc *sc; /* ptr to snpa table entry */ ! 245: caddr_t found_snpa; ! 246: int addrlen; ! 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: */ ! 252: if (dest->siso_data[0] == AFI_SNA) { ! 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 ! 259: addrlen = dest->siso_nlen - 1; /* subtract size of AFI */ ! 260: found_snpa = (caddr_t) dest->siso_data + 1; ! 261: /* ! 262: * If we are an IS, we can't do much with the packet; ! 263: * Check if we know about an IS. ! 264: */ ! 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" ! 281: */ ! 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); ! 287: return (0); ! 288: } ! 289: ! 290: ! 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: */ ! 303: snpac_free(lc) ! 304: register struct llinfo_llc *lc; /* entry to free */ ! 305: { ! 306: register struct rtentry *rt = lc->lc_rt; ! 307: register struct iso_addr *r; ! 308: ! 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))) { ! 313: RTFREE(rt); ! 314: rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt), ! 315: rt->rt_flags, (struct rtentry **)0); ! 316: RTFREE(rt); ! 317: } ! 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: */ ! 331: snpac_add(ifp, nsap, snpa, type, ht, nsellength) ! 332: struct ifnet *ifp; /* interface info is related to */ ! 333: struct iso_addr *nsap; /* nsap to add */ ! 334: caddr_t snpa; /* translation */ ! 335: char type; /* SNPA_IS or SNPA_ES */ ! 336: u_short ht; /* holding time (in seconds) */ ! 337: int nsellength; /* nsaps may differ only in trailing bytes */ ! 338: { ! 339: register struct llinfo_llc *lc; ! 340: register struct rtentry *rt; ! 341: struct rtentry *mrt = 0; ! 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: ! 346: IFDEBUG(D_SNPA) ! 347: printf("snpac_add(%x, %x, %x, %x, %x, %x)\n", ! 348: ifp, nsap, snpa, type, ht, nsellength); ! 349: ENDDEBUG ! 350: zap_isoaddr(dst, nsap); ! 351: rt = rtalloc1(S(dst), 0); ! 352: IFDEBUG(D_SNPA) ! 353: printf("snpac_add: rtalloc1 returns %x\n", rt); ! 354: ENDDEBUG ! 355: if (rt == 0) { ! 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: } ! 365: new_entry = 1; ! 366: zap_linkaddr((>e_dl), snpa, snpalen, index); ! 367: if (rtrequest(RTM_ADD, S(dst), S(gte_dl), netmask, flags, &mrt) || ! 368: mrt == 0) ! 369: return (0); ! 370: rt = mrt; ! 371: rt->rt_refcnt--; ! 372: } else { ! 373: register struct sockaddr_dl *sdl = (struct sockaddr_dl *)rt->rt_gateway; ! 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: } ! 392: if (sdl->sdl_family != AF_LINK || sdl->sdl_alen == 0) { ! 393: int old_sdl_len = sdl->sdl_len; ! 394: if (old_sdl_len < sizeof(*sdl)) { ! 395: log("snpac_add: cant make room for lladdr\n"); ! 396: return (0); ! 397: } ! 398: zap_linkaddr(sdl, snpa, snpalen, index); ! 399: sdl->sdl_len = old_sdl_len; ! 400: new_entry = 1; ! 401: } ! 402: } ! 403: if ((lc = (struct llinfo_llc *)rt->rt_llinfo) == 0) ! 404: panic("snpac_rtrequest"); ! 405: rt->rt_idle = ht; ! 406: lc->lc_flags = SNPA_VALID | type; ! 407: if (type & SNPA_IS) ! 408: snpac_logdefis(rt); ! 409: return (new_entry); ! 410: } ! 411: ! 412: static 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; ! 425: } ! 426: ! 427: /* ! 428: * FUNCTION: snpac_ioctl ! 429: * ! 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: */ ! 438: snpac_ioctl (cmd, data) ! 439: int cmd; /* ioctl to process */ ! 440: caddr_t data; /* data for the cmd */ ! 441: { ! 442: register struct systype_req *rq = (struct systype_req *)data; ! 443: ! 444: IFDEBUG(D_IOCTL) ! 445: if (cmd == SIOCSSTYPE) ! 446: printf("snpac_ioctl: cmd set, type x%x, ht %d, ct %d\n", ! 447: rq->sr_type, rq->sr_holdt, rq->sr_configt); ! 448: else ! 449: printf("snpac_ioctl: cmd get\n"); ! 450: ENDDEBUG ! 451: ! 452: if (cmd == SIOCSSTYPE) { ! 453: if (suser(u.u_cred, &u.u_acflag)) ! 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; ! 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: } ! 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; ! 475: rq->sr_esconfigt = esis_esconfig_time; ! 476: } else { ! 477: return (EINVAL); ! 478: } ! 479: return (0); ! 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: */ ! 493: snpac_logdefis(sc) ! 494: register struct rtentry *sc; ! 495: { ! 496: register struct iso_addr *r; ! 497: register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sc->rt_gateway; ! 498: register struct rtentry *rt = rtalloc1((struct sockaddr *)&zsi, 0); ! 499: ! 500: zap_linkaddr((>e_dl), LLADDR(sdl), sdl->sdl_alen, sdl->sdl_index); ! 501: if (known_is == 0) ! 502: known_is = sc; ! 503: if (known_is != sc) { ! 504: rtfree(known_is); ! 505: known_is = sc; ! 506: } ! 507: if (rt == 0) { ! 508: rtrequest(RTM_ADD, S(zsi), S(gte_dl), S(zmk), ! 509: RTF_DYNAMIC|RTF_GATEWAY|RTF_CLONING, 0); ! 510: return; ! 511: } ! 512: rt->rt_refcnt--; ! 513: if (rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED)) { ! 514: *((struct sockaddr_dl *)rt->rt_gateway) = gte_dl; ! 515: } ! 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: */ ! 539: snpac_age() ! 540: { ! 541: register struct llinfo_llc *lc; ! 542: ! 543: timeout(snpac_age, (caddr_t)0, SNPAC_AGE * hz); ! 544: ! 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)) { ! 547: lc->lc_rt->rt_idle -= SNPAC_AGE; ! 548: if (lc->lc_rt->rt_idle > 0) ! 549: continue; ! 550: else ! 551: snpac_free(lc); ! 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: */ ! 570: snpac_ownmulti(snpa, len) ! 571: caddr_t snpa; ! 572: u_int len; ! 573: { ! 574: return (((iso_systype & SNPA_ES) && ! 575: (!bcmp(snpa, (caddr_t)all_es_snpa, len))) || ! 576: ((iso_systype & SNPA_IS) && ! 577: (!bcmp(snpa, (caddr_t)all_is_snpa, len)))); ! 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: */ ! 591: snpac_flushifp(ifp) ! 592: struct ifnet *ifp; ! 593: { ! 594: register struct llinfo_llc *lc; ! 595: ! 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); ! 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: */ ! 614: snpac_rtrequest(req, host, gateway, netmask, flags, ret_nrt) ! 615: int req; ! 616: struct iso_addr *host; ! 617: struct iso_addr *gateway; ! 618: struct iso_addr *netmask; ! 619: short flags; ! 620: struct rtentry **ret_nrt; ! 621: { ! 622: register struct iso_addr *r; ! 623: ! 624: IFDEBUG(D_SNPA) ! 625: printf("snpac_rtrequest: "); ! 626: if (req == RTM_ADD) ! 627: printf("add"); ! 628: else if (req == RTM_DELETE) ! 629: printf("delete"); ! 630: else ! 631: printf("unknown command"); ! 632: printf(" dst: %s\n", clnp_iso_addrp(host)); ! 633: printf("\tgateway: %s\n", clnp_iso_addrp(gateway)); ! 634: ENDDEBUG ! 635: ! 636: ! 637: zap_isoaddr(dst, host); ! 638: zap_isoaddr(gte, gateway); ! 639: if (netmask) { ! 640: zap_isoaddr(msk, netmask); ! 641: msk.siso_nlen = 0; ! 642: msk.siso_len = msk.siso_pad - (u_char *)&msk; ! 643: } ! 644: ! 645: rtrequest(req, S(dst), S(gte), (netmask ? S(msk) : (struct sockaddr *)0), ! 646: flags, ret_nrt); ! 647: } ! 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: */ ! 668: snpac_addrt(ifp, host, gateway, netmask) ! 669: struct ifnet *ifp; ! 670: struct iso_addr *host, *gateway, *netmask; ! 671: { ! 672: register struct iso_addr *r; ! 673: ! 674: zap_isoaddr(dst, host); ! 675: zap_isoaddr(gte, gateway); ! 676: if (netmask) { ! 677: zap_isoaddr(msk, netmask); ! 678: msk.siso_nlen = 0; ! 679: msk.siso_len = msk.siso_pad - (u_char *)&msk; ! 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); ! 684: } ! 685: #endif ISO
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.