[BACK]Return to in6_src.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netinet6

Annotation of src/sys/netinet6/in6_src.c, Revision 1.2

1.2     ! itojun      1: /*     $NetBSD: in6_src.c,v 1.1 2000/06/03 14:36:36 itojun Exp $       */
        !             2: /*     $KAME: in6_src.c,v 1.27 2000/06/21 08:07:13 itojun Exp $        */
1.1       itojun      3:
                      4: /*
                      5:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. Neither the name of the project nor the names of its contributors
                     17:  *    may be used to endorse or promote products derived from this software
                     18:  *    without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*
                     34:  * Copyright (c) 1982, 1986, 1991, 1993
                     35:  *     The Regents of the University of California.  All rights reserved.
                     36:  *
                     37:  * Redistribution and use in source and binary forms, with or without
                     38:  * modification, are permitted provided that the following conditions
                     39:  * are met:
                     40:  * 1. Redistributions of source code must retain the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer.
                     42:  * 2. Redistributions in binary form must reproduce the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer in the
                     44:  *    documentation and/or other materials provided with the distribution.
                     45:  * 3. All advertising materials mentioning features or use of this software
                     46:  *    must display the following acknowledgement:
                     47:  *     This product includes software developed by the University of
                     48:  *     California, Berkeley and its contributors.
                     49:  * 4. Neither the name of the University nor the names of its contributors
                     50:  *    may be used to endorse or promote products derived from this software
                     51:  *    without specific prior written permission.
                     52:  *
                     53:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     54:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     55:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     56:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     57:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     58:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     59:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     60:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     61:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     62:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     63:  * SUCH DAMAGE.
                     64:  *
                     65:  *     @(#)in_pcb.c    8.2 (Berkeley) 1/4/94
                     66:  */
                     67:
                     68: #include "opt_inet.h"
                     69:
                     70: #include <sys/param.h>
                     71: #include <sys/systm.h>
                     72: #include <sys/malloc.h>
                     73: #include <sys/mbuf.h>
                     74: #include <sys/protosw.h>
                     75: #include <sys/socket.h>
                     76: #include <sys/socketvar.h>
                     77: #include <sys/ioctl.h>
                     78: #include <sys/errno.h>
                     79: #include <sys/time.h>
                     80: #include <sys/proc.h>
                     81:
                     82: #include <net/if.h>
                     83: #include <net/route.h>
                     84:
                     85: #include <netinet/in.h>
                     86: #include <netinet/in_var.h>
                     87: #include <netinet/in_systm.h>
                     88: #include <netinet/ip.h>
                     89: #include <netinet/in_pcb.h>
                     90: #include <netinet6/in6_var.h>
                     91: #include <netinet/ip6.h>
                     92: #include <netinet6/in6_pcb.h>
                     93: #include <netinet6/ip6_var.h>
                     94: #include <netinet6/nd6.h>
1.2     ! itojun     95: #ifdef ENABLE_DEFAULT_SCOPE
        !            96: #include <netinet6/scope6_var.h>
        !            97: #endif
1.1       itojun     98:
                     99: #include <net/net_osdep.h>
                    100:
                    101: #include "loop.h"
                    102: extern struct ifnet loif[NLOOP];
                    103:
                    104: /*
                    105:  * Return an IPv6 address, which is the most appropriate for given
                    106:  * destination and user specified options.
                    107:  * If necessary, this function lookups the routing table and return
                    108:  * an entry to the caller for later use.
                    109:  */
                    110: struct in6_addr *
                    111: in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp)
                    112:        struct sockaddr_in6 *dstsock;
                    113:        struct ip6_pktopts *opts;
                    114:        struct ip6_moptions *mopts;
                    115:        struct route_in6 *ro;
                    116:        struct in6_addr *laddr;
                    117:        int *errorp;
                    118: {
                    119:        struct in6_addr *dst;
                    120:        struct in6_ifaddr *ia6 = 0;
                    121:        struct in6_pktinfo *pi = NULL;
                    122:
                    123:        dst = &dstsock->sin6_addr;
                    124:        *errorp = 0;
                    125:
                    126:        /*
                    127:         * If the source address is explicitly specified by the caller,
                    128:         * use it.
                    129:         */
                    130:        if (opts && (pi = opts->ip6po_pktinfo) &&
                    131:            !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr))
                    132:                return(&pi->ipi6_addr);
                    133:
                    134:        /*
                    135:         * If the source address is not specified but the socket(if any)
                    136:         * is already bound, use the bound address.
                    137:         */
                    138:        if (laddr && !IN6_IS_ADDR_UNSPECIFIED(laddr))
                    139:                return(laddr);
                    140:
                    141:        /*
                    142:         * If the caller doesn't specify the source address but
                    143:         * the outgoing interface, use an address associated with
                    144:         * the interface.
                    145:         */
                    146:        if (pi && pi->ipi6_ifindex) {
                    147:                /* XXX boundary check is assumed to be already done. */
                    148:                ia6 = in6_ifawithscope(ifindex2ifnet[pi->ipi6_ifindex],
                    149:                                       dst);
                    150:                if (ia6 == 0) {
                    151:                        *errorp = EADDRNOTAVAIL;
                    152:                        return(0);
                    153:                }
                    154:                return(&satosin6(&ia6->ia_addr)->sin6_addr);
                    155:        }
                    156:
                    157:        /*
                    158:         * If the destination address is a link-local unicast address or
                    159:         * a multicast address, and if the outgoing interface is specified
                    160:         * by the sin6_scope_id filed, use an address associated with the
                    161:         * interface.
                    162:         * XXX: We're now trying to define more specific semantics of
                    163:         *      sin6_scope_id field, so this part will be rewritten in
                    164:         *      the near future.
                    165:         */
                    166:        if ((IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MULTICAST(dst)) &&
                    167:            dstsock->sin6_scope_id) {
                    168:                /*
                    169:                 * I'm not sure if boundary check for scope_id is done
                    170:                 * somewhere...
                    171:                 */
                    172:                if (dstsock->sin6_scope_id < 0 ||
                    173:                    if_index < dstsock->sin6_scope_id) {
                    174:                        *errorp = ENXIO; /* XXX: better error? */
                    175:                        return(0);
                    176:                }
                    177:                ia6 = in6_ifawithscope(ifindex2ifnet[dstsock->sin6_scope_id],
                    178:                                       dst);
                    179:                if (ia6 == 0) {
                    180:                        *errorp = EADDRNOTAVAIL;
                    181:                        return(0);
                    182:                }
                    183:                return(&satosin6(&ia6->ia_addr)->sin6_addr);
                    184:        }
                    185:
                    186:        /*
                    187:         * If the destination address is a multicast address and
                    188:         * the outgoing interface for the address is specified
                    189:         * by the caller, use an address associated with the interface.
                    190:         * There is a sanity check here; if the destination has node-local
                    191:         * scope, the outgoing interfacde should be a loopback address.
                    192:         * Even if the outgoing interface is not specified, we also
                    193:         * choose a loopback interface as the outgoing interface.
                    194:         */
                    195:        if (IN6_IS_ADDR_MULTICAST(dst)) {
                    196:                struct ifnet *ifp = mopts ? mopts->im6o_multicast_ifp : NULL;
                    197:
                    198:                if (ifp == NULL && IN6_IS_ADDR_MC_NODELOCAL(dst)) {
                    199:                        ifp = &loif[0];
                    200:                }
                    201:
                    202:                if (ifp) {
                    203:                        ia6 = in6_ifawithscope(ifp, dst);
                    204:                        if (ia6 == 0) {
                    205:                                *errorp = EADDRNOTAVAIL;
                    206:                                return(0);
                    207:                        }
                    208:                        return(&satosin6(&ia6->ia_addr)->sin6_addr);
                    209:                }
                    210:        }
                    211:
                    212:        /*
                    213:         * If the next hop address for the packet is specified
                    214:         * by caller, use an address associated with the route
                    215:         * to the next hop.
                    216:         */
                    217:        {
                    218:                struct sockaddr_in6 *sin6_next;
                    219:                struct rtentry *rt;
                    220:
                    221:                if (opts && opts->ip6po_nexthop) {
                    222:                        sin6_next = satosin6(opts->ip6po_nexthop);
                    223:                        rt = nd6_lookup(&sin6_next->sin6_addr, 1, NULL);
                    224:                        if (rt) {
                    225:                                ia6 = in6_ifawithscope(rt->rt_ifp, dst);
                    226:                                if (ia6 == 0)
                    227:                                        ia6 = ifatoia6(rt->rt_ifa);
                    228:                        }
                    229:                        if (ia6 == 0) {
                    230:                                *errorp = EADDRNOTAVAIL;
                    231:                                return(0);
                    232:                        }
                    233:                        return(&satosin6(&ia6->ia_addr)->sin6_addr);
                    234:                }
                    235:        }
                    236:
                    237:        /*
                    238:         * If route is known or can be allocated now,
                    239:         * our src addr is taken from the i/f, else punt.
                    240:         */
                    241:        if (ro) {
                    242:                if (ro->ro_rt &&
                    243:                    !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) {
                    244:                        RTFREE(ro->ro_rt);
                    245:                        ro->ro_rt = (struct rtentry *)0;
                    246:                }
                    247:                if (ro->ro_rt == (struct rtentry *)0 ||
                    248:                    ro->ro_rt->rt_ifp == (struct ifnet *)0) {
                    249:                        /* No route yet, so try to acquire one */
                    250:                        bzero(&ro->ro_dst, sizeof(struct sockaddr_in6));
                    251:                        ro->ro_dst.sin6_family = AF_INET6;
                    252:                        ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6);
                    253:                        ro->ro_dst.sin6_addr = *dst;
                    254:                        ro->ro_dst.sin6_scope_id = dstsock->sin6_scope_id;
                    255:                        if (IN6_IS_ADDR_MULTICAST(dst)) {
                    256:                                ro->ro_rt = rtalloc1(&((struct route *)ro)
                    257:                                                     ->ro_dst, 0);
                    258:                        } else {
                    259:                                rtalloc((struct route *)ro);
                    260:                        }
                    261:                }
                    262:
                    263:                /*
                    264:                 * in_pcbconnect() checks out IFF_LOOPBACK to skip using
                    265:                 * the address. But we don't know why it does so.
                    266:                 * It is necessary to ensure the scope even for lo0
                    267:                 * so doesn't check out IFF_LOOPBACK.
                    268:                 */
                    269:
                    270:                if (ro->ro_rt) {
                    271:                        ia6 = in6_ifawithscope(ro->ro_rt->rt_ifa->ifa_ifp, dst);
                    272:                        if (ia6 == 0) /* xxx scope error ?*/
                    273:                                ia6 = ifatoia6(ro->ro_rt->rt_ifa);
                    274:                }
                    275: #if 0
                    276:                /*
                    277:                 * xxx The followings are necessary? (kazu)
                    278:                 * I don't think so.
                    279:                 * It's for SO_DONTROUTE option in IPv4.(jinmei)
                    280:                 */
                    281:                if (ia6 == 0) {
                    282:                        struct sockaddr_in6 sin6 = {sizeof(sin6), AF_INET6, 0};
                    283:
                    284:                        sin6->sin6_addr = *dst;
                    285:
                    286:                        ia6 = ifatoia6(ifa_ifwithdstaddr(sin6tosa(&sin6)));
                    287:                        if (ia6 == 0)
                    288:                                ia6 = ifatoia6(ifa_ifwithnet(sin6tosa(&sin6)));
                    289:                        if (ia6 == 0)
                    290:                                return(0);
                    291:                        return(&satosin6(&ia6->ia_addr)->sin6_addr);
                    292:                }
                    293: #endif /* 0 */
                    294:                if (ia6 == 0) {
                    295:                        *errorp = EHOSTUNREACH; /* no route */
                    296:                        return(0);
                    297:                }
                    298:                return(&satosin6(&ia6->ia_addr)->sin6_addr);
                    299:        }
                    300:
                    301:        *errorp = EADDRNOTAVAIL;
                    302:        return(0);
                    303: }
                    304:
                    305: /*
                    306:  * Default hop limit selection. The precedence is as follows:
                    307:  * 1. Hoplimit value specified via ioctl.
                    308:  * 2. (If the outgoing interface is detected) the current
                    309:  *     hop limit of the interface specified by router advertisement.
                    310:  * 3. The system default hoplimit.
                    311: */
                    312: int
                    313: in6_selecthlim(in6p, ifp)
                    314:        struct in6pcb *in6p;
                    315:        struct ifnet *ifp;
                    316: {
                    317:        if (in6p && in6p->in6p_hops >= 0)
                    318:                return(in6p->in6p_hops);
                    319:        else if (ifp)
                    320:                return(nd_ifinfo[ifp->if_index].chlim);
                    321:        else
                    322:                return(ip6_defhlim);
                    323: }
                    324:
                    325: /*
                    326:  * Find an empty port and set it to the specified PCB.
                    327:  */
                    328: int
                    329: in6_pcbsetport(laddr, in6p)
                    330:        struct in6_addr *laddr;
                    331:        struct in6pcb *in6p;
                    332: {
                    333:        struct socket *so = in6p->in6p_socket;
                    334:        struct in6pcb *head = in6p->in6p_head;
                    335:        u_int16_t last_port, lport = 0;
                    336:        int wild = 0;
                    337:        void *t;
                    338:        u_int16_t min, max;
                    339:        struct proc *p = curproc;               /* XXX */
                    340:
                    341:        /* XXX: this is redundant when called from in6_pcbbind */
                    342:        if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
                    343:           ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
                    344:            (so->so_options & SO_ACCEPTCONN) == 0))
                    345:                wild = IN6PLOOKUP_WILDCARD;
                    346:
                    347:        if (in6p->in6p_flags & IN6P_LOWPORT) {
                    348:                if (p == 0 || (suser(p->p_ucred, &p->p_acflag) != 0))
                    349:                        return (EACCES);
                    350:                min = IPV6PORT_RESERVEDMIN;
                    351:                max = IPV6PORT_RESERVEDMAX;
                    352:        } else {
                    353:                min = IPV6PORT_ANONMIN;
                    354:                max = IPV6PORT_ANONMAX;
                    355:        }
                    356:
                    357:        /* value out of range */
                    358:        if (head->in6p_lport < min)
                    359:                head->in6p_lport = min;
                    360:        else if (head->in6p_lport > max)
                    361:                head->in6p_lport = min;
                    362:        last_port = head->in6p_lport;
                    363:        goto startover; /*to randomize*/
                    364:        for (;;) {
                    365:                lport = htons(head->in6p_lport);
                    366:                if (IN6_IS_ADDR_V4MAPPED(laddr)) {
                    367: #if 0
                    368:                        t = in_pcblookup_bind(&tcbtable,
                    369:                                              (struct in_addr *)&in6p->in6p_laddr.s6_addr32[3],
                    370:                                              lport);
                    371: #else
                    372:                        t = NULL;
                    373: #endif
                    374:                } else {
                    375:                        t = in6_pcblookup(head, &zeroin6_addr, 0, laddr,
                    376:                                          lport, wild);
                    377:                }
                    378:                if (t == 0)
                    379:                        break;
                    380:          startover:
                    381:                if (head->in6p_lport >= max)
                    382:                        head->in6p_lport = min;
                    383:                else
                    384:                        head->in6p_lport++;
                    385:                if (head->in6p_lport == last_port)
                    386:                        return (EADDRINUSE);
                    387:        }
                    388:
                    389:        in6p->in6p_lport = lport;
                    390:        return(0);              /* success */
1.2     ! itojun    391: }
        !           392:
        !           393: /*
        !           394:  * generate kernel-internal form (scopeid embedded into s6_addr16[1]).
        !           395:  * If the address scope of is link-local, embed the interface index in the
        !           396:  * address.  The routine determines our precedence
        !           397:  * between advanced API scope/interface specification and basic API
        !           398:  * specification.
        !           399:  *
        !           400:  * this function should be nuked in the future, when we get rid of
        !           401:  * embedded scopeid thing.
        !           402:  *
        !           403:  * XXX actually, it is over-specification to return ifp against sin6_scope_id.
        !           404:  * there can be multiple interfaces that belong to a particular scope zone
        !           405:  * (in specification, we have 1:N mapping between a scope zone and interfaces).
        !           406:  * we may want to change the function to return something other than ifp.
        !           407:  */
        !           408: int
        !           409: in6_embedscope(in6, sin6, in6p, ifpp)
        !           410:        struct in6_addr *in6;
        !           411:        const struct sockaddr_in6 *sin6;
        !           412:        struct in6pcb *in6p;
        !           413:        struct ifnet **ifpp;
        !           414: {
        !           415:        struct ifnet *ifp = NULL;
        !           416:        u_int32_t scopeid;
        !           417:
        !           418:        *in6 = sin6->sin6_addr;
        !           419:        scopeid = sin6->sin6_scope_id;
        !           420:        if (ifpp)
        !           421:                *ifpp = NULL;
        !           422:
        !           423:        /*
        !           424:         * don't try to read sin6->sin6_addr beyond here, since the caller may
        !           425:         * ask us to overwrite existing sockaddr_in6
        !           426:         */
        !           427:
        !           428: #ifdef ENABLE_DEFAULT_SCOPE
        !           429:        if (scopeid == 0)
        !           430:                scopeid = scope6_addr2default(in6);
        !           431: #endif
        !           432:
        !           433:        if (IN6_IS_SCOPE_LINKLOCAL(in6)) {
        !           434:                struct in6_pktinfo *pi;
        !           435:
        !           436:                /*
        !           437:                 * KAME assumption: link id == interface id
        !           438:                 */
        !           439:
        !           440:                if (in6p && in6p->in6p_outputopts &&
        !           441:                    (pi = in6p->in6p_outputopts->ip6po_pktinfo) &&
        !           442:                    pi->ipi6_ifindex) {
        !           443:                        ifp = ifindex2ifnet[pi->ipi6_ifindex];
        !           444:                        in6->s6_addr16[1] = htons(pi->ipi6_ifindex);
        !           445:                } else if (in6p && IN6_IS_ADDR_MULTICAST(in6) &&
        !           446:                           in6p->in6p_moptions &&
        !           447:                           in6p->in6p_moptions->im6o_multicast_ifp) {
        !           448:                        ifp = in6p->in6p_moptions->im6o_multicast_ifp;
        !           449:                        in6->s6_addr16[1] = htons(ifp->if_index);
        !           450:                } else if (scopeid) {
        !           451:                        /* boundary check */
        !           452:                        if (scopeid < 0 || if_index < scopeid)
        !           453:                                return ENXIO;  /* XXX EINVAL? */
        !           454:                        ifp = ifindex2ifnet[scopeid];
        !           455:                        /*XXX assignment to 16bit from 32bit variable */
        !           456:                        in6->s6_addr16[1] = htons(scopeid & 0xffff);
        !           457:                }
        !           458:
        !           459:                if (ifpp)
        !           460:                        *ifpp = ifp;
        !           461:        }
        !           462:
        !           463:        return 0;
        !           464: }
        !           465:
        !           466: /*
        !           467:  * generate standard sockaddr_in6 from embedded form.
        !           468:  * touches sin6_addr and sin6_scope_id only.
        !           469:  *
        !           470:  * this function should be nuked in the future, when we get rid of
        !           471:  * embedded scopeid thing.
        !           472:  */
        !           473: int
        !           474: in6_recoverscope(sin6, in6, ifp)
        !           475:        struct sockaddr_in6 *sin6;
        !           476:        const struct in6_addr *in6;
        !           477:        struct ifnet *ifp;
        !           478: {
        !           479:        u_int32_t scopeid;
        !           480:
        !           481:        sin6->sin6_addr = *in6;
        !           482:
        !           483:        /*
        !           484:         * don't try to read *in6 beyond here, since the caller may
        !           485:         * ask us to overwrite existing sockaddr_in6
        !           486:         */
        !           487:
        !           488:        sin6->sin6_scope_id = 0;
        !           489:        if (IN6_IS_SCOPE_LINKLOCAL(in6)) {
        !           490:                /*
        !           491:                 * KAME assumption: link id == interface id
        !           492:                 */
        !           493:                scopeid = ntohs(sin6->sin6_addr.s6_addr16[1]);
        !           494:                if (scopeid) {
        !           495:                        /* sanity check */
        !           496:                        if (scopeid < 0 || if_index < scopeid)
        !           497:                                return ENXIO;
        !           498: #ifndef FAKE_LOOPBACK_IF
        !           499:                        if (ifp && (ifp->if_flags & IFF_LOOPBACK) == 0 &&
        !           500:                            ifp->if_index != scopeid) {
        !           501:                                return ENXIO;
        !           502:                        }
        !           503: #else
        !           504:                        if (ifp && ifp->if_index != scopeid)
        !           505:                                return ENXIO;
        !           506: #endif
        !           507:                        sin6->sin6_addr.s6_addr16[1] = 0;
        !           508:                        sin6->sin6_scope_id = scopeid;
        !           509:                }
        !           510:        }
        !           511:
        !           512:        return 0;
1.1       itojun    513: }

CVSweb <webmaster@jp.NetBSD.org>