/* * scamper_trace.c * * $Id: scamper_trace.c,v 1.62 2007/11/02 22:26:54 mjl Exp $ * * Copyright (C) 2003-2007 The University of Waikato * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include #include #include #include #include #if defined(__APPLE__) #include #endif #if defined(DMALLOC) #include #endif #include "scamper_addr.h" #include "scamper_list.h" #include "scamper_tlv.h" #include "scamper_trace.h" #include "utils.h" int scamper_trace_pmtud_alloc(scamper_trace_t *trace) { if((trace->pmtud = malloc_zero(sizeof(scamper_trace_pmtud_t))) == NULL) { return -1; } return 0; } void scamper_trace_pmtud_free(scamper_trace_t *trace) { scamper_trace_hop_t *hop, *hop_next; if(trace->pmtud != NULL) { hop = trace->pmtud->hops; while(hop != NULL) { hop_next = hop->hop_next; scamper_trace_hop_free(hop); hop = hop_next; } if(trace->pmtud->tlvs != NULL) { scamper_tlv_free(trace->pmtud->tlvs); } free(trace->pmtud); trace->pmtud = NULL; } return; } int scamper_trace_pmtud_hop_count(const scamper_trace_t *trace) { scamper_trace_hop_t *hop; int count = 0; if(trace == NULL || trace->pmtud == NULL) { return -1; } for(hop = trace->pmtud->hops; hop != NULL; hop = hop->hop_next) { count++; } return count; } int scamper_trace_hops_alloc(scamper_trace_t *trace, const int hops) { scamper_trace_hop_t **h; size_t size; size = sizeof(scamper_trace_hop_t *) * hops; if(trace->hops == NULL) { h = (scamper_trace_hop_t **)malloc_zero(size); } else { h = (scamper_trace_hop_t **)realloc(trace->hops, size); } if(h != NULL) { trace->hops = h; return 0; } return -1; } void scamper_trace_hop_free(scamper_trace_hop_t *hop) { if(hop != NULL) { scamper_tlv_free(hop->hop_tlvs); scamper_addr_free(hop->hop_addr); free(hop); } return; } scamper_trace_hop_t *scamper_trace_hop_alloc() { scamper_trace_hop_t *hop; if((hop = malloc_zero(sizeof(struct scamper_trace_hop))) == NULL) { return NULL; } return hop; } int scamper_trace_hop_count(const scamper_trace_t *trace) { scamper_trace_hop_t *hop; int i, hops = 0; for(i=0; ihop_count; i++) { for(hop = trace->hops[i]; hop != NULL; hop = hop->hop_next) { hops++; } } return hops; } /* * scamper_trace_addr * * return the target address of the traceroute. the caller doesn't know * that this is a trace structure, they merely get passed the address * of this function. */ scamper_addr_t *scamper_trace_addr(const void *va) { return ((const scamper_trace_t *)va)->dst; } const char *scamper_trace_type_tostr(const scamper_trace_t *trace) { switch(trace->type) { case SCAMPER_TRACE_TYPE_UDP: return "udp"; case SCAMPER_TRACE_TYPE_UDP_PARIS: return "udp-paris"; case SCAMPER_TRACE_TYPE_ICMP_ECHO: return "icmp-echo"; case SCAMPER_TRACE_TYPE_ICMP_ECHO_PARIS: return "icmp-echo-paris"; case SCAMPER_TRACE_TYPE_TCP: return "tcp"; } return NULL; } /* * scamper_trace_probe_headerlen * * return the length of headers sent on probe packets with this trace */ int scamper_trace_probe_headerlen(const scamper_trace_t *trace) { int len; switch(trace->dst->type) { case SCAMPER_ADDR_TYPE_IPV4: len = 20; break; case SCAMPER_ADDR_TYPE_IPV6: len = 40; break; default: return -1; } switch(trace->type) { case SCAMPER_TRACE_TYPE_UDP: case SCAMPER_TRACE_TYPE_UDP_PARIS: len += 8; break; case SCAMPER_TRACE_TYPE_ICMP_ECHO: case SCAMPER_TRACE_TYPE_ICMP_ECHO_PARIS: len += (1 + 1 + 2 + 2 + 2); break; case SCAMPER_TRACE_TYPE_TCP: len += 20; break; default: return -1; } return len; } uint16_t scamper_trace_pathlength(const scamper_trace_t *trace) { uint16_t i=0, max = 0; for(i=0; i != trace->hop_count; i++) { if(trace->hops[i] != NULL) max = i; } return max; } /* * scamper_trace_free * */ void scamper_trace_free(scamper_trace_t *trace) { scamper_trace_hop_t *hop, *hop_next; int i; if(trace == NULL) return; if(trace->hops != NULL) { for(i=0; ihop_count; i++) { hop = trace->hops[i]; while(hop != NULL) { hop_next = hop->hop_next; scamper_trace_hop_free(hop); hop = hop_next; } } free(trace->hops); } scamper_trace_pmtud_free(trace); if(trace->tlvs != NULL) scamper_tlv_free(trace->tlvs); if(trace->dst != NULL) scamper_addr_free(trace->dst); if(trace->src != NULL) scamper_addr_free(trace->src); if(trace->cycle != NULL) scamper_cycle_free(trace->cycle); if(trace->list != NULL) scamper_list_free(trace->list); free(trace); return; } /* * scamper_trace_alloc * * allocate the trace and all the possibly necessary data fields */ scamper_trace_t *scamper_trace_alloc() { return (struct scamper_trace *)malloc_zero(sizeof(struct scamper_trace)); }