Annotation of 43BSDReno/sys/netinet/in.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 1986 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution is only permitted until one year after the first shipment
        !             6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !             7:  * binary forms are permitted provided that: (1) source distributions retain
        !             8:  * this entire copyright notice and comment, and (2) distributions including
        !             9:  * binaries display the following acknowledgement:  This product includes
        !            10:  * software developed by the University of California, Berkeley and its
        !            11:  * contributors'' in the documentation or other materials provided with the
        !            12:  * distribution and in all advertising materials mentioning features or use
        !            13:  * of this software.  Neither the name of the University nor the names of
        !            14:  * its contributors may be used to endorse or promote products derived from
        !            15:  * this software without specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  *
        !            20:  *     @(#)in.c        7.15 (Berkeley) 6/28/90
        !            21:  */
        !            22: 
        !            23: #include "param.h"
        !            24: #include "ioctl.h"
        !            25: #include "mbuf.h"
        !            26: #include "protosw.h"
        !            27: #include "socket.h"
        !            28: #include "socketvar.h"
        !            29: #include "user.h"
        !            30: #include "in_systm.h"
        !            31: #include "../net/if.h"
        !            32: #include "../net/route.h"
        !            33: #include "../net/af.h"
        !            34: #include "in.h"
        !            35: #include "in_var.h"
        !            36: 
        !            37: #ifdef INET
        !            38: /*
        !            39:  * Formulate an Internet address from network + host.
        !            40:  */
        !            41: struct in_addr
        !            42: in_makeaddr(net, host)
        !            43:        u_long net, host;
        !            44: {
        !            45:        register struct in_ifaddr *ia;
        !            46:        register u_long mask;
        !            47:        u_long addr;
        !            48: 
        !            49:        if (IN_CLASSA(net))
        !            50:                mask = IN_CLASSA_HOST;
        !            51:        else if (IN_CLASSB(net))
        !            52:                mask = IN_CLASSB_HOST;
        !            53:        else
        !            54:                mask = IN_CLASSC_HOST;
        !            55:        for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !            56:                if ((ia->ia_netmask & net) == ia->ia_net) {
        !            57:                        mask = ~ia->ia_subnetmask;
        !            58:                        break;
        !            59:                }
        !            60:        addr = htonl(net | (host & mask));
        !            61:        return (*(struct in_addr *)&addr);
        !            62: }
        !            63: 
        !            64: /*
        !            65:  * Return the network number from an internet address.
        !            66:  */
        !            67: u_long
        !            68: in_netof(in)
        !            69:        struct in_addr in;
        !            70: {
        !            71:        register u_long i = ntohl(in.s_addr);
        !            72:        register u_long net;
        !            73:        register struct in_ifaddr *ia;
        !            74: 
        !            75:        if (IN_CLASSA(i))
        !            76:                net = i & IN_CLASSA_NET;
        !            77:        else if (IN_CLASSB(i))
        !            78:                net = i & IN_CLASSB_NET;
        !            79:        else if (IN_CLASSC(i))
        !            80:                net = i & IN_CLASSC_NET;
        !            81:        else
        !            82:                return (0);
        !            83: 
        !            84:        /*
        !            85:         * Check whether network is a subnet;
        !            86:         * if so, return subnet number.
        !            87:         */
        !            88:        for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !            89:                if (net == ia->ia_net)
        !            90:                        return (i & ia->ia_subnetmask);
        !            91:        return (net);
        !            92: }
        !            93: 
        !            94: /*
        !            95:  * Compute and save network mask as sockaddr from an internet address.
        !            96:  */
        !            97: in_sockmaskof(in, sockmask)
        !            98:        struct in_addr in;
        !            99:        register struct sockaddr_in *sockmask;
        !           100: {
        !           101:        register u_long net;
        !           102:        register u_long mask;
        !           103:     {
        !           104:        register u_long i = ntohl(in.s_addr);
        !           105: 
        !           106:        if (i == 0)
        !           107:                net = 0, mask = 0;
        !           108:        else if (IN_CLASSA(i))
        !           109:                net = i & IN_CLASSA_NET, mask = IN_CLASSA_NET;
        !           110:        else if (IN_CLASSB(i))
        !           111:                net = i & IN_CLASSB_NET, mask = IN_CLASSB_NET;
        !           112:        else if (IN_CLASSC(i))
        !           113:                net = i & IN_CLASSC_NET, mask = IN_CLASSC_NET;
        !           114:        else
        !           115:                net = i, mask = -1;
        !           116:     }
        !           117:     {
        !           118:        register struct in_ifaddr *ia;
        !           119:        /*
        !           120:         * Check whether network is a subnet;
        !           121:         * if so, return subnet number.
        !           122:         */
        !           123:        for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !           124:                if (net == ia->ia_net)
        !           125:                        mask =  ia->ia_subnetmask;
        !           126:     }
        !           127:     {
        !           128:        register char *cpbase = (char *)&(sockmask->sin_addr);
        !           129:        register char *cp = (char *)(1 + &(sockmask->sin_addr));
        !           130: 
        !           131:        sockmask->sin_addr.s_addr = htonl(mask);
        !           132:        sockmask->sin_len = 0;
        !           133:        while (--cp >= cpbase)
        !           134:                if (*cp) {
        !           135:                        sockmask->sin_len = 1 + cp - (caddr_t)sockmask;
        !           136:                        break;
        !           137:                }
        !           138:     }
        !           139: }
        !           140: 
        !           141: /*
        !           142:  * Return the host portion of an internet address.
        !           143:  */
        !           144: u_long
        !           145: in_lnaof(in)
        !           146:        struct in_addr in;
        !           147: {
        !           148:        register u_long i = ntohl(in.s_addr);
        !           149:        register u_long net, host;
        !           150:        register struct in_ifaddr *ia;
        !           151: 
        !           152:        if (IN_CLASSA(i)) {
        !           153:                net = i & IN_CLASSA_NET;
        !           154:                host = i & IN_CLASSA_HOST;
        !           155:        } else if (IN_CLASSB(i)) {
        !           156:                net = i & IN_CLASSB_NET;
        !           157:                host = i & IN_CLASSB_HOST;
        !           158:        } else if (IN_CLASSC(i)) {
        !           159:                net = i & IN_CLASSC_NET;
        !           160:                host = i & IN_CLASSC_HOST;
        !           161:        } else
        !           162:                return (i);
        !           163: 
        !           164:        /*
        !           165:         * Check whether network is a subnet;
        !           166:         * if so, use the modified interpretation of `host'.
        !           167:         */
        !           168:        for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !           169:                if (net == ia->ia_net)
        !           170:                        return (host &~ ia->ia_subnetmask);
        !           171:        return (host);
        !           172: }
        !           173: 
        !           174: #ifndef SUBNETSARELOCAL
        !           175: #define        SUBNETSARELOCAL 1
        !           176: #endif
        !           177: int subnetsarelocal = SUBNETSARELOCAL;
        !           178: /*
        !           179:  * Return 1 if an internet address is for a ``local'' host
        !           180:  * (one to which we have a connection).  If subnetsarelocal
        !           181:  * is true, this includes other subnets of the local net.
        !           182:  * Otherwise, it includes only the directly-connected (sub)nets.
        !           183:  */
        !           184: in_localaddr(in)
        !           185:        struct in_addr in;
        !           186: {
        !           187:        register u_long i = ntohl(in.s_addr);
        !           188:        register struct in_ifaddr *ia;
        !           189: 
        !           190:        if (subnetsarelocal) {
        !           191:                for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !           192:                        if ((i & ia->ia_netmask) == ia->ia_net)
        !           193:                                return (1);
        !           194:        } else {
        !           195:                for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !           196:                        if ((i & ia->ia_subnetmask) == ia->ia_subnet)
        !           197:                                return (1);
        !           198:        }
        !           199:        return (0);
        !           200: }
        !           201: 
        !           202: /*
        !           203:  * Determine whether an IP address is in a reserved set of addresses
        !           204:  * that may not be forwarded, or whether datagrams to that destination
        !           205:  * may be forwarded.
        !           206:  */
        !           207: in_canforward(in)
        !           208:        struct in_addr in;
        !           209: {
        !           210:        register u_long i = ntohl(in.s_addr);
        !           211:        register u_long net;
        !           212: 
        !           213:        if (IN_EXPERIMENTAL(i))
        !           214:                return (0);
        !           215:        if (IN_CLASSA(i)) {
        !           216:                net = i & IN_CLASSA_NET;
        !           217:                if (net == 0 || net == IN_LOOPBACKNET)
        !           218:                        return (0);
        !           219:        }
        !           220:        return (1);
        !           221: }
        !           222: 
        !           223: int    in_interfaces;          /* number of external internet interfaces */
        !           224: extern struct ifnet loif;
        !           225: 
        !           226: /*
        !           227:  * Generic internet control operations (ioctl's).
        !           228:  * Ifp is 0 if not an interface-specific ioctl.
        !           229:  */
        !           230: /* ARGSUSED */
        !           231: in_control(so, cmd, data, ifp)
        !           232:        struct socket *so;
        !           233:        int cmd;
        !           234:        caddr_t data;
        !           235:        register struct ifnet *ifp;
        !           236: {
        !           237:        register struct ifreq *ifr = (struct ifreq *)data;
        !           238:        register struct in_ifaddr *ia = 0;
        !           239:        register struct ifaddr *ifa;
        !           240:        struct in_ifaddr *oia;
        !           241:        struct in_aliasreq *ifra = (struct in_aliasreq *)data;
        !           242:        struct mbuf *m;
        !           243:        struct sockaddr_in oldaddr;
        !           244:        int error, hostIsNew, maskIsNew;
        !           245:        u_long i;
        !           246: 
        !           247:        /*
        !           248:         * Find address for this interface, if it exists.
        !           249:         */
        !           250:        if (ifp)
        !           251:                for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !           252:                        if (ia->ia_ifp == ifp)
        !           253:                                break;
        !           254: 
        !           255:        switch (cmd) {
        !           256: 
        !           257:        case SIOCAIFADDR:
        !           258:        case SIOCDIFADDR:
        !           259:                if (ifra->ifra_addr.sin_family == AF_INET)
        !           260:                    for (oia = ia; ia; ia = ia->ia_next) {
        !           261:                        if (ia->ia_ifp == ifp  &&
        !           262:                            ia->ia_addr.sin_addr.s_addr ==
        !           263:                                ifra->ifra_addr.sin_addr.s_addr)
        !           264:                            break;
        !           265:                }
        !           266:                if (cmd == SIOCDIFADDR && ia == 0)
        !           267:                        return (EADDRNOTAVAIL);
        !           268:                /* FALLTHROUGH */
        !           269:        case SIOCSIFADDR:
        !           270:        case SIOCSIFNETMASK:
        !           271:        case SIOCSIFDSTADDR:
        !           272:                if (error = suser(u.u_cred, &u.u_acflag))
        !           273:                        return (error);
        !           274: 
        !           275:                if (ifp == 0)
        !           276:                        panic("in_control");
        !           277:                if (ia == (struct in_ifaddr *)0) {
        !           278:                        m = m_getclr(M_WAIT, MT_IFADDR);
        !           279:                        if (m == (struct mbuf *)NULL)
        !           280:                                return (ENOBUFS);
        !           281:                        if (ia = in_ifaddr) {
        !           282:                                for ( ; ia->ia_next; ia = ia->ia_next)
        !           283:                                        ;
        !           284:                                ia->ia_next = mtod(m, struct in_ifaddr *);
        !           285:                        } else
        !           286:                                in_ifaddr = mtod(m, struct in_ifaddr *);
        !           287:                        ia = mtod(m, struct in_ifaddr *);
        !           288:                        if (ifa = ifp->if_addrlist) {
        !           289:                                for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
        !           290:                                        ;
        !           291:                                ifa->ifa_next = (struct ifaddr *) ia;
        !           292:                        } else
        !           293:                                ifp->if_addrlist = (struct ifaddr *) ia;
        !           294:                        ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
        !           295:                        ia->ia_ifa.ifa_dstaddr
        !           296:                                        = (struct sockaddr *)&ia->ia_dstaddr;
        !           297:                        ia->ia_ifa.ifa_netmask
        !           298:                                        = (struct sockaddr *)&ia->ia_sockmask;
        !           299:                        ia->ia_sockmask.sin_len = 8;
        !           300:                        if (ifp->if_flags & IFF_BROADCAST) {
        !           301:                                ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
        !           302:                                ia->ia_broadaddr.sin_family = AF_INET;
        !           303:                        }
        !           304:                        ia->ia_ifp = ifp;
        !           305:                        if (ifp != &loif)
        !           306:                                in_interfaces++;
        !           307:                }
        !           308:                break;
        !           309: 
        !           310:        case SIOCSIFBRDADDR:
        !           311:                if (error = suser(u.u_cred, &u.u_acflag))
        !           312:                        return (error);
        !           313:                /* FALLTHROUGH */
        !           314: 
        !           315:        case SIOCGIFADDR:
        !           316:        case SIOCGIFNETMASK:
        !           317:        case SIOCGIFDSTADDR:
        !           318:        case SIOCGIFBRDADDR:
        !           319:                if (ia == (struct in_ifaddr *)0)
        !           320:                        return (EADDRNOTAVAIL);
        !           321:                break;
        !           322: 
        !           323:        default:
        !           324:                return (EOPNOTSUPP);
        !           325:                break;
        !           326:        }
        !           327:        switch (cmd) {
        !           328: 
        !           329:        case SIOCGIFADDR:
        !           330:                *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
        !           331:                break;
        !           332: 
        !           333:        case SIOCGIFBRDADDR:
        !           334:                if ((ifp->if_flags & IFF_BROADCAST) == 0)
        !           335:                        return (EINVAL);
        !           336:                *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
        !           337:                break;
        !           338: 
        !           339:        case SIOCGIFDSTADDR:
        !           340:                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
        !           341:                        return (EINVAL);
        !           342:                *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
        !           343:                break;
        !           344: 
        !           345:        case SIOCGIFNETMASK:
        !           346:                *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
        !           347:                break;
        !           348: 
        !           349:        case SIOCSIFDSTADDR:
        !           350:                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
        !           351:                        return (EINVAL);
        !           352:                oldaddr = ia->ia_dstaddr;
        !           353:                ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
        !           354:                if (ifp->if_ioctl &&
        !           355:                    (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia))) {
        !           356:                        ia->ia_dstaddr = oldaddr;
        !           357:                        return (error);
        !           358:                }
        !           359:                if (ia->ia_flags & IFA_ROUTE) {
        !           360:                        ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
        !           361:                        rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
        !           362:                        ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_addr;
        !           363:                        rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
        !           364:                }
        !           365:                break;
        !           366: 
        !           367:        case SIOCSIFBRDADDR:
        !           368:                if ((ifp->if_flags & IFF_BROADCAST) == 0)
        !           369:                        return (EINVAL);
        !           370:                ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
        !           371:                break;
        !           372: 
        !           373:        case SIOCSIFADDR:
        !           374:                return (in_ifinit(ifp, ia,
        !           375:                    (struct sockaddr_in *) &ifr->ifr_addr, 1));
        !           376: 
        !           377:        case SIOCSIFNETMASK:
        !           378:                i = ifra->ifra_addr.sin_addr.s_addr;
        !           379:                ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
        !           380:                break;
        !           381: 
        !           382:        case SIOCAIFADDR:
        !           383:                maskIsNew = 0;
        !           384:                hostIsNew = 1;
        !           385:                error = 0;
        !           386:                if (ia->ia_addr.sin_family == AF_INET) {
        !           387:                        if (ifra->ifra_addr.sin_len == 0) {
        !           388:                                ifra->ifra_addr = ia->ia_addr;
        !           389:                                hostIsNew = 0;
        !           390:                        } else if (ifra->ifra_addr.sin_addr.s_addr ==
        !           391:                                               ia->ia_addr.sin_addr.s_addr)
        !           392:                                hostIsNew = 0;
        !           393:                }
        !           394:                if (ifra->ifra_mask.sin_len) {
        !           395:                        in_ifscrub(ifp, ia);
        !           396:                        ia->ia_sockmask = ifra->ifra_mask;
        !           397:                        ia->ia_subnetmask =
        !           398:                             ntohl(ia->ia_sockmask.sin_addr.s_addr);
        !           399:                        maskIsNew = 1;
        !           400:                }
        !           401:                if ((ifp->if_flags & IFF_POINTOPOINT) &&
        !           402:                    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
        !           403:                        in_ifscrub(ifp, ia);
        !           404:                        ia->ia_dstaddr = ifra->ifra_dstaddr;
        !           405:                        maskIsNew  = 1; /* We lie; but the effect's the same */
        !           406:                }
        !           407:                if (ifra->ifra_addr.sin_family == AF_INET &&
        !           408:                    (hostIsNew || maskIsNew))
        !           409:                        error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
        !           410:                if ((ifp->if_flags & IFF_BROADCAST) &&
        !           411:                    (ifra->ifra_broadaddr.sin_family == AF_INET))
        !           412:                        ia->ia_broadaddr = ifra->ifra_broadaddr;
        !           413:                return (error);
        !           414: 
        !           415:        case SIOCDIFADDR:
        !           416:                in_ifscrub(ifp, ia);
        !           417:                if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
        !           418:                        ifp->if_addrlist = ifa->ifa_next;
        !           419:                else {
        !           420:                        while (ifa->ifa_next &&
        !           421:                               (ifa->ifa_next != (struct ifaddr *)ia))
        !           422:                                    ifa = ifa->ifa_next;
        !           423:                        if (ifa->ifa_next)
        !           424:                                ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
        !           425:                        else
        !           426:                                printf("Couldn't unlink inifaddr from ifp\n");
        !           427:                }
        !           428:                oia = ia;
        !           429:                if (oia == (ia = in_ifaddr))
        !           430:                        in_ifaddr = ia->ia_next;
        !           431:                else {
        !           432:                        while (ia->ia_next && (ia->ia_next != oia))
        !           433:                                ia = ia->ia_next;
        !           434:                        if (ia->ia_next)
        !           435:                                ia->ia_next = oia->ia_next;
        !           436:                        else
        !           437:                                printf("Didn't unlink inifadr from list\n");
        !           438:                }
        !           439:                (void) m_free(dtom(oia));
        !           440:                break;
        !           441: 
        !           442:        default:
        !           443:                if (ifp == 0 || ifp->if_ioctl == 0)
        !           444:                        return (EOPNOTSUPP);
        !           445:                return ((*ifp->if_ioctl)(ifp, cmd, data));
        !           446:        }
        !           447:        return (0);
        !           448: }
        !           449: 
        !           450: /*
        !           451:  * Delete any existing route for an interface.
        !           452:  */
        !           453: in_ifscrub(ifp, ia)
        !           454:        register struct ifnet *ifp;
        !           455:        register struct in_ifaddr *ia;
        !           456: {
        !           457: 
        !           458:        if ((ia->ia_flags & IFA_ROUTE) == 0)
        !           459:                return;
        !           460:        if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
        !           461:                rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
        !           462:        else
        !           463:                rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
        !           464:        ia->ia_flags &= ~IFA_ROUTE;
        !           465: }
        !           466: 
        !           467: /*
        !           468:  * Initialize an interface's internet address
        !           469:  * and routing table entry.
        !           470:  */
        !           471: in_ifinit(ifp, ia, sin, scrub)
        !           472:        register struct ifnet *ifp;
        !           473:        register struct in_ifaddr *ia;
        !           474:        struct sockaddr_in *sin;
        !           475: {
        !           476:        register u_long i = ntohl(sin->sin_addr.s_addr);
        !           477:        struct sockaddr_in oldaddr;
        !           478:        int s = splimp(), error;
        !           479: 
        !           480:        oldaddr = ia->ia_addr;
        !           481:        ia->ia_addr = *sin;
        !           482:        /*
        !           483:         * Give the interface a chance to initialize
        !           484:         * if this is its first address,
        !           485:         * and to validate the address if necessary.
        !           486:         */
        !           487:        if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
        !           488:                splx(s);
        !           489:                ia->ia_addr = oldaddr;
        !           490:                return (error);
        !           491:        }
        !           492:        if (scrub) {
        !           493:                ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
        !           494:                in_ifscrub(ifp, ia);
        !           495:                ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
        !           496:        }
        !           497:        if (IN_CLASSA(i))
        !           498:                ia->ia_netmask = IN_CLASSA_NET;
        !           499:        else if (IN_CLASSB(i))
        !           500:                ia->ia_netmask = IN_CLASSB_NET;
        !           501:        else
        !           502:                ia->ia_netmask = IN_CLASSC_NET;
        !           503:        ia->ia_net = i & ia->ia_netmask;
        !           504:        /*
        !           505:         * The subnet mask includes at least the standard network part,
        !           506:         * but may already have been set to a larger value.
        !           507:         */
        !           508:        ia->ia_subnetmask |= ia->ia_netmask;
        !           509:        ia->ia_subnet = i & ia->ia_subnetmask;
        !           510:        ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
        !           511:        {
        !           512:                register char *cp = (char *) (1 + &(ia->ia_sockmask.sin_addr));
        !           513:                register char *cpbase = (char *) &(ia->ia_sockmask.sin_addr);
        !           514:                while (--cp >= cpbase)
        !           515:                        if (*cp) {
        !           516:                                ia->ia_sockmask.sin_len =
        !           517:                                        1 + cp - (char *) &(ia->ia_sockmask);
        !           518:                                break;
        !           519:                        }
        !           520:        }
        !           521:        if (ifp->if_flags & IFF_BROADCAST) {
        !           522:                ia->ia_broadaddr.sin_addr = 
        !           523:                        in_makeaddr(ia->ia_subnet, INADDR_BROADCAST);
        !           524:                ia->ia_netbroadcast.s_addr =
        !           525:                    htonl(ia->ia_net | (INADDR_BROADCAST &~ ia->ia_netmask));
        !           526:        }
        !           527:        /*
        !           528:         * Add route for the network.
        !           529:         */
        !           530:        if (ifp->if_flags & IFF_LOOPBACK) {
        !           531:                ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
        !           532:                rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
        !           533:        } else if (ifp->if_flags & IFF_POINTOPOINT &&
        !           534:                 ia->ia_dstaddr.sin_family == AF_INET)
        !           535:                rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
        !           536:        else {
        !           537:                rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
        !           538:        }
        !           539:        ia->ia_flags |= IFA_ROUTE;
        !           540:        splx(s);
        !           541:        return (0);
        !           542: }
        !           543: 
        !           544: /*
        !           545:  * Return address info for specified internet network.
        !           546:  */
        !           547: struct in_ifaddr *
        !           548: in_iaonnetof(net)
        !           549:        u_long net;
        !           550: {
        !           551:        register struct in_ifaddr *ia;
        !           552: 
        !           553:        for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !           554:                if (ia->ia_subnet == net)
        !           555:                        return (ia);
        !           556:        return ((struct in_ifaddr *)0);
        !           557: }
        !           558: 
        !           559: /*
        !           560:  * Return 1 if the address might be a local broadcast address.
        !           561:  */
        !           562: in_broadcast(in)
        !           563:        struct in_addr in;
        !           564: {
        !           565:        register struct in_ifaddr *ia;
        !           566:        u_long t;
        !           567: 
        !           568:        /*
        !           569:         * Look through the list of addresses for a match
        !           570:         * with a broadcast address.
        !           571:         */
        !           572:        for (ia = in_ifaddr; ia; ia = ia->ia_next)
        !           573:            if (ia->ia_ifp->if_flags & IFF_BROADCAST) {
        !           574:                if (ia->ia_broadaddr.sin_addr.s_addr == in.s_addr)
        !           575:                     return (1);
        !           576:                /*
        !           577:                 * Check for old-style (host 0) broadcast.
        !           578:                 */
        !           579:                if ((t = ntohl(in.s_addr)) == ia->ia_subnet || t == ia->ia_net)
        !           580:                    return (1);
        !           581:        }
        !           582:        if (in.s_addr == INADDR_BROADCAST || in.s_addr == INADDR_ANY)
        !           583:                return (1);
        !           584:        return (0);
        !           585: }
        !           586: #endif

unix.superglobalmegacorp.com

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