diff options
Diffstat (limited to 'libglouglou/libggnet_traceroute.c')
-rw-r--r-- | libglouglou/libggnet_traceroute.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/libglouglou/libggnet_traceroute.c b/libglouglou/libggnet_traceroute.c index 2691d3e..0efafb4 100644 --- a/libglouglou/libggnet_traceroute.c +++ b/libglouglou/libggnet_traceroute.c @@ -144,8 +144,33 @@ ggnet_traceroute_free(struct ggnet_traceroute *ggtr) } struct ggnet_traceroute_req * -ggnet_traceroute_trace(struct ggnet_traceroute *ggtr, - struct addr *ip, enum tracemode mode, +ggnet_traceroute_trace_tcp(struct ggnet_traceroute *ggtr, struct addr *ip, + int dport, + void (*cb_done)(struct ggnet_traceroute_req *, void *), + void (*cb_hop)(struct ggnet_traceroute_req *, + struct ggnet_traceroute_hop *, void *), + void *data) +{ + struct ggnet_traceroute_req_params *params; + + params = calloc(1, sizeof(struct ggnet_traceroute_req_params)); + if (!params) + err(1, "could not allocate ggnet_traceroute_req_params\n"); + params->mode = TRACEMODE_TCP; + params->tcp.dport = dport; + + return ggnet_traceroute_trace(ggtr, ip, params, cb_done, cb_hop, data); +} + +/** + * Run a traceroute on ip + * + * mode_param: for TRACEMODE_TCP it specifies source port and activates + * 'intrace' like mode + */ +struct ggnet_traceroute_req * +ggnet_traceroute_trace(struct ggnet_traceroute *ggtr, struct addr *ip, + struct ggnet_traceroute_req_params *params, void (*cb_done)(struct ggnet_traceroute_req *, void *), void (*cb_hop)(struct ggnet_traceroute_req *, struct ggnet_traceroute_hop *, void *), @@ -172,11 +197,7 @@ ggnet_traceroute_trace(struct ggnet_traceroute *ggtr, goto err; } memcpy(&req->srcip, &intf_entry.intf_addr, sizeof(struct addr)); - req->mode = mode; - if (mode == TRACEMODE_ICMP) { - printf("ERROR: ICMP trace not supported yet\n"); - return NULL; - } + req->params = params; TAILQ_INIT(&req->hops_list); req->run.ev_recv = event_new(ggtr->ev_base, @@ -217,6 +238,8 @@ _req_free(struct ggnet_traceroute_req *req) { if (req->target) free(req->target); + if (req->params) + free(req->params); if (req->run.ev_recv) event_free(req->run.ev_recv); if (req->run.ev_send) @@ -251,15 +274,14 @@ _cb_send(evutil_socket_t fd, short what, void *arg) //addr_pack(hop->ip, ADDR_TYPE_IP, IP_ADDR_BITS, ip, IP_ADDR_LEN); ip_id = rand_uint16(ggtr->pkt_rand); sport = rand_uint16(ggtr->pkt_rand); - switch (req->mode) { + switch (req->params->mode) { case TRACEMODE_AUTO: case TRACEMODE_TCP: - req->params.tcp.dport = TRACE_DPORT; ip_pack_hdr(&pkt->pkt_hdr_i.ip, IP_TOS_LOWDELAY, len, ip_id, 0, ttl, IP_PROTO_TCP, req->srcip.addr_ip, req->target->ip.addr_ip); tcp_pack_hdr(&pkt->pkt_hdr_t.tcp, - sport, req->params.tcp.dport, + sport, req->params->tcp.dport, rand_uint32(ggtr->pkt_rand), 0, TH_SYN, rand_uint16(ggtr->pkt_rand), 0); break; @@ -331,10 +353,10 @@ _cb_recv(evutil_socket_t fd, short what, void *arg) goto reschedule_recv; tcp = (struct tcp_hdr *)((u_char *)ip + IP_HDR_LEN); printf("XXX TCP %d %d %d\n", ntohs(tcp->th_sport), - req->params.tcp.dport, tcp->th_seq); + req->params->tcp.dport, tcp->th_seq); if (((tcp->th_flags == TH_SYN + TH_ACK) || (tcp->th_flags == TH_RST + TH_ACK)) && - (ntohs(tcp->th_sport) == req->params.tcp.dport)) { + (ntohs(tcp->th_sport) == req->params->tcp.dport)) { /* target answer */ printf("XXX found target !\n"); hop = _hop_sport(req, ntohs(tcp->th_dport)); |