mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 06:50:17 +00:00
2004-07-23 Paul Jakma <paul@dishone.st>
* sockopt.h: Add SOPT_SIZE_CMSG_PKTINFO{_IPV{4,6}} define, for sizeof pktinfo as appropriate, to be used when allocating msg buffers. export setsockopt_pktinfo() and getsockopt_pktinfo_ifindex() * sockopt.c: (setsockopt_pktinfo_ifindex) new function to portably set received ifindex sock option. (getsockopt_pktinfo_ifindex) portably retrieve ifindex. (getsockopt_cmsg_data) retrieve indicated control info from message header. (getsockopt_ipv6_pktinfo_ifindex) ipv6 version of above. (setsockopt_ipv4_pktinfo) v4 version (setsockopt_pktinfo) the exported version (getsockopt_ipv4_pktinfo_ifindex) v4 specific version (getsockopt_pktinfo_ifindex) the exported version
This commit is contained in:
parent
05c447dd2e
commit
4f7baa0e43
@ -1,3 +1,20 @@
|
||||
2004-07-23 Paul Jakma <paul@dishone.st>
|
||||
|
||||
* sockopt.h: Add SOPT_SIZE_CMSG_PKTINFO{_IPV{4,6}} define, for
|
||||
sizeof pktinfo as appropriate, to be used when allocating msg
|
||||
buffers. export setsockopt_pktinfo() and
|
||||
getsockopt_pktinfo_ifindex()
|
||||
* sockopt.c: (setsockopt_pktinfo_ifindex) new function to portably
|
||||
set received ifindex sock option.
|
||||
(getsockopt_pktinfo_ifindex) portably retrieve ifindex.
|
||||
(getsockopt_cmsg_data) retrieve indicated control info from
|
||||
message header.
|
||||
(getsockopt_ipv6_pktinfo_ifindex) ipv6 version of above.
|
||||
(setsockopt_ipv4_pktinfo) v4 version
|
||||
(setsockopt_pktinfo) the exported version
|
||||
(getsockopt_ipv4_pktinfo_ifindex) v4 specific version
|
||||
(getsockopt_pktinfo_ifindex) the exported version
|
||||
|
||||
2004-07-14 Paul Jakma <paul@dishone.st>
|
||||
|
||||
* sigevent.c: (quagga_signal_handler) add a global caught flag, set
|
||||
|
124
lib/sockopt.c
124
lib/sockopt.c
@ -22,6 +22,19 @@
|
||||
#include <zebra.h>
|
||||
#include "log.h"
|
||||
|
||||
static void *
|
||||
getsockopt_cmsg_data (struct msghdr *msgh, int level, int type)
|
||||
{
|
||||
struct cmsghdr *cmsg;
|
||||
void *ptr = NULL;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(msgh);
|
||||
cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(msgh, cmsg))
|
||||
if (cmsg->cmsg_level == level && cmsg->cmsg_type)
|
||||
return (ptr = CMSG_DATA(cmsg));
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
/* Set IPv6 packet info to the socket. */
|
||||
int
|
||||
@ -111,6 +124,15 @@ setsockopt_ipv6_multicast_loop (int sock, int val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
getsockopt_ipv6_pktinfo_ifindex (struct msghdr *msgh)
|
||||
{
|
||||
struct in6_pktinfo *pktinfo;
|
||||
|
||||
pktinfo = getsockopt_cmsg_data (msgh, IPPROTO_IPV6, IPV6_PKTINFO);
|
||||
|
||||
return pktinfo->ipi6_ifindex;
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
|
||||
@ -197,3 +219,105 @@ setsockopt_multicast_ipv4(int sock,
|
||||
#endif /* #if OS_TYPE */
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
setsockopt_ipv4_pktinfo (int sock, int val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if defined (IP_PKTINFO)
|
||||
ret = setsockopt (sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof (val));
|
||||
#elif defined (IP_RECVIF)
|
||||
ret = setsockopt (sock, IPPROTO_IP, IP_RECVIF, &val, sizeof (val));
|
||||
#else
|
||||
#warning "Neither IP_PKTINFO nor IP_RECVIF is available."
|
||||
#warning "Will not be able to receive link info."
|
||||
#warning "Things might be seriously broken.."
|
||||
#endif
|
||||
|
||||
if (ret < 0)
|
||||
zlog_warn ("Can't set IP_PKTINFO option");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set appropriate pktinfo socket option
|
||||
* on systems without PKTINFO, sets RECVIF, which only retrieves
|
||||
* interface index.
|
||||
*/
|
||||
int
|
||||
setsockopt_pktinfo (int af, int sock, int val)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
ret = setsockopt_ipv4_pktinfo (sock, val);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
ret = setsockopt_ipv6_pktinfo (sock, val);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
zlog_warn ("setsockopt_pktinfo: unknown address family %d");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
getsockopt_ipv4_pktinfo_ifindex (struct msghdr *msgh)
|
||||
{
|
||||
int ifindex = 0;
|
||||
#if defined (IP_PKTINFO)
|
||||
struct in_pktinfo *pktinfo;
|
||||
#elif defined (IP_REVCIF)
|
||||
#ifndef SUNOS_5
|
||||
struct sockaddr_dl *sdl;
|
||||
#endif /* SUNOS_5 */
|
||||
#else /* IP_RECVIF */
|
||||
char *pktinfo;
|
||||
#endif /* IP_PKTINFO */
|
||||
|
||||
#ifdef IP_PKTINFO
|
||||
pktinfo =
|
||||
(struct in_pktinfo *)getsockopt_cmsg_data (msgh, IPPROTO_IP, IP_PKTINFO);
|
||||
#elif defined (IP_RECVIF)
|
||||
#ifdef SUNOS_5
|
||||
ifindex = *(uint_t *)getsockopt_cmsg_data (msgh, IPPROTO_IP, IP_RECVIF);
|
||||
#else
|
||||
pktinfo =
|
||||
(struct sockaddr_dl *)getsockopt_cmsg_data (msgh, IPPROTO_IP, IP_RECVIF);
|
||||
ifindex = pktinfo->sdl_index;
|
||||
#endif /* SUNOS_5 */
|
||||
#else
|
||||
#warning "getsockopt_ipv4_pktinfo_ifindex: dont have PKTINFO or RECVIF"
|
||||
ifindex = 0;
|
||||
#endif /* IP_PKTINFO */
|
||||
|
||||
return ifindex;
|
||||
}
|
||||
|
||||
/* return ifindex, 0 if none found */
|
||||
int
|
||||
getsockopt_pktinfo_ifindex (int af, struct msghdr *msgh)
|
||||
{
|
||||
int ifindex = 0;
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
return (getsockopt_ipv4_pktinfo_ifindex (msgh));
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
return (getsockopt_ipv6_pktinfo_ifindex (msgh));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
zlog_warn ("getsockopt_pktinfo_ifindex: unknown address family %d");
|
||||
return (ifindex = 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,27 @@ int setsockopt_ipv6_hoplimit (int, int);
|
||||
int setsockopt_ipv6_multicast_loop (int, int);
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
#if defined (IP_PKTINFO)
|
||||
#define SOPT_SIZE_CMSG_PKTINFO_IPV4() (sizeof (struct in_pktinfo))
|
||||
#elif defined (IP_RECVIF)
|
||||
#if defined (SUNOS_5)
|
||||
#define SOPT_SIZE_CMSG_PKTINFO_IPV4() (sizeof (uint_t))
|
||||
#else
|
||||
#define SOPT_SIZE_CMSG_PKTINFO_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()
|
||||
|
||||
int setsockopt_multicast_ipv4(int sock,
|
||||
int optname,
|
||||
struct in_addr if_addr,
|
||||
unsigned int mcast_addr,
|
||||
unsigned int ifindex);
|
||||
|
||||
|
||||
int setsockopt_pktinfo (int, int, int);
|
||||
int getsockopt_pktinfo_ifindex (int, struct msghdr *);
|
||||
#endif /*_ZEBRA_SOCKOPT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user