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

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

unix.superglobalmegacorp.com

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