示例#1
0
int scamper_ip4_build(scamper_probe_t *pr, uint8_t *buf, size_t *len)
{
    scamper_probe_ipopt_t *opt;
    struct ip *ip;
    size_t off, ip4hlen;
    int i, j;

    if(scamper_ip4_hlen(pr, &ip4hlen) != 0)
        return -1;

    if(ip4hlen > *len)
    {
        *len = ip4hlen;
        return -1;
    }

    ip  = (struct ip *)buf;
    off = sizeof(struct ip);

#ifndef _WIN32
    ip->ip_v   = 4;
    ip->ip_hl  = (ip4hlen / 4);
#else
    ip->ip_vhl = 0x40 | (ip4hlen / 4);
#endif

    if((pr->pr_ip_off & IP_OFFMASK) != 0 || pr->pr_no_trans)
        ip->ip_len = htons(ip4hlen + pr->pr_len);
    else if(pr->pr_ip_proto == IPPROTO_ICMP || pr->pr_ip_proto == IPPROTO_UDP)
        ip->ip_len = htons(ip4hlen + 8 + pr->pr_len);
    else if(pr->pr_ip_proto == IPPROTO_TCP)
        ip->ip_len = htons(ip4hlen + scamper_tcp4_hlen(pr) + pr->pr_len);
    else
    {
        scamper_debug(__func__, "unimplemented pr %d", pr->pr_ip_proto);
        return -1;
    }

    ip->ip_tos = pr->pr_ip_tos;
    ip->ip_id  = htons(pr->pr_ip_id);
    ip->ip_off = htons(pr->pr_ip_off);
    ip->ip_ttl = pr->pr_ip_ttl;
    ip->ip_p   = pr->pr_ip_proto;
    ip->ip_sum = 0;
    memcpy(&ip->ip_src, pr->pr_ip_src->addr, sizeof(ip->ip_src));
    memcpy(&ip->ip_dst, pr->pr_ip_dst->addr, sizeof(ip->ip_dst));

    for(i=0; i<pr->pr_ipoptc; i++)
    {
        opt = &pr->pr_ipopts[i];
        if(opt->type == SCAMPER_PROBE_IPOPTS_V4RR)
        {
            memset(buf+off+3, 0, 37);
            buf[off+0] = 7;
            buf[off+1] = 39;
            buf[off+2] = 4;
            off = 60;
        }
        else if(opt->type == SCAMPER_PROBE_IPOPTS_V4TSPS ||
                opt->type == SCAMPER_PROBE_IPOPTS_V4TSO  ||
                opt->type == SCAMPER_PROBE_IPOPTS_V4TSAA)
        {
            buf[off+0] = 68;
            buf[off+2] = 5;

            if(opt->type == SCAMPER_PROBE_IPOPTS_V4TSPS)
            {
                buf[off+1] = (opt->opt_v4tsps_ipc * 4 * 2) + 4;
                buf[off+3] = 3;
                off += 4;
                for(j=0; j<opt->opt_v4tsps_ipc; j++)
                {
                    memcpy(buf+off, &opt->opt_v4tsps_ips[j], 4);
                    off += 4;
                    memset(buf+off, 0, 4);
                    off += 4;
                }
            }
            else if(opt->type == SCAMPER_PROBE_IPOPTS_V4TSO)
            {
                buf[off+1] = 40;
                memset(buf+off+3, 0, 41);
                off += 40;
            }
            else if(opt->type == SCAMPER_PROBE_IPOPTS_V4TSAA)
            {
                buf[off+1] = 36;
                buf[off+3] = 1;
                memset(buf+off+4, 0, 36);
                off += 36;
            }
        }
        else if(opt->type == SCAMPER_PROBE_IPOPTS_QUICKSTART)
        {
            assert(opt->opt_qs_func <= 0xf);
            assert(opt->opt_qs_rate <= 0xf);
            buf[off+0] = 25;
            buf[off+1] = 8;
            buf[off+2] = (opt->opt_qs_func << 4) | opt->opt_qs_rate;
            buf[off+3] = opt->opt_qs_ttl;
            bytes_htonl(&buf[off+4], opt->opt_qs_nonce << 2);
            off += 8;
        }
        else return -1;
    }

    assert(off == ip4hlen);
    ip->ip_sum = in_cksum(ip, ip4hlen);

    *len = off;
    return 0;
}
示例#2
0
static void probe_print(scamper_probe_t *probe)
{
  size_t iphl;
  char tcp[16];
  char pos[32];
  char addr[128];
  char icmp[16];
  char tos[8];

  assert(probe->pr_ip_dst != NULL);

  scamper_addr_tostr(probe->pr_ip_dst, addr, sizeof(addr));

  tos[0] = '\0';
  icmp[0] = '\0';

  if(probe->pr_ip_proto == IPPROTO_TCP)
    {
      if((probe->pr_ip_tos & IPTOS_ECN_CE) == IPTOS_ECN_CE)
	snprintf(tos, sizeof(tos), ", ce");
      else if(probe->pr_ip_tos & IPTOS_ECN_ECT1)
	snprintf(tos, sizeof(tos), ", ect1");
      else if(probe->pr_ip_tos & IPTOS_ECN_ECT0)
	snprintf(tos, sizeof(tos), ", ect0");
    }

  if(probe->pr_ip_dst->type == SCAMPER_ADDR_TYPE_IPV4)
    {
      if(scamper_ip4_hlen(probe, &iphl) != 0)
	return;

      if((probe->pr_ip_off & IP_OFFMASK) != 0)
	{
	  scamper_debug("tx", "frag %s %04x:%d ttl %d, len %d",
			addr, probe->pr_ip_id, probe->pr_ip_off << 3,
			probe->pr_ip_ttl, iphl + probe->pr_len);
	  return;
	}

      switch(probe->pr_ip_proto)
	{
	case IPPROTO_UDP:
	  scamper_debug("tx", "udp %s, ttl %d, %d:%d, len %d",
			addr, probe->pr_ip_ttl, probe->pr_udp_sport,
			probe->pr_udp_dport, iphl + 8 + probe->pr_len);
	  break;

	case IPPROTO_TCP:
	  scamper_debug("tx",
			"tcp %s%s, ttl %d, %d:%d%s, ipid %04x, %s, len %d",
			addr, tos, probe->pr_ip_ttl,
			probe->pr_tcp_sport, probe->pr_tcp_dport,
			tcp_flags(tcp, sizeof(tcp), probe),
			probe->pr_ip_id, tcp_pos(pos, sizeof(pos), probe),
			iphl + scamper_tcp4_hlen(probe) + probe->pr_len);
	  break;

	case IPPROTO_ICMP:
	  if(probe->pr_icmp_type == ICMP_ECHO)
	    {
	      if(probe->pr_icmp_sum != 0)
		{
		  snprintf(icmp, sizeof(icmp), ", sum %04x",
			   ntohs(probe->pr_icmp_sum));
		}
	      scamper_debug("tx", "icmp %s echo, ttl %d%s, seq %d, len %d",
			    addr, probe->pr_ip_ttl, icmp, probe->pr_icmp_seq,
			    iphl + 8 + probe->pr_len);
	    }
	  else if(probe->pr_icmp_type == ICMP_UNREACH)
	    {
	      if(probe->pr_icmp_code == ICMP_UNREACH_NEEDFRAG)
		snprintf(icmp,sizeof(icmp),"ptb %d", probe->pr_icmp_mtu);
	      else
		snprintf(icmp,sizeof(icmp),"unreach %d", probe->pr_icmp_code);
	      scamper_debug("tx", "icmp %s %s, len %d",
			    addr, icmp, iphl + 8 + probe->pr_len);
	    }
	  else
	    {
	      scamper_debug("tx", "icmp %s type %d, code %d, len %d",
			    addr, probe->pr_icmp_type, probe->pr_icmp_code,
			    iphl + 8 + probe->pr_len);
	    }
	  break;
	}
    }
  else if(probe->pr_ip_dst->type == SCAMPER_ADDR_TYPE_IPV6)
    {
      if(scamper_ip6_hlen(probe, &iphl) != 0)
	return;

      if(probe->pr_ip_off != 0)
	{
	  scamper_debug("tx", "frag %s off %04x, ttl %d, len %d",
			addr, probe->pr_ip_off, probe->pr_ip_ttl,
			iphl + probe->pr_len);
	  return;
	}

      switch(probe->pr_ip_proto)
	{
	case IPPROTO_UDP:
	  scamper_debug("tx", "udp %s, ttl %d, %d:%d, len %d",
			addr, probe->pr_ip_ttl, probe->pr_udp_sport,
			probe->pr_udp_dport, iphl + 8 + probe->pr_len);
	  break;

	case IPPROTO_TCP:
	  scamper_debug("tx", "tcp %s%s, ttl %d, %d:%d%s, %s, len %d",
			addr, tos, probe->pr_ip_ttl,
			probe->pr_tcp_sport, probe->pr_tcp_dport,
			tcp_flags(tcp, sizeof(tcp), probe),
			tcp_pos(pos, sizeof(pos), probe),
			iphl + scamper_tcp6_hlen(probe) + probe->pr_len);
	  break;

	case IPPROTO_ICMPV6:
	  if(probe->pr_icmp_type == ICMP6_ECHO_REQUEST)
	    {
	      if(probe->pr_icmp_sum != 0)
		{
		  snprintf(icmp, sizeof(icmp), ", sum %04x",
			   ntohs(probe->pr_icmp_sum));
		}
	      scamper_debug("tx", "icmp %s echo, ttl %d%s, seq %d, len %d",
			    addr, probe->pr_ip_ttl, icmp, probe->pr_icmp_seq,
			    iphl + 8 + probe->pr_len);
	    }
	  else if(probe->pr_icmp_type == ICMP6_PACKET_TOO_BIG)
	    {
	      scamper_debug("tx", "icmp %s ptb %d, len %d", addr,
			    probe->pr_icmp_mtu, iphl + 8 + probe->pr_len);
	    }
	  else if(probe->pr_icmp_type == ICMP6_DST_UNREACH)
	    {
	      scamper_debug("tx", "icmp %s unreach %d, len %d", addr,
			    probe->pr_icmp_code, iphl + 8 + probe->pr_len);
	    }
	  else 
	    {
	      scamper_debug("tx", "icmp %s type %d, code %d, len %d",
			    addr, probe->pr_icmp_type, probe->pr_icmp_code,
			    iphl + 8 + probe->pr_len);
	    }
	  break;
	}
    }

  return;
}