Annotation of 43BSDReno/sys/netiso/iso_snpac.c, revision 1.1.1.1

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((&gte_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((&gte_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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.