summaryrefslogtreecommitdiffstats
path: root/pimd/pim_sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_sock.c')
-rw-r--r--pimd/pim_sock.c115
1 files changed, 68 insertions, 47 deletions
diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c
index 54816d126..de56eb607 100644
--- a/pimd/pim_sock.c
+++ b/pimd/pim_sock.c
@@ -44,7 +44,8 @@
/* GLOBAL VARS */
extern struct zebra_privs_t pimd_privs;
-int pim_socket_raw(int protocol)
+int
+pim_socket_raw (int protocol)
{
int fd;
@@ -67,8 +68,52 @@ int pim_socket_raw(int protocol)
return fd;
}
+int
+pim_socket_ip_hdr (int fd)
+{
+ const int on = 1;
+ int ret;
+
+ if (pimd_privs.change (ZPRIVS_RAISE))
+ zlog_err ("%s: could not raise privs, %s",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+
+ ret = setsockopt (fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on));
+
+ if (pimd_privs.change (ZPRIVS_LOWER))
+ zlog_err ("%s: could not lower privs, %s",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+
+ return ret;
+}
+
+/*
+ * Given a socket and a interface,
+ * Bind that socket to that interface
+ */
+int
+pim_socket_bind (int fd, struct interface *ifp)
+{
+ int ret;
+
+ if (pimd_privs.change (ZPRIVS_RAISE))
+ zlog_err ("%s: could not raise privs, %s",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+
+ ret = setsockopt (fd, SOL_SOCKET,
+ SO_BINDTODEVICE, ifp->name, strlen (ifp->name));
+
+ if (pimd_privs.change (ZPRIVS_LOWER))
+ zlog_err ("%s: could not lower privs, %s",
+ __PRETTY_FUNCTION__, safe_strerror (errno));
+
+ return ret;
+}
+
int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char loop)
{
+ int rcvbuf = 1024 * 1024 * 8;
+ struct ip_mreqn mreq;
int fd;
fd = pim_socket_raw(protocol);
@@ -86,17 +131,7 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char lo
ifp = if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
- if (pimd_privs.change (ZPRIVS_RAISE))
- zlog_err ("%s: could not raise privs, %s",
- __PRETTY_FUNCTION__, safe_strerror (errno));
-
- ret = setsockopt (fd, SOL_SOCKET,
- SO_BINDTODEVICE, ifp->name, strlen (ifp->name));
-
- if (pimd_privs.change (ZPRIVS_LOWER))
- zlog_err ("%s: could not lower privs, %s",
- __PRETTY_FUNCTION__, safe_strerror (errno));
-
+ ret = pim_socket_bind (fd, ifp);
if (ret)
{
zlog_warn("Could not set fd: %d for interface: %s to device",
@@ -180,14 +215,20 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char lo
return PIM_SOCK_ERR_LOOP;
}
+ memset (&mreq, 0, sizeof (mreq));
+ mreq.imr_ifindex = ifindex;
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (void *) &ifaddr, sizeof(ifaddr))) {
+ (void *) &mreq, sizeof(mreq))) {
zlog_warn("Could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
fd, errno, safe_strerror(errno));
close(fd);
return PIM_SOCK_ERR_IFACE;
}
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)))
+ zlog_warn("%s: Failure to set buffer size to %d",
+ __PRETTY_FUNCTION__, rcvbuf);
+
{
long flags;
@@ -232,8 +273,8 @@ int pim_socket_join(int fd, struct in_addr group,
ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &opt, sizeof(opt));
if (ret) {
- char group_str[100];
- char ifaddr_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char ifaddr_str[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, &group, group_str , sizeof(group_str)))
sprintf(group_str, "<group?>");
if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str , sizeof(ifaddr_str)))
@@ -245,8 +286,8 @@ int pim_socket_join(int fd, struct in_addr group,
}
if (PIM_DEBUG_TRACE) {
- char group_str[100];
- char ifaddr_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char ifaddr_str[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, &group, group_str , sizeof(group_str)))
sprintf(group_str, "<group?>");
if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str , sizeof(ifaddr_str)))
@@ -265,15 +306,14 @@ int pim_socket_join_source(int fd, ifindex_t ifindex,
const char *ifname)
{
if (pim_igmp_join_source(fd, ifindex, group_addr, source_addr)) {
- int e = errno;
- char group_str[100];
- char source_str[100];
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
zlog_warn("%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s",
__PRETTY_FUNCTION__,
fd, group_str, source_str, ifindex, ifname,
- e, safe_strerror(e));
+ errno, safe_strerror(errno));
return -1;
}
@@ -298,17 +338,14 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
if (to) {
struct sockaddr_in si;
socklen_t si_len = sizeof(si);
-
- ((struct sockaddr_in *) to)->sin_family = AF_INET;
- if (pim_socket_getsockname(fd, (struct sockaddr *) &si, &si_len)) {
- ((struct sockaddr_in *) to)->sin_port = ntohs(0);
- ((struct sockaddr_in *) to)->sin_addr.s_addr = ntohl(0);
- }
- else {
- ((struct sockaddr_in *) to)->sin_port = si.sin_port;
- ((struct sockaddr_in *) to)->sin_addr = si.sin_addr;
- }
+ memset (&si, 0, sizeof (si));
+ to->sin_family = AF_INET;
+
+ pim_socket_getsockname(fd, (struct sockaddr *) &si, &si_len);
+
+ to->sin_port = si.sin_port;
+ to->sin_addr = si.sin_addr;
if (tolen)
*tolen = sizeof(si);
@@ -346,14 +383,6 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
if (ifindex)
*ifindex = i->ipi_ifindex;
- if (to && PIM_DEBUG_PACKETS) {
- char to_str[100];
- pim_inet4_dump("<to?>", to->sin_addr, to_str, sizeof(to_str));
- zlog_debug("%s: HAVE_IP_PKTINFO to=%s,%d",
- __PRETTY_FUNCTION__,
- to_str, ntohs(to->sin_port));
- }
-
break;
}
#endif
@@ -366,14 +395,6 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
if (tolen)
*tolen = sizeof(struct sockaddr_in);
- if (to && PIM_DEBUG_PACKETS) {
- char to_str[100];
- pim_inet4_dump("<to?>", to->sin_addr, to_str, sizeof(to_str));
- zlog_debug("%s: HAVE_IP_RECVDSTADDR to=%s,%d",
- __PRETTY_FUNCTION__,
- to_str, ntohs(to->sin_port));
- }
-
break;
}
#endif