static void outfile_free(scamper_outfile_t *sof) { assert(sof != NULL); if(sof->name != NULL && sof->sf != NULL) scamper_debug(__func__, "name %s fd %d", sof->name, scamper_file_getfd(sof->sf)); if(sof->name != NULL) { splaytree_remove_item(outfiles, sof); free(sof->name); } if(sof->sf != NULL) { scamper_file_close(sof->sf); } free(sof); return; }
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 scamper_outfile_t *outfile_alloc(char *name, scamper_file_t *sf) { scamper_outfile_t *sof = NULL; if((sof = malloc_zero(sizeof(scamper_outfile_t))) == NULL) { printerror(errno, strerror, __func__, "could not malloc sof"); goto err; } sof->sf = sf; sof->refcnt = 1; if((sof->name = strdup(name)) == NULL) { printerror(errno, strerror, __func__, "could not strdup"); goto err; } if(splaytree_insert(outfiles, sof) == NULL) { printerror(errno, strerror, __func__, "could not insert"); goto err; } scamper_debug(__func__, "name %s fd %d", name, scamper_file_getfd(sf)); return sof; err: if(sof != NULL) { if(sof->name != NULL) free(sof->name); free(sof); } return NULL; }
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; }
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; }
int scamper_file_text_tbit_write(const scamper_file_t *sf, const scamper_tbit_t *tbit) { scamper_tbit_pkt_t *pkt; scamper_tbit_app_http_t *http; char buf[131072]; char src[64], dst[64], tmp[256], ipid[12], fstr[32], tfstr[32], sack[128]; struct timeval diff; uint32_t i; uint32_t seq, ack, server_isn, client_isn, off, id, u32; uint16_t len, u16, datalen; uint8_t proto, flags, iphlen, tcphlen, mf, ecn, u8, *ptr; size_t soff = 0, toff; int frag; int fd = scamper_file_getfd(sf); ipid[0] = '\0'; string_concat(buf, sizeof(buf), &soff, "tbit from %s to %s\n server-mss %d, result: %s\n", scamper_addr_tostr(tbit->src, src, sizeof(src)), scamper_addr_tostr(tbit->dst, dst, sizeof(dst)), tbit->server_mss, scamper_tbit_res2str(tbit, tmp, sizeof(tmp))); if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP && tbit->app_data != NULL) { http = tbit->app_data; string_concat(buf, sizeof(buf), &soff, " app: http"); if(http->host != NULL && http->file != NULL) string_concat(buf, sizeof(buf), &soff, ", url: http://%s%s", http->host, http->file); else if(http->host != NULL) string_concat(buf, sizeof(buf), &soff, ", url: http://%s", http->host); else string_concat(buf, sizeof(buf), &soff, ", file: %s", http->file); string_concat(buf, sizeof(buf), &soff, "\n"); } client_isn = 0; server_isn = 0; for(i=0; i<tbit->pktc; i++) { pkt = tbit->pkts[i]; frag = 0; mf = 0; id = 0; off = 0; if((pkt->data[0] >> 4) == 4) { iphlen = (pkt->data[0] & 0xf) * 4; len = bytes_ntohs(pkt->data+2); proto = pkt->data[9]; ecn = pkt->data[1] & 0x3; if(pkt->data[6] & 0x20) mf = 1; id = bytes_ntohs(pkt->data+4); off = (bytes_ntohs(pkt->data+6) & 0x1fff) * 8; if(mf != 0 || off != 0) frag = 1; snprintf(ipid, sizeof(ipid), " %04x", bytes_ntohs(pkt->data+4)); } else if((pkt->data[0] >> 4) == 6) { iphlen = 40; len = bytes_ntohs(pkt->data+4) + iphlen; proto = pkt->data[6]; ecn = (pkt->data[1] & 0x30) >> 4; for(;;) { switch(proto) { case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: case IPPROTO_ROUTING: proto = pkt->data[iphlen+0]; iphlen += (pkt->data[iphlen+1] * 8) + 8; continue; case IPPROTO_FRAGMENT: if(pkt->data[iphlen+3] & 0x1) mf = 1; off = (bytes_ntohs(pkt->data+iphlen+2) & 0xfff8); id = bytes_ntohl(pkt->data+iphlen+4); proto = pkt->data[iphlen+0]; iphlen += 8; frag = 1; continue; } break; } } else { continue;