示例#1
0
int scamper_dealias_probe_add(scamper_dealias_t *dealias,
			      scamper_dealias_probe_t *probe)
{
  size_t size = (dealias->probec+1) * sizeof(scamper_dealias_probe_t *);
  if(realloc_wrap((void **)&dealias->probes, size) == 0)
    {
      dealias->probes[dealias->probec++] = probe;
      return 0;
    }
  return -1;
}
示例#2
0
int scamper_dealias_reply_add(scamper_dealias_probe_t *probe,
			      scamper_dealias_reply_t *reply)
{
  size_t size = (probe->replyc+1) * sizeof(scamper_dealias_reply_t *);
  if(realloc_wrap((void **)&probe->replies, size) == 0)
    {
      probe->replies[probe->replyc++] = reply;
      return 0;
    }
  return -1;
}
示例#3
0
static scamper_fd_t *fd_alloc_dm(int type, int fd, const char *file,
				 const int line)
#endif
{
  scamper_fd_t *fdn = NULL;
  size_t size;
  int i;

#ifndef DMALLOC
  if((fdn = malloc_zero(sizeof(scamper_fd_t))) == NULL)
#else
  if((fdn = malloc_zero_dm(sizeof(scamper_fd_t), file, line)) == NULL)
#endif
    {
      goto err;
    }
  fdn->type   = type;
  fdn->fd     = fd;
  fdn->refcnt = 1;

  /* set up to poll read ability */
  if((fdn->read.node = dlist_node_alloc(&fdn->read)) == NULL)
    {
      goto err;
    }
  fdn->read.fdn   = fdn;
  fdn->read.flags = SCAMPER_FD_POLL_FLAG_INACTIVE;

  /* set up to poll write ability */
  if((fdn->write.node = dlist_node_alloc(&fdn->write)) == NULL)
    {
      goto err;
    }
  fdn->write.fdn   = fdn;
  fdn->write.flags = SCAMPER_FD_POLL_FLAG_INACTIVE;

  /* store the fd in an array indexed by the fd number */
  if(fd+1 > fd_array_s)
    {
      size = sizeof(scamper_fd_t *) * (fd+1);
      if(realloc_wrap((void **)&fd_array, size) != 0)
	goto err;
      for(i=fd_array_s; i<fd+1; i++)
	fd_array[i] = NULL;
      fd_array_s = fd+1;
    }
  fd_array[fd] = fdn;

  return fdn;

 err:
  if(fdn != NULL) fd_free(fdn);
  return NULL;
}
示例#4
0
static int fds_kqueue(struct timeval *tv)
{
  scamper_fd_t *fdp;
  struct timespec ts, *tsp = NULL;
  struct kevent *kev;
  int fd, i, c;

  if((c = dlist_count(read_fds) + dlist_count(write_fds)) >= kevlistlen)
    {
      c += 8;
      if(realloc_wrap((void **)&kevlist, sizeof(struct kevent) * c) != 0)
	{
	  if(kevlistlen == 0)
	    {
	      printerror(errno, strerror, __func__, "could not alloc kevlist");
	      return -1;
	    }
	}
      else
	{
	  kevlistlen = c;
	}
    }

  if(tv != NULL)
    {
      ts.tv_sec  = tv->tv_sec;
      ts.tv_nsec = tv->tv_usec * 1000;
      tsp = &ts;
    }

  if((c = kevent(kq, NULL, 0, kevlist, kevlistlen, tsp)) == -1)
    {
      printerror(errno, strerror, __func__, "kevent failed");
      return -1;
    }

  for(i=0; i<c; i++)
    {
      kev = &kevlist[i];
      fd = kev->ident;

      if(fd < 0 || fd >= fd_array_s)
	continue;
      if((fdp = fd_array[fd]) == NULL)
	continue;
      if(kev->filter == EVFILT_READ)
	fdp->read.cb(fd, fdp->read.param);
      else if(kev->filter == EVFILT_WRITE)
	fdp->write.cb(fd, fdp->write.param);
    }

  return 0;
}
示例#5
0
int scamper_dealias_prefixscan_probedef_add(scamper_dealias_t *dealias,
					    scamper_dealias_probedef_t *def)
{
  scamper_dealias_prefixscan_t *prefixscan = dealias->data;
  size_t size;

  /* make the probedef array one bigger */
  size = sizeof(scamper_dealias_probedef_t) * (prefixscan->probedefc+1);
  if(realloc_wrap((void **)&prefixscan->probedefs, size) != 0)
    return -1;

  /* add the probedef to the array */
  memcpy(&prefixscan->probedefs[prefixscan->probedefc],
	 def, sizeof(scamper_dealias_probedef_t));

  /* update the probedef with an id, and get references to the addresses */
  def = &prefixscan->probedefs[prefixscan->probedefc];
  def->id = prefixscan->probedefc++;
  scamper_addr_use(def->src);
  scamper_addr_use(def->dst);

  return 0;
}
示例#6
0
static int fds_epoll(struct timeval *tv)
{
  int i, fd, rc, timeout;
  scamper_fd_t *fdp;
  size_t size;

  if(ep_fdc >= ep_event_c)
    {
      rc = ep_fdc + 8;
      size = sizeof(struct epoll_event) * rc;
      if(realloc_wrap((void **)&ep_events, size) != 0)
	{
	  if(ep_event_c == 0)
	    {
	      printerror(errno, strerror, __func__, "could not alloc events");
	      return -1;
	    }
	}
      else
	{
	  ep_event_c = rc;
	}
    }

  if(tv != NULL)
    {
      timeout = (tv->tv_sec * 1000) + (tv->tv_usec / 1000);
      if(timeout == 0 && tv->tv_usec != 0)
	timeout++;
    }
  else
    {
      timeout = -1;
    }

  if((rc = epoll_wait(ep, ep_events, ep_event_c, timeout)) == -1)
    {
      printerror(errno, strerror, __func__, "could not epoll_wait");
      return -1;
    }

  for(i=0; i<rc; i++)
    {
      fd = ep_events[i].data.fd;
      if(fd < 0 || fd >= fd_array_s)
	continue;

      if(ep_events[i].events & EPOLLIN)
	{
	  if((fdp = fd_array[fd]) == NULL)
	    continue;
	  fdp->read.cb(fd, fdp->read.param);
	}

      if(ep_events[i].events & EPOLLOUT)
	{
	  if((fdp = fd_array[fd]) == NULL)
	    continue;
	  fdp->write.cb(fd, fdp->write.param);
	}
    }

  return 0;
}
示例#7
0
static int fds_poll(struct timeval *tv)
{
  scamper_fd_t *fd;
  dlist_node_t *n;
  int timeout;
  int rc, count = 0, in = 0, out = 0;
  size_t size;

  n = dlist_head_node(fd_list);
  while(n != NULL)
    {
      fd = dlist_node_item(n);
      n  = dlist_node_next(n);

      /* if there is nothing using this fdn any longer, then stop polling it */
      if(fd->refcnt == 0 && fd->rc0 == NULL)
	{
	  fd_refcnt_0(fd);
	  continue;
	}

      /* don't poll an inactive fd */
      if((fd->read.flags & SCAMPER_FD_POLL_FLAG_INACTIVE) != 0 &&
	 (fd->write.flags & SCAMPER_FD_POLL_FLAG_INACTIVE) != 0)
	continue;

      if(count + 1 > poll_fdc)
	{
	  size = (count+1) * sizeof(struct pollfd);
	  if(realloc_wrap((void **)&poll_fds, size) != 0)
	    {
	      printerror(errno,strerror,__func__,"could not realloc poll_fds");
	      return -1;
	    }
	  poll_fdc = count + 1;
	}

      poll_fds[count].fd = fd->fd;
      poll_fds[count].events = 0;
      poll_fds[count].revents = 0;

      if((fd->read.flags & SCAMPER_FD_POLL_FLAG_INACTIVE) == 0)
	{
	  poll_fds[count].events |= POLLIN;
	  in++;
	}
      if((fd->write.flags & SCAMPER_FD_POLL_FLAG_INACTIVE) == 0)
	{
	  poll_fds[count].events |= POLLOUT;
	  out++;
	}

      count++;
    }

  if(tv != NULL)
    {
      timeout = (tv->tv_sec * 1000) + (tv->tv_usec / 1000);
      if(timeout == 0 && tv->tv_usec != 0)
	timeout++;
    }
  else
    {
      timeout = -1;
    }

  if((rc = poll(poll_fds, count, timeout)) < 0)
    {
      printerror(errno, strerror, __func__, "could not poll");
      return -1;
    }

  if(rc > 0)
    {
      if(in != 0)
	fds_poll_check(POLLIN, rc < in ? rc : in, count);
      if(out != 0)
	fds_poll_check(POLLOUT, rc < out ? rc : out, count);
    }

  return 0;
}
示例#8
0
/*
 * probe_build
 *
 * determine how to build the packet and call the appropriate function
 * to do so.
 */
static probe_t *probe_build(scamper_probe_t *pr)
{
  int (*build_func)(scamper_probe_t *, uint8_t *, size_t *) = NULL;
  probe_t *pt = NULL;
  size_t len;

  if(SCAMPER_ADDR_TYPE_IS_IPV4(pr->pr_ip_dst))
    {
      if((pr->pr_ip_off & IP_OFFMASK) != 0)
	build_func = scamper_ip4_frag_build;
      else if(pr->pr_ip_proto == IPPROTO_UDP)
	build_func = scamper_udp4_build;
      else if(pr->pr_ip_proto == IPPROTO_ICMP)
	build_func = scamper_icmp4_build;
      else if(pr->pr_ip_proto == IPPROTO_TCP)
	build_func = scamper_tcp4_build;
    }
  else if(SCAMPER_ADDR_TYPE_IS_IPV6(pr->pr_ip_dst))
    {
      if(pr->pr_ip_off != 0)
	build_func = scamper_ip6_frag_build;
      if(pr->pr_ip_proto == IPPROTO_UDP)
	build_func = scamper_udp6_build;
      else if(pr->pr_ip_proto == IPPROTO_ICMPV6)
	build_func = scamper_icmp6_build;
      else if(pr->pr_ip_proto == IPPROTO_TCP)
	build_func = scamper_tcp6_build;
    }

  if(build_func == NULL)
    {
      pr->pr_errno = EINVAL;
      goto err;
    }

  /* allow 16 bytes at the front of the packet for layer-2 headers */
  if(16 >= pktbuf_len)
    len = 0;
  else
    len = pktbuf_len-16;

  if(build_func(pr, pktbuf+16, &len) != 0)
    {
      /* reallocate the packet buffer */
      if(realloc_wrap((void **)&pktbuf, len+16) != 0)
	{
	  pr->pr_errno = errno;
	  goto err;
	}
      pktbuf_len = len+16;
      if(build_func(pr, pktbuf+16, &len) != 0)
	{
	  pr->pr_errno = EINVAL;
	  goto err;
	}
    }

  if((pt = malloc_zero(sizeof(probe_t))) == NULL)
    {
      pr->pr_errno = errno;
      goto err;
    }
  pt->buf     = pktbuf;
  pt->len     = len;

  return pt;

 err:
  return NULL;
}