static int sort_cat_fill(heap_t *heap, sort_struct_t *s) { int i = s->file; if(scamper_file_read(infiles[i], filter, &s->type, &s->data) == 0) { /* EOF */ if(s->data == NULL) { scamper_file_close(infiles[i]); infiles[i] = NULL; return 0; } switch(s->type) { case SCAMPER_FILE_OBJ_TRACELB: timeval_cpy(&s->tv, &((scamper_tracelb_t *)s->data)->start); break; case SCAMPER_FILE_OBJ_TRACE: timeval_cpy(&s->tv, &((scamper_trace_t *)s->data)->start); break; case SCAMPER_FILE_OBJ_PING: timeval_cpy(&s->tv, &((scamper_ping_t *)s->data)->start); break; case SCAMPER_FILE_OBJ_DEALIAS: timeval_cpy(&s->tv, &((scamper_dealias_t *)s->data)->start); break; case SCAMPER_FILE_OBJ_TBIT: timeval_cpy(&s->tv, &((scamper_tbit_t *)s->data)->start); break; case SCAMPER_FILE_OBJ_NEIGHBOURDISC: timeval_cpy(&s->tv, &((scamper_neighbourdisc_t *)s->data)->start); break; case SCAMPER_FILE_OBJ_STING: timeval_cpy(&s->tv, &((scamper_sting_t *)s->data)->start); break; case SCAMPER_FILE_OBJ_CYCLE_START: s->tv.tv_sec = ((scamper_cycle_t *)s->data)->start_time; s->tv.tv_usec = 0; break; case SCAMPER_FILE_OBJ_CYCLE_STOP: s->tv.tv_sec = ((scamper_cycle_t *)s->data)->stop_time; s->tv.tv_usec = 1000000; break; } if(heap_insert(heap, s) == NULL) { return -1; } } else return -1; return 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; }