int scamper_file_warts_ping_read(scamper_file_t *sf, const warts_hdr_t *hdr,
				 scamper_ping_t **ping_out)
{
  warts_state_t *state = scamper_file_getstate(sf);
  scamper_ping_t *ping = NULL;
  uint8_t *buf = NULL;
  uint32_t off = 0;
  uint16_t i;
  scamper_ping_reply_t *reply;
  uint16_t reply_count;
  warts_addrtable_t table;

  memset(&table, 0, sizeof(table));

  if(warts_read(sf, &buf, hdr->len) != 0)
    {
      goto err;
    }
  if(buf == NULL)
    {
      *ping_out = NULL;
      return 0;
    }

  if((ping = scamper_ping_alloc()) == NULL)
    {
      goto err;
    }

  if(warts_ping_params_read(ping, state, &table, buf, &off, hdr->len) != 0)
    {
      goto err;
    }

  /* determine how many replies to read */
  if(extract_uint16(buf, &off, hdr->len, &reply_count, NULL) != 0)
    {
      goto err;
    }

  /* allocate the ping_replies array */
  if(scamper_ping_replies_alloc(ping, ping->ping_sent) != 0)
    {
      goto err;
    }

  /* if there are no replies, then we are done */
  if(reply_count == 0)
    {
      goto done;
    }

  /* for each reply, read it and insert it into the ping structure */
  for(i=0; i<reply_count; i++)
    {
      if((reply = scamper_ping_reply_alloc()) == NULL)
	{
	  goto err;
	}

      if(warts_ping_reply_read(ping,reply,state,&table,buf,&off,hdr->len) != 0)
	{
	  goto err;
	}

      if(scamper_ping_reply_append(ping, reply) != 0)
	{
	  goto err;
	}
    }

  assert(off == hdr->len);

 done:
  warts_addrtable_clean(&table);
  *ping_out = ping;
  free(buf);
  return 0;

 err:
  warts_addrtable_clean(&table);
  if(buf != NULL) free(buf);
  if(ping != NULL) scamper_ping_free(ping);
  return -1;
}
示例#2
0
int scamper_file_warts_dealias_read(scamper_file_t *sf, const warts_hdr_t *hdr,
				    scamper_dealias_t **dealias_out)
{
  static int (*const read[])(scamper_dealias_t *,warts_state_t *,
			     warts_addrtable_t *,scamper_dealias_probedef_t **,
			     uint8_t *, uint32_t *, uint32_t) = {
    warts_dealias_mercator_read,
    warts_dealias_ally_read,
    warts_dealias_radargun_read,
    warts_dealias_prefixscan_read,
    warts_dealias_bump_read,
  };
  scamper_dealias_t *dealias = NULL;
  scamper_dealias_probedef_t *defs;
  scamper_dealias_probe_t *probe;
  warts_addrtable_t table;
  warts_state_t *state = scamper_file_getstate(sf);
  uint8_t *buf = NULL;
  uint32_t off = 0;
  uint32_t i;

  memset(&table, 0, sizeof(table));

  if(warts_read(sf, &buf, hdr->len) != 0)
    {
      goto err;
    }
  if(buf == NULL)
    {
      *dealias_out = NULL;
      return 0;
    }

  if((dealias = scamper_dealias_alloc()) == NULL)
    {
      goto err;
    }

  if(warts_dealias_params_read(dealias, state, buf, &off, hdr->len) != 0)
    {
      goto err;
    }

  if(read[dealias->method-1](dealias,state,&table,&defs,buf,&off,hdr->len)!=0)
    goto err;

  if(dealias->probec == 0)
    goto done;

  if(scamper_dealias_probes_alloc(dealias, dealias->probec) != 0)
    {
      goto err;
    }

  for(i=0; i<dealias->probec; i++)
    {
      if((probe = scamper_dealias_probe_alloc()) == NULL)
	{
	  goto err;
	}
      dealias->probes[i] = probe;

      if(warts_dealias_probe_read(probe, state, defs, &table,
				  buf, &off, hdr->len) != 0)
	{
	  goto err;
	}
    }

 done:
  assert(off == hdr->len);
  warts_addrtable_clean(&table);
  *dealias_out = dealias;
  free(buf);
  return 0;

 err:
  warts_addrtable_clean(&table);
  if(buf != NULL) free(buf);
  if(dealias != NULL) scamper_dealias_free(dealias);
  return -1;
}
/*
 * warts_tracelb_read
 *
 */
int scamper_file_warts_tracelb_read(scamper_file_t *sf, const warts_hdr_t *hdr,
				    scamper_tracelb_t **trace_out)
{
  warts_state_t          *state = scamper_file_getstate(sf);
  scamper_tracelb_t      *trace = NULL;
  uint8_t                *buf = NULL;
  uint32_t                i, off = 0;
  uint16_t               *nlc = NULL, j;
  scamper_tracelb_node_t *node;
  warts_addrtable_t       table;

  memset(&table, 0, sizeof(table));

  if(warts_read(sf, &buf, hdr->len) != 0)
    {
      goto err;
    }
  if(buf == NULL)
    {
      *trace_out = NULL;
      return 0;
    }

  if((trace = scamper_tracelb_alloc()) == NULL)
    {
      goto err;
    }

  /* read the trace's parameters */
  if(warts_tracelb_params_read(trace, state, &table, buf, &off, hdr->len) != 0)
    {
      goto err;
    }

  /* read the nodes */
  if(trace->nodec > 0)
    {
      if(scamper_tracelb_nodes_alloc(trace, trace->nodec) != 0)
	{
	  goto err;
	}
      for(i=0; i<trace->nodec; i++)
	{
	  if((trace->nodes[i] = scamper_tracelb_node_alloc(NULL)) == NULL)
	    goto err;

	  if(warts_tracelb_node_read(trace->nodes[i], state, &table,
				     buf, &off, hdr->len) != 0)
	    goto err;
	}
    }

  /* read the links */
  if(trace->linkc > 0)
    {
      if(scamper_tracelb_links_alloc(trace, trace->linkc) != 0)
	{
	  goto err;
	}
      for(i=0; i<trace->linkc; i++)
	{
	  if((trace->links[i] = scamper_tracelb_link_alloc()) == NULL)
	    goto err;

	  if(warts_tracelb_link_read(trace, trace->links[i], state, &table,
				     buf, &off, hdr->len) != 0)
	    goto err;
	}
    }

  /* don't need the buf any more */
  free(buf); buf = NULL;

  /*
   * add the links to their respective nodes.
   */
  if(trace->nodec > 0)
    {
      if((nlc = malloc_zero(sizeof(uint16_t) * trace->nodec)) == NULL)
	{
	  goto err;
	}
      for(i=0; i<trace->linkc; i++)
	{
	  for(j=0; j<trace->nodec; j++)
	    {
	      if(trace->links[i]->from == trace->nodes[j])
		break;
	    }

	  if(j == trace->nodec)
	    goto err;

	  node = trace->nodes[j];

	  if(node->links == NULL &&
	     scamper_tracelb_node_links_alloc(node, node->linkc) != 0)
	    goto err;

	  if(nlc[j] == node->linkc)
	    goto err;

	  node->links[nlc[j]++] = trace->links[i];
	}

      for(i=0; i<trace->nodec; i++)
	{
	  if(nlc[i] != trace->nodes[i]->linkc)
	    goto err;
	}

      free(nlc); nlc = NULL;
    }

  warts_addrtable_clean(&table);
  *trace_out = trace;
  return 0;

 err:
  warts_addrtable_clean(&table);
  if(buf != NULL) free(buf);
  if(nlc != NULL) free(nlc);
  if(trace != NULL) scamper_tracelb_free(trace);
  return -1;
}
示例#4
0
/*
 * warts_trace_read
 *
 */
int scamper_file_warts_trace_read(scamper_file_t *sf, const warts_hdr_t *hdr,
				  scamper_trace_t **trace_out)
{
  warts_state_t       *state = scamper_file_getstate(sf);
  scamper_trace_t     *trace = NULL;
  uint8_t             *buf = NULL;
  uint32_t             i, off = 0;
  scamper_trace_hop_t *hops = NULL;
  scamper_trace_hop_t *hop;
  uint16_t             count;
  uint8_t              max_ttl;
  uint8_t              type;
  uint16_t             len;
  uint16_t             u16;
  warts_addrtable_t   *table = NULL;

  if(warts_read(sf, &buf, hdr->len) != 0)
    {
      goto err;
    }
  if(buf == NULL)
    {
      *trace_out = NULL;
      return 0;
    }

  if((trace = scamper_trace_alloc()) == NULL)
    {
      goto err;
    }

  if((table = warts_addrtable_alloc_byid()) == NULL)
    goto err;

  /* read the trace's parameters */
  if(warts_trace_params_read(trace, state, table, buf, &off, hdr->len) != 0)
    {
      goto err;
    }

  /*
   * the next two bytes tell us how many scamper_hops to read out of trace
   * if we did not get any responses, we are done.
   */
  if(extract_uint16(buf, &off, hdr->len, &count, NULL) != 0)
    {
      goto err;
    }

  /* read all the hop records */
  if(warts_trace_hops_read(&hops,state,table,buf,&off,hdr->len,count) != 0)
    goto err;

  /* work out the maximum ttl probed with that got a response */
  max_ttl = 0;
  for(i=0, hop = hops; i < count; i++)
    {
      if(hop->hop_probe_ttl > max_ttl)
	max_ttl = hop->hop_probe_ttl;
      hop = hop->hop_next;
    }

  /*
   * if the hop_count field was provided in the file, then
   * make sure it makes sense based on the hop data we've just scanned
   */
  if(trace->hop_count != 0)
    {
      if(trace->hop_count < max_ttl)
	goto err;
      if(trace->hop_count > 255)
	goto err;
    }
  else
    {
      trace->hop_count = max_ttl;
    }

  /* allocate enough hops to string the trace together */
  if(scamper_trace_hops_alloc(trace, trace->hop_count) == -1)
    {
      goto err;
    }

  if(hops == NULL)
    {
      assert(count == 0);
      goto done;
    }

  /*
   * now loop through the hops array stored in this procedure
   * and assemble the responses into trace->hops.
   */
  trace->hops[hops->hop_probe_ttl-1] = hop = hops;
  while(hop->hop_next != NULL)
    {
      if(hop->hop_probe_ttl != hop->hop_next->hop_probe_ttl)
	{
	  i = hop->hop_next->hop_probe_ttl-1;
	  trace->hops[i] = hop->hop_next;
	  hop->hop_next = NULL;
	  hop = trace->hops[i];
	}
      else hop = hop->hop_next;
    }
  hops = NULL;

  for(;;)
    {
      if(extract_uint16(buf, &off, hdr->len, &u16, NULL) != 0)
	goto err;
      if(u16 == WARTS_TRACE_ATTR_EOF)
	break;

      type = WARTS_TRACE_ATTR_HDR_TYPE(u16);
      len  = WARTS_TRACE_ATTR_HDR_LEN(u16);

      if(type == WARTS_TRACE_ATTR_PMTUD)
	{
	  i = off;
	  if(warts_trace_pmtud_read(trace,state,table,buf,&i,hdr->len) != 0)
	    goto err;
	}
      else if(type == WARTS_TRACE_ATTR_LASTDITCH)
	{
	  i = off;
	  if(warts_trace_lastditch_read(trace, state, table,
 					buf, &i, hdr->len) != 0)
	    goto err;
	}
      else if(type == WARTS_TRACE_ATTR_DTREE)
	{
	  i = off;
	  if(warts_trace_dtree_read(trace,state,table,buf,&i,hdr->len) != 0)
	    goto err;
	}

      off += len;
    }

 done:
  warts_addrtable_free(table);
  free(buf);
  *trace_out = trace;
  return 0;

 err:
  if(table != NULL) warts_addrtable_free(table);
  if(hops != NULL) free(hops);
  if(buf != NULL) free(buf);
  if(trace != NULL) scamper_trace_free(trace);
  return -1;
}
int scamper_file_warts_tbit_read(scamper_file_t *sf, const warts_hdr_t *hdr,
				 scamper_tbit_t **tbit_out)
{
  scamper_tbit_t *tbit = NULL;
  warts_addrtable_t table;
  warts_state_t *state = scamper_file_getstate(sf);
  uint8_t *buf = NULL;
  uint16_t junk16;
  uint32_t junk32;
  uint32_t off = 0;
  uint32_t i;

  memset(&table, 0, sizeof(table));

  /* Read in the header */
  if(warts_read(sf, &buf, hdr->len) != 0)
    {
      goto err;
    }

  if(buf == NULL)
    {
      *tbit_out = NULL;
      return 0;
    }

  /* Allocate space for a tbit object */
  if((tbit = scamper_tbit_alloc()) == NULL)
    {
      goto err;
    }

  /* Read in the tbit data from the warts file */
  if(warts_tbit_params_read(tbit, &table, state, buf, &off, hdr->len) != 0)
    {
      goto err;
    }

  switch(tbit->type)
    {
    case SCAMPER_TBIT_TYPE_PMTUD:
      if((tbit->data = scamper_tbit_pmtud_alloc()) == NULL)
	goto err;
      break;

    case SCAMPER_TBIT_TYPE_NULL:
      if((tbit->data = scamper_tbit_null_alloc()) == NULL)
	goto err;
      break;
    }

  /* Determine how many tbit_pkts to read */
  if(tbit->pktc > 0)
    {
      /* Allocate the tbit_pkts array */
      if(scamper_tbit_pkts_alloc(tbit, tbit->pktc) != 0)
	goto err;

      /* For each tbit packet, read it and insert it into the tbit structure */
      for(i=0; i<tbit->pktc; i++)
        {
	  tbit->pkts[i] = warts_tbit_pkt_read(state, buf, &off, hdr->len);
	  if(tbit->pkts[i] == NULL)
	    goto err;
        }
    }

  for(;;)
    {
      if(extract_uint16(buf, &off, hdr->len, &junk16, NULL) != 0)
	goto err;
      if(junk16 == WARTS_TBIT_STRUCT_EOF)
	break;
      if(extract_uint32(buf, &off, hdr->len, &junk32, NULL) != 0)
	goto err;

      i = off;
      if(junk16 == WARTS_TBIT_STRUCT_TYPE)
	{
	  switch(tbit->type)
	    {
	    case SCAMPER_TBIT_TYPE_PMTUD:
	      if(warts_tbit_pmtud_read(tbit, &table, buf, &i, hdr->len) != 0)
		goto err;
	      break;

	    case SCAMPER_TBIT_TYPE_NULL:
	      if(warts_tbit_null_read(tbit, buf, &i, hdr->len) != 0)
		goto err;
	      break;
	    }
	}
      else if(junk16 == WARTS_TBIT_STRUCT_APP)
	{
	  if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP)
	    {
	      if(warts_tbit_app_http_read(tbit, buf, &i, hdr->len) != 0)
		goto err;
	    }
	}

      off += junk32;
    }

  assert(off == hdr->len);
  warts_addrtable_clean(&table);
  *tbit_out = tbit;
  free(buf);
  return 0;

 err:
  warts_addrtable_clean(&table);
  if(buf != NULL) free(buf);
  if(tbit != NULL) scamper_tbit_free(tbit);
  return -1;
}
int scamper_file_warts_neighbourdisc_read(scamper_file_t *sf,
					  const warts_hdr_t *hdr,
					  scamper_neighbourdisc_t **nd_out)
{
  scamper_neighbourdisc_t *nd = NULL;
  scamper_neighbourdisc_probe_t *probe;
  warts_addrtable_t table;
  warts_state_t *state = scamper_file_getstate(sf);
  uint8_t *buf = NULL;
  uint32_t off = 0;
  uint16_t i;

  memset(&table, 0, sizeof(table));

  if(warts_read(sf, &buf, hdr->len) != 0)
    {
      goto err;
    }
  if(buf == NULL)
    {
      *nd_out = NULL;
      return 0;
    }

  if((nd = scamper_neighbourdisc_alloc()) == NULL)
    {
      goto err;
    }

  if(warts_neighbourdisc_params_read(nd,&table,state,buf,&off,hdr->len) != 0)
    {
      goto err;
    }

  if(nd->probec == 0)
    goto done;

  if(scamper_neighbourdisc_probes_alloc(nd, nd->probec) != 0)
    {
      goto err;
    }

  for(i=0; i<nd->probec; i++)
    {
      if((probe = scamper_neighbourdisc_probe_alloc()) == NULL)
	{
	  goto err;
	}
      nd->probes[i] = probe;

      if(warts_neighbourdisc_probe_read(probe, state, &table,
					buf, &off, hdr->len) != 0)
	{
	  goto err;
	}
    }

 done:
  assert(off == hdr->len);
  warts_addrtable_clean(&table);
  *nd_out = nd;
  free(buf);
  return 0;

 err:
  warts_addrtable_clean(&table);
  if(buf != NULL) free(buf);
  if(nd != NULL) scamper_neighbourdisc_free(nd);
  return -1;
}