コード例 #1
0
ファイル: traceroute.c プロジェクト: millken/zhuxianB30
int
trace_read (trace_t * t)
{
  int len;
  unsigned char data[56];		/* For a TIME_EXCEEDED datagram. */
  struct ip *ip;
  icmphdr_t *ic;
  socklen_t siz;

  assert (t);

  siz = sizeof (t->from);

  len = recvfrom (t->icmpfd, (char *) data, 56, 0,
		  (struct sockaddr *) &t->from, &siz);
  if (len < 0)
    error (EXIT_FAILURE, errno, "recvfrom");

  icmp_generic_decode (data, 56, &ip, &ic);

  switch (t->type)
    {
    case TRACE_UDP:
      {
	unsigned short *port;
	if ((ic->icmp_type != ICMP_TIME_EXCEEDED
	     && ic->icmp_type != ICMP_DEST_UNREACH)
	    || (ic->icmp_type == ICMP_DEST_UNREACH
		&& ic->icmp_code != ICMP_PORT_UNREACH))
	  return -1;

	/* check whether it's for us */
        port = (unsigned short *) &ic->icmp_ip + 11;
	if (*port != t->to.sin_port)
	  return -1;

	if (ic->icmp_code == ICMP_PORT_UNREACH)
	  /* FIXME: Ugly hack. */
	  stop = 1;
      }
      break;

    case TRACE_ICMP:
      if (ic->icmp_type != ICMP_TIME_EXCEEDED
	  && ic->icmp_type != ICMP_ECHOREPLY)
	return -1;

      if (ic->icmp_type == ICMP_ECHOREPLY
	  && (ic->icmp_seq != pid || ic->icmp_id != pid))
	return -1;
      else if (ic->icmp_type == ICMP_TIME_EXCEEDED)
	{
	  unsigned short *seq = (unsigned short *) &ic->icmp_ip + 12;
	  unsigned short *ident = (unsigned short *) &ic->icmp_ip + 13;
	  if (*seq != pid || *ident != pid)
	    return -1;
	}

      if (ip->ip_src.s_addr == dest.sin_addr.s_addr)
	/* FIXME: Ugly hack. */
	stop = 1;
      break;

      /* FIXME: Type according to RFC 1393. */

    default:
      break;
    }

  return 0;
}
コード例 #2
0
ファイル: libping.c プロジェクト: 274914765/C
int ping_recv (PING * p)
{
    socklen_t fromlen = sizeof (p->ping_from.ping_sockaddr);

    int n, rc;

    icmphdr_t *icmp;

    struct ip *ip;

    int dupflag;

    n = recvfrom (p->ping_fd,
                  (char *) p->ping_buffer, _PING_BUFLEN (p, USE_IPV6), 0,
                  (struct sockaddr *) &p->ping_from.ping_sockaddr, &fromlen);
    if (n < 0)
        return -1;

    rc = icmp_generic_decode (p->ping_buffer, n, &ip, &icmp);
    if (rc < 0)
    {
        /*FIXME: conditional */
        fprintf (stderr, "packet too short (%d bytes) from %s\n", n, inet_ntoa (p->ping_from.ping_sockaddr.sin_addr));
        return -1;
    }

    switch (icmp->icmp_type)
    {
        case ICMP_ECHOREPLY:
        case ICMP_TIMESTAMPREPLY:
        case ICMP_ADDRESSREPLY:
            /*    case ICMP_ROUTERADV: */

            if (icmp->icmp_id != p->ping_ident)
                return -1;

            if (rc)
                fprintf (stderr, "checksum mismatch from %s\n", inet_ntoa (p->ping_from.ping_sockaddr.sin_addr));

            p->ping_num_recv++;
            if (_PING_TST (p, icmp->icmp_seq))
            {
                p->ping_num_rept++;
                p->ping_num_recv--;
                dupflag = 1;
            }
            else
            {
                _PING_SET (p, icmp->icmp_seq);
                dupflag = 0;
            }

            if (p->ping_event.handler)
                (*p->ping_event.handler) (dupflag ? PEV_DUPLICATE : PEV_RESPONSE,
                                          p->ping_closure,
                                          &p->ping_dest.ping_sockaddr, &p->ping_from.ping_sockaddr, ip, icmp, n);
            break;

        case ICMP_ECHO:
        case ICMP_TIMESTAMP:
        case ICMP_ADDRESS:
            return -1;

        default:
            if (!my_echo_reply (p, icmp))
                return -1;

            if (p->ping_event.handler)
                (*p->ping_event.handler) (PEV_NOECHO,
                                          p->ping_closure,
                                          &p->ping_dest.ping_sockaddr, &p->ping_from.ping_sockaddr, ip, icmp, n);
    }
    return 0;
}
コード例 #3
0
ファイル: icmp_echo.c プロジェクト: Distrotech/inetutils
int
icmp_echo_decode (unsigned char * buffer, size_t bufsize,
		  struct ip **ipp, icmphdr_t ** icmpp)
{
  return icmp_generic_decode (buffer, bufsize, ipp, icmpp);
}