Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}