summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ChangeLog22
-rw-r--r--lib/sockopt.c76
-rw-r--r--lib/sockopt.h23
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 */