diff options
Diffstat (limited to 'pimd/pim_sock.c')
-rw-r--r-- | pimd/pim_sock.c | 115 |
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 |