diff options
-rw-r--r-- | lib/ChangeLog | 22 | ||||
-rw-r--r-- | lib/sockopt.c | 76 | ||||
-rw-r--r-- | lib/sockopt.h | 23 |
3 files changed, 89 insertions, 32 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog index 421a4f0b..0e1960b1 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,25 @@ +2004-08-19 Paul Jakma <paul@dishone.st> + + * sockopt.c: include sockopt.h + rename some of the _pktinfo_ functions to _ifindex, where that is + their purpose. + (getsockopt_ipv6_pktinfo_ifindex) renamed to + getsockopt_ipv6_ifindex. + (setsockopt_ipv4_pktinfo) renamed to setsockopt_ipv4_ifindex + (setsockopt_pktinfo) update with previous and add comment re + AF_INET portability. + (setsockopt_ifindex) generic ifindex function ala + setsockopt_pktinfo. + (getsockopt_ipv4_pktinfo_ifindex) renamed to + getsockopt_ipv4_ifindex. + (getsockopt_ipv4_ifindex) rejiggling to reduce repeated + ifdef/elses. pktinfo case forgot to set ifindex. + (getsockopt_pktinfo_ifindex) renamed to + getsockopt_ifindex. update some calls to renamed functions. + * sockopt.h: Update renamed exported functions + Rename the CMSG_SIZE macros to IFINDEX. + Guard IPv4 PKTINFO in a conditional define. + 2004-08-18 Paul Jakma <paul@dishone.st> * vty.c: (vty_serv_un) set unix vty socket to nonblocking diff --git a/lib/sockopt.c b/lib/sockopt.c index 682b7397..d0b034f5 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -21,6 +21,7 @@ #include <zebra.h> #include "log.h" +#include "sockopt.h" static void * getsockopt_cmsg_data (struct msghdr *msgh, int level, int type) @@ -125,7 +126,7 @@ setsockopt_ipv6_multicast_loop (int sock, int val) } static int -getsockopt_ipv6_pktinfo_ifindex (struct msghdr *msgh) +getsockopt_ipv6_ifindex (struct msghdr *msgh) { struct in6_pktinfo *pktinfo; @@ -221,7 +222,7 @@ setsockopt_multicast_ipv4(int sock, } static int -setsockopt_ipv4_pktinfo (int sock, int val) +setsockopt_ipv4_ifindex (int sock, int val) { int ret; @@ -243,6 +244,7 @@ setsockopt_ipv4_pktinfo (int sock, int val) /* set appropriate pktinfo socket option * on systems without PKTINFO, sets RECVIF, which only retrieves * interface index. + * Not portable for IPv4, use only setsockopt_ifindex for v4. */ int setsockopt_pktinfo (int af, int sock, int val) @@ -252,7 +254,8 @@ setsockopt_pktinfo (int af, int sock, int val) switch (af) { case AF_INET: - ret = setsockopt_ipv4_pktinfo (sock, val); + /* _ifindex will use PKTINFO if available.. */ + ret = setsockopt_ipv4_ifindex (sock, val); break; #ifdef HAVE_IPV6 case AF_INET6: @@ -265,62 +268,83 @@ setsockopt_pktinfo (int af, int sock, int val) return ret; } - +int +setsockopt_ifindex (int af, int sock, int val) +{ + int ret = -1; + + switch (af) + { + case AF_INET: + ret = setsockopt_ipv4_ifindex (sock, val); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + ret = setsockopt_ipv6_pktinfo (sock, val); + break; +#endif + default: + zlog_warn ("setsockopt_ifindex: unknown address family %d"); + } + return ret; +} + static int -getsockopt_ipv4_pktinfo_ifindex (struct msghdr *msgh) +getsockopt_ipv4_ifindex (struct msghdr *msgh) { - int ifindex = 0; -#if defined (IP_PKTINFO) + int ifindex = -1; +#if defined(IP_PKTINFO) +/* Linux pktinfo based ifindex retrieval */ struct in_pktinfo *pktinfo; -#elif defined (IP_RECVIF) + + pktinfo = + (struct in_pktinfo *)getsockopt_cmsg_data (msgh, IPPROTO_IP, IP_PKTINFO); + ifindex = pktinfo->ipi_ifindex; + +#elif defined(IP_RECVIF) +/* BSD/other IP_RECVIF based ifindex retrieval */ #ifndef SUNOS_5 /* RECVIF, but not SUNOS, so BSD */ struct sockaddr_dl *sdl; #endif /* SUNOS_5 */ /* SUNOS_5 doesn't need a structure to extract ifindex */ -#else /* IP_RECVIF */ - /* XXX Neither, so we are going to lose. */ -#endif /* IP_PKTINFO */ - -#ifdef IP_PKTINFO - pktinfo = - (struct in_pktinfo *)getsockopt_cmsg_data (msgh, IPPROTO_IP, IP_PKTINFO); -#elif defined (IP_RECVIF) + #ifndef SUNOS_5 sdl = (struct sockaddr_dl *)getsockopt_cmsg_data (msgh, IPPROTO_IP, IP_RECVIF); ifindex = sdl->sdl_index; -#else +#else /* !SUNOS_5 */ ifindex = *(uint_t *)getsockopt_cmsg_data (msgh, IPPROTO_IP, IP_RECVIF); #endif /* SUNOS_5 */ -#else + +#else /* neither IP_PKTINFO nor IP_RECVIF, broken */ + #warning "getsockopt_ipv4_pktinfo_ifindex: dont have PKTINFO or RECVIF" +#warning "things will be broken on this platform!" /* XXX why not -1 - this is a failure condition. */ - ifindex = 0; -#endif /* IP_PKTINFO */ - + ifindex = -1; +#endif /* IP_PKTINFO */ return ifindex; } /* return ifindex, 0 if none found */ int -getsockopt_pktinfo_ifindex (int af, struct msghdr *msgh) +getsockopt_ifindex (int af, struct msghdr *msgh) { int ifindex = 0; switch (af) { case AF_INET: - return (getsockopt_ipv4_pktinfo_ifindex (msgh)); + return (getsockopt_ipv4_ifindex (msgh)); break; #ifdef HAVE_IPV6 case AF_INET6: - return (getsockopt_ipv6_pktinfo_ifindex (msgh)); + return (getsockopt_ipv6_ifindex (msgh)); break; #endif default: - zlog_warn ("getsockopt_pktinfo_ifindex: unknown address family %d"); + zlog_warn ("getsockopt_ifindex: unknown address family %d"); return (ifindex = 0); } } - diff --git a/lib/sockopt.h b/lib/sockopt.h index c5d171c2..b7aa1b3a 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -32,26 +32,37 @@ int setsockopt_ipv6_multicast_loop (int, int); #endif /* HAVE_IPV6 */ #if defined (IP_PKTINFO) + #define SOPT_SIZE_CMSG_PKTINFO_IPV4() (sizeof (struct in_pktinfo)) +#define SOPT_SIZE_CMSG_IFINDEX_IPV4 SOPT_SIZE_CMSG_PKTINFO_IPV4 +#define SOPT_SIZE_CMSG_PKTINFO(af) \ + ((af == AF_INET) ? SOPT_SIZE_CMSG_PKTINFO_IPV4() \ + : SOPT_SIZE_CMSG_PKTINFO_IPV6() + #elif defined (IP_RECVIF) #if defined (SUNOS_5) -#define SOPT_SIZE_CMSG_PKTINFO_IPV4() (sizeof (uint_t)) +#define SOPT_SIZE_CMSG_IFINDEX_IPV4() (sizeof (uint_t)) #else -#define SOPT_SIZE_CMSG_PKTINFO_IPV4() (sizeof (struct sockaddr_dl)) +#define SOPT_SIZE_CMSG_IFINDEX_IPV4() (sizeof (struct sockaddr_dl)) #endif /* SUNOS_5 */ + #endif #define SOPT_SIZE_CMSG_PKTINFO_IPV6() (sizeof (struct in6_pktinfo)); -#define SOPT_SIZE_CMSG_PKTINFO(af) \ - ((af == AF_INET) ? SOPT_SIZE_CMSG_PKTINFO_IPV4() \ - : SOPT_SIZE_CMSG_PKTINFO_IPV6() +#define SOPT_SIZE_CMSG_IFINDEX(af) \ + ((af == AF_INET) ? SOPT_SIZE_CMSG_IFINDEX_IPV4() \ + : SOPT_SIZE_CMSG_IFINDEX_IPV6() int setsockopt_multicast_ipv4(int sock, int optname, struct in_addr if_addr, unsigned int mcast_addr, unsigned int ifindex); + +#if defined (IP_PKTINFO) int setsockopt_pktinfo (int, int, int); -int getsockopt_pktinfo_ifindex (int, struct msghdr *); +#endif +int setsockopt_ifindex (int, int, int); +int getsockopt_ifindex (int, struct msghdr *); #endif /*_ZEBRA_SOCKOPT_H */ |