diff options
author | hasso <hasso> | 2004-05-18 20:57:06 +0200 |
---|---|---|
committer | hasso <hasso> | 2004-05-18 20:57:06 +0200 |
commit | 508e53e2eef3eefba4c1aa771529027fd4486ea8 (patch) | |
tree | 0e25e1b344a7b8e2c4551cfcb74d5a011dd0865d /ospf6d/ospf6_network.c | |
parent | Start of new ospf6d merge from Zebra. (diff) | |
download | frr-508e53e2eef3eefba4c1aa771529027fd4486ea8.tar.xz frr-508e53e2eef3eefba4c1aa771529027fd4486ea8.zip |
Ospf6d merge from Zebra repository with added privs stuff and merged
zclient changes.
Diffstat (limited to 'ospf6d/ospf6_network.c')
-rw-r--r-- | ospf6d/ospf6_network.c | 362 |
1 files changed, 93 insertions, 269 deletions
diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c index ece34135a..b4f37f6a9 100644 --- a/ospf6d/ospf6_network.c +++ b/ospf6d/ospf6_network.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1999 Yasuhiro Ohara + * Copyright (C) 2003 Yasuhiro Ohara * * This file is part of GNU Zebra. * @@ -20,212 +20,106 @@ */ #include <zebra.h> -#include "memory.h" + #include "log.h" +#include "memory.h" #include "sockunion.h" #include "privs.h" -#include "ospf6d.h" #include "ospf6_proto.h" +#include "ospf6_network.h" -extern int errno; -extern struct sockaddr_in6 allspfrouters6; -extern struct sockaddr_in6 alldrouters6; -extern int ospf6_sock; -extern struct thread_master *master; extern struct zebra_privs_t ospf6d_privs; -/* iovec functions */ -void -iov_clear (struct iovec *iov, size_t iovlen) -{ - int i; - for (i = 0; i < iovlen; i++) - { - iov[i].iov_base = NULL; - iov[i].iov_len = 0; - } -} - -int -iov_count (struct iovec *iov) -{ - int i; - for (i = 0; iov[i].iov_base; i++) - ; - return i; -} - -int -iov_totallen (struct iovec *iov) -{ - int i; - int totallen = 0; - for (i = 0; iov[i].iov_base; i++) - totallen += iov[i].iov_len; - return totallen; -} - -void * -iov_prepend (int mtype, struct iovec *iov, size_t len) -{ - int i, iovlen; - void *base; - - base = (void *) XMALLOC (mtype, len); - if (!base) - { - zlog_warn ("Network: iov_prepend failed"); - return NULL; - } - memset (base, 0, len); - - iovlen = iov_count (iov); - for (i = iovlen; i; i--) - { - iov[i].iov_base = iov[i - 1].iov_base; - iov[i].iov_len = iov[i - 1].iov_len; - } - iov[0].iov_base = (char *)base; - iov[0].iov_len = len; - - return base; -} - -void * -iov_append (int mtype, struct iovec *iov, size_t len) -{ - int i; - void *base; - - base = (void *)XMALLOC (mtype, len); - if (!base) - { - zlog_warn ("Network: iov_append failed"); - return NULL; - } - memset (base, 0, len); +int ospf6_sock; +struct in6_addr allspfrouters6; +struct in6_addr alldrouters6; - /* proceed to the end */ - i = iov_count (iov); - - iov[i].iov_base = (char *)base; - iov[i].iov_len = len; - - return base; -} - -void * -iov_attach_last (struct iovec *iov, void *base, size_t len) -{ - int i; - i = iov_count (iov); - iov[i].iov_base = (char *)base; - iov[i].iov_len = len; - return base; -} - -void * -iov_detach_first (struct iovec *iov) -{ - int i, iovlen; - void *base; - size_t len; - - base = iov[0].iov_base; - len = iov[0].iov_len; - iovlen = iov_count (iov); - for (i = 0; i < iovlen; i++) - { - iov[i].iov_base = iov[i + 1].iov_base; - iov[i].iov_len = iov[i + 1].iov_len; - } - return base; -} - -int -iov_free (int mtype, struct iovec *iov, u_int begin, u_int end) +/* setsockopt ReUseAddr to on */ +void +ospf6_set_reuseaddr () { - int i; - - for (i = begin; i < end; i++) - { - XFREE (mtype, iov[i].iov_base); - iov[i].iov_base = NULL; - iov[i].iov_len = 0; - } - - return 0; + u_int on = 0; + if (setsockopt (ospf6_sock, SOL_SOCKET, SO_REUSEADDR, &on, + sizeof (u_int)) < 0) + zlog_warn ("Network: set SO_REUSEADDR failed: %s", strerror (errno)); } +/* setsockopt MulticastLoop to off */ void -iov_trim_head (int mtype, struct iovec *iov) +ospf6_reset_mcastloop () { - void *base; - - base = iov_detach_first (iov); - XFREE (mtype, base); - return; + u_int off = 0; + if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + &off, sizeof (u_int)) < 0) + zlog_warn ("Network: reset IPV6_MULTICAST_LOOP failed: %s", + strerror (errno)); } void -iov_free_all (int mtype, struct iovec *iov) +ospf6_set_pktinfo () { - int i, end = iov_count (iov); - for (i = 0; i < end; i++) - { - XFREE (mtype, iov[i].iov_base); - iov[i].iov_base = NULL; - iov[i].iov_len = 0; - } + u_int on = 1; +#ifdef IPV6_RECVPKTINFO /*2292bis-01*/ + if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, + &on, sizeof (u_int)) < 0) + zlog_warn ("Network: set IPV6_RECVPKTINFO failed: %s", strerror (errno)); +#else /*RFC2292*/ + if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_PKTINFO, + &on, sizeof (u_int)) < 0) + zlog_warn ("Network: set IPV6_PKTINFO failed: %s", strerror (errno)); +#endif } void -iov_copy_all (struct iovec *dst, struct iovec *src, size_t size) +ospf6_set_checksum () { - int i; - for (i = 0; i < size; i++) - { - dst[i].iov_base = src[i].iov_base; - dst[i].iov_len = src[i].iov_len; - } + int offset = 12; +#ifndef DISABLE_IPV6_CHECKSUM + if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_CHECKSUM, + &offset, sizeof (offset)) < 0) + zlog_warn ("Network: set IPV6_CHECKSUM failed: %s", strerror (errno)); +#else + zlog_warn ("Network: Don't set IPV6_CHECKSUM"); +#endif /* DISABLE_IPV6_CHECKSUM */ } - /* Make ospf6d's server socket. */ int ospf6_serv_sock () { - if (ospf6d_privs.change (ZPRIVS_RAISE)) - zlog_err ("ospf6_serv_sock: could not raise privs"); - + zlog_err ("ospf6_serv_sock: could not raise privs"); + ospf6_sock = socket (AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP); if (ospf6_sock < 0) { zlog_warn ("Network: can't create OSPF6 socket."); + if (ospf6d_privs.change (ZPRIVS_LOWER)) + zlog_err ("ospf_sock_init: could not lower privs"); return -1; } - sockopt_reuseaddr (ospf6_sock); - if (ospf6d_privs.change (ZPRIVS_LOWER)) zlog_err ("ospf_sock_init: could not lower privs"); - - /* setup global sockaddr_in6, allspf6 & alldr6 for later use */ - allspfrouters6.sin6_family = AF_INET6; - alldrouters6.sin6_family = AF_INET6; -#ifdef SIN6_LEN - allspfrouters6.sin6_len = sizeof (struct sockaddr_in6); - alldrouters6.sin6_len = sizeof (struct sockaddr_in6); -#endif /* SIN6_LEN */ - inet_pton (AF_INET6, ALLSPFROUTERS6, &allspfrouters6.sin6_addr); - inet_pton (AF_INET6, ALLDROUTERS6, &alldrouters6.sin6_addr); + + /* set socket options */ +#if 1 + sockopt_reuseaddr (ospf6_sock); +#else + ospf6_set_reuseaddr (); +#endif /*1*/ + ospf6_reset_mcastloop (); + ospf6_set_pktinfo (); + ospf6_set_checksum (); + + /* setup global in6_addr, allspf6 and alldr6 for later use */ + inet_pton (AF_INET6, ALLSPFROUTERS6, &allspfrouters6); + inet_pton (AF_INET6, ALLDROUTERS6, &alldrouters6); return 0; } -/* returns 0 if succeed, else returns -1 */ -int +void ospf6_join_allspfrouters (u_int ifindex) { struct ipv6_mreq mreq6; @@ -233,7 +127,7 @@ ospf6_join_allspfrouters (u_int ifindex) assert (ifindex); mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, &allspfrouters6.sin6_addr, + memcpy (&mreq6.ipv6mr_multiaddr, &allspfrouters6, sizeof (struct in6_addr)); retval = setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, @@ -241,13 +135,11 @@ ospf6_join_allspfrouters (u_int ifindex) if (retval < 0) zlog_err ("Network: Join AllSPFRouters on ifindex %d failed: %s", - ifindex, strerror (errno)); + ifindex, strerror (errno)); #if 0 else zlog_info ("Network: Join AllSPFRouters on ifindex %d", ifindex); #endif - - return retval; } void @@ -257,15 +149,17 @@ ospf6_leave_allspfrouters (u_int ifindex) assert (ifindex); mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, &allspfrouters6.sin6_addr, + memcpy (&mreq6.ipv6mr_multiaddr, &allspfrouters6, sizeof (struct in6_addr)); if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq6, sizeof (mreq6)) < 0) zlog_warn ("Network: Leave AllSPFRouters on ifindex %d Failed: %s", ifindex, strerror (errno)); +#if 0 else zlog_info ("Network: Leave AllSPFRouters on ifindex %d", ifindex); +#endif } void @@ -275,15 +169,17 @@ ospf6_join_alldrouters (u_int ifindex) assert (ifindex); mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, &alldrouters6.sin6_addr, + memcpy (&mreq6.ipv6mr_multiaddr, &alldrouters6, sizeof (struct in6_addr)); if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, sizeof (mreq6)) < 0) zlog_warn ("Network: Join AllDRouters on ifindex %d Failed: %s", ifindex, strerror (errno)); +#if 0 else zlog_info ("Network: Join AllDRouters on ifindex %d", ifindex); +#endif } void @@ -293,66 +189,38 @@ ospf6_leave_alldrouters (u_int ifindex) assert (ifindex); mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, &alldrouters6.sin6_addr, + memcpy (&mreq6.ipv6mr_multiaddr, &alldrouters6, sizeof (struct in6_addr)); if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq6, sizeof (mreq6)) < 0) zlog_warn ("Network: Leave AllDRouters on ifindex %d Failed", ifindex); +#if 0 else zlog_info ("Network: Leave AllDRouters on ifindex %d", ifindex); +#endif } -/* setsockopt ReUseAddr to on */ -void -ospf6_set_reuseaddr () -{ - u_int on = 0; - if (setsockopt (ospf6_sock, SOL_SOCKET, SO_REUSEADDR, &on, - sizeof (u_int)) < 0) - zlog_warn ("Network: set SO_REUSEADDR failed: %s", strerror (errno)); -} - -/* setsockopt MulticastLoop to off */ -void -ospf6_reset_mcastloop () -{ - u_int off = 0; - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, - &off, sizeof (u_int)) < 0) - zlog_warn ("Network: reset IPV6_MULTICAST_LOOP failed: %s", - strerror (errno)); -} - -void -ospf6_set_pktinfo () +int +iov_count (struct iovec *iov) { - u_int on = 1; -#ifdef IPV6_RECVPKTINFO /*2292bis-01*/ - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, - &on, sizeof (u_int)) < 0) - zlog_warn ("Network: set IPV6_RECVPKTINFO failed: %s", strerror (errno)); -#else /*RFC2292*/ - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_PKTINFO, - &on, sizeof (u_int)) < 0) - zlog_warn ("Network: set IPV6_PKTINFO failed: %s", strerror (errno)); -#endif + int i; + for (i = 0; iov[i].iov_base; i++) + ; + return i; } -void -ospf6_set_checksum () +int +iov_totallen (struct iovec *iov) { - int offset = 12; -#if !defined(DISABLE_IPV6_CHECKSUM) - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_CHECKSUM, - &offset, sizeof (offset)) < 0) - zlog_warn ("Network: set IPV6_CHECKSUM failed: %s", strerror (errno)); -#else - zlog_warn ("Network: Don't set IPV6_CHECKSUM"); -#endif /* DISABLE_IPV6_CHECKSUM */ + int i; + int totallen = 0; + for (i = 0; iov[i].iov_base; i++) + totallen += iov[i].iov_len; + return totallen; } -void +int ospf6_sendmsg (struct in6_addr *src, struct in6_addr *dst, unsigned int *ifindex, struct iovec *message) { @@ -403,11 +271,13 @@ ospf6_sendmsg (struct in6_addr *src, struct in6_addr *dst, retval = sendmsg (ospf6_sock, &smsghdr, 0); if (retval != iov_totallen (message)) - zlog_warn ("Network: sendmsg (ifindex: %d) failed: %s(%d)", + zlog_warn ("sendmsg failed: ifindex: %d: %s (%d)", *ifindex, strerror (errno), errno); + + return retval; } -void +int ospf6_recvmsg (struct in6_addr *src, struct in6_addr *dst, unsigned int *ifindex, struct iovec *message) { @@ -438,14 +308,9 @@ ospf6_recvmsg (struct in6_addr *src, struct in6_addr *dst, retval = recvmsg (ospf6_sock, &rmsghdr, 0); if (retval < 0) - { - zlog_warn ("Network: recvmsg failed: %s", strerror (errno)); - } + zlog_warn ("recvmsg failed: %s", strerror (errno)); else if (retval == iov_totallen (message)) - { - zlog_warn ("Network: possibly buffer shortage: %d received, buffer size: %d", - retval, iov_totallen (message)); - } + zlog_warn ("recvmsg read full buffer size: %d", retval); /* source address */ assert (src); @@ -456,49 +321,8 @@ ospf6_recvmsg (struct in6_addr *src, struct in6_addr *dst, *ifindex = pktinfo->ipi6_ifindex; if (dst) memcpy (dst, &pktinfo->ipi6_addr, sizeof (struct in6_addr)); -} - -void -ospf6_recvmsg_peek (struct in6_addr *src, struct in6_addr *dst, - unsigned int *ifindex, struct iovec *message) -{ - int retval; - struct msghdr rmsghdr; - struct cmsghdr *rcmsgp; - u_char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))]; - struct in6_pktinfo *pktinfo; - struct sockaddr_in6 src_sin6; - rcmsgp = (struct cmsghdr *)cmsgbuf; - pktinfo = (struct in6_pktinfo *)(CMSG_DATA(rcmsgp)); - memset (&src_sin6, 0, sizeof (struct sockaddr_in6)); - - /* receive control msg */ - rcmsgp->cmsg_level = IPPROTO_IPV6; - rcmsgp->cmsg_type = IPV6_PKTINFO; - rcmsgp->cmsg_len = CMSG_LEN (sizeof (struct in6_pktinfo)); - /* rcmsgp = CMSG_NXTHDR (&rmsghdr, rcmsgp); */ - - /* receive msg hdr */ - rmsghdr.msg_iov = message; - rmsghdr.msg_iovlen = iov_count (message); - rmsghdr.msg_name = (caddr_t) &src_sin6; - rmsghdr.msg_namelen = sizeof (struct sockaddr_in6); - rmsghdr.msg_control = (caddr_t) cmsgbuf; - rmsghdr.msg_controllen = sizeof (cmsgbuf); - - retval = recvmsg (ospf6_sock, &rmsghdr, MSG_PEEK); - if (retval != iov_totallen (message)) - zlog_warn ("Network: recvmsg failed: %s", strerror (errno)); - - /* source address */ - assert (src); - memcpy (src, &src_sin6.sin6_addr, sizeof (struct in6_addr)); - - /* destination address */ - if (ifindex) - *ifindex = pktinfo->ipi6_ifindex; - if (dst) - memcpy (dst, &pktinfo->ipi6_addr, sizeof (struct in6_addr)); + return retval; } + |