void scamper_icmp_resp_handle(scamper_icmp_resp_t *resp) { scamper_task_sig_t sig; scamper_task_t *task; scamper_addr_t addr; if(SCAMPER_ICMP_RESP_IS_TTL_EXP(resp) || SCAMPER_ICMP_RESP_IS_UNREACH(resp) || SCAMPER_ICMP_RESP_IS_PACKET_TOO_BIG(resp)) { /* the probe signature is embedded in the response */ if(!SCAMPER_ICMP_RESP_INNER_IS_SET(resp)) return; if(scamper_icmp_resp_inner_dst(resp, &addr) != 0) return; } else if(SCAMPER_ICMP_RESP_IS_ECHO_REPLY(resp) || SCAMPER_ICMP_RESP_IS_TIME_REPLY(resp)) { /* the probe signature is an ICMP echo/ts request */ if(scamper_icmp_resp_src(resp, &addr) != 0) return; } else { return; } memset(&sig, 0, sizeof(sig)); sig.sig_type = SCAMPER_TASK_SIG_TYPE_TX_IP; sig.sig_tx_ip_dst = &addr; if((task = scamper_task_find(&sig)) != NULL) scamper_task_handleicmp(task, resp); return; }
/* * scamper_task_sig_block * * go through the signatures and see if any conflict with other tasks. * if there is a conflict, return the task, otherwise return NULL. * scamper_task_sig_install assumes that this function has been called. */ scamper_task_t *scamper_task_sig_block(scamper_task_t *task) { scamper_task_sig_t *sig; scamper_task_t *tf; slist_node_t *n; s2t_t *s2t; for(n=slist_head_node(task->siglist); n != NULL; n = slist_node_next(n)) { s2t = slist_node_item(n); sig = s2t->sig; if((tf = scamper_task_find(sig)) != NULL && tf != task) return tf; } return NULL; }
int scamper_task_sig_install(scamper_task_t *task) { scamper_task_sig_t *sig; scamper_task_t *tf; s2t_t *s2t; slist_node_t *n; if(slist_count(task->siglist) < 1) return -1; for(n=slist_head_node(task->siglist); n != NULL; n = slist_node_next(n)) { s2t = slist_node_item(n); sig = s2t->sig; /* check if another task has this signature already */ if((tf = scamper_task_find(sig)) != NULL) { if(tf != task) goto err; continue; } if(sig->sig_type == SCAMPER_TASK_SIG_TYPE_TX_IP) s2t->node = splaytree_insert(tx_ip, s2t); else if(sig->sig_type == SCAMPER_TASK_SIG_TYPE_TX_ND) s2t->node = splaytree_insert(tx_nd, s2t); else if(sig->sig_type == SCAMPER_TASK_SIG_TYPE_SNIFF) s2t->node = dlist_tail_push(sniff, s2t); if(s2t->node == NULL) { scamper_debug(__func__, "could not install sig"); goto err; } } return 0; err: scamper_task_sig_deinstall(task); return -1; }