Beispiel #1
0
/** Implements the end_interval function of the plugin API */
int bgpcorsaro_pacifier_end_interval(bgpcorsaro_t *bgpcorsaro,
				 bgpcorsaro_interval_t *int_end)
{
  struct bgpcorsaro_pacifier_state_t *state = STATE(bgpcorsaro);

  bgpcorsaro_io_write_interval_end(bgpcorsaro, state->outfile, int_end);

  /* if we are rotating, now is when we should do it */
  if(bgpcorsaro_is_rotate_interval(bgpcorsaro))
    {
      /* leave the current file to finish draining buffers */
      assert(state->outfile != NULL);

      /* move on to the next output pointer */
      state->outfile_n = (state->outfile_n+1) %
	OUTFILE_POINTERS;

      if(state->outfile_p[state->outfile_n] != NULL)
	{
	  /* we're gonna have to wait for this to close */
	  wandio_wdestroy(state->outfile_p[state->outfile_n]);
	  state->outfile_p[state->outfile_n] =  NULL;
	}

      state->outfile = NULL;
    }


  struct timeval tv;
  gettimeofday_wrap(&tv);
  
  int expected_time = 0;
  int diff = 0;

  if(state->adaptive == 0)
    {
      diff = state->wait - (tv.tv_sec - state->tv_start);
    }
  else
    {
      expected_time = state->tv_first_time + state->intervals *  state->wait;
      diff = expected_time - tv.tv_sec ;
    }
  // if the end interval is faster than "the wait" time
  // then we wait for the remaining seconds
  if(diff > 0)
    {
      // fprintf(stderr, "\tWaiting: %d s\n", diff);
      sleep(diff);
      gettimeofday_wrap(&tv);
    }  
  state->tv_start = tv.tv_sec;

  // fprintf(stderr, "END INTERVAL TIME: %d \n", state->tv_start);
  return 0;
}
Beispiel #2
0
/*
 * scamper_fds_poll
 *
 * the money function: this function polls the file descriptors held by
 * scamper.  for each fd with an event, it calls the callback registered
 * with the fd.
 */
int scamper_fds_poll(struct timeval *timeout)
{
  scamper_fd_t *fdn;
  struct timeval tv;

  /*
   * if there are fds that can be reaped, then do so.
   * if there are fds left over after, use that to guide the select timeout.
   */
  if(dlist_count(refcnt_0) > 0)
    {
      gettimeofday_wrap(&tv);

      while((fdn = (scamper_fd_t *)dlist_head_get(refcnt_0)) != NULL)
	{
	  assert(fdn->refcnt == 0);

	  if(timeval_cmp(&fdn->tv, &tv) > 0)
	    break;

	  fd_close(fdn);
	  fd_free(fdn);
	}

      if(fdn != NULL)
	{
	  timeval_diff_tv(&tv, &tv, &fdn->tv);
	  if(timeout == NULL || timeval_cmp(&tv, timeout) < 0)
	    timeout = &tv;
	}
    }

  return pollfunc(timeout);
}
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;
}
Beispiel #4
0
static char *timestamp_str(char *buf, const size_t len)
{
  struct timeval  tv;
  struct tm      *tm;
  int             ms;
  time_t          t;

  buf[0] = '\0';
  gettimeofday_wrap(&tv);
  t = tv.tv_sec;
  if((tm = localtime(&t)) == NULL) return buf;

  ms = tv.tv_usec / 1000;
  snprintf(buf, len, "[%02d:%02d:%02d:%03d] ",
	   tm->tm_hour, tm->tm_min, tm->tm_sec, ms);

  return buf;
}
Beispiel #5
0
static void probe_dlhdr_cb(scamper_dlhdr_t *dlhdr)
{
  probe_t *pr = dlhdr->param;
  scamper_fd_t *fd = NULL;
  scamper_dl_t *dl = NULL;
  uint8_t *pkt;

  if(dlhdr->error != 0)
    {
      pr->error = dlhdr->error;
      goto err;
    }

  assert(dlhdr->len < 16);
  pkt = pr->buf+16-dlhdr->len;
  if(dlhdr->len > 0)
    memcpy(pkt, dlhdr->buf, dlhdr->len);

  if((fd = scamper_task_fd_dl(pr->task, pr->rt->ifindex)) == NULL)
    {
      pr->error = EINVAL;
      goto err;
    }

  if(pr->buf == pktbuf)
    gettimeofday_wrap(&pr->tv);
  dl = scamper_fd_dl_get(fd);
  if(scamper_dl_tx(dl, pkt, dlhdr->len + pr->len) == -1)
    {
      pr->error = errno;
      goto err;
    }
  pr->mode = PROBE_MODE_TX;
  goto done;

 err:
  pr->mode = PROBE_MODE_ERR;

 done:
  if(pr->anc != NULL)
    probe_free(pr);
  return;
}
Beispiel #6
0
/*
 * fd_refcnt_0
 *
 * this function is called whenever a fdn with a refcnt field of zero is
 * found.
 */
static void fd_refcnt_0(scamper_fd_t *fdn)
{
  /*
   * if the fd is in a list that is currently locked, then it can't be
   * removed just yet
   */
  if(dlist_islocked(fd_list) != 0 ||
     (fdn->read.list  != NULL && dlist_islocked(fdn->read.list)  != 0) ||
     (fdn->write.list != NULL && dlist_islocked(fdn->write.list) != 0))
    {
      return;
    }

  /*
   * if this is a private fd and the reference count has reached zero,
   * then the scamper_fd structure can be freed up completely now
   */
  if(fdn->type == SCAMPER_FD_TYPE_PRIVATE)
    {
      fd_free(fdn);
      return;
    }

  /* if it is not possible to put the node on a list, just free it */
  if((fdn->rc0 = dlist_tail_push(refcnt_0, fdn)) == NULL)
    {
      fd_close(fdn);
      fd_free(fdn);
      return;
    }

  /*
   * set this fd to be closed in ten seconds unless something else comes
   * along and wants to use it.
   */
  gettimeofday_wrap(&fdn->tv);
  fdn->tv.tv_sec += 10;

  return;
}
Beispiel #7
0
/** Implements the start_interval function of the plugin API */
int bgpcorsaro_pacifier_start_interval(bgpcorsaro_t *bgpcorsaro,
				       bgpcorsaro_interval_t *int_start)
{
  struct bgpcorsaro_pacifier_state_t *state = STATE(bgpcorsaro);

  if(state->outfile == NULL)
    {
      if((
	  state->outfile_p[state->outfile_n] =
	  bgpcorsaro_io_prepare_file(bgpcorsaro,
				     PLUGIN(bgpcorsaro)->name,
				     int_start)) == NULL)
	{
	  bgpcorsaro_log(__func__, bgpcorsaro, "could not open %s output file",
			 PLUGIN(bgpcorsaro)->name);
	  return -1;
	}
      state->outfile = state->
	outfile_p[state->outfile_n];
    }

  bgpcorsaro_io_write_interval_start(bgpcorsaro, state->outfile, int_start);

  struct timeval tv;

  if(state->tv_start == 0)
    {
      gettimeofday_wrap(&tv);
      state->tv_start = tv.tv_sec;
      state->tv_first_time = state->tv_start;
    }

  // a new interval is starting
  state->intervals++;
  
  // fprintf(stderr, "START INTERVAL TIME: %d \n", state->tv_start);

  return 0;
}
Beispiel #8
0
static int addr2mac_init_linux()
{
  struct nlmsghdr   *nlmsg;
  struct ndmsg      *ndmsg;
  struct rtattr     *rta, *tb[NDA_MAX];
  struct sockaddr_nl snl;
  struct msghdr      msg;
  struct iovec       iov;
  struct timeval     tv;
  pid_t              pid;
  uint8_t            buf[16384];
  ssize_t            ssize;
  ssize_t            len;
  int                rlen;
  int                fd = -1;
  void              *ip, *mac;
  int                iptype;

  pid = getpid();

  memset(buf, 0, sizeof(buf));
  nlmsg = (struct nlmsghdr *)buf;
  nlmsg->nlmsg_len   = NLMSG_LENGTH(sizeof(struct ndmsg));
  nlmsg->nlmsg_type  = RTM_GETNEIGH;
  nlmsg->nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
  nlmsg->nlmsg_seq   = 0;
  nlmsg->nlmsg_pid   = pid;

  ndmsg = NLMSG_DATA(nlmsg);
  ndmsg->ndm_family = AF_UNSPEC;

  if((fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) == -1)
    {
      printerror(errno, strerror, __func__, "could not open netlink");
      goto err;
    }

  len = nlmsg->nlmsg_len;
  if((ssize = send(fd, buf, len, 0)) < len)
    {
      if(ssize == -1)
	{
	  printerror(errno, strerror, __func__, "could not send netlink");
	}
      goto err;
    }

  for(;;)
    {
      iov.iov_base = buf;
      iov.iov_len = sizeof(buf);

      msg.msg_name = &snl;
      msg.msg_namelen = sizeof(snl);
      msg.msg_iov = &iov;
      msg.msg_iovlen = 1;
      msg.msg_control = NULL;
      msg.msg_controllen = 0;
      msg.msg_flags = 0;

      if((len = recvmsg(fd, &msg, 0)) == -1)
	{
	  if(errno == EINTR) continue;
	  printerror(errno, strerror, __func__, "could not recvmsg");
	  goto err;
	}

      gettimeofday_wrap(&tv);

      nlmsg = (struct nlmsghdr *)buf;
      while(NLMSG_OK(nlmsg, len))
	{
	  if(nlmsg->nlmsg_pid != pid || nlmsg->nlmsg_seq != 0)
	    {
	      goto skip;
	    }

	  if(nlmsg->nlmsg_type == NLMSG_DONE)
	    {
	      goto done;
	    }

	  if(nlmsg->nlmsg_type == NLMSG_ERROR)
	    {
	      scamper_debug(__func__, "nlmsg error");
	      goto err;
	    }

	  /* get current neighbour entries only */
	  if(nlmsg->nlmsg_type != RTM_NEWNEIGH)
	    {
	      goto skip;
	    }

	  /* make sure the address is reachable */
	  ndmsg = NLMSG_DATA(nlmsg);
	  if((ndmsg->ndm_state & NUD_REACHABLE) == 0)
	    {
	      goto skip;
	    }

	  /* make sure we can process this address type */
	  switch(ndmsg->ndm_family)
	    {
	    case AF_INET:
	      iptype = SCAMPER_ADDR_TYPE_IPV4;
	      break;

	    case AF_INET6:
	      iptype = SCAMPER_ADDR_TYPE_IPV6;
	      break;

	    default:
	      goto skip;
	    }

	  /* fill a table with parameters from the payload */
	  memset(tb, 0, sizeof(tb));
	  rlen = nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(struct ndmsg));
	  for(rta = NDA_RTA(ndmsg); RTA_OK(rta,rlen); rta = RTA_NEXT(rta,rlen))
	    {
	      if(rta->rta_type >= NDA_MAX)
		continue;
	      tb[rta->rta_type] = rta;
	    }

	  /*
	   * skip if we don't have a destination IP address, or if
	   * we don't have an ethernet mac address
	   */
	  if(tb[NDA_DST] == NULL ||
	     tb[NDA_LLADDR] == NULL || RTA_PAYLOAD(tb[NDA_LLADDR]) != 6)
	    {
	      goto skip;
	    }

	  ip = RTA_DATA(tb[NDA_DST]);
	  mac = RTA_DATA(tb[NDA_LLADDR]);

	  addr2mac_add(ndmsg->ndm_ifindex, iptype, ip, mac, tv.tv_sec+600);

	skip:
	  nlmsg = NLMSG_NEXT(nlmsg, len);
	}
    }

 done:
  close(fd);
  return 0;

 err:
  close(fd);
  return -1;
}
Beispiel #9
0
/*
 * scamper_probe_send
 *
 * this meta-function is responsible for
 *  1. sending a probe
 *  2. handling any error condition incurred when sending the probe
 *  3. recording details of the probe with the trace's state
 */
int scamper_probe(scamper_probe_t *probe)
{
  int (*send_func)(scamper_probe_t *) = NULL;
  int (*build_func)(scamper_probe_t *, uint8_t *, size_t *) = NULL;
  size_t pad, len;
  uint8_t *buf;

  probe->pr_errno = 0;
  probe_print(probe);

  /* determine which function scamper should use to build or send the probe */
  if(probe->pr_ip_dst->type == SCAMPER_ADDR_TYPE_IPV4)
    {
      if((probe->pr_ip_off & IP_OFFMASK) != 0)
	{
	  build_func = scamper_ip4_frag_build;
	}
      else if(probe->pr_ip_proto == IPPROTO_UDP)
	{
	  send_func = scamper_udp4_probe;
	  build_func = scamper_udp4_build;
	}
      else if(probe->pr_ip_proto == IPPROTO_TCP)
	{
	  build_func = scamper_tcp4_build;
	  if(probe->pr_fd != -1)
	    send_func = scamper_tcp4_probe;
	}
      else if(probe->pr_ip_proto == IPPROTO_ICMP)
	{
	  send_func = scamper_icmp4_probe;
	  build_func = scamper_icmp4_build;
	}
    }
  else if(probe->pr_ip_dst->type == SCAMPER_ADDR_TYPE_IPV6)
    {
      if(probe->pr_ip_off != 0)
	{
	  build_func = scamper_ip6_frag_build;
	}
      else if(probe->pr_ip_proto == IPPROTO_UDP)
	{
	  send_func = scamper_udp6_probe;
	  build_func = scamper_udp6_build;
	}
      else if(probe->pr_ip_proto == IPPROTO_TCP)
	{
	  build_func = scamper_tcp6_build;
	}
      else if(probe->pr_ip_proto == IPPROTO_ICMPV6)
	{
	  send_func = scamper_icmp6_probe;
	  build_func = scamper_icmp6_build;
	}
    }

  /* if we're not using the datalink to send the packet, then send it now */
  if(probe->pr_dl == NULL)
    {
      if(send_func != NULL)
	return send_func(probe);
      probe->pr_errno = EINVAL;
      return -1;
    }

  /* if the header type is not known (we cannot build it) then bail */
  if(build_func == NULL)
    {
      probe->pr_errno = EINVAL;
      return -1;
    }

  /*
   * determine a suitable value for the length parameter for passing
   * to build_func.  to do so we also need to calculate the number of pad
   * bytes to put at the front of the packet buffer so that the IP layer
   * is properly aligned for the architecture
   */
  pad = PAD(probe->pr_dl_len);
  if(pad + probe->pr_dl_len >= pktbuf_len)
    len = 0;
  else
    len = pktbuf_len - pad - probe->pr_dl_len;

  /*
   * try building the probe.  if it returns -1, then hopefully the len field
   * will supply a clue as to what it should be
   */
  if(build_func(probe, pktbuf + pad + probe->pr_dl_len, &len) != 0)
    {
      assert(pktbuf_len < pad + probe->pr_dl_len + len);

      /* reallocate the packet buffer */
      len += pad + probe->pr_dl_len;
      if((buf = realloc(pktbuf, len)) == NULL)
	{
	  probe->pr_errno = errno;
	  printerror(errno, strerror, __func__, "could not realloc");
	  return -1;
	}
      pktbuf     = buf;
      pktbuf_len = len;

      len = pktbuf_len - pad - probe->pr_dl_len;
      if(build_func(probe, pktbuf + pad + probe->pr_dl_len, &len) != 0)
	{
	  probe->pr_errno = EINVAL;
	  return -1;
	}
    }

  /* add the datalink header size back to the length field */
  len += probe->pr_dl_len;

  /* pre-pend the datalink header, if there is one */
  if(probe->pr_dl_len > 0)
    memcpy(pktbuf+pad, probe->pr_dl_buf, probe->pr_dl_len);

  gettimeofday_wrap(&probe->pr_tx);
  if(scamper_dl_tx(probe->pr_dl, pktbuf+pad, len) == -1)
    {
      probe->pr_errno = errno;
      return -1;
    }

  probe->pr_tx_raw = pktbuf + pad + probe->pr_dl_len;
  probe->pr_tx_rawlen = len - probe->pr_dl_len;
  return 0;
}
Beispiel #10
0
int scamper_probe_task(scamper_probe_t *pr, scamper_task_t *task)
{
  probe_t *pt = NULL;
  scamper_fd_t *icmp = NULL;
  scamper_fd_t *fd;
  int spoof = 0;
  uint16_t sp;
  void *src = NULL;
  int dl = 0;

  probe_print(pr);

  if((pr->pr_flags & SCAMPER_PROBE_FLAG_SPOOF) != 0)
    spoof = 1;

  /* get an ICMP socket to listen for responses */
  if(SCAMPER_ADDR_TYPE_IS_IPV4(pr->pr_ip_dst))
    {
      if(spoof == 0)
	{
	  src = pr->pr_ip_src->addr;
	  if((icmp = scamper_task_fd_icmp4(task, src)) == NULL)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	}
    }
  else if(SCAMPER_ADDR_TYPE_IS_IPV6(pr->pr_ip_dst))
    {
      if(spoof == 0)
	{
	  src = pr->pr_ip_src->addr;
	  if((icmp = scamper_task_fd_icmp6(task, src)) == NULL)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	}
    }
  else
    {
      scamper_debug(__func__, "missing destination address");
      pr->pr_errno = EINVAL;
      goto err;
    }

  /*
   * even though many operating systems allow the use of RAW TCP sockets to
   * send TCP probes, we still need to be able to receive TCP responses.
   * so we use a datalink socket to both send and receive TCP probes rather
   * than open both a socket to send and another to receive.
   */
  if(dl == 0 && pr->pr_ip_proto == IPPROTO_TCP)
    dl = 1;
  else if(dl == 0 && ipid_dl != 0 && SCAMPER_PROBE_IS_IPID(pr))
    dl = 1;
  else if(dl == 0 && (pr->pr_flags & SCAMPER_PROBE_FLAG_NOFRAG))
    dl = 1;
  else if(dl == 0 && spoof != 0)
    dl = 1;

  if(dl != 0)
    {
      if((pt = probe_build(pr)) == NULL)
	{
	  pr->pr_errno = errno;
	  goto err;
	}
      pt->task = task;
      pt->mode = PROBE_MODE_RT;
      pt->rt = scamper_route_alloc(pr->pr_ip_dst, pt, probe_route_cb);
      if(pt->rt == NULL)
	{
	  pr->pr_errno = errno;
	  goto err;
	}

#ifndef _WIN32
      if((pt->rtsock = scamper_task_fd_rtsock(task)) == NULL)
	{
	  pr->pr_errno = errno;
	  goto err;
	}
      if(scamper_rtsock_getroute(pt->rtsock, pt->rt) != 0)
	{
	  pr->pr_errno = errno;
	  goto err;
	}
#else
      if(scamper_rtsock_getroute(pt->rt) != 0)
	{
	  pr->pr_errno = errno;
	  goto err;
	}
#endif

      if(pt->mode == PROBE_MODE_ERR)
	{
	  pr->pr_errno = pt->error;
	  goto err;
	}

      if(pt->mode != PROBE_MODE_TX)
	{
	  if((pt->buf = memdup(pktbuf, pt->len + 16)) == NULL)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	  if((pt->anc = scamper_task_anc_add(task, pt, probe_free_cb)) == NULL)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	  gettimeofday_wrap(&pr->pr_tx);
	}
      else
	{
	  timeval_cpy(&pr->pr_tx, &pt->tv);
	  probe_free(pt);
	}
      return 0;
    }
  else if(SCAMPER_ADDR_TYPE_IS_IPV4(pr->pr_ip_dst))
    {
      if(pr->pr_ip_proto == IPPROTO_UDP)
	{
	  sp = pr->pr_udp_sport;
	  if((fd = scamper_task_fd_udp4(task, src, sp)) == NULL)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	  pr->pr_fd = scamper_fd_fd_get(fd);
	  if(scamper_udp4_probe(pr) != 0)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	}
      else if(pr->pr_ip_proto == IPPROTO_ICMP)
	{
	  pr->pr_fd = scamper_fd_fd_get(icmp);
	  if(scamper_icmp4_probe(pr) != 0)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	}
      else
	{
	  scamper_debug(__func__, "unhandled protocol %d", pr->pr_ip_proto);
	  pr->pr_errno = EINVAL; /* actually a bug in the caller */
	  goto err;
	}
    }
  else if(SCAMPER_ADDR_TYPE_IS_IPV6(pr->pr_ip_dst))
    {
      if(pr->pr_ip_proto == IPPROTO_UDP)
	{
	  sp = pr->pr_udp_sport;
      	  if((fd = scamper_task_fd_udp6(task, src, sp)) == NULL)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	  pr->pr_fd = scamper_fd_fd_get(fd);
	  if(scamper_udp6_probe(pr) != 0)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	}
      else if(pr->pr_ip_proto == IPPROTO_ICMPV6)
	{
	  pr->pr_fd = scamper_fd_fd_get(icmp);
	  if(scamper_icmp6_probe(pr) != 0)
	    {
	      pr->pr_errno = errno;
	      goto err;
	    }
	}
      else
	{
	  pr->pr_errno = EINVAL; /* actually a bug in the caller */
	  goto err;
	}
    }
  else
    {
      pr->pr_errno = EINVAL;
      goto err;
    }

  return 0;

 err:
  printerror(pr->pr_errno, strerror, __func__, "could not probe");
  if(pt != NULL)
    probe_free(pt);
  return -1;
}