Exemple #1
0
static void warts_trace_pmtud_write(const scamper_trace_t *trace,
				    uint8_t *buf, uint32_t *off, uint32_t len,
				    warts_trace_pmtud_t *state,
				    warts_addrtable_t *table)
{
  warts_param_writer_t handlers[] = {
    {&trace->pmtud->ifmtu,  (wpw_t)insert_uint16, NULL},
    {&trace->pmtud->pmtu,   (wpw_t)insert_uint16, NULL},
    {&trace->pmtud->outmtu, (wpw_t)insert_uint16, NULL},
    {&trace->pmtud->ver,    (wpw_t)insert_byte,   NULL},
    {&trace->pmtud->notec,  (wpw_t)insert_byte,   NULL},
  };
  const int handler_cnt = sizeof(handlers)/sizeof(warts_param_writer_t);
  uint16_t u16;
  uint8_t u8;

  warts_params_write(buf, off, len, state->flags, state->flags_len,
		     state->params_len, handlers, handler_cnt);

  /* write the number of hop records */
  insert_uint16(buf, off, len, &state->hopc, NULL);

  /* write the hop records */
  for(u16=0; u16<state->hopc; u16++)
    warts_trace_hop_write(&state->hops[u16], table, buf, off, len);

  /* write the notes */
  for(u8=0; u8<trace->pmtud->notec; u8++)
    warts_trace_pmtud_n_write(trace->pmtud->notes[u8], buf, off, len,
			      &state->notes[u8]);

  return;
}
static void insert_dealias_prefixscan_xs(uint8_t *buf, uint32_t *off,
					 const uint32_t len,
					 const scamper_dealias_prefixscan_t *p,
					 void *param)
{
  uint16_t i;

  i = htons(p->xc);
  insert_uint16(buf, off, len, &i, NULL);

  for(i=0; i<p->xc; i++)
    insert_addr(buf, off, len, p->xs[i], param);

  return;
}
int scamper_file_warts_ping_write(const scamper_file_t *sf,
				  const scamper_ping_t *ping)
{
  warts_addrtable_t table;
  warts_ping_reply_t *reply_state = NULL;
  scamper_ping_reply_t *reply;
  uint8_t *buf = NULL;
  uint8_t  flags[ping_vars_mfb];
  uint16_t flags_len, params_len;
  uint32_t len, off = 0;
  uint16_t reply_count;
  size_t   size;
  int      i, j;

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

  /* figure out which ping data items we'll store in this record */
  warts_ping_params(ping, &table, flags, &flags_len, &params_len);

  /* length of the ping's flags, parameters, and number of reply records */
  len = 8 + flags_len + 2 + params_len + 2;

  if((reply_count = scamper_ping_reply_count(ping)) > 0)
    {
      size = reply_count * sizeof(warts_ping_reply_t);
      if((reply_state = (warts_ping_reply_t *)malloc_zero(size)) == NULL)
	{
	  goto err;
	}

      for(i=0, j=0; i<ping->ping_sent; i++)
	{
	  for(reply=ping->ping_replies[i]; reply != NULL; reply = reply->next)
	    {
	      if(warts_ping_reply_state(sf, ping, reply, &reply_state[j++],
					&table, &len) == -1)
		{
		  goto err;
		}
	    }
	}
    }

  if((buf = malloc(len)) == NULL)
    {
      goto err;
    }

  insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_PING);

  if(warts_ping_params_write(ping, sf, &table, buf, &off, len,
			     flags, flags_len, params_len) == -1)
    {
      goto err;
    }

  /* reply record count */
  insert_uint16(buf, &off, len, &reply_count, NULL);

  /* write each ping reply record */
  for(i=0; i<reply_count; i++)
    {
      warts_ping_reply_write(&reply_state[i], &table, buf, &off, len);
    }
  if(reply_state != NULL)
    {
      free(reply_state);
      reply_state = NULL;
    }

  assert(off == len);

  if(warts_write(sf, buf, len) == -1)
    {
      goto err;
    }

  warts_addrtable_clean(&table);
  free(buf);
  return 0;

 err:
  warts_addrtable_clean(&table);
  if(reply_state != NULL) free(reply_state);
  if(buf != NULL) free(buf);
  return -1;
}
Exemple #4
0
int scamper_file_warts_trace_write(const scamper_file_t *sf,
				   const scamper_trace_t *trace)
{
  scamper_trace_hop_t *hop;
  uint8_t             *buf = NULL;
  uint8_t              trace_flags[trace_vars_mfb];
  uint16_t             trace_flags_len, trace_params_len;
  warts_trace_hop_t   *hop_state = NULL;
  uint16_t             hop_recs;
  warts_trace_pmtud_t *pmtud = NULL;
  warts_trace_hop_t   *ld_state = NULL;
  uint16_t             ld_recs = 0;
  uint32_t             ld_len = 0;
  warts_trace_dtree_t  dtree_state;
  uint16_t             u16;
  uint8_t              u8;
  uint32_t             off = 0, len, len2;
  size_t               size;
  int                  i, j;
  warts_addrtable_t   *table = NULL;

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

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

  /* figure out which trace data items we'll store in this record */
  warts_trace_params(trace, table,
		     trace_flags, &trace_flags_len, &trace_params_len);

  /*
   * this represents the length of the trace's flags and parameters, and the
   * 2-byte field that records the number of hop records that follow
   */
  len = 8 + trace_flags_len + trace_params_len + 2;
  if(trace_params_len != 0) len += 2;

  /* for each hop, figure out what is going to be stored in this record */
  if((hop_recs = scamper_trace_hop_count(trace)) > 0)
    {
      size = hop_recs * sizeof(warts_trace_hop_t);
      if((hop_state = (warts_trace_hop_t *)malloc_zero(size)) == NULL)
	{
	  goto err;
	}

      for(i=0, j=0; i<trace->hop_count; i++)
	{
	  for(hop = trace->hops[i]; hop != NULL; hop = hop->hop_next)
	    {
	      /* record basic hop state */
	      len2 = len;
	      warts_trace_hop_state(trace,hop,&hop_state[j++],table,&len2);
	      if(len2 < len)
		goto err;
	      len = len2;
	    }
	}
    }

  /* figure out how much space we need for PMTUD data, if we have it */
  if(trace->pmtud != NULL)
    {
      if((pmtud = malloc_zero(sizeof(warts_trace_pmtud_t))) == NULL)
	goto err;

      if(warts_trace_pmtud_state(trace, pmtud, table) != 0)
	goto err;

      len += (2 + pmtud->len); /* 2 = size of attribute header */
    }

  if(trace->lastditch != NULL)
    {
      /* count the number of last-ditch hop records */
      ld_recs = scamper_trace_lastditch_hop_count(trace);

      /* allocate an array of hop state structs for the lastditch hops */
      size = ld_recs * sizeof(warts_trace_hop_t);
      if((ld_state = (warts_trace_hop_t *)malloc_zero(size)) == NULL)
	goto err;

      /* need to record count of lastditch hops and a single zero flags byte */
      ld_len = 3;

      /* record hop state for each lastditch reply */
      for(hop = trace->lastditch, j=0; hop != NULL; hop = hop->hop_next)
	warts_trace_hop_state(trace, hop, &ld_state[j++], table, &ld_len);

      len += (2 + ld_len); /* 2 = size of attribute header */
    }

  if(trace->dtree != NULL)
    {
      /* figure out what the structure of the dtree header looks like */
      if(warts_trace_dtree_params(sf, trace, table, &dtree_state) != 0)
	goto err;

      /* 2 = size of attribute header */
      len += (2 + dtree_state.len);
    }

  len += 2; /* EOF */

  if((buf = malloc_zero(len)) == NULL)
    {
      goto err;
    }

  insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_TRACE);

  /* write trace parameters */
  if(warts_trace_params_write(trace, sf, table, buf, &off, len, trace_flags,
			      trace_flags_len, trace_params_len) == -1)
    {
      goto err;
    }

  /* hop record count */
  insert_uint16(buf, &off, len, &hop_recs, NULL);

  /* write each traceroute hop record */
  for(i=0; i<hop_recs; i++)
    warts_trace_hop_write(&hop_state[i], table, buf, &off, len);
  if(hop_state != NULL)
    free(hop_state);
  hop_state = NULL;

  /* write the PMTUD data */
  if(pmtud != NULL)
    {
      /* write the attribute header */
      u16 = WARTS_TRACE_ATTR_HDR(WARTS_TRACE_ATTR_PMTUD, pmtud->len);
      insert_uint16(buf, &off, len, &u16, NULL);

      /* write details of the pmtud measurement */
      warts_trace_pmtud_write(trace, buf, &off, len, pmtud, table);

      warts_trace_pmtud_free(pmtud);
      pmtud = NULL;
    }

  /* write the last-ditch data */
  if(trace->lastditch != NULL)
    {
      /* write the attribute header */
      u16 = WARTS_TRACE_ATTR_HDR(WARTS_TRACE_ATTR_LASTDITCH, ld_len);
      insert_uint16(buf, &off, len, &u16, NULL);

      /* write the last-ditch flags: currently zero */
      u8 = 0;
      insert_byte(buf, &off, len, &u8, NULL);

      /* write the number of hop records */
      insert_uint16(buf, &off, len, &ld_recs, NULL);

      for(i=0; i<ld_recs; i++)
	warts_trace_hop_write(&ld_state[i], table, buf, &off, len);

      free(ld_state);
      ld_state = NULL;
    }

  /* write doubletree data */
  if(trace->dtree != NULL)
    {
      u16 = WARTS_TRACE_ATTR_HDR(WARTS_TRACE_ATTR_DTREE, dtree_state.len);
      insert_uint16(buf, &off, len, &u16, NULL);

      /* write details of the pmtud measurement */
      warts_trace_dtree_write(trace, table, buf, &off, len, &dtree_state);
    }

  /* write the end of trace attributes header */
  u16 = WARTS_TRACE_ATTR_EOF;
  insert_uint16(buf, &off, len, &u16, NULL);

  assert(off == len);

  if(warts_write(sf, buf, len) == -1)
    {
      goto err;
    }

  warts_addrtable_free(table);
  free(buf);
  return 0;

 err:
  if(table != NULL) warts_addrtable_free(table);
  if(buf != NULL) free(buf);
  if(hop_state != NULL) free(hop_state);
  if(pmtud != NULL) warts_trace_pmtud_free(pmtud);
  if(ld_state != NULL) free(ld_state);
  return -1;
}
/* Write data from a scamper tbit object to a warts file */
int scamper_file_warts_tbit_write(const scamper_file_t *sf,
				  const scamper_tbit_t *tbit)
{
  warts_addrtable_t table;
  warts_tbit_pkt_t *pkts = NULL;
  warts_tbit_pmtud_t pmtud;
  warts_tbit_null_t null;
  warts_tbit_app_http_t http;
  uint8_t *buf = NULL;
  uint8_t  flags[tbit_vars_mfb];
  uint16_t junk16;
  uint16_t flags_len, params_len;
  uint32_t len, i, off = 0;
  size_t size;

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

  /* Set the tbit data (not including the packets) */
  warts_tbit_params(tbit, &table, flags, &flags_len, &params_len);
  len = 8 + flags_len + params_len + 2;

  if(tbit->pktc > 0)
    {
      /* Allocate memory for the state */
      size = tbit->pktc * sizeof(warts_tbit_pkt_t);
      if((pkts = (warts_tbit_pkt_t *)malloc_zero(size)) == NULL)
	goto err;

      for(i=0; i<tbit->pktc; i++)
	warts_tbit_pkt_params(tbit->pkts[i], &pkts[i], &len);
    }

  if(tbit->data != NULL)
    {
      switch(tbit->type)
	{
	case SCAMPER_TBIT_TYPE_PMTUD:
	  warts_tbit_pmtud_params(tbit, &table, &pmtud);
	  len += (2 + 4 + pmtud.len);
	  break;

	case SCAMPER_TBIT_TYPE_NULL:
	  warts_tbit_null_params(tbit, &null);
	  len += (2 + 4 + null.len);
	  break;

	default:
	  goto err;
	}
    }

  if(tbit->app_data != NULL)
    {
      if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP)
	{
	  warts_tbit_app_http_params(tbit, &http);
	  len += (2 + 4 + http.len);
	}
      else goto err;
    }

  /* struct eof */
  len += 2;

  /* Allocate memory to store all of the data (including packets) */
  if((buf = malloc(len)) == NULL)
    goto err;
  insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_TBIT);

  /* Write the tbit data (excluding packets) to the buffer */
  if(warts_tbit_params_write(tbit, sf, &table, buf, &off, len,
			     flags, flags_len, params_len) != 0)
    {
      goto err;
    }

  if(tbit->pktc > 0)
    {
      for(i=0; i<tbit->pktc; i++)
	warts_tbit_pkt_write(tbit->pkts[i], sf, buf, &off, len, &pkts[i]);
      free(pkts); pkts = NULL;
    }

  if(tbit->data != NULL)
    {
      junk16 = WARTS_TBIT_STRUCT_TYPE;
      insert_uint16(buf, &off, len, &junk16, NULL);

      switch(tbit->type)
	{
	case SCAMPER_TBIT_TYPE_PMTUD:
	  insert_uint32(buf, &off, len, &pmtud.len, NULL);
	  warts_tbit_pmtud_write(tbit, buf, &off, len, &table, &pmtud);
	  break;

	case SCAMPER_TBIT_TYPE_NULL:
	  insert_uint32(buf, &off, len, &null.len, NULL);
	  warts_tbit_null_write(tbit, buf, &off, len, &null);
	  break;

	default:
	  goto err;
	}
    }

  if(tbit->app_data != NULL)
    {
      junk16 = WARTS_TBIT_STRUCT_APP;
      insert_uint16(buf, &off, len, &junk16, NULL);

      if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP)
	{
	  insert_uint32(buf, &off, len, &http.len, NULL);
	  warts_tbit_app_http_write(tbit, buf, &off, len, &http);
	}
      else goto err;
    }

  junk16 = WARTS_TBIT_STRUCT_EOF;
  insert_uint16(buf, &off, len, &junk16, NULL);

  assert(off == len);

  /* Write the whole buffer to a warts file */
  if(warts_write(sf, buf, len) == -1)
    goto err;

  warts_addrtable_clean(&table);
  free(buf);
  return 0;

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