Annotation of embedaddon/quagga/zebra/ioctl.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Common ioctl functions.
        !             3:  * Copyright (C) 1997, 98 Kunihiro Ishiguro
        !             4:  *
        !             5:  * This file is part of GNU Zebra.
        !             6:  *
        !             7:  * GNU Zebra is free software; you can redistribute it and/or modify it
        !             8:  * under the terms of the GNU General Public License as published by the
        !             9:  * Free Software Foundation; either version 2, or (at your option) any
        !            10:  * later version.
        !            11:  *
        !            12:  * GNU Zebra is distributed in the hope that it will be useful, but
        !            13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            15:  * General Public License for more details.
        !            16:  *
        !            17:  * You should have received a copy of the GNU General Public License
        !            18:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
        !            19:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
        !            20:  * 02111-1307, USA.  
        !            21:  */
        !            22: 
        !            23: #include <zebra.h>
        !            24: 
        !            25: #include "linklist.h"
        !            26: #include "if.h"
        !            27: #include "prefix.h"
        !            28: #include "ioctl.h"
        !            29: #include "log.h"
        !            30: #include "privs.h"
        !            31: 
        !            32: #include "zebra/rib.h"
        !            33: #include "zebra/rt.h"
        !            34: #include "zebra/interface.h"
        !            35: 
        !            36: #ifdef HAVE_BSD_LINK_DETECT
        !            37: #include <net/if_media.h>
        !            38: #endif /* HAVE_BSD_LINK_DETECT*/
        !            39: 
        !            40: extern struct zebra_privs_t zserv_privs;
        !            41: 
        !            42: /* clear and set interface name string */
        !            43: void
        !            44: ifreq_set_name (struct ifreq *ifreq, struct interface *ifp)
        !            45: {
        !            46:   strncpy (ifreq->ifr_name, ifp->name, IFNAMSIZ);
        !            47: }
        !            48: 
        !            49: /* call ioctl system call */
        !            50: int
        !            51: if_ioctl (u_long request, caddr_t buffer)
        !            52: {
        !            53:   int sock;
        !            54:   int ret;
        !            55:   int err;
        !            56: 
        !            57:   if (zserv_privs.change(ZPRIVS_RAISE))
        !            58:     zlog (NULL, LOG_ERR, "Can't raise privileges");
        !            59:   sock = socket (AF_INET, SOCK_DGRAM, 0);
        !            60:   if (sock < 0)
        !            61:     {
        !            62:       int save_errno = errno;
        !            63:       if (zserv_privs.change(ZPRIVS_LOWER))
        !            64:         zlog (NULL, LOG_ERR, "Can't lower privileges");
        !            65:       zlog_err("Cannot create UDP socket: %s", safe_strerror(save_errno));
        !            66:       exit (1);
        !            67:     }
        !            68:   if ((ret = ioctl (sock, request, buffer)) < 0)
        !            69:     err = errno;
        !            70:   if (zserv_privs.change(ZPRIVS_LOWER))
        !            71:     zlog (NULL, LOG_ERR, "Can't lower privileges");
        !            72:   close (sock);
        !            73:   
        !            74:   if (ret < 0) 
        !            75:     {
        !            76:       errno = err;
        !            77:       return ret;
        !            78:     }
        !            79:   return 0;
        !            80: }
        !            81: 
        !            82: #ifdef HAVE_IPV6
        !            83: static int
        !            84: if_ioctl_ipv6 (u_long request, caddr_t buffer)
        !            85: {
        !            86:   int sock;
        !            87:   int ret;
        !            88:   int err;
        !            89: 
        !            90:   if (zserv_privs.change(ZPRIVS_RAISE))
        !            91:     zlog (NULL, LOG_ERR, "Can't raise privileges");
        !            92:   sock = socket (AF_INET6, SOCK_DGRAM, 0);
        !            93:   if (sock < 0)
        !            94:     {
        !            95:       int save_errno = errno;
        !            96:       if (zserv_privs.change(ZPRIVS_LOWER))
        !            97:         zlog (NULL, LOG_ERR, "Can't lower privileges");
        !            98:       zlog_err("Cannot create IPv6 datagram socket: %s",
        !            99:               safe_strerror(save_errno));
        !           100:       exit (1);
        !           101:     }
        !           102: 
        !           103:   if ((ret = ioctl (sock, request, buffer)) < 0)
        !           104:     err = errno;
        !           105:   if (zserv_privs.change(ZPRIVS_LOWER))
        !           106:     zlog (NULL, LOG_ERR, "Can't lower privileges");
        !           107:   close (sock);
        !           108:   
        !           109:   if (ret < 0) 
        !           110:     {
        !           111:       errno = err;
        !           112:       return ret;
        !           113:     }
        !           114:   return 0;
        !           115: }
        !           116: #endif /* HAVE_IPV6 */
        !           117: 
        !           118: /*
        !           119:  * get interface metric
        !           120:  *   -- if value is not avaliable set -1
        !           121:  */
        !           122: void
        !           123: if_get_metric (struct interface *ifp)
        !           124: {
        !           125: #ifdef SIOCGIFMETRIC
        !           126:   struct ifreq ifreq;
        !           127: 
        !           128:   ifreq_set_name (&ifreq, ifp);
        !           129: 
        !           130:   if (if_ioctl (SIOCGIFMETRIC, (caddr_t) &ifreq) < 0) 
        !           131:     return;
        !           132:   ifp->metric = ifreq.ifr_metric;
        !           133:   if (ifp->metric == 0)
        !           134:     ifp->metric = 1;
        !           135: #else /* SIOCGIFMETRIC */
        !           136:   ifp->metric = -1;
        !           137: #endif /* SIOCGIFMETRIC */
        !           138: }
        !           139: 
        !           140: /* get interface MTU */
        !           141: void
        !           142: if_get_mtu (struct interface *ifp)
        !           143: {
        !           144:   struct ifreq ifreq;
        !           145: 
        !           146:   ifreq_set_name (&ifreq, ifp);
        !           147: 
        !           148: #if defined(SIOCGIFMTU)
        !           149:   if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0) 
        !           150:     {
        !           151:       zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)");
        !           152:       ifp->mtu6 = ifp->mtu = -1;
        !           153:       return;
        !           154:     }
        !           155: 
        !           156: #ifdef SUNOS_5
        !           157:   ifp->mtu6 = ifp->mtu = ifreq.ifr_metric;
        !           158: #else
        !           159:   ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu;
        !           160: #endif /* SUNOS_5 */
        !           161: 
        !           162:   /* propogate */
        !           163:   zebra_interface_up_update(ifp);
        !           164: 
        !           165: #else
        !           166:   zlog (NULL, LOG_INFO, "Can't lookup mtu on this system");
        !           167:   ifp->mtu6 = ifp->mtu = -1;
        !           168: #endif
        !           169: }
        !           170: 
        !           171: #ifdef HAVE_NETLINK
        !           172: /* Interface address setting via netlink interface. */
        !           173: int
        !           174: if_set_prefix (struct interface *ifp, struct connected *ifc)
        !           175: {
        !           176:   return kernel_address_add_ipv4 (ifp, ifc);
        !           177: }
        !           178: 
        !           179: /* Interface address is removed using netlink interface. */
        !           180: int
        !           181: if_unset_prefix (struct interface *ifp, struct connected *ifc)
        !           182: {
        !           183:   return kernel_address_delete_ipv4 (ifp, ifc);
        !           184: }
        !           185: #else /* ! HAVE_NETLINK */
        !           186: #ifdef HAVE_STRUCT_IFALIASREQ
        !           187: /* Set up interface's IP address, netmask (and broadcas? ).  *BSD may
        !           188:    has ifaliasreq structure.  */
        !           189: int
        !           190: if_set_prefix (struct interface *ifp, struct connected *ifc)
        !           191: {
        !           192:   int ret;
        !           193:   struct ifaliasreq addreq;
        !           194:   struct sockaddr_in addr;
        !           195:   struct sockaddr_in mask;
        !           196:   struct prefix_ipv4 *p;
        !           197: 
        !           198:   p = (struct prefix_ipv4 *) ifc->address;
        !           199:   rib_lookup_and_pushup (p);
        !           200: 
        !           201:   memset (&addreq, 0, sizeof addreq);
        !           202:   strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
        !           203: 
        !           204:   memset (&addr, 0, sizeof (struct sockaddr_in));
        !           205:   addr.sin_addr = p->prefix;
        !           206:   addr.sin_family = p->family;
        !           207: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
        !           208:   addr.sin_len = sizeof (struct sockaddr_in);
        !           209: #endif
        !           210:   memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in));
        !           211: 
        !           212:   memset (&mask, 0, sizeof (struct sockaddr_in));
        !           213:   masklen2ip (p->prefixlen, &mask.sin_addr);
        !           214:   mask.sin_family = p->family;
        !           215: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
        !           216:   mask.sin_len = sizeof (struct sockaddr_in);
        !           217: #endif
        !           218:   memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in));
        !           219:   
        !           220:   ret = if_ioctl (SIOCAIFADDR, (caddr_t) &addreq);
        !           221:   if (ret < 0)
        !           222:     return ret;
        !           223:   return 0;
        !           224: }
        !           225: 
        !           226: /* Set up interface's IP address, netmask (and broadcas? ).  *BSD may
        !           227:    has ifaliasreq structure.  */
        !           228: int
        !           229: if_unset_prefix (struct interface *ifp, struct connected *ifc)
        !           230: {
        !           231:   int ret;
        !           232:   struct ifaliasreq addreq;
        !           233:   struct sockaddr_in addr;
        !           234:   struct sockaddr_in mask;
        !           235:   struct prefix_ipv4 *p;
        !           236: 
        !           237:   p = (struct prefix_ipv4 *)ifc->address;
        !           238: 
        !           239:   memset (&addreq, 0, sizeof addreq);
        !           240:   strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
        !           241: 
        !           242:   memset (&addr, 0, sizeof (struct sockaddr_in));
        !           243:   addr.sin_addr = p->prefix;
        !           244:   addr.sin_family = p->family;
        !           245: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
        !           246:   addr.sin_len = sizeof (struct sockaddr_in);
        !           247: #endif
        !           248:   memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in));
        !           249: 
        !           250:   memset (&mask, 0, sizeof (struct sockaddr_in));
        !           251:   masklen2ip (p->prefixlen, &mask.sin_addr);
        !           252:   mask.sin_family = p->family;
        !           253: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
        !           254:   mask.sin_len = sizeof (struct sockaddr_in);
        !           255: #endif
        !           256:   memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in));
        !           257:   
        !           258:   ret = if_ioctl (SIOCDIFADDR, (caddr_t) &addreq);
        !           259:   if (ret < 0)
        !           260:     return ret;
        !           261:   return 0;
        !           262: }
        !           263: #else
        !           264: /* Set up interface's address, netmask (and broadcas? ).  Linux or
        !           265:    Solaris uses ifname:number semantics to set IP address aliases. */
        !           266: int
        !           267: if_set_prefix (struct interface *ifp, struct connected *ifc)
        !           268: {
        !           269:   int ret;
        !           270:   struct ifreq ifreq;
        !           271:   struct sockaddr_in addr;
        !           272:   struct sockaddr_in broad;
        !           273:   struct sockaddr_in mask;
        !           274:   struct prefix_ipv4 ifaddr;
        !           275:   struct prefix_ipv4 *p;
        !           276: 
        !           277:   p = (struct prefix_ipv4 *) ifc->address;
        !           278: 
        !           279:   ifaddr = *p;
        !           280: 
        !           281:   ifreq_set_name (&ifreq, ifp);
        !           282: 
        !           283:   addr.sin_addr = p->prefix;
        !           284:   addr.sin_family = p->family;
        !           285:   memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in));
        !           286:   ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq);
        !           287:   if (ret < 0)
        !           288:     return ret;
        !           289:   
        !           290:   /* We need mask for make broadcast addr. */
        !           291:   masklen2ip (p->prefixlen, &mask.sin_addr);
        !           292: 
        !           293:   if (if_is_broadcast (ifp))
        !           294:     {
        !           295:       apply_mask_ipv4 (&ifaddr);
        !           296:       addr.sin_addr = ifaddr.prefix;
        !           297: 
        !           298:       broad.sin_addr.s_addr = (addr.sin_addr.s_addr | ~mask.sin_addr.s_addr);
        !           299:       broad.sin_family = p->family;
        !           300: 
        !           301:       memcpy (&ifreq.ifr_broadaddr, &broad, sizeof (struct sockaddr_in));
        !           302:       ret = if_ioctl (SIOCSIFBRDADDR, (caddr_t) &ifreq);
        !           303:       if (ret < 0)
        !           304:        return ret;
        !           305:     }
        !           306: 
        !           307:   mask.sin_family = p->family;
        !           308: #ifdef SUNOS_5
        !           309:   memcpy (&mask, &ifreq.ifr_addr, sizeof (mask));
        !           310: #else
        !           311:   memcpy (&ifreq.ifr_netmask, &mask, sizeof (struct sockaddr_in));
        !           312: #endif /* SUNOS5 */
        !           313:   ret = if_ioctl (SIOCSIFNETMASK, (caddr_t) &ifreq);
        !           314:   if (ret < 0)
        !           315:     return ret;
        !           316: 
        !           317:   return 0;
        !           318: }
        !           319: 
        !           320: /* Set up interface's address, netmask (and broadcas? ).  Linux or
        !           321:    Solaris uses ifname:number semantics to set IP address aliases. */
        !           322: int
        !           323: if_unset_prefix (struct interface *ifp, struct connected *ifc)
        !           324: {
        !           325:   int ret;
        !           326:   struct ifreq ifreq;
        !           327:   struct sockaddr_in addr;
        !           328:   struct prefix_ipv4 *p;
        !           329: 
        !           330:   p = (struct prefix_ipv4 *) ifc->address;
        !           331: 
        !           332:   ifreq_set_name (&ifreq, ifp);
        !           333: 
        !           334:   memset (&addr, 0, sizeof (struct sockaddr_in));
        !           335:   addr.sin_family = p->family;
        !           336:   memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in));
        !           337:   ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq);
        !           338:   if (ret < 0)
        !           339:     return ret;
        !           340: 
        !           341:   return 0;
        !           342: }
        !           343: #endif /* HAVE_STRUCT_IFALIASREQ */
        !           344: #endif /* HAVE_NETLINK */
        !           345: 
        !           346: /* get interface flags */
        !           347: void
        !           348: if_get_flags (struct interface *ifp)
        !           349: {
        !           350:   int ret;
        !           351:   struct ifreq ifreq;
        !           352: #ifdef HAVE_BSD_LINK_DETECT
        !           353:   struct ifmediareq ifmr;
        !           354: #endif /* HAVE_BSD_LINK_DETECT */
        !           355: 
        !           356:   ifreq_set_name (&ifreq, ifp);
        !           357: 
        !           358:   ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq);
        !           359:   if (ret < 0) 
        !           360:     {
        !           361:       zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno));
        !           362:       return;
        !           363:     }
        !           364: #ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */
        !           365: 
        !           366:   /* Per-default, IFF_RUNNING is held high, unless link-detect says
        !           367:    * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag,
        !           368:    * following practice on Linux and Solaris kernels
        !           369:    */
        !           370:   SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
        !           371:   
        !           372:   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
        !           373:     {
        !           374:       (void) memset(&ifmr, 0, sizeof(ifmr));
        !           375:       strncpy (ifmr.ifm_name, ifp->name, IFNAMSIZ);
        !           376:       
        !           377:       /* Seems not all interfaces implement this ioctl */
        !           378:       if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0)
        !           379:         zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno));
        !           380:       else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
        !           381:         {
        !           382:           if (ifmr.ifm_status & IFM_ACTIVE)
        !           383:             SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
        !           384:           else
        !           385:             UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
        !           386:         }
        !           387:   }
        !           388: #endif /* HAVE_BSD_LINK_DETECT */
        !           389: 
        !           390:   if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff));
        !           391: }
        !           392: 
        !           393: /* Set interface flags */
        !           394: int
        !           395: if_set_flags (struct interface *ifp, uint64_t flags)
        !           396: {
        !           397:   int ret;
        !           398:   struct ifreq ifreq;
        !           399: 
        !           400:   memset (&ifreq, 0, sizeof(struct ifreq));
        !           401:   ifreq_set_name (&ifreq, ifp);
        !           402: 
        !           403:   ifreq.ifr_flags = ifp->flags;
        !           404:   ifreq.ifr_flags |= flags;
        !           405: 
        !           406:   ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq);
        !           407: 
        !           408:   if (ret < 0)
        !           409:     {
        !           410:       zlog_info ("can't set interface flags");
        !           411:       return ret;
        !           412:     }
        !           413:   return 0;
        !           414: }
        !           415: 
        !           416: /* Unset interface's flag. */
        !           417: int
        !           418: if_unset_flags (struct interface *ifp, uint64_t flags)
        !           419: {
        !           420:   int ret;
        !           421:   struct ifreq ifreq;
        !           422: 
        !           423:   memset (&ifreq, 0, sizeof(struct ifreq));
        !           424:   ifreq_set_name (&ifreq, ifp);
        !           425: 
        !           426:   ifreq.ifr_flags = ifp->flags;
        !           427:   ifreq.ifr_flags &= ~flags;
        !           428: 
        !           429:   ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq);
        !           430: 
        !           431:   if (ret < 0)
        !           432:     {
        !           433:       zlog_info ("can't unset interface flags");
        !           434:       return ret;
        !           435:     }
        !           436:   return 0;
        !           437: }
        !           438: 
        !           439: #ifdef HAVE_IPV6
        !           440: 
        !           441: #ifdef LINUX_IPV6
        !           442: #ifndef _LINUX_IN6_H
        !           443: /* linux/include/net/ipv6.h */
        !           444: struct in6_ifreq 
        !           445: {
        !           446:   struct in6_addr ifr6_addr;
        !           447:   u_int32_t ifr6_prefixlen;
        !           448:   int ifr6_ifindex;
        !           449: };
        !           450: #endif /* _LINUX_IN6_H */
        !           451: 
        !           452: /* Interface's address add/delete functions. */
        !           453: int
        !           454: if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc)
        !           455: {
        !           456:   int ret;
        !           457:   struct prefix_ipv6 *p;
        !           458:   struct in6_ifreq ifreq;
        !           459: 
        !           460:   p = (struct prefix_ipv6 *) ifc->address;
        !           461: 
        !           462:   memset (&ifreq, 0, sizeof (struct in6_ifreq));
        !           463: 
        !           464:   memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr));
        !           465:   ifreq.ifr6_ifindex = ifp->ifindex;
        !           466:   ifreq.ifr6_prefixlen = p->prefixlen;
        !           467: 
        !           468:   ret = if_ioctl_ipv6 (SIOCSIFADDR, (caddr_t) &ifreq);
        !           469: 
        !           470:   return ret;
        !           471: }
        !           472: 
        !           473: int
        !           474: if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc)
        !           475: {
        !           476:   int ret;
        !           477:   struct prefix_ipv6 *p;
        !           478:   struct in6_ifreq ifreq;
        !           479: 
        !           480:   p = (struct prefix_ipv6 *) ifc->address;
        !           481: 
        !           482:   memset (&ifreq, 0, sizeof (struct in6_ifreq));
        !           483: 
        !           484:   memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr));
        !           485:   ifreq.ifr6_ifindex = ifp->ifindex;
        !           486:   ifreq.ifr6_prefixlen = p->prefixlen;
        !           487: 
        !           488:   ret = if_ioctl_ipv6 (SIOCDIFADDR, (caddr_t) &ifreq);
        !           489: 
        !           490:   return ret;
        !           491: }
        !           492: #else /* LINUX_IPV6 */
        !           493: #ifdef HAVE_STRUCT_IN6_ALIASREQ
        !           494: #ifndef ND6_INFINITE_LIFETIME
        !           495: #define ND6_INFINITE_LIFETIME 0xffffffffL
        !           496: #endif /* ND6_INFINITE_LIFETIME */
        !           497: int
        !           498: if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc)
        !           499: {
        !           500:   int ret;
        !           501:   struct in6_aliasreq addreq;
        !           502:   struct sockaddr_in6 addr;
        !           503:   struct sockaddr_in6 mask;
        !           504:   struct prefix_ipv6 *p;
        !           505: 
        !           506:   p = (struct prefix_ipv6 * ) ifc->address;
        !           507: 
        !           508:   memset (&addreq, 0, sizeof addreq);
        !           509:   strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
        !           510: 
        !           511:   memset (&addr, 0, sizeof (struct sockaddr_in6));
        !           512:   addr.sin6_addr = p->prefix;
        !           513:   addr.sin6_family = p->family;
        !           514: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
        !           515:   addr.sin6_len = sizeof (struct sockaddr_in6);
        !           516: #endif
        !           517:   memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6));
        !           518: 
        !           519:   memset (&mask, 0, sizeof (struct sockaddr_in6));
        !           520:   masklen2ip6 (p->prefixlen, &mask.sin6_addr);
        !           521:   mask.sin6_family = p->family;
        !           522: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
        !           523:   mask.sin6_len = sizeof (struct sockaddr_in6);
        !           524: #endif
        !           525:   memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6));
        !           526: 
        !           527:   addreq.ifra_lifetime.ia6t_vltime = 0xffffffff;
        !           528:   addreq.ifra_lifetime.ia6t_pltime = 0xffffffff;
        !           529:   
        !           530: #ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME 
        !           531:   addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; 
        !           532:   addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; 
        !           533: #endif
        !           534: 
        !           535:   ret = if_ioctl_ipv6 (SIOCAIFADDR_IN6, (caddr_t) &addreq);
        !           536:   if (ret < 0)
        !           537:     return ret;
        !           538:   return 0;
        !           539: }
        !           540: 
        !           541: int
        !           542: if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc)
        !           543: {
        !           544:   int ret;
        !           545:   struct in6_aliasreq addreq;
        !           546:   struct sockaddr_in6 addr;
        !           547:   struct sockaddr_in6 mask;
        !           548:   struct prefix_ipv6 *p;
        !           549: 
        !           550:   p = (struct prefix_ipv6 *) ifc->address;
        !           551: 
        !           552:   memset (&addreq, 0, sizeof addreq);
        !           553:   strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
        !           554: 
        !           555:   memset (&addr, 0, sizeof (struct sockaddr_in6));
        !           556:   addr.sin6_addr = p->prefix;
        !           557:   addr.sin6_family = p->family;
        !           558: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
        !           559:   addr.sin6_len = sizeof (struct sockaddr_in6);
        !           560: #endif
        !           561:   memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6));
        !           562: 
        !           563:   memset (&mask, 0, sizeof (struct sockaddr_in6));
        !           564:   masklen2ip6 (p->prefixlen, &mask.sin6_addr);
        !           565:   mask.sin6_family = p->family;
        !           566: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
        !           567:   mask.sin6_len = sizeof (struct sockaddr_in6);
        !           568: #endif
        !           569:   memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6));
        !           570: 
        !           571: #ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME
        !           572:   addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; 
        !           573:   addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; 
        !           574: #endif
        !           575: 
        !           576:   ret = if_ioctl_ipv6 (SIOCDIFADDR_IN6, (caddr_t) &addreq);
        !           577:   if (ret < 0)
        !           578:     return ret;
        !           579:   return 0;
        !           580: }
        !           581: #else
        !           582: int
        !           583: if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc)
        !           584: {
        !           585:   return 0;
        !           586: }
        !           587: 
        !           588: int
        !           589: if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc)
        !           590: {
        !           591:   return 0;
        !           592: }
        !           593: #endif /* HAVE_STRUCT_IN6_ALIASREQ */
        !           594: 
        !           595: #endif /* LINUX_IPV6 */
        !           596: 
        !           597: #endif /* HAVE_IPV6 */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>