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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* * 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; }