static char *hop_tostr(const scamper_trace_t *trace, int i, char *buf, size_t *len_out) { scamper_trace_hop_t *hop; char addr[128]; size_t len = *len_out, off = 0; if(i<trace->firsthop-1 || trace->hop_count <= i) { string_concat(buf, len, &off, "-"); goto done; } else if((hop = trace->hops[i]) == NULL) { string_concat(buf, len, &off, "*"); goto done; } if((options & OPT_NAMES) == 0 || addr_toname(hop->hop_addr, addr, sizeof(addr)) == NULL) scamper_addr_tostr(hop->hop_addr, addr, sizeof(addr)); string_concat(buf, len, &off, "%s", addr); if(SCAMPER_TRACE_HOP_IS_ICMP_TTL_EXP(hop) || SCAMPER_TRACE_HOP_IS_ICMP_ECHO_REPLY(hop) || SCAMPER_TRACE_HOP_IS_TCP(hop)) { goto done; } if(hop->hop_addr->type == SCAMPER_ADDR_TYPE_IPV4) { if(hop->hop_icmp_type == ICMP_UNREACH) { if(hop->hop_icmp_code == ICMP_UNREACH_FILTER_PROHIB) string_concat(buf, len, &off, " !X"); else if(hop->hop_icmp_code == ICMP_UNREACH_HOST) string_concat(buf, len, &off, " !H"); else if(hop->hop_icmp_code == ICMP_UNREACH_NEEDFRAG) string_concat(buf, len, &off, " !F"); else if(hop->hop_icmp_code == ICMP_UNREACH_SRCFAIL) string_concat(buf, len, &off, " !S"); else if(hop->hop_icmp_code == ICMP_UNREACH_PROTOCOL) string_concat(buf, len, &off, " !P"); else if(hop->hop_icmp_code == ICMP_UNREACH_NET) string_concat(buf, len, &off, " !N"); else if(hop->hop_icmp_code != ICMP_UNREACH_PORT) string_concat(buf, len, &off, " !<%d>", hop->hop_icmp_code); } else { string_concat(buf, len, &off, " !<%d,%d>", hop->hop_icmp_type, hop->hop_icmp_code); } } else if(hop->hop_addr->type == SCAMPER_ADDR_TYPE_IPV6) { if(hop->hop_icmp_type == ICMP6_DST_UNREACH) { if(hop->hop_icmp_code == ICMP6_DST_UNREACH_ADDR) string_concat(buf, len, &off, " !A"); else if(hop->hop_icmp_code == ICMP6_DST_UNREACH_BEYONDSCOPE) string_concat(buf, len, &off, " !S"); else if(hop->hop_icmp_code == ICMP6_DST_UNREACH_ADMIN) string_concat(buf, len, &off, " !P"); else if(hop->hop_icmp_code == ICMP6_DST_UNREACH_NOROUTE) string_concat(buf, len, &off, " !N"); else if(hop->hop_icmp_code != ICMP6_DST_UNREACH_NOPORT) string_concat(buf, len, &off, " !<%d>", hop->hop_icmp_code); } else if(hop->hop_icmp_type == ICMP6_PACKET_TOO_BIG) { string_concat(buf, len, &off, " !F"); } else { string_concat(buf, len, &off, " !<%d,%d>", hop->hop_icmp_type, hop->hop_icmp_code); } } done: *len_out = off; return buf; }
static void warts_trace_hop_params(const scamper_trace_t *trace, const scamper_trace_hop_t *hop, warts_addrtable_t *table, uint8_t *flags, uint16_t *flags_len, uint16_t *params_len) { scamper_icmpext_t *ie; const warts_var_t *var; int i, max_id = 0; /* unset all the flags possible */ memset(flags, 0, hop_vars_mfb); *params_len = 0; for(i=0; i<sizeof(hop_vars)/sizeof(warts_var_t); i++) { var = &hop_vars[i]; /* not used any more */ if(var->id == WARTS_TRACE_HOP_ADDR_GID) continue; if(var->id == WARTS_TRACE_HOP_ADDR) { if(hop->hop_addr == NULL) continue; } else if(var->id == WARTS_TRACE_HOP_TCP_FLAGS) { if(SCAMPER_TRACE_HOP_IS_TCP(hop) == 0) continue; } else if(var->id == WARTS_TRACE_HOP_ICMP_TC) { if(SCAMPER_TRACE_HOP_IS_ICMP(hop) == 0) continue; } else if(var->id == WARTS_TRACE_HOP_Q_IPLEN) { if(SCAMPER_TRACE_HOP_IS_ICMP_Q(hop) == 0) continue; if(hop->hop_icmp_q_ipl == trace->probe_size) continue; } else if(var->id == WARTS_TRACE_HOP_Q_IPTTL) { if(SCAMPER_TRACE_HOP_IS_ICMP_Q(hop) == 0) continue; if(hop->hop_icmp_q_ttl == 1) continue; } else if(var->id == WARTS_TRACE_HOP_Q_IPTOS) { if(SCAMPER_TRACE_HOP_IS_ICMP_Q(hop) == 0) continue; if(hop->hop_addr->type != SCAMPER_ADDR_TYPE_IPV4) continue; } else if(var->id == WARTS_TRACE_HOP_NHMTU) { if(SCAMPER_TRACE_HOP_IS_ICMP_PTB(hop) == 0) continue; } else if(var->id == WARTS_TRACE_HOP_ICMPEXT) { if(hop->hop_icmpext == NULL) continue; } else if(var->id == WARTS_TRACE_HOP_REPLY_IPID) { if(hop->hop_reply_ipid == 0) continue; } else if(var->id == WARTS_TRACE_HOP_TX) { if(hop->hop_tx.tv_sec == 0) continue; } flag_set(flags, var->id, &max_id); if(var->id == WARTS_TRACE_HOP_ADDR) { *params_len += warts_addr_size(table, hop->hop_addr); } else if(var->id == WARTS_TRACE_HOP_ICMPEXT) { *params_len += 2; for(ie = hop->hop_icmpext; ie != NULL; ie = ie->ie_next) *params_len += (2 + 1 + 1 + ie->ie_dl); } else { assert(var->size >= 0); *params_len += var->size; } } *flags_len = fold_flags(flags, max_id); return; }