Annotation of Net2/netinet/in.c, revision 1.1

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

unix.superglobalmegacorp.com

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