static void tracepair_free(tracepair_t *pair) { int i; for(i=0; i<filec; i++) if(pair->traces[i] != NULL) scamper_trace_free(pair->traces[i]); free(pair); return; }
static int write_obj(uint16_t type, void *data) { /* write the object out */ switch(type) { case SCAMPER_FILE_OBJ_TRACELB: if(scamper_file_write_tracelb(outfile, data) != 0) return -1; scamper_tracelb_free(data); break; case SCAMPER_FILE_OBJ_TRACE: if(scamper_file_write_trace(outfile, data) != 0) return -1; scamper_trace_free(data); break; case SCAMPER_FILE_OBJ_PING: if(scamper_file_write_ping(outfile, data) != 0) return -1; scamper_ping_free(data); break; case SCAMPER_FILE_OBJ_DEALIAS: if(scamper_file_write_dealias(outfile, data) != 0) return -1; scamper_dealias_free(data); break; case SCAMPER_FILE_OBJ_CYCLE_START: if(scamper_file_write_cycle_start(outfile, data) != 0) return -1; scamper_cycle_free(data); break; case SCAMPER_FILE_OBJ_CYCLE_STOP: if(scamper_file_write_cycle_stop(outfile, data) != 0) return -1; scamper_cycle_free(data); break; default: fprintf(stderr, "unhandled data object 0x%04x\n", type); break; } return 0; }
/* * warts_trace_read * */ int scamper_file_warts_trace_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_trace_t **trace_out) { warts_state_t *state = scamper_file_getstate(sf); scamper_trace_t *trace = NULL; uint8_t *buf = NULL; uint32_t i, off = 0; scamper_trace_hop_t *hops = NULL; scamper_trace_hop_t *hop; uint16_t count; uint8_t max_ttl; uint8_t type; uint16_t len; uint16_t u16; warts_addrtable_t *table = NULL; if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *trace_out = NULL; return 0; } if((trace = scamper_trace_alloc()) == NULL) { goto err; } if((table = warts_addrtable_alloc_byid()) == NULL) goto err; /* read the trace's parameters */ if(warts_trace_params_read(trace, state, table, buf, &off, hdr->len) != 0) { goto err; } /* * the next two bytes tell us how many scamper_hops to read out of trace * if we did not get any responses, we are done. */ if(extract_uint16(buf, &off, hdr->len, &count, NULL) != 0) { goto err; } /* read all the hop records */ if(warts_trace_hops_read(&hops,state,table,buf,&off,hdr->len,count) != 0) goto err; /* work out the maximum ttl probed with that got a response */ max_ttl = 0; for(i=0, hop = hops; i < count; i++) { if(hop->hop_probe_ttl > max_ttl) max_ttl = hop->hop_probe_ttl; hop = hop->hop_next; } /* * if the hop_count field was provided in the file, then * make sure it makes sense based on the hop data we've just scanned */ if(trace->hop_count != 0) { if(trace->hop_count < max_ttl) goto err; if(trace->hop_count > 255) goto err; } else { trace->hop_count = max_ttl; } /* allocate enough hops to string the trace together */ if(scamper_trace_hops_alloc(trace, trace->hop_count) == -1) { goto err; } if(hops == NULL) { assert(count == 0); goto done; } /* * now loop through the hops array stored in this procedure * and assemble the responses into trace->hops. */ trace->hops[hops->hop_probe_ttl-1] = hop = hops; while(hop->hop_next != NULL) { if(hop->hop_probe_ttl != hop->hop_next->hop_probe_ttl) { i = hop->hop_next->hop_probe_ttl-1; trace->hops[i] = hop->hop_next; hop->hop_next = NULL; hop = trace->hops[i]; } else hop = hop->hop_next; } hops = NULL; for(;;) { if(extract_uint16(buf, &off, hdr->len, &u16, NULL) != 0) goto err; if(u16 == WARTS_TRACE_ATTR_EOF) break; type = WARTS_TRACE_ATTR_HDR_TYPE(u16); len = WARTS_TRACE_ATTR_HDR_LEN(u16); if(type == WARTS_TRACE_ATTR_PMTUD) { i = off; if(warts_trace_pmtud_read(trace,state,table,buf,&i,hdr->len) != 0) goto err; } else if(type == WARTS_TRACE_ATTR_LASTDITCH) { i = off; if(warts_trace_lastditch_read(trace, state, table, buf, &i, hdr->len) != 0) goto err; } else if(type == WARTS_TRACE_ATTR_DTREE) { i = off; if(warts_trace_dtree_read(trace,state,table,buf,&i,hdr->len) != 0) goto err; } off += len; } done: warts_addrtable_free(table); free(buf); *trace_out = trace; return 0; err: if(table != NULL) warts_addrtable_free(table); if(hops != NULL) free(hops); if(buf != NULL) free(buf); if(trace != NULL) scamper_trace_free(trace); return -1; }
int main(int argc, char *argv[]) { uint16_t types[] = { SCAMPER_FILE_OBJ_CYCLE_START, SCAMPER_FILE_OBJ_CYCLE_STOP, SCAMPER_FILE_OBJ_PING, SCAMPER_FILE_OBJ_TRACE, SCAMPER_FILE_OBJ_DEALIAS, SCAMPER_FILE_OBJ_TBIT, }; scamper_file_t *in, *out; scamper_file_filter_t *filter; char **files = NULL; int filec; uint16_t type; void *data; int i; if((out = scamper_file_openfd(STDOUT_FILENO, NULL, 'w', "json")) == NULL) { fprintf(stderr, "could not associate stdout\n"); return -1; } filter = scamper_file_filter_alloc(types, sizeof(types)/sizeof(uint16_t)); if(filter == NULL) { fprintf(stderr, "could not allocate filter\n"); return -1; } filec = argc - 1; if(filec > 0) files = argv + 1; for(i=0; i<=filec; i++) { if(filec == 0) { if((in = scamper_file_openfd(STDIN_FILENO,"-",'r',"warts")) == NULL) { fprintf(stderr, "could not use stdin\n"); return -1; } } else if(i < filec) { if((in = scamper_file_open(files[i], 'r', NULL)) == NULL) { fprintf(stderr, "could not open %s: %s\n", files[i], strerror(errno)); return -1; } } else break; while(scamper_file_read(in, filter, &type, (void *)&data) == 0) { if(data == NULL) break; /* EOF */ if(scamper_file_write_obj(out, type, data) != 0) return -1; if(type == SCAMPER_FILE_OBJ_PING) scamper_ping_free(data); else if(type == SCAMPER_FILE_OBJ_TRACE) scamper_trace_free(data); else if(type == SCAMPER_FILE_OBJ_DEALIAS) scamper_dealias_free(data); else if(type == SCAMPER_FILE_OBJ_TBIT) scamper_tbit_free(data); } scamper_file_close(in); } scamper_file_filter_free(filter); scamper_file_close(out); return 0; }