Annotation of Net2/netinet/in.c, revision 1.1.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.