int scamper_file_warts_ping_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_ping_t **ping_out) { warts_state_t *state = scamper_file_getstate(sf); scamper_ping_t *ping = NULL; uint8_t *buf = NULL; uint32_t off = 0; uint16_t i; scamper_ping_reply_t *reply; uint16_t reply_count; warts_addrtable_t table; memset(&table, 0, sizeof(table)); if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *ping_out = NULL; return 0; } if((ping = scamper_ping_alloc()) == NULL) { goto err; } if(warts_ping_params_read(ping, state, &table, buf, &off, hdr->len) != 0) { goto err; } /* determine how many replies to read */ if(extract_uint16(buf, &off, hdr->len, &reply_count, NULL) != 0) { goto err; } /* allocate the ping_replies array */ if(scamper_ping_replies_alloc(ping, ping->ping_sent) != 0) { goto err; } /* if there are no replies, then we are done */ if(reply_count == 0) { goto done; } /* for each reply, read it and insert it into the ping structure */ for(i=0; i<reply_count; i++) { if((reply = scamper_ping_reply_alloc()) == NULL) { goto err; } if(warts_ping_reply_read(ping,reply,state,&table,buf,&off,hdr->len) != 0) { goto err; } if(scamper_ping_reply_append(ping, reply) != 0) { goto err; } } assert(off == hdr->len); done: warts_addrtable_clean(&table); *ping_out = ping; free(buf); return 0; err: warts_addrtable_clean(&table); if(buf != NULL) free(buf); if(ping != NULL) scamper_ping_free(ping); return -1; }
int scamper_file_warts_dealias_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_dealias_t **dealias_out) { static int (*const read[])(scamper_dealias_t *,warts_state_t *, warts_addrtable_t *,scamper_dealias_probedef_t **, uint8_t *, uint32_t *, uint32_t) = { warts_dealias_mercator_read, warts_dealias_ally_read, warts_dealias_radargun_read, warts_dealias_prefixscan_read, warts_dealias_bump_read, }; scamper_dealias_t *dealias = NULL; scamper_dealias_probedef_t *defs; scamper_dealias_probe_t *probe; warts_addrtable_t table; warts_state_t *state = scamper_file_getstate(sf); uint8_t *buf = NULL; uint32_t off = 0; uint32_t i; memset(&table, 0, sizeof(table)); if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *dealias_out = NULL; return 0; } if((dealias = scamper_dealias_alloc()) == NULL) { goto err; } if(warts_dealias_params_read(dealias, state, buf, &off, hdr->len) != 0) { goto err; } if(read[dealias->method-1](dealias,state,&table,&defs,buf,&off,hdr->len)!=0) goto err; if(dealias->probec == 0) goto done; if(scamper_dealias_probes_alloc(dealias, dealias->probec) != 0) { goto err; } for(i=0; i<dealias->probec; i++) { if((probe = scamper_dealias_probe_alloc()) == NULL) { goto err; } dealias->probes[i] = probe; if(warts_dealias_probe_read(probe, state, defs, &table, buf, &off, hdr->len) != 0) { goto err; } } done: assert(off == hdr->len); warts_addrtable_clean(&table); *dealias_out = dealias; free(buf); return 0; err: warts_addrtable_clean(&table); if(buf != NULL) free(buf); if(dealias != NULL) scamper_dealias_free(dealias); return -1; }
/* * warts_tracelb_read * */ int scamper_file_warts_tracelb_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_tracelb_t **trace_out) { warts_state_t *state = scamper_file_getstate(sf); scamper_tracelb_t *trace = NULL; uint8_t *buf = NULL; uint32_t i, off = 0; uint16_t *nlc = NULL, j; scamper_tracelb_node_t *node; warts_addrtable_t table; memset(&table, 0, sizeof(table)); if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *trace_out = NULL; return 0; } if((trace = scamper_tracelb_alloc()) == NULL) { goto err; } /* read the trace's parameters */ if(warts_tracelb_params_read(trace, state, &table, buf, &off, hdr->len) != 0) { goto err; } /* read the nodes */ if(trace->nodec > 0) { if(scamper_tracelb_nodes_alloc(trace, trace->nodec) != 0) { goto err; } for(i=0; i<trace->nodec; i++) { if((trace->nodes[i] = scamper_tracelb_node_alloc(NULL)) == NULL) goto err; if(warts_tracelb_node_read(trace->nodes[i], state, &table, buf, &off, hdr->len) != 0) goto err; } } /* read the links */ if(trace->linkc > 0) { if(scamper_tracelb_links_alloc(trace, trace->linkc) != 0) { goto err; } for(i=0; i<trace->linkc; i++) { if((trace->links[i] = scamper_tracelb_link_alloc()) == NULL) goto err; if(warts_tracelb_link_read(trace, trace->links[i], state, &table, buf, &off, hdr->len) != 0) goto err; } } /* don't need the buf any more */ free(buf); buf = NULL; /* * add the links to their respective nodes. */ if(trace->nodec > 0) { if((nlc = malloc_zero(sizeof(uint16_t) * trace->nodec)) == NULL) { goto err; } for(i=0; i<trace->linkc; i++) { for(j=0; j<trace->nodec; j++) { if(trace->links[i]->from == trace->nodes[j]) break; } if(j == trace->nodec) goto err; node = trace->nodes[j]; if(node->links == NULL && scamper_tracelb_node_links_alloc(node, node->linkc) != 0) goto err; if(nlc[j] == node->linkc) goto err; node->links[nlc[j]++] = trace->links[i]; } for(i=0; i<trace->nodec; i++) { if(nlc[i] != trace->nodes[i]->linkc) goto err; } free(nlc); nlc = NULL; } warts_addrtable_clean(&table); *trace_out = trace; return 0; err: warts_addrtable_clean(&table); if(buf != NULL) free(buf); if(nlc != NULL) free(nlc); if(trace != NULL) scamper_tracelb_free(trace); return -1; }
/* * 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 scamper_file_warts_tbit_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_tbit_t **tbit_out) { scamper_tbit_t *tbit = NULL; warts_addrtable_t table; warts_state_t *state = scamper_file_getstate(sf); uint8_t *buf = NULL; uint16_t junk16; uint32_t junk32; uint32_t off = 0; uint32_t i; memset(&table, 0, sizeof(table)); /* Read in the header */ if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *tbit_out = NULL; return 0; } /* Allocate space for a tbit object */ if((tbit = scamper_tbit_alloc()) == NULL) { goto err; } /* Read in the tbit data from the warts file */ if(warts_tbit_params_read(tbit, &table, state, buf, &off, hdr->len) != 0) { goto err; } switch(tbit->type) { case SCAMPER_TBIT_TYPE_PMTUD: if((tbit->data = scamper_tbit_pmtud_alloc()) == NULL) goto err; break; case SCAMPER_TBIT_TYPE_NULL: if((tbit->data = scamper_tbit_null_alloc()) == NULL) goto err; break; } /* Determine how many tbit_pkts to read */ if(tbit->pktc > 0) { /* Allocate the tbit_pkts array */ if(scamper_tbit_pkts_alloc(tbit, tbit->pktc) != 0) goto err; /* For each tbit packet, read it and insert it into the tbit structure */ for(i=0; i<tbit->pktc; i++) { tbit->pkts[i] = warts_tbit_pkt_read(state, buf, &off, hdr->len); if(tbit->pkts[i] == NULL) goto err; } } for(;;) { if(extract_uint16(buf, &off, hdr->len, &junk16, NULL) != 0) goto err; if(junk16 == WARTS_TBIT_STRUCT_EOF) break; if(extract_uint32(buf, &off, hdr->len, &junk32, NULL) != 0) goto err; i = off; if(junk16 == WARTS_TBIT_STRUCT_TYPE) { switch(tbit->type) { case SCAMPER_TBIT_TYPE_PMTUD: if(warts_tbit_pmtud_read(tbit, &table, buf, &i, hdr->len) != 0) goto err; break; case SCAMPER_TBIT_TYPE_NULL: if(warts_tbit_null_read(tbit, buf, &i, hdr->len) != 0) goto err; break; } } else if(junk16 == WARTS_TBIT_STRUCT_APP) { if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP) { if(warts_tbit_app_http_read(tbit, buf, &i, hdr->len) != 0) goto err; } } off += junk32; } assert(off == hdr->len); warts_addrtable_clean(&table); *tbit_out = tbit; free(buf); return 0; err: warts_addrtable_clean(&table); if(buf != NULL) free(buf); if(tbit != NULL) scamper_tbit_free(tbit); return -1; }
int scamper_file_warts_neighbourdisc_read(scamper_file_t *sf, const warts_hdr_t *hdr, scamper_neighbourdisc_t **nd_out) { scamper_neighbourdisc_t *nd = NULL; scamper_neighbourdisc_probe_t *probe; warts_addrtable_t table; warts_state_t *state = scamper_file_getstate(sf); uint8_t *buf = NULL; uint32_t off = 0; uint16_t i; memset(&table, 0, sizeof(table)); if(warts_read(sf, &buf, hdr->len) != 0) { goto err; } if(buf == NULL) { *nd_out = NULL; return 0; } if((nd = scamper_neighbourdisc_alloc()) == NULL) { goto err; } if(warts_neighbourdisc_params_read(nd,&table,state,buf,&off,hdr->len) != 0) { goto err; } if(nd->probec == 0) goto done; if(scamper_neighbourdisc_probes_alloc(nd, nd->probec) != 0) { goto err; } for(i=0; i<nd->probec; i++) { if((probe = scamper_neighbourdisc_probe_alloc()) == NULL) { goto err; } nd->probes[i] = probe; if(warts_neighbourdisc_probe_read(probe, state, &table, buf, &off, hdr->len) != 0) { goto err; } } done: assert(off == hdr->len); warts_addrtable_clean(&table); *nd_out = nd; free(buf); return 0; err: warts_addrtable_clean(&table); if(buf != NULL) free(buf); if(nd != NULL) scamper_neighbourdisc_free(nd); return -1; }