static int warts_tracelb_params_read(scamper_tracelb_t *trace, warts_state_t *state, warts_addrtable_t *table, uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&trace->list, (wpr_t)extract_list, state}, {&trace->cycle, (wpr_t)extract_cycle, state}, {&trace->src, (wpr_t)extract_addr_gid, state}, {&trace->dst, (wpr_t)extract_addr_gid, state}, {&trace->start, (wpr_t)extract_timeval, NULL}, {&trace->sport, (wpr_t)extract_uint16, NULL}, {&trace->dport, (wpr_t)extract_uint16, NULL}, {&trace->probe_size, (wpr_t)extract_uint16, NULL}, {&trace->type, (wpr_t)extract_byte, NULL}, {&trace->firsthop, (wpr_t)extract_byte, NULL}, {&trace->wait_timeout, (wpr_t)extract_byte, NULL}, {&trace->wait_probe, (wpr_t)extract_byte, NULL}, {&trace->attempts, (wpr_t)extract_byte, NULL}, {&trace->confidence, (wpr_t)extract_byte, NULL}, {&trace->tos, (wpr_t)extract_byte, NULL}, {&trace->nodec, (wpr_t)extract_uint16, NULL}, {&trace->linkc, (wpr_t)extract_uint16, NULL}, {&trace->probec, (wpr_t)extract_uint32, NULL}, {&trace->probec_max, (wpr_t)extract_uint32, NULL}, {&trace->gaplimit, (wpr_t)extract_byte, NULL}, {&trace->src, (wpr_t)extract_addr, table}, {&trace->dst, (wpr_t)extract_addr, table}, {&trace->userid, (wpr_t)extract_uint32, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); return warts_params_read(buf, off, len, handlers, handler_cnt); }
static int warts_neighbourdisc_probe_read(scamper_neighbourdisc_probe_t *pr, warts_state_t *state, warts_addrtable_t *table, uint8_t *buf, uint32_t *off, uint32_t len) { scamper_neighbourdisc_reply_t *reply; uint16_t i; warts_param_reader_t handlers[] = { {&pr->tx, (wpr_t)extract_timeval, NULL}, {&pr->rxc, (wpr_t)extract_uint16, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; if(pr->rxc == 0) return 0; if(scamper_neighbourdisc_replies_alloc(pr, pr->rxc) != 0) return -1; for(i=0; i<pr->rxc; i++) { if((reply = scamper_neighbourdisc_reply_alloc()) == NULL) return -1; pr->rxs[i] = reply; if(warts_neighbourdisc_reply_read(reply,state,table,buf,off,len) != 0) return -1; } return 0; }
static int warts_trace_pmtud_n_read(const scamper_trace_pmtud_t *pmtud, scamper_trace_pmtud_n_t *note, const uint8_t *buf, uint32_t *off, uint32_t len) { scamper_trace_hop_t *hop; uint16_t u16 = 0; warts_param_reader_t handlers[] = { {¬e->type, (wpr_t)extract_byte, NULL}, {¬e->nhmtu, (wpr_t)extract_uint16, NULL}, {&u16, (wpr_t)extract_uint16, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); uint32_t o = *off; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; if(flag_isset(&buf[o], WARTS_TRACE_PMTUD_N_HOP)) { hop = pmtud->hops; while(u16 > 0) { if(hop == NULL) break; hop = hop->hop_next; u16--; } if(hop == NULL) return -1; note->hop = hop; } return 0; }
static int warts_trace_dtree_read(scamper_trace_t *trace, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { scamper_addr_t *lss_stop = NULL, *gss_stop = NULL; uint8_t firsthop = 0, flags = 0; char *lss = NULL; warts_param_reader_t handlers[] = { {&lss_stop, (wpr_t)extract_addr_gid, state}, {&gss_stop, (wpr_t)extract_addr_gid, state}, {&firsthop, (wpr_t)extract_byte, NULL}, {&lss_stop, (wpr_t)extract_addr, table}, {&gss_stop, (wpr_t)extract_addr, table}, {&lss, (wpr_t)extract_string, NULL}, {&flags, (wpr_t)extract_byte, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(scamper_trace_dtree_alloc(trace) != 0 || warts_params_read(buf, off, len, handlers, handler_cnt) != 0) { if(lss_stop != NULL) scamper_addr_free(lss_stop); if(gss_stop != NULL) scamper_addr_free(gss_stop); if(lss != NULL) free(lss); return -1; } trace->dtree->lss_stop = lss_stop; trace->dtree->gss_stop = gss_stop; trace->dtree->firsthop = firsthop; trace->dtree->lss = lss; trace->dtree->flags = flags; return 0; }
static int warts_dealias_mercator_read(scamper_dealias_t *dealias, warts_state_t *state, warts_addrtable_t *table, scamper_dealias_probedef_t **def, uint8_t *buf, uint32_t *off, uint32_t len) { scamper_dealias_mercator_t *mercator; uint8_t attempts = 0; uint8_t wait_timeout = 0; warts_param_reader_t handlers[] = { {&attempts, (wpr_t)extract_byte, NULL}, {&wait_timeout, (wpr_t)extract_byte, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(scamper_dealias_mercator_alloc(dealias) != 0) return -1; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; mercator = dealias->data; mercator->attempts = attempts; mercator->wait_timeout = wait_timeout; if(warts_dealias_probedef_read(&mercator->probedef, state, table, buf, off, len) != 0) { return -1; } *def = &mercator->probedef; return 0; }
static int warts_tbit_app_http_read(scamper_tbit_t *tbit, const uint8_t *buf, uint32_t *off, uint32_t len) { scamper_tbit_app_http_t *http; char *host = NULL, *file = NULL; warts_param_reader_t handlers[] = { {&host, (wpr_t)extract_string, NULL}, {&file, (wpr_t)extract_string, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) goto err; if((http = scamper_tbit_app_http_alloc(host, file)) == NULL) goto err; if(host != NULL) { free(host); host = NULL; } if(file != NULL) { free(file); file = NULL; } tbit->app_data = http; return 0; err: if(host != NULL) free(host); if(file != NULL) free(file); return -1; }
static int warts_trace_lastditch_read(scamper_trace_t *trace, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { scamper_trace_hop_t *hops; uint16_t count; if(warts_params_read(buf, off, len, NULL, 0) != 0) goto err; if(extract_uint16(buf, off, len, &count, NULL) != 0) goto err; if(count != 0) { if(warts_trace_hops_read(&hops,state,table,buf,off,len,count) != 0) goto err; trace->lastditch = hops; } return 0; err: return -1; }
static scamper_tbit_pkt_t *warts_tbit_pkt_read(warts_state_t *state, uint8_t *buf, uint32_t *off, uint32_t len) { scamper_tbit_pkt_t *pkt = NULL; uint8_t dir, *data = NULL; struct timeval tv; uint16_t plen; warts_param_reader_t handlers[] = { {&dir, (wpr_t)extract_byte, NULL}, {&tv, (wpr_t)extract_timeval, NULL}, {&plen, (wpr_t)extract_uint16, NULL}, {&data, (wpr_t)extract_bytes_ptr, &plen}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0 || (pkt = scamper_tbit_pkt_alloc(dir, data, plen, &tv)) == NULL) goto err; return pkt; err: if(pkt != NULL) scamper_tbit_pkt_free(pkt); return NULL; }
static int warts_tbit_pmtud_read(scamper_tbit_t *tbit, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { scamper_tbit_pmtud_t *pmtud = tbit->data; scamper_addr_t *ptbsrc = NULL; uint16_t mtu = 0; uint8_t ptb_retx = 0; uint8_t options = 0; warts_param_reader_t handlers[] = { {&mtu, (wpr_t)extract_uint16, NULL}, {&ptb_retx, (wpr_t)extract_byte, NULL}, {&options, (wpr_t)extract_byte, NULL}, {&ptbsrc, (wpr_t)extract_addr, table}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) goto err; pmtud->mtu = mtu; pmtud->ptb_retx = ptb_retx; pmtud->options = options; pmtud->ptbsrc = ptbsrc; tbit->data = pmtud; return 0; err: return -1; }
static int warts_tracelb_probeset_read(scamper_tracelb_probeset_t *set, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&set->probec, (wpr_t)extract_uint16, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); uint16_t i; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; if(set->probec > 0) { if(scamper_tracelb_probeset_probes_alloc(set, set->probec) != 0) return -1; for(i=0; i<set->probec; i++) { if((set->probes[i] = scamper_tracelb_probe_alloc()) == NULL || warts_tracelb_probe_read(set->probes[i], state, table, buf, off, len) != 0) { return -1; } } } return 0; }
static int warts_neighbourdisc_params_read(scamper_neighbourdisc_t *nd, warts_addrtable_t *table, warts_state_t *state, uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&nd->list, (wpr_t)extract_list, state}, {&nd->cycle, (wpr_t)extract_cycle, state}, {&nd->userid, (wpr_t)extract_uint32, NULL}, {&nd->ifname, (wpr_t)extract_string, NULL}, {&nd->start, (wpr_t)extract_timeval, NULL}, {&nd->method, (wpr_t)extract_byte, NULL}, {&nd->wait, (wpr_t)extract_uint16, NULL}, {&nd->flags, (wpr_t)extract_byte, NULL}, {&nd->attempts, (wpr_t)extract_uint16, NULL}, {&nd->replyc, (wpr_t)extract_uint16, NULL}, {&nd->src_ip, (wpr_t)extract_addr, table}, {&nd->src_mac, (wpr_t)extract_addr, table}, {&nd->dst_ip, (wpr_t)extract_addr, table}, {&nd->dst_mac, (wpr_t)extract_addr, table}, {&nd->probec, (wpr_t)extract_uint16, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); return warts_params_read(buf, off, len, handlers, handler_cnt); }
static int warts_dealias_reply_read(scamper_dealias_reply_t *reply, warts_state_t *state, warts_addrtable_t *table, uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&reply->src, (wpr_t)extract_addr_gid, state}, {&reply->rx, (wpr_t)extract_timeval, NULL}, {&reply->ipid, (wpr_t)extract_uint16, NULL}, {&reply->ttl, (wpr_t)extract_byte, NULL}, {reply, (wpr_t)extract_dealias_reply_icmptc, NULL}, {&reply->icmp_q_ip_ttl, (wpr_t)extract_byte, NULL}, {reply, (wpr_t)extract_dealias_reply_icmpext, NULL}, {&reply->proto, (wpr_t)extract_byte, NULL}, {&reply->tcp_flags, (wpr_t)extract_byte, NULL}, {&reply->src, (wpr_t)extract_addr, table}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); uint32_t o = *off; int i; if((i = warts_params_read(buf, off, len, handlers, handler_cnt)) != 0) return i; if(flag_isset(&buf[o], WARTS_DEALIAS_REPLY_PROTO) == 0) { if(reply->src->type == SCAMPER_ADDR_TYPE_IPV4) reply->proto = IPPROTO_ICMP; else reply->proto = IPPROTO_ICMPV6; } return i; }
static int warts_dealias_probedef_read(scamper_dealias_probedef_t *p, warts_state_t *state, warts_addrtable_t *table, uint8_t *buf,uint32_t *off,uint32_t len) { uint8_t bytes[4]; uint16_t bytes_len = 4; uint16_t u16; uint8_t tcp_flags = 0; uint16_t icmpid = 0; warts_param_reader_t handlers[] = { {&p->dst, (wpr_t)extract_addr_gid, state}, {&p->src, (wpr_t)extract_addr_gid, state}, {&p->id, (wpr_t)extract_uint32, NULL}, {&p->method, (wpr_t)extract_byte, NULL}, {&p->ttl, (wpr_t)extract_byte, NULL}, {&p->tos, (wpr_t)extract_byte, NULL}, {bytes, (wpr_t)extract_bytes, &bytes_len}, {&tcp_flags, (wpr_t)extract_byte, NULL}, {&icmpid, (wpr_t)extract_uint16, NULL}, {&p->dst, (wpr_t)extract_addr, table}, {&p->src, (wpr_t)extract_addr, table}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_ICMP(p)) { p->un.icmp.type = bytes[0]; p->un.icmp.code = bytes[1]; memcpy(&u16, bytes+2, 2); p->un.icmp.csum = ntohs(u16); p->un.icmp.id = icmpid; } else if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_TCP(p)) { memcpy(&u16, bytes+0, 2); p->un.tcp.sport = ntohs(u16); memcpy(&u16, bytes+2, 2); p->un.tcp.dport = ntohs(u16); p->un.tcp.flags = tcp_flags; } else if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_UDP(p)) { memcpy(&u16, bytes+0, 2); p->un.udp.sport = ntohs(u16); memcpy(&u16, bytes+2, 2); p->un.udp.dport = ntohs(u16); } else { return -1; } return 0; }
static int warts_dealias_prefixscan_read(scamper_dealias_t *dealias, warts_state_t *state, warts_addrtable_t *table, scamper_dealias_probedef_t **defs, uint8_t *buf, uint32_t *off, uint32_t len) { scamper_dealias_prefixscan_t pfs, *p; warts_param_reader_t handlers[] = { {&pfs.a, (wpr_t)extract_addr, table}, {&pfs.b, (wpr_t)extract_addr, table}, {&pfs.ab, (wpr_t)extract_addr, table}, {&pfs, (wpr_t)extract_dealias_prefixscan_xs, table}, {&pfs.prefix, (wpr_t)extract_byte, NULL}, {&pfs.attempts, (wpr_t)extract_byte, NULL}, {&pfs.fudge, (wpr_t)extract_uint16, NULL}, {&pfs.wait_probe, (wpr_t)extract_uint16, NULL}, {&pfs.wait_timeout, (wpr_t)extract_byte, NULL}, {&pfs.probedefc, (wpr_t)extract_uint16, NULL}, {&pfs.flags, (wpr_t)extract_byte, NULL}, {&pfs.replyc, (wpr_t)extract_byte, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); uint32_t o = *off; uint16_t i; memset(&pfs, 0, sizeof(pfs)); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; if(scamper_dealias_prefixscan_alloc(dealias) != 0) return -1; p = dealias->data; memcpy(p, &pfs, sizeof(pfs)); /* by default we require five replies before inferring an alias */ if(flag_isset(&buf[o], WARTS_DEALIAS_PREFIXSCAN_REPLYC) == 0) p->replyc = 5; if(p->probedefc > 0) { if(scamper_dealias_prefixscan_probedefs_alloc(p, p->probedefc) != 0) return -1; for(i=0; i<p->probedefc; i++) { if(warts_dealias_probedef_read(&p->probedefs[i], state, table, buf, off, len) != 0) return -1; } } *defs = p->probedefs; return 0; }
static int warts_neighbourdisc_reply_read(scamper_neighbourdisc_reply_t *reply, warts_state_t *state, warts_addrtable_t *table, uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&reply->rx, (wpr_t)extract_timeval, NULL}, {&reply->mac, (wpr_t)extract_addr, table}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); return warts_params_read(buf, off, len, handlers, handler_cnt); }
static int warts_dealias_radargun_read(scamper_dealias_t *dealias, warts_state_t *state, warts_addrtable_t *table, scamper_dealias_probedef_t **defs, uint8_t *buf,uint32_t *off,uint32_t len) { scamper_dealias_radargun_t *rg; uint32_t probedefc = 0; uint16_t attempts = 0; uint16_t wait_probe = 0; uint32_t wait_round = 0; uint8_t wait_timeout = 0; uint8_t flags = 0; uint32_t i; warts_param_reader_t handlers[] = { {&probedefc, (wpr_t)extract_uint32, NULL}, {&attempts, (wpr_t)extract_uint16, NULL}, {&wait_probe, (wpr_t)extract_uint16, NULL}, {&wait_round, (wpr_t)extract_uint32, NULL}, {&wait_timeout, (wpr_t)extract_byte, NULL}, {&flags, (wpr_t)extract_byte, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(scamper_dealias_radargun_alloc(dealias) != 0) return -1; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; rg = dealias->data; if(scamper_dealias_radargun_probedefs_alloc(rg, probedefc) != 0) return -1; rg->probedefc = probedefc; rg->attempts = attempts; rg->wait_probe = wait_probe; rg->wait_round = wait_round; rg->wait_timeout = wait_timeout; rg->flags = flags; for(i=0; i<probedefc; i++) { if(warts_dealias_probedef_read(&rg->probedefs[i], state, table, buf, off, len) != 0) return -1; } *defs = rg->probedefs; return 0; }
static int warts_dealias_probe_read(scamper_dealias_probe_t *probe, warts_state_t *state, scamper_dealias_probedef_t *defs, warts_addrtable_t *table, uint8_t *buf, uint32_t *off, uint32_t len) { int i; uint32_t probedef_id; warts_param_reader_t handlers[] = { {&probedef_id, (wpr_t)extract_uint32, NULL}, {&probe->tx, (wpr_t)extract_timeval, NULL}, {&probe->replyc, (wpr_t)extract_uint16, NULL}, {&probe->ipid, (wpr_t)extract_uint16, NULL}, {&probe->seq, (wpr_t)extract_uint32, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); scamper_dealias_reply_t *reply; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) { return -1; } probe->probedef = defs + probedef_id; if(probe->replyc == 0) return 0; if(scamper_dealias_replies_alloc(probe, probe->replyc) != 0) { return -1; } for(i=0; i<probe->replyc; i++) { if((reply = scamper_dealias_reply_alloc()) == NULL) { return -1; } probe->replies[i] = reply; if(warts_dealias_reply_read(reply, state, table, buf, off, len) != 0) { return -1; } } return 0; }
static int warts_dealias_params_read(scamper_dealias_t *dealias, warts_state_t *state, uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&dealias->list, (wpr_t)extract_list, state}, {&dealias->cycle, (wpr_t)extract_cycle, state}, {&dealias->start, (wpr_t)extract_timeval, NULL}, {&dealias->method, (wpr_t)extract_byte, NULL}, {&dealias->result, (wpr_t)extract_byte, NULL}, {&dealias->probec, (wpr_t)extract_uint32, NULL}, {&dealias->userid, (wpr_t)extract_uint32, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); return warts_params_read(buf, off, len, handlers, handler_cnt); }
static int warts_trace_params_read(scamper_trace_t *trace,warts_state_t *state, warts_addrtable_t *table, uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&trace->list, (wpr_t)extract_list, state}, {&trace->cycle, (wpr_t)extract_cycle, state}, {&trace->src, (wpr_t)extract_addr_gid, state}, {&trace->dst, (wpr_t)extract_addr_gid, state}, {&trace->start, (wpr_t)extract_timeval, NULL}, {&trace->stop_reason, (wpr_t)extract_byte, NULL}, {&trace->stop_data, (wpr_t)extract_byte, NULL}, {&trace->flags, (wpr_t)extract_byte, NULL}, {&trace->attempts, (wpr_t)extract_byte, NULL}, {&trace->hoplimit, (wpr_t)extract_byte, NULL}, {&trace->type, (wpr_t)extract_byte, NULL}, {&trace->probe_size, (wpr_t)extract_uint16, NULL}, {&trace->sport, (wpr_t)extract_uint16, NULL}, {&trace->dport, (wpr_t)extract_uint16, NULL}, {&trace->firsthop, (wpr_t)extract_byte, NULL}, {&trace->tos, (wpr_t)extract_byte, NULL}, {&trace->wait, (wpr_t)extract_byte, NULL}, {&trace->loops, (wpr_t)extract_byte, NULL}, {&trace->hop_count, (wpr_t)extract_uint16, NULL}, {&trace->gaplimit, (wpr_t)extract_byte, NULL}, {&trace->gapaction, (wpr_t)extract_byte, NULL}, {&trace->loopaction, (wpr_t)extract_byte, NULL}, {&trace->probec, (wpr_t)extract_uint16, NULL}, {&trace->wait_probe, (wpr_t)extract_byte, NULL}, {&trace->confidence, (wpr_t)extract_byte, NULL}, {&trace->src, (wpr_t)extract_addr, table}, {&trace->dst, (wpr_t)extract_addr, table}, {&trace->userid, (wpr_t)extract_uint32, NULL}, {&trace->offset, (wpr_t)extract_uint16, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); int rc; if((rc = warts_params_read(buf, off, len, handlers, handler_cnt)) != 0) return rc; if(trace->dst == NULL) return -1; if(trace->firsthop == 0) trace->firsthop = 1; return 0; }
static int warts_tracelb_link_read(scamper_tracelb_t *trace, scamper_tracelb_link_t *link, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { uint16_t from, to; warts_param_reader_t handlers[] = { {&from, (wpr_t)extract_uint16, NULL}, {&to, (wpr_t)extract_uint16, NULL}, {&link->hopc, (wpr_t)extract_byte, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); scamper_tracelb_probeset_t *set; uint8_t i; uint32_t o = *off; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) { return -1; } link->from = trace->nodes[from]; if(flag_isset(&buf[o], WARTS_TRACELB_LINK_TO) != 0) link->to = trace->nodes[to]; else link->to = NULL; if(link->hopc > 0) { if(scamper_tracelb_link_probesets_alloc(link, link->hopc) != 0) return -1; for(i=0; i<link->hopc; i++) { if((set = scamper_tracelb_probeset_alloc()) == NULL) return -1; link->sets[i] = set; if(warts_tracelb_probeset_read(set, state, table, buf, off, len) != 0) return -1; } } return 0; }
static int warts_trace_hop_read(scamper_trace_hop_t *hop, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf,uint32_t *off,uint32_t len) { warts_param_reader_t handlers[] = { {&hop->hop_addr, (wpr_t)extract_addr_gid, state}, {&hop->hop_probe_ttl, (wpr_t)extract_byte, NULL}, {&hop->hop_reply_ttl, (wpr_t)extract_byte, NULL}, {&hop->hop_flags, (wpr_t)extract_byte, NULL}, {&hop->hop_probe_id, (wpr_t)warts_trace_hop_read_probe_id, NULL}, {&hop->hop_rtt, (wpr_t)extract_rtt, NULL}, {hop, (wpr_t)warts_trace_hop_read_icmp_tc, NULL}, {&hop->hop_probe_size, (wpr_t)extract_uint16, NULL}, {&hop->hop_reply_size, (wpr_t)extract_uint16, NULL}, {&hop->hop_reply_ipid, (wpr_t)extract_uint16, NULL}, {&hop->hop_reply_tos, (wpr_t)extract_byte, NULL}, {&hop->hop_icmp_nhmtu, (wpr_t)extract_uint16, NULL}, {&hop->hop_icmp_q_ipl, (wpr_t)extract_uint16, NULL}, {&hop->hop_icmp_q_ttl, (wpr_t)extract_byte, NULL}, {&hop->hop_tcp_flags, (wpr_t)extract_byte, NULL}, {&hop->hop_icmp_q_tos, (wpr_t)extract_byte, NULL}, {hop, (wpr_t)warts_trace_hop_read_icmpext, NULL}, {&hop->hop_addr, (wpr_t)extract_addr, table}, {&hop->hop_tx, (wpr_t)extract_timeval, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); uint32_t o = *off; int rc; if((rc = warts_params_read(buf, off, len, handlers, handler_cnt)) != 0) return rc; if(hop->hop_addr == NULL) return -1; if(hop->hop_probe_ttl == 0) return -1; if(SCAMPER_TRACE_HOP_IS_ICMP_Q(hop)) { if(flag_isset(&buf[o], WARTS_TRACE_HOP_Q_IPTTL) == 0) hop->hop_icmp_q_ttl = 1; if(flag_isset(&buf[o], WARTS_TRACE_HOP_Q_IPLEN) == 0) hop->hop_icmp_q_ipl = hop->hop_probe_size; } return 0; }
static int warts_ping_reply_read(const scamper_ping_t *ping, scamper_ping_reply_t *reply, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&reply->addr, (wpr_t)extract_addr_gid, state}, {&reply->flags, (wpr_t)extract_byte, NULL}, {&reply->reply_ttl, (wpr_t)extract_byte, NULL}, {&reply->reply_size, (wpr_t)extract_uint16, NULL}, {reply, (wpr_t)extract_ping_reply_icmptc, NULL}, {&reply->rtt, (wpr_t)extract_rtt, NULL}, {&reply->probe_id, (wpr_t)extract_uint16, NULL}, {&reply->reply_ipid, (wpr_t)extract_uint16, NULL}, {&reply->probe_ipid, (wpr_t)extract_uint16, NULL}, {&reply->reply_proto, (wpr_t)extract_byte, NULL}, {&reply->tcp_flags, (wpr_t)extract_byte, NULL}, {&reply->addr, (wpr_t)extract_addr, table}, {&reply->v4rr, (wpr_t)extract_ping_reply_v4rr, table}, {&reply->v4ts, (wpr_t)extract_ping_reply_v4ts, table}, {&reply->reply_ipid32, (wpr_t)extract_uint32, NULL}, {&reply->tx, (wpr_t)extract_timeval, NULL}, {&reply->tsreply, (wpr_t)extract_ping_reply_tsreply, NULL}, }; const int handler_cnt = sizeof(handlers) / sizeof(warts_param_reader_t); uint32_t o = *off; int i; if((i = warts_params_read(buf, off, len, handlers, handler_cnt)) != 0) return i; /* * some earlier versions of the ping reply structure did not include * the reply protocol field. fill it with something valid. */ if(flag_isset(&buf[o], WARTS_PING_REPLY_REPLY_PROTO) == 0) { if(ping->dst->type == SCAMPER_ADDR_TYPE_IPV4) reply->reply_proto = IPPROTO_ICMP; else reply->reply_proto = IPPROTO_ICMPV6; } return 0; }
static int warts_dealias_ally_read(scamper_dealias_t *dealias, warts_state_t *state, warts_addrtable_t *table, scamper_dealias_probedef_t **defs, uint8_t *buf, uint32_t *off, uint32_t len) { scamper_dealias_ally_t *ally; uint16_t wait_probe = 0; uint8_t wait_timeout = 0; uint8_t attempts = 0; uint16_t fudge = 0; uint8_t flags = 0; warts_param_reader_t handlers[] = { {&wait_probe, (wpr_t)extract_uint16, NULL}, {&wait_timeout, (wpr_t)extract_byte, NULL}, {&attempts, (wpr_t)extract_byte, NULL}, {&fudge, (wpr_t)extract_uint16, NULL}, {&flags, (wpr_t)extract_byte, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(scamper_dealias_ally_alloc(dealias) != 0) return -1; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; ally = dealias->data; ally->wait_probe = wait_probe; ally->wait_timeout = wait_timeout; ally->attempts = attempts; ally->fudge = fudge; ally->flags = flags; if(warts_dealias_probedef_read(&ally->probedefs[0], state, table, buf, off, len) != 0 || warts_dealias_probedef_read(&ally->probedefs[1], state, table, buf, off, len) != 0) { return -1; } *defs = ally->probedefs; return 0; }
static int warts_ping_params_read(scamper_ping_t *ping, warts_state_t *state, warts_addrtable_t *table, uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&ping->list, (wpr_t)extract_list, state}, {&ping->cycle, (wpr_t)extract_cycle, state}, {&ping->src, (wpr_t)extract_addr_gid, state}, {&ping->dst, (wpr_t)extract_addr_gid, state}, {&ping->start, (wpr_t)extract_timeval, NULL}, {&ping->stop_reason, (wpr_t)extract_byte, NULL}, {&ping->stop_data, (wpr_t)extract_byte, NULL}, {&ping->probe_datalen, (wpr_t)extract_uint16, NULL}, {&ping->probe_data, (wpr_t)extract_bytes_alloc, &ping->probe_datalen}, {&ping->probe_count, (wpr_t)extract_uint16, NULL}, {&ping->probe_size, (wpr_t)extract_uint16, NULL}, {&ping->probe_wait, (wpr_t)extract_byte, NULL}, {&ping->probe_ttl, (wpr_t)extract_byte, NULL}, {&ping->reply_count, (wpr_t)extract_uint16, NULL}, {&ping->ping_sent, (wpr_t)extract_uint16, NULL}, {&ping->probe_method, (wpr_t)extract_byte, NULL}, {&ping->probe_sport, (wpr_t)extract_uint16, NULL}, {&ping->probe_dport, (wpr_t)extract_uint16, NULL}, {&ping->userid, (wpr_t)extract_uint32, NULL}, {&ping->src, (wpr_t)extract_addr, table}, {&ping->dst, (wpr_t)extract_addr, table}, {&ping->flags, (wpr_t)extract_byte, NULL}, {&ping->probe_tos, (wpr_t)extract_byte, NULL}, {&ping->probe_tsps, (wpr_t)extract_ping_probe_tsps, table}, {&ping->probe_icmpsum, (wpr_t)extract_uint16, NULL}, {&ping->reply_pmtu, (wpr_t)extract_uint16, NULL}, {&ping->probe_timeout, (wpr_t)extract_byte, NULL}, {&ping->probe_wait_us, (wpr_t)extract_uint32, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); uint32_t o = *off; int rc; if((rc = warts_params_read(buf, off, len, handlers, handler_cnt)) != 0) return rc; if(flag_isset(&buf[o], WARTS_PING_PROBE_TIMEOUT) == 0) ping->probe_timeout = ping->probe_wait; return 0; }
static int warts_tbit_null_read(scamper_tbit_t *tbit, const uint8_t *buf, uint32_t *off, uint32_t len) { scamper_tbit_null_t *null = tbit->data; uint16_t options = 0; uint16_t results = 0; warts_param_reader_t handlers[] = { {&options, (wpr_t)extract_uint16, NULL}, {&results, (wpr_t)extract_uint16, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) goto err; null->options = options; null->results = results; tbit->data = null; return 0; err: return -1; }
static int warts_tracelb_node_read(scamper_tracelb_node_t *node, warts_state_t *state, warts_addrtable_t *table,const uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&node->addr, (wpr_t)extract_addr_gid, state}, {&node->flags, (wpr_t)extract_byte, NULL}, {&node->linkc, (wpr_t)extract_uint16, NULL}, {&node->q_ttl, (wpr_t)extract_byte, NULL}, {&node->addr, (wpr_t)extract_addr, table}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) { return -1; } return 0; }
static int warts_tbit_params_read(scamper_tbit_t *tbit, warts_addrtable_t *table, warts_state_t *state, uint8_t *buf, uint32_t *off, uint32_t len) { uint16_t pktc16 = 0; uint32_t pktc32 = 0; warts_param_reader_t handlers[] = { {&tbit->list, (wpr_t)extract_list, state}, {&tbit->cycle, (wpr_t)extract_cycle, state}, {&tbit->userid, (wpr_t)extract_uint32, NULL}, {&tbit->src, (wpr_t)extract_addr, table}, {&tbit->dst, (wpr_t)extract_addr, table}, {&tbit->sport, (wpr_t)extract_uint16, NULL}, {&tbit->dport, (wpr_t)extract_uint16, NULL}, {&tbit->start, (wpr_t)extract_timeval, NULL}, {&tbit->result, (wpr_t)extract_uint16, NULL}, {&tbit->type, (wpr_t)extract_byte, NULL}, {&tbit->app_proto, (wpr_t)extract_byte, NULL}, {&tbit->client_mss, (wpr_t)extract_uint16, NULL}, {&tbit->server_mss, (wpr_t)extract_uint16, NULL}, {&tbit->syn_retx, (wpr_t)extract_byte, NULL}, {&tbit->dat_retx, (wpr_t)extract_byte, NULL}, {&pktc16, (wpr_t)extract_uint16, NULL}, {&pktc32, (wpr_t)extract_uint32, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; /* handle the fact the pktc param changed from 16 to 32 bits */ if(pktc32 != 0) tbit->pktc = pktc32; else if(pktc16 != 0) tbit->pktc = pktc16; return 0; }
static int warts_tracelb_reply_read(scamper_tracelb_reply_t *reply, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&reply->reply_rx, (wpr_t)extract_timeval, NULL}, {&reply->reply_ipid, (wpr_t)extract_uint16, NULL}, {&reply->reply_ttl, (wpr_t)extract_byte, NULL}, {&reply->reply_flags, (wpr_t)extract_byte, NULL}, {reply, (wpr_t)extract_tracelb_reply_icmp_tc, NULL}, {&reply->reply_tcp_flags, (wpr_t)extract_byte, NULL}, {reply, (wpr_t)extract_tracelb_reply_icmp_ext, NULL}, {&reply->reply_icmp_q_ttl, (wpr_t)extract_byte, NULL}, {&reply->reply_icmp_q_tos, (wpr_t)extract_byte, NULL}, {&reply->reply_from, (wpr_t)extract_addr_gid, state}, {&reply->reply_from, (wpr_t)extract_addr, table}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); return warts_params_read(buf, off, len, handlers, handler_cnt); }
static int warts_dealias_bump_read(scamper_dealias_t *dealias, warts_state_t *state, warts_addrtable_t *table, scamper_dealias_probedef_t **defs, uint8_t *buf, uint32_t *off, uint32_t len) { scamper_dealias_bump_t *bump; uint16_t wait_probe = 0; uint16_t bump_limit = 0; uint8_t attempts = 0; warts_param_reader_t handlers[] = { {&wait_probe, (wpr_t)extract_uint16, NULL}, {&bump_limit, (wpr_t)extract_uint16, NULL}, {&attempts, (wpr_t)extract_byte, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); if(scamper_dealias_bump_alloc(dealias) != 0) return -1; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; bump = dealias->data; bump->wait_probe = wait_probe; bump->bump_limit = bump_limit; bump->attempts = attempts; if(warts_dealias_probedef_read(&bump->probedefs[0], state, table, buf, off, len) != 0 || warts_dealias_probedef_read(&bump->probedefs[1], state, table, buf, off, len) != 0) { return -1; } *defs = bump->probedefs; return 0; }
static int warts_tracelb_probe_read(scamper_tracelb_probe_t *probe, warts_state_t *state, warts_addrtable_t *table, const uint8_t *buf, uint32_t *off, uint32_t len) { warts_param_reader_t handlers[] = { {&probe->tx, (wpr_t)extract_timeval, NULL}, {&probe->flowid, (wpr_t)extract_uint16, NULL}, {&probe->ttl, (wpr_t)extract_byte, NULL}, {&probe->attempt, (wpr_t)extract_byte, NULL}, {&probe->rxc, (wpr_t)extract_uint16, NULL}, }; const int handler_cnt = sizeof(handlers)/sizeof(warts_param_reader_t); scamper_tracelb_reply_t *reply; uint16_t i; if(warts_params_read(buf, off, len, handlers, handler_cnt) != 0) return -1; if(probe->rxc > 0) { if(scamper_tracelb_probe_replies_alloc(probe, probe->rxc) != 0) return -1; for(i=0; i<probe->rxc; i++) { if((reply = scamper_tracelb_reply_alloc(NULL)) == NULL) return -1; probe->rxs[i] = reply; if(warts_tracelb_reply_read(reply, state, table, buf, off, len) != 0) return -1; } } return 0; }