static int pim_sock_read(struct thread *t) { struct interface *ifp; struct pim_interface *pim_ifp; int fd; struct sockaddr_in from; struct sockaddr_in to; socklen_t fromlen = sizeof(from); socklen_t tolen = sizeof(to); uint8_t buf[PIM_PIM_BUFSIZE_READ]; int len; int ifindex = -1; int result = -1; /* defaults to bad */ zassert(t); ifp = THREAD_ARG(t); zassert(ifp); fd = THREAD_FD(t); pim_ifp = ifp->info; zassert(pim_ifp); zassert(fd == pim_ifp->pim_sock_fd); len = pim_socket_recvfromto(fd, buf, sizeof(buf), &from, &fromlen, &to, &tolen, &ifindex); if (len < 0) { zlog_warn("Failure receiving IP PIM packet on fd=%d: errno=%d: %s", fd, errno, safe_strerror(errno)); goto done; } if (PIM_DEBUG_PIM_PACKETS) { char from_str[100]; char to_str[100]; if (!inet_ntop(AF_INET, &from.sin_addr, from_str, sizeof(from_str))) sprintf(from_str, "<from?>"); if (!inet_ntop(AF_INET, &to.sin_addr, to_str, sizeof(to_str))) sprintf(to_str, "<to?>"); zlog_debug("Recv IP PIM pkt size=%d from %s to %s on fd=%d on ifindex=%d (sock_ifindex=%d)", len, from_str, to_str, fd, ifindex, ifp->ifindex); } if (PIM_DEBUG_PIM_PACKETDUMP_RECV) { pim_pkt_dump(__PRETTY_FUNCTION__, buf, len); } #ifdef PIM_CHECK_RECV_IFINDEX_SANITY /* ifindex sanity check */ if (ifindex != (int) ifp->ifindex) { char from_str[100]; char to_str[100]; struct interface *recv_ifp; if (!inet_ntop(AF_INET, &from.sin_addr, from_str , sizeof(from_str))) sprintf(from_str, "<from?>"); if (!inet_ntop(AF_INET, &to.sin_addr, to_str , sizeof(to_str))) sprintf(to_str, "<to?>"); recv_ifp = if_lookup_by_index(ifindex); if (recv_ifp) { zassert(ifindex == (int) recv_ifp->ifindex); } #ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH zlog_warn("Interface mismatch: recv PIM pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)", from_str, to_str, fd, ifindex, recv_ifp ? recv_ifp->name : "<if-notfound>", ifp->ifindex, ifp->name); #endif goto done; } #endif int fail = pim_pim_packet(ifp, buf, len); if (fail) { zlog_warn("%s: pim_pim_packet() return=%d", __PRETTY_FUNCTION__, fail); goto done; } result = 0; /* good */ done: pim_sock_read_on(ifp); if (result) { ++pim_ifp->pim_ifstat_hello_recvfail; } return result; }
static int ssmpingd_read_msg(struct ssmpingd_sock *ss) { struct interface *ifp; struct sockaddr_in from; struct sockaddr_in to; socklen_t fromlen = sizeof(from); socklen_t tolen = sizeof(to); ifindex_t ifindex = -1; uint8_t buf[1000]; int len; ++ss->requests; len = pim_socket_recvfromto(ss->sock_fd, buf, sizeof(buf), &from, &fromlen, &to, &tolen, &ifindex); if (len < 0) { char source_str[INET_ADDRSTRLEN]; pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str)); zlog_warn( "%s: failure receiving ssmping for source %s on fd=%d: errno=%d: %s", __PRETTY_FUNCTION__, source_str, ss->sock_fd, errno, safe_strerror(errno)); return -1; } ifp = if_lookup_by_index(ifindex, ss->pim->vrf_id); if (buf[0] != PIM_SSMPINGD_REQUEST) { char source_str[INET_ADDRSTRLEN]; char from_str[INET_ADDRSTRLEN]; char to_str[INET_ADDRSTRLEN]; pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str)); pim_inet4_dump("<from?>", from.sin_addr, from_str, sizeof(from_str)); pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str)); zlog_warn( "%s: bad ssmping type=%d from %s,%d to %s,%d on interface %s ifindex=%d fd=%d src=%s", __PRETTY_FUNCTION__, buf[0], from_str, ntohs(from.sin_port), to_str, ntohs(to.sin_port), ifp ? ifp->name : "<iface?>", ifindex, ss->sock_fd, source_str); return 0; } if (PIM_DEBUG_SSMPINGD) { char source_str[INET_ADDRSTRLEN]; char from_str[INET_ADDRSTRLEN]; char to_str[INET_ADDRSTRLEN]; pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str)); pim_inet4_dump("<from?>", from.sin_addr, from_str, sizeof(from_str)); pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str)); zlog_debug( "%s: recv ssmping from %s,%d to %s,%d on interface %s ifindex=%d fd=%d src=%s", __PRETTY_FUNCTION__, from_str, ntohs(from.sin_port), to_str, ntohs(to.sin_port), ifp ? ifp->name : "<iface?>", ifindex, ss->sock_fd, source_str); } buf[0] = PIM_SSMPINGD_REPLY; /* unicast reply */ ssmpingd_sendto(ss, buf, len, from); /* multicast reply */ from.sin_addr = ss->pim->ssmpingd_group_addr; ssmpingd_sendto(ss, buf, len, from); return 0; }
static int pim_igmp_read(struct thread *t) { struct igmp_sock *igmp; int fd; struct sockaddr_in from; struct sockaddr_in to; socklen_t fromlen = sizeof(from); socklen_t tolen = sizeof(to); uint8_t buf[PIM_IGMP_BUFSIZE_READ]; int len; int ifindex = -1; int result = -1; /* defaults to bad */ zassert(t); igmp = THREAD_ARG(t); zassert(igmp); fd = THREAD_FD(t); zassert(fd == igmp->fd); len = pim_socket_recvfromto(fd, buf, sizeof(buf), &from, &fromlen, &to, &tolen, &ifindex); if (len < 0) { zlog_warn("Failure receiving IP IGMP packet on fd=%d: errno=%d: %s", fd, errno, safe_strerror(errno)); goto done; } if (PIM_DEBUG_IGMP_PACKETS) { char from_str[100]; char to_str[100]; if (!inet_ntop(AF_INET, &from.sin_addr, from_str, sizeof(from_str))) sprintf(from_str, "<from?>"); if (!inet_ntop(AF_INET, &to.sin_addr, to_str, sizeof(to_str))) sprintf(to_str, "<to?>"); zlog_debug("Recv IP IGMP pkt size=%d from %s to %s on fd=%d on ifindex=%d (sock_ifindex=%d)", len, from_str, to_str, fd, ifindex, igmp->interface->ifindex); } #ifdef PIM_CHECK_RECV_IFINDEX_SANITY /* ifindex sanity check */ if (ifindex != (int) igmp->interface->ifindex) { char from_str[100]; char to_str[100]; struct interface *ifp; if (!inet_ntop(AF_INET, &from.sin_addr, from_str , sizeof(from_str))) sprintf(from_str, "<from?>"); if (!inet_ntop(AF_INET, &to.sin_addr, to_str , sizeof(to_str))) sprintf(to_str, "<to?>"); ifp = if_lookup_by_index(ifindex); if (ifp) { zassert(ifindex == (int) ifp->ifindex); } #ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH zlog_warn("Interface mismatch: recv IGMP pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)", from_str, to_str, fd, ifindex, ifp ? ifp->name : "<if-notfound>", igmp->interface->ifindex, igmp->interface->name); #endif goto done; } #endif if (pim_igmp_packet(igmp, (char *)buf, len)) { goto done; } result = 0; /* good */ done: igmp_read_on(igmp); return result; }