int scamper_file_warts_ping_write(const scamper_file_t *sf, const scamper_ping_t *ping) { warts_addrtable_t table; warts_ping_reply_t *reply_state = NULL; scamper_ping_reply_t *reply; uint8_t *buf = NULL; uint8_t flags[ping_vars_mfb]; uint16_t flags_len, params_len; uint32_t len, off = 0; uint16_t reply_count; size_t size; int i, j; memset(&table, 0, sizeof(table)); /* figure out which ping data items we'll store in this record */ warts_ping_params(ping, &table, flags, &flags_len, ¶ms_len); /* length of the ping's flags, parameters, and number of reply records */ len = 8 + flags_len + 2 + params_len + 2; if((reply_count = scamper_ping_reply_count(ping)) > 0) { size = reply_count * sizeof(warts_ping_reply_t); if((reply_state = (warts_ping_reply_t *)malloc_zero(size)) == NULL) { goto err; } for(i=0, j=0; i<ping->ping_sent; i++) { for(reply=ping->ping_replies[i]; reply != NULL; reply = reply->next) { if(warts_ping_reply_state(sf, ping, reply, &reply_state[j++], &table, &len) == -1) { goto err; } } } } if((buf = malloc(len)) == NULL) { goto err; } insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_PING); if(warts_ping_params_write(ping, sf, &table, buf, &off, len, flags, flags_len, params_len) == -1) { goto err; } /* reply record count */ insert_uint16(buf, &off, len, &reply_count, NULL); /* write each ping reply record */ for(i=0; i<reply_count; i++) { warts_ping_reply_write(&reply_state[i], &table, buf, &off, len); } if(reply_state != NULL) { free(reply_state); reply_state = NULL; } assert(off == len); if(warts_write(sf, buf, len) == -1) { goto err; } warts_addrtable_clean(&table); free(buf); return 0; err: warts_addrtable_clean(&table); if(reply_state != NULL) free(reply_state); if(buf != NULL) free(buf); return -1; }
int scamper_file_warts_dealias_write(const scamper_file_t *sf, const scamper_dealias_t *dealias) { static int (*const state[])(const scamper_file_t *, const void *, warts_dealias_data_t *, warts_addrtable_t *, uint32_t *) = { warts_dealias_mercator_state, warts_dealias_ally_state, warts_dealias_radargun_state, warts_dealias_prefixscan_state, warts_dealias_bump_state, }; static void (*const write[])(const void *, const scamper_file_t *, warts_addrtable_t *, uint8_t *, uint32_t *, const uint32_t, warts_dealias_data_t *) = { warts_dealias_mercator_write, warts_dealias_ally_write, warts_dealias_radargun_write, warts_dealias_prefixscan_write, warts_dealias_bump_write, }; uint8_t *buf = NULL; uint8_t flags[dealias_vars_mfb]; uint16_t flags_len, params_len; scamper_dealias_probe_t *probe; warts_dealias_data_t data; warts_dealias_probe_t *probes = NULL; uint32_t len, len2, off = 0; size_t size; uint32_t i; warts_addrtable_t table; memset(&data, 0, sizeof(data)); memset(&table, 0, sizeof(table)); /* figure out which dealias data items we'll store in this record */ warts_dealias_params(dealias, flags, &flags_len, ¶ms_len); len = 8 + flags_len + params_len + 2; /* figure out the state that we have to allocate */ if(state[dealias->method-1](sf, dealias->data, &data, &table, &len) != 0) { goto err; } /* * figure out the state that we have to allocate to store the * probes sent (and their responses) */ if(dealias->probec > 0) { size = dealias->probec * sizeof(warts_dealias_probe_t); if((probes = (warts_dealias_probe_t *)malloc_zero(size)) == NULL) { goto err; } for(i=0; i<dealias->probec; i++) { probe = dealias->probes[i]; len2 = len; if(warts_dealias_probe_state(sf,probe,&probes[i],&table,&len2) != 0) goto err; if(len2 < len) goto err; len = len2; } } if((buf = malloc(len)) == NULL) goto err; insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_DEALIAS); if(warts_dealias_params_write(dealias, sf, buf, &off, len, flags, flags_len, params_len) != 0) { goto err; } write[dealias->method-1](dealias->data, sf, &table, buf, &off, len, &data); if(data.probedefs != NULL) free(data.probedefs); data.probedefs = NULL; if(dealias->probec > 0) { for(i=0; i<dealias->probec; i++) { probe = dealias->probes[i]; warts_dealias_probe_write(probe,sf,&table,buf,&off, len, &probes[i]); } } warts_dealias_probes_free(probes, dealias->probec); probes = NULL; assert(off == len); if(warts_write(sf, buf, len) == -1) { goto err; } warts_addrtable_clean(&table); free(buf); return 0; err: warts_addrtable_clean(&table); if(probes != NULL) warts_dealias_probes_free(probes, dealias->probec); if(data.probedefs != NULL) free(data.probedefs); if(buf != NULL) free(buf); return -1; }
int scamper_file_warts_tracelb_write(const scamper_file_t *sf, const scamper_tracelb_t *trace) { const scamper_tracelb_node_t *node; const scamper_tracelb_link_t *link; uint8_t *buf = NULL; uint32_t off = 0, len, len2; uint8_t trace_flags[tracelb_vars_mfb]; uint16_t trace_flags_len, trace_params_len; warts_tracelb_node_t *node_state = NULL; warts_tracelb_link_t *link_state = NULL; size_t size; int i; warts_addrtable_t table; /* make sure the table is nulled out */ memset(&table, 0, sizeof(table)); /* figure out which tracelb data items we'll store in this record */ warts_tracelb_params(trace, &table, trace_flags, &trace_flags_len, &trace_params_len); /* this represents the length of the trace's flags and parameters */ len = 8 + trace_flags_len + trace_params_len; if(trace_params_len != 0) len += 2; /* record the node records */ if(trace->nodec > 0) { size = trace->nodec * sizeof(warts_tracelb_node_t); if((node_state = (warts_tracelb_node_t *)malloc_zero(size)) == NULL) { goto err; } for(i=0; i<trace->nodec; i++) { len2 = len; node = trace->nodes[i]; if(warts_tracelb_node_state(sf, node, &table, &node_state[i], &len2) != 0) { goto err; } /* check for wrapping */ if(len2 < len) goto err; len = len2; } } /* record the link records */ if(trace->linkc > 0) { size = trace->linkc * sizeof(warts_tracelb_link_t); if((link_state = (warts_tracelb_link_t *)malloc_zero(size)) == NULL) { goto err; } for(i=0; i<trace->linkc; i++) { len2 = len; link = trace->links[i]; if(warts_tracelb_link_state(sf, trace, link, &link_state[i], &table, &len2) != 0) { goto err; } /* check for wrapping */ if(len2 < len) goto err; len = len2; } } if((buf = malloc_zero(len)) == NULL) { goto err; } insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_TRACELB); /* write trace params */ if(warts_tracelb_params_write(trace, sf, &table, buf, &off, len, trace_flags, trace_flags_len, trace_params_len) != 0) { goto err; } /* write trace nodes */ for(i=0; i<trace->nodec; i++) { warts_tracelb_node_write(trace->nodes[i], &node_state[i], &table, buf, &off, len); } if(node_state != NULL) { free(node_state); node_state = NULL; } /* write trace links */ for(i=0; i<trace->linkc; i++) { link = trace->links[i]; warts_tracelb_link_write(link, &link_state[i], &table, buf, &off, len); warts_tracelb_link_free(&link_state[i]); } if(link_state != NULL) { free(link_state); link_state = NULL; } assert(off == len); if(warts_write(sf, buf, off) == -1) { goto err; } warts_addrtable_clean(&table); free(buf); return 0; err: warts_addrtable_clean(&table); if(node_state != NULL) free(node_state); if(link_state != NULL) free(link_state); if(buf != NULL) free(buf); return -1; }
int scamper_file_warts_trace_write(const scamper_file_t *sf, const scamper_trace_t *trace) { scamper_trace_hop_t *hop; uint8_t *buf = NULL; uint8_t trace_flags[trace_vars_mfb]; uint16_t trace_flags_len, trace_params_len; warts_trace_hop_t *hop_state = NULL; uint16_t hop_recs; warts_trace_pmtud_t *pmtud = NULL; warts_trace_hop_t *ld_state = NULL; uint16_t ld_recs = 0; uint32_t ld_len = 0; warts_trace_dtree_t dtree_state; uint16_t u16; uint8_t u8; uint32_t off = 0, len, len2; size_t size; int i, j; warts_addrtable_t *table = NULL; memset(&dtree_state, 0, sizeof(dtree_state)); if((table = warts_addrtable_alloc_byaddr()) == NULL) goto err; /* figure out which trace data items we'll store in this record */ warts_trace_params(trace, table, trace_flags, &trace_flags_len, &trace_params_len); /* * this represents the length of the trace's flags and parameters, and the * 2-byte field that records the number of hop records that follow */ len = 8 + trace_flags_len + trace_params_len + 2; if(trace_params_len != 0) len += 2; /* for each hop, figure out what is going to be stored in this record */ if((hop_recs = scamper_trace_hop_count(trace)) > 0) { size = hop_recs * sizeof(warts_trace_hop_t); if((hop_state = (warts_trace_hop_t *)malloc_zero(size)) == NULL) { goto err; } for(i=0, j=0; i<trace->hop_count; i++) { for(hop = trace->hops[i]; hop != NULL; hop = hop->hop_next) { /* record basic hop state */ len2 = len; warts_trace_hop_state(trace,hop,&hop_state[j++],table,&len2); if(len2 < len) goto err; len = len2; } } } /* figure out how much space we need for PMTUD data, if we have it */ if(trace->pmtud != NULL) { if((pmtud = malloc_zero(sizeof(warts_trace_pmtud_t))) == NULL) goto err; if(warts_trace_pmtud_state(trace, pmtud, table) != 0) goto err; len += (2 + pmtud->len); /* 2 = size of attribute header */ } if(trace->lastditch != NULL) { /* count the number of last-ditch hop records */ ld_recs = scamper_trace_lastditch_hop_count(trace); /* allocate an array of hop state structs for the lastditch hops */ size = ld_recs * sizeof(warts_trace_hop_t); if((ld_state = (warts_trace_hop_t *)malloc_zero(size)) == NULL) goto err; /* need to record count of lastditch hops and a single zero flags byte */ ld_len = 3; /* record hop state for each lastditch reply */ for(hop = trace->lastditch, j=0; hop != NULL; hop = hop->hop_next) warts_trace_hop_state(trace, hop, &ld_state[j++], table, &ld_len); len += (2 + ld_len); /* 2 = size of attribute header */ } if(trace->dtree != NULL) { /* figure out what the structure of the dtree header looks like */ if(warts_trace_dtree_params(sf, trace, table, &dtree_state) != 0) goto err; /* 2 = size of attribute header */ len += (2 + dtree_state.len); } len += 2; /* EOF */ if((buf = malloc_zero(len)) == NULL) { goto err; } insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_TRACE); /* write trace parameters */ if(warts_trace_params_write(trace, sf, table, buf, &off, len, trace_flags, trace_flags_len, trace_params_len) == -1) { goto err; } /* hop record count */ insert_uint16(buf, &off, len, &hop_recs, NULL); /* write each traceroute hop record */ for(i=0; i<hop_recs; i++) warts_trace_hop_write(&hop_state[i], table, buf, &off, len); if(hop_state != NULL) free(hop_state); hop_state = NULL; /* write the PMTUD data */ if(pmtud != NULL) { /* write the attribute header */ u16 = WARTS_TRACE_ATTR_HDR(WARTS_TRACE_ATTR_PMTUD, pmtud->len); insert_uint16(buf, &off, len, &u16, NULL); /* write details of the pmtud measurement */ warts_trace_pmtud_write(trace, buf, &off, len, pmtud, table); warts_trace_pmtud_free(pmtud); pmtud = NULL; } /* write the last-ditch data */ if(trace->lastditch != NULL) { /* write the attribute header */ u16 = WARTS_TRACE_ATTR_HDR(WARTS_TRACE_ATTR_LASTDITCH, ld_len); insert_uint16(buf, &off, len, &u16, NULL); /* write the last-ditch flags: currently zero */ u8 = 0; insert_byte(buf, &off, len, &u8, NULL); /* write the number of hop records */ insert_uint16(buf, &off, len, &ld_recs, NULL); for(i=0; i<ld_recs; i++) warts_trace_hop_write(&ld_state[i], table, buf, &off, len); free(ld_state); ld_state = NULL; } /* write doubletree data */ if(trace->dtree != NULL) { u16 = WARTS_TRACE_ATTR_HDR(WARTS_TRACE_ATTR_DTREE, dtree_state.len); insert_uint16(buf, &off, len, &u16, NULL); /* write details of the pmtud measurement */ warts_trace_dtree_write(trace, table, buf, &off, len, &dtree_state); } /* write the end of trace attributes header */ u16 = WARTS_TRACE_ATTR_EOF; insert_uint16(buf, &off, len, &u16, NULL); assert(off == len); if(warts_write(sf, buf, len) == -1) { goto err; } warts_addrtable_free(table); free(buf); return 0; err: if(table != NULL) warts_addrtable_free(table); if(buf != NULL) free(buf); if(hop_state != NULL) free(hop_state); if(pmtud != NULL) warts_trace_pmtud_free(pmtud); if(ld_state != NULL) free(ld_state); return -1; }
/* Write data from a scamper tbit object to a warts file */ int scamper_file_warts_tbit_write(const scamper_file_t *sf, const scamper_tbit_t *tbit) { warts_addrtable_t table; warts_tbit_pkt_t *pkts = NULL; warts_tbit_pmtud_t pmtud; warts_tbit_null_t null; warts_tbit_app_http_t http; uint8_t *buf = NULL; uint8_t flags[tbit_vars_mfb]; uint16_t junk16; uint16_t flags_len, params_len; uint32_t len, i, off = 0; size_t size; memset(&table, 0, sizeof(table)); /* Set the tbit data (not including the packets) */ warts_tbit_params(tbit, &table, flags, &flags_len, ¶ms_len); len = 8 + flags_len + params_len + 2; if(tbit->pktc > 0) { /* Allocate memory for the state */ size = tbit->pktc * sizeof(warts_tbit_pkt_t); if((pkts = (warts_tbit_pkt_t *)malloc_zero(size)) == NULL) goto err; for(i=0; i<tbit->pktc; i++) warts_tbit_pkt_params(tbit->pkts[i], &pkts[i], &len); } if(tbit->data != NULL) { switch(tbit->type) { case SCAMPER_TBIT_TYPE_PMTUD: warts_tbit_pmtud_params(tbit, &table, &pmtud); len += (2 + 4 + pmtud.len); break; case SCAMPER_TBIT_TYPE_NULL: warts_tbit_null_params(tbit, &null); len += (2 + 4 + null.len); break; default: goto err; } } if(tbit->app_data != NULL) { if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP) { warts_tbit_app_http_params(tbit, &http); len += (2 + 4 + http.len); } else goto err; } /* struct eof */ len += 2; /* Allocate memory to store all of the data (including packets) */ if((buf = malloc(len)) == NULL) goto err; insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_TBIT); /* Write the tbit data (excluding packets) to the buffer */ if(warts_tbit_params_write(tbit, sf, &table, buf, &off, len, flags, flags_len, params_len) != 0) { goto err; } if(tbit->pktc > 0) { for(i=0; i<tbit->pktc; i++) warts_tbit_pkt_write(tbit->pkts[i], sf, buf, &off, len, &pkts[i]); free(pkts); pkts = NULL; } if(tbit->data != NULL) { junk16 = WARTS_TBIT_STRUCT_TYPE; insert_uint16(buf, &off, len, &junk16, NULL); switch(tbit->type) { case SCAMPER_TBIT_TYPE_PMTUD: insert_uint32(buf, &off, len, &pmtud.len, NULL); warts_tbit_pmtud_write(tbit, buf, &off, len, &table, &pmtud); break; case SCAMPER_TBIT_TYPE_NULL: insert_uint32(buf, &off, len, &null.len, NULL); warts_tbit_null_write(tbit, buf, &off, len, &null); break; default: goto err; } } if(tbit->app_data != NULL) { junk16 = WARTS_TBIT_STRUCT_APP; insert_uint16(buf, &off, len, &junk16, NULL); if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP) { insert_uint32(buf, &off, len, &http.len, NULL); warts_tbit_app_http_write(tbit, buf, &off, len, &http); } else goto err; } junk16 = WARTS_TBIT_STRUCT_EOF; insert_uint16(buf, &off, len, &junk16, NULL); assert(off == len); /* Write the whole buffer to a warts file */ if(warts_write(sf, buf, len) == -1) goto err; warts_addrtable_clean(&table); free(buf); return 0; err: warts_addrtable_clean(&table); if(pkts != NULL) free(pkts); if(buf != NULL) free(buf); return -1; }
int scamper_file_warts_neighbourdisc_write(const scamper_file_t *sf, const scamper_neighbourdisc_t *nd) { warts_addrtable_t table; warts_neighbourdisc_probe_t *probes = NULL; scamper_neighbourdisc_probe_t *probe; uint8_t *buf = NULL; uint8_t flags[neighbourdisc_vars_mfb]; uint16_t flags_len, params_len; uint32_t len, len2, off = 0; size_t size; int i; memset(&table, 0, sizeof(table)); /* figure out which neighbourdisc items we'll store in this record */ warts_neighbourdisc_params(nd, &table, flags, &flags_len, ¶ms_len); len = 8 + flags_len + params_len + 2; if(nd->probec > 0) { size = nd->probec * sizeof(warts_neighbourdisc_probe_t); if((probes = (warts_neighbourdisc_probe_t *)malloc_zero(size)) == NULL) goto err; for(i=0; i<nd->probec; i++) { probe = nd->probes[i]; len2 = len; if(warts_neighbourdisc_probe_state(sf, probe, &probes[i], &table, &len2) != 0) goto err; if(len2 < len) goto err; len = len2; } } if((buf = malloc(len)) == NULL) goto err; insert_wartshdr(buf, &off, len, SCAMPER_FILE_OBJ_NEIGHBOURDISC); if(warts_neighbourdisc_params_write(nd, sf, &table, buf, &off, len, flags, flags_len, params_len) != 0) { goto err; } if(nd->probec > 0) { for(i=0; i<nd->probec; i++) { probe = nd->probes[i]; warts_neighbourdisc_probe_write(probe, sf, &table, buf, &off, len, &probes[i]); } } warts_neighbourdisc_probes_free(probes, nd->probec); probes = NULL; assert(off == len); if(warts_write(sf, buf, len) == -1) { goto err; } warts_addrtable_clean(&table); free(buf); return 0; err: warts_addrtable_clean(&table); if(probes != NULL) warts_neighbourdisc_probes_free(probes, nd->probec); if(buf != NULL) free(buf); return -1; }