static int do_method(void)
{
  struct timeval tv;
  char *command;

  if(slist_count(commands) == 0)
    return 0;

  gettimeofday_wrap(&tv);
  command = slist_head_pop(commands);
  write_wrap(scamper_fd, command, NULL, strlen(command));
  more--;

  if((options & OPT_DEBUG) != 0)
    fprintf(stderr, "%ld: %s", (long int)tv.tv_sec, command);

  if(lastcommand != NULL)
    free(lastcommand);
  lastcommand = command;

  if(slist_count(commands) == 0 && stdin_fd == -1 && done == 0)
    {
      write_wrap(scamper_fd, "done\n", NULL, 5);
      done = 1;
    }

  return 0;
}
Exemple #2
0
/******************************************************************************
* mailbox_deliver
*   Deliver a message to the mailbox.
*   There is a lot of arithmetic here because the compiler and
*   assembler refuse to align mailbox buffers to arbitrary powers
*   of two (which would allow a simple and neat mask-based wrap).
*   On the plus side, this way there is no alignment or size
*   restriction on the mailbox buffer. 
*******************************************************************************/
u8 mailbox_deliver(mailbox_t *box, u8 code, u8 payload_length, u8 *payload)
{
    u8 len, flags, freespace;
    if (payload_length)
    {
        len = payload_length + 2;
        code |= 0x80;
    }
    else
    {
        len = 1;
        code &= ~0x80;
    }

    flags = disable_interrupts();

    if (box->tail >= box->head)
    {        
        freespace = box->size - (box->tail - box->head);
    }
    else
    {
        freespace = box->head - box->tail;
    }

	/* If we write 1 into the last byte and increment tail,
	 * then head will equal tail but the mailbox is actually
	 * full, not empty.  Don't do this. */
        
    /* check for space.  */
    if (freespace < len )//|| freespace == 1)
    {
        restore_flags(flags);
        DEBUG("mailbox_deliver: out of room");
        return 1;   /* no room */
    }
    write_wrap(box, code);
    
    if (payload_length)
    {
        u8 i;
        write_wrap(box, payload_length);
        for(i=0; i<payload_length; i++)
        {
            write_wrap(box, payload[i]);
        }
    }
    restore_flags(flags);
    return 0;
}
Exemple #3
0
int scamper_file_text_sting_write(const scamper_file_t *sf,
				  const scamper_sting_t *sting)
{
  int      fd = scamper_file_getfd(sf);
  char     buf[192], src[64], dst[64];
  size_t   len;
  uint32_t i, txc = 0;

  snprintf(buf, sizeof(buf),
	   "sting from %s:%d to %s:%d, %d probes, %dms mean\n"
	   " data-ack count %d, holec %d\n",
	   scamper_addr_tostr(sting->src, src, sizeof(src)), sting->sport,
	   scamper_addr_tostr(sting->dst, dst, sizeof(dst)), sting->dport,
	   sting->count, sting->mean, sting->dataackc, sting->holec);

  len = strlen(buf);
  write_wrap(fd, buf, NULL, len);

  if(sting->holec > 0)
    {
      for(i=0; i<sting->pktc; i++)
	{
	  if((sting->pkts[i]->flags & SCAMPER_STING_PKT_FLAG_DATA) == 0)
	    continue;
	  txc++;

	  if(sting->pkts[i]->flags & SCAMPER_STING_PKT_FLAG_HOLE)
	    {
	      snprintf(buf, sizeof(buf), "  probe %d hole\n", txc);
	      len = strlen(buf);
	      write_wrap(fd, buf, NULL, len);
	    }
	}
    }

  return 0;
}
static int do_attach(void)
{
  char buf[256];
  size_t off = 0;

  string_concat(buf, sizeof(buf), &off, "attach");
  if((options & OPT_PRIORITY) != 0)
    string_concat(buf, sizeof(buf), &off, " priority %d", priority);
  string_concat(buf, sizeof(buf), &off, "\n");

  if(write_wrap(scamper_fd, buf, NULL, off) != 0)
    {
      fprintf(stderr, "could not attach to scamper process\n");
      return -1;
    }

  return 0;
}
int scamper_file_text_ping_write(const scamper_file_t *sf,
				 const scamper_ping_t *ping)
{
  scamper_ping_reply_t *reply;
  int       fd          = scamper_file_getfd(sf);
  off_t     off         = 0;
  uint32_t  reply_count = scamper_ping_reply_count(ping);
  char     *header      = NULL;
  size_t    header_len  = 0;
  char    **replies     = NULL;
  size_t   *reply_lens  = NULL;
  char     *stats       = NULL;
  size_t    stats_len   = 0;
  char     *str         = NULL;
  size_t    len         = 0;
  size_t    wc          = 0;
  int       ret         = -1;
  uint32_t  i,j;

  /* get current position incase trunction is required */
  if(fd != 1 && (off = lseek(fd, 0, SEEK_CUR)) == -1)
    return -1;

  /* get the header string */
  if((header = ping_header(ping)) == NULL)
    goto cleanup;
  len = (header_len = strlen(header));

  /* put together a string for each reply */
  if(reply_count > 0)
    {
      if((replies    = malloc_zero(sizeof(char *) * reply_count)) == NULL ||
	 (reply_lens = malloc_zero(sizeof(size_t) * reply_count)) == NULL)
	goto cleanup;

      for(i=0, j=0; i<ping->ping_sent; i++)
	{
	  reply = ping->ping_replies[i];
	  while(reply != NULL)
	    {
	      /* build string representation of this reply */
	      if((replies[j] = ping_reply(ping, reply)) == NULL)
		{
		  goto cleanup;
		}
	      len += (reply_lens[j] = strlen(replies[j]));
	      reply = reply->next;
	      j++;
	    }
	}
    }

  /* put together the summary stats */
  stats = ping_stats(ping);
  if(stats != NULL)
    len += (stats_len = strlen(stats));

  /* allocate a string long enough to combine the above strings */
  if((str = malloc(len)) == NULL)
    goto cleanup;

  /* combine the strings created above */
  memcpy(str+wc, header, header_len); wc += header_len;
  for(i=0; i<reply_count; i++)
    {
      memcpy(str+wc, replies[i], reply_lens[i]);
      wc += reply_lens[i];
    }

  if(stats != NULL)
    {
      memcpy(str+wc, stats, stats_len);
      wc += stats_len;
    }

  /*
   * try and write the string to disk.  if it fails, then truncate the
   * write and fail
   */
  if(write_wrap(fd, str, &wc, len) != 0)
    {
      if(fd != 1)
	{
	  if(ftruncate(fd, off) != 0)
	    goto cleanup;
	}
      goto cleanup;
    }

  ret = 0; /* we succeeded */

 cleanup:
  if(str != NULL) free(str);
  if(header != NULL) free(header);
  if(stats != NULL) free(stats);
  if(reply_lens != NULL) free(reply_lens);
  if(replies != NULL)
    {
      for(i=0; i<reply_count; i++)
	if(replies[i] != NULL)
	  free(replies[i]);
      free(replies);
    }

  return ret;
}
/*
 * do_scamperread
 *
 * the fd for the scamper process is marked as readable, so do a read
 * on it.
 */
static int do_scamperread(void)
{
  ssize_t rc;
  uint8_t uu[64];
  char   *ptr, *head;
  char    buf[512];
  void   *tmp;
  long    l;
  size_t  i, uus, linelen;

  if((rc = read(scamper_fd, buf, sizeof(buf))) > 0)
    {
      if(readbuf_len == 0)
	{
	  if((readbuf = memdup(buf, rc)) == NULL)
	    {
	      return -1;
	    }
	  readbuf_len = rc;
	}
      else
	{
	  if((tmp = realloc(readbuf, readbuf_len + rc)) != NULL)
	    {
	      readbuf = tmp;
	      memcpy(readbuf+readbuf_len, buf, rc);
	      readbuf_len += rc;
	    }
	  else return -1;
	}
    }
  else if(rc == 0)
    {
      close(scamper_fd);
      scamper_fd = -1;
    }
  else if(errno == EINTR || errno == EAGAIN)
    {
      return 0;
    }
  else
    {
      fprintf(stderr, "could not read: errno %d\n", errno);
      return -1;
    }

  /* process whatever is in the readbuf */
  if(readbuf_len == 0)
    {
      goto done;
    }

  head = readbuf;
  for(i=0; i<readbuf_len; i++)
    {
      if(readbuf[i] != '\n')
	continue;

      /* skip empty lines */
      if(head == &readbuf[i])
	{
	  head = &readbuf[i+1];
	  continue;
	}

      /* calculate the length of the line, excluding newline */
      linelen = &readbuf[i] - head;

      /* if currently decoding data, then pass it to uudecode */
      if(data_left > 0)
	{
	  uus = sizeof(uu);
	  if(uudecode_line(head, linelen, uu, &uus) != 0)
	    {
	      fprintf(stderr, "could not uudecode_line\n");
	      goto err;
	    }

	  if(uus != 0)
	    {
	      if(outfile_fd != -1)
		write_wrap(outfile_fd, uu, NULL, uus);
	      if(options & OPT_STDOUT)
		write_wrap(STDOUT_FILENO, uu, NULL, uus);
	    }

	  data_left -= (linelen + 1);
	}
      /* if the scamper process is asking for more tasks, give it more */
      else if(linelen == 4 && strncasecmp(head, "MORE", linelen) == 0)
	{
	  more++;
	}
      /* new piece of data */
      else if(linelen > 5 && strncasecmp(head, "DATA ", 5) == 0)
	{
	  l = strtol(head+5, &ptr, 10);
	  if(*ptr != '\n' || l < 1)
	    {
	      head[linelen] = '\0';
	      fprintf(stderr, "could not parse %s\n", head);
	      goto err;
	    }

	  data_left = l;
	}
      /* feedback letting us know that the command was accepted */
      else if(linelen >= 2 && strncasecmp(head, "OK", 2) == 0)
	{
	  /* err, nothing to do */
	}
      /* feedback letting us know that the command was not accepted */
      else if(linelen >= 3 && strncasecmp(head, "ERR", 3) == 0)
	{
	  if(lastcommand != NULL)
	    {
	      fprintf(stderr, "command not accepted: %s", lastcommand);
	      more++;
	    }
	  else
	    {
	      goto err;
	    }
	}
      else
	{
	  head[linelen] = '\0';
	  fprintf(stderr, "unknown response '%s'\n", head);
	  goto err;
	}

      head = &readbuf[i+1];
    }

  if(head != &readbuf[readbuf_len])
    {
      readbuf_len = &readbuf[readbuf_len] - head;
      ptr = memdup(head, readbuf_len);
      free(readbuf);
      readbuf = ptr;
    }
  else
    {
      readbuf_len = 0;
      free(readbuf);
      readbuf = NULL;
    }

 done:
  return 0;

 err:
  return -1;
}
static int do_stdinread(void)
{
  ssize_t rc;
  char   *ptr, *head, *command;
  char    buf[512];
  void   *tmp;
  size_t  i, linelen;

  if((rc = read(stdin_fd, buf, sizeof(buf))) > 0)
    {
      if(stdinbuf_len == 0)
	{
	  if((stdinbuf = memdup(buf, rc)) == NULL)
	    {
	      return -1;
	    }
	  stdinbuf_len = rc;
	}
      else
	{
	  if((tmp = realloc(stdinbuf, stdinbuf_len + rc)) != NULL)
	    {
	      stdinbuf = tmp;
	      memcpy(stdinbuf+stdinbuf_len, buf, rc);
	      stdinbuf_len += rc;
	    }
	  else return -1;
	}
    }
  else if(rc == 0)
    {
      if(done == 0)
	write_wrap(scamper_fd, "done\n", NULL, 5);
      done = 1;
      stdin_fd = -1;
      return 0;
    }
  else if(errno == EINTR || errno == EAGAIN)
    {
      return 0;
    }
  else
    {
      fprintf(stderr, "could not read: errno %d\n", errno);
      return -1;
    }

  /* process whatever is in the stdinbuf */
  if(stdinbuf_len == 0)
    {
      goto done;
    }

  head = stdinbuf;
  for(i=0; i<stdinbuf_len; i++)
    {
      if(stdinbuf[i] != '\n')
	continue;

      /* calculate the length of the line, including newline */
      linelen = &stdinbuf[i] - head + 1;

      /* skip empty lines */
      if(linelen == 1 || head[0] == '#')
	{
	  head = &stdinbuf[i+1];
	  continue;
	}

      /* make a copy of the command string */
      if((command = malloc(linelen+1)) == NULL)
	{
	  fprintf(stderr, "could not malloc command\n");
	  goto err;
	}
      memcpy(command, head, linelen);
      command[linelen] = '\0';

      /* put the command string on the list of things to do */
      if(slist_tail_push(commands, command) == NULL)
	{
	  fprintf(stderr, "could not push command onto list\n");
	  free(command);
	  goto err;
	}

      head = &stdinbuf[i+1];
    }

  if(head != &stdinbuf[stdinbuf_len])
    {
      stdinbuf_len = &stdinbuf[stdinbuf_len] - head;
      ptr = memdup(head, stdinbuf_len);
      free(stdinbuf);
      stdinbuf = ptr;
    }
  else
    {
      stdinbuf_len = 0;
      free(stdinbuf);
      stdinbuf = NULL;
    }

 done:
  return 0;

 err:
  return -1;
}
int scamper_file_csv_trace_write(const scamper_file_t *sf,
				  const scamper_trace_t *trace) {

  scamper_trace_hop_t *hop;
  int fd = scamper_file_getfd(sf);
  size_t wc, len, off = 0;
  off_t foff = 0;
  char *str = NULL, *header = NULL, **hops = NULL;
  int i, j, hopc = 0, rc = -1;

  if(fd != STDOUT_FILENO && (foff = lseek(fd, 0, SEEK_CUR)) == -1)
    return -1;

  if((header = header_tostr()) == NULL) goto cleanup;
  len = strlen(header);

  for(i=trace->firsthop-1; i<trace->hop_count; i++)
    for(hop = trace->hops[i]; hop != NULL; hop = hop->hop_next)
      hopc++;

  if(hopc > 0) {
    if((hops = malloc_zero(sizeof(char *) * hopc)) == NULL) goto cleanup;
    for(i=trace->firsthop-1, j=0; i<trace->hop_count; i++) {
      for(hop = trace->hops[i]; hop != NULL; hop = hop->hop_next) {
        if((hops[j] = hop_tostr(trace, hop)) == NULL) goto cleanup;
        len += strlen(hops[j]);
	      j++;
	    }
    }
  }

  len += 1; /* \0 */

  if((str = malloc(len)) == NULL)
    goto cleanup;

  string_concat(str, len, &off, "%s", header);

  if(hopc > 0) {
    for(j=0; j<hopc; j++)
      string_concat(str, len, &off, "%s", hops[j]);
  }

  assert(off+1 == len);

  if(write_wrap(fd, str, &wc, off) != 0) {
    if(fd != STDOUT_FILENO) {
      if(ftruncate(fd, foff) != 0) goto cleanup;
    }
    goto cleanup;
  }

  rc = 0; /* we succeeded */

 cleanup:
  if(hops != NULL) {
      for(i=0; i<hopc; i++)
        if(hops[i] != NULL)
          free(hops[i]);
      free(hops);
  }
  if(header != NULL) free(header);
  if(str != NULL) free(str);

  return rc;
}