1 /* 2 * scamper_do_dealias.c 3 * 4 * $Id: scamper_dealias_do.c,v 1.167 2020/06/12 23:26:53 mjl Exp $ 5 * 6 * Copyright (C) 2008-2011 The University of Waikato 7 * Copyright (C) 2012-2013 Matthew Luckie 8 * Copyright (C) 2012-2014 The Regents of the University of California 9 * Copyright (C) 2016-2020 Matthew Luckie 10 * Author: Matthew Luckie 11 * 12 * This code implements alias resolution techniques published by others 13 * which require the network to be probed; the author of each technique 14 * is detailed with its data structures. 15 * 16 * This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License as published by 18 * the Free Software Foundation, version 2. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, write to the Free Software 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 * 29 */ 30 31 #ifdef HAVE_CONFIG_H 32 #include "config.h" 33 #endif 34 #include "internal.h" 35 36 #include "scamper.h" 37 #include "scamper_addr.h" 38 #include "scamper_list.h" 39 #include "scamper_icmpext.h" 40 #include "scamper_dealias.h" 41 #include "scamper_task.h" 42 #include "scamper_icmp_resp.h" 43 #include "scamper_fds.h" 44 #include "scamper_dl.h" 45 #include "scamper_dlhdr.h" 46 #include "scamper_rtsock.h" 47 #include "scamper_probe.h" 48 #include "scamper_getsrc.h" 49 #include "scamper_udp4.h" 50 #include "scamper_udp6.h" 51 #include "scamper_icmp4.h" 52 #include "scamper_icmp6.h" 53 #include "scamper_queue.h" 54 #include "scamper_file.h" 55 #include "scamper_options.h" 56 #include "scamper_debug.h" 57 #include "scamper_dealias_do.h" 58 #include "mjl_splaytree.h" 59 #include "mjl_list.h" 60 #include "utils.h" 61 62 static scamper_task_funcs_t funcs; 63 64 /* packet buffer for generating the payload of each packet */ 65 static uint8_t *pktbuf = NULL; 66 static size_t pktbuf_len = 0; 67 68 /* address cache used to avoid reallocating the same address multiple times */ 69 extern scamper_addrcache_t *addrcache; 70 71 #define DEALIAS_OPT_DPORT 1 72 #define DEALIAS_OPT_FUDGE 2 73 #define DEALIAS_OPT_METHOD 3 74 #define DEALIAS_OPT_REPLYC 4 75 #define DEALIAS_OPT_OPTION 5 76 #define DEALIAS_OPT_PROBEDEF 6 77 #define DEALIAS_OPT_ATTEMPTS 7 78 #define DEALIAS_OPT_WAIT_ROUND 8 79 #define DEALIAS_OPT_SPORT 9 80 #define DEALIAS_OPT_TTL 10 81 #define DEALIAS_OPT_USERID 11 82 #define DEALIAS_OPT_WAIT_TIMEOUT 12 83 #define DEALIAS_OPT_WAIT_PROBE 13 84 #define DEALIAS_OPT_EXCLUDE 14 85 86 static const scamper_option_in_t opts[] = { 87 {'d', NULL, DEALIAS_OPT_DPORT, SCAMPER_OPTION_TYPE_NUM}, 88 {'f', NULL, DEALIAS_OPT_FUDGE, SCAMPER_OPTION_TYPE_NUM}, 89 {'m', NULL, DEALIAS_OPT_METHOD, SCAMPER_OPTION_TYPE_STR}, 90 {'o', NULL, DEALIAS_OPT_REPLYC, SCAMPER_OPTION_TYPE_NUM}, 91 {'O', NULL, DEALIAS_OPT_OPTION, SCAMPER_OPTION_TYPE_STR}, 92 {'p', NULL, DEALIAS_OPT_PROBEDEF, SCAMPER_OPTION_TYPE_STR}, 93 {'q', NULL, DEALIAS_OPT_ATTEMPTS, SCAMPER_OPTION_TYPE_NUM}, 94 {'r', NULL, DEALIAS_OPT_WAIT_ROUND, SCAMPER_OPTION_TYPE_NUM}, 95 {'s', NULL, DEALIAS_OPT_SPORT, SCAMPER_OPTION_TYPE_NUM}, 96 {'t', NULL, DEALIAS_OPT_TTL, SCAMPER_OPTION_TYPE_NUM}, 97 {'U', NULL, DEALIAS_OPT_USERID, SCAMPER_OPTION_TYPE_NUM}, 98 {'w', NULL, DEALIAS_OPT_WAIT_TIMEOUT, SCAMPER_OPTION_TYPE_NUM}, 99 {'W', NULL, DEALIAS_OPT_WAIT_PROBE, SCAMPER_OPTION_TYPE_NUM}, 100 {'x', NULL, DEALIAS_OPT_EXCLUDE, SCAMPER_OPTION_TYPE_STR}, 101 }; 102 static const int opts_cnt = SCAMPER_OPTION_COUNT(opts); 103 104 #define DEALIAS_PROBEDEF_OPT_CSUM 1 105 #define DEALIAS_PROBEDEF_OPT_DPORT 2 106 #define DEALIAS_PROBEDEF_OPT_IP 3 107 #define DEALIAS_PROBEDEF_OPT_PROTO 4 108 #define DEALIAS_PROBEDEF_OPT_SPORT 5 109 #define DEALIAS_PROBEDEF_OPT_TTL 6 110 #define DEALIAS_PROBEDEF_OPT_SIZE 7 111 #define DEALIAS_PROBEDEF_OPT_MTU 8 112 113 static const scamper_option_in_t probedef_opts[] = { 114 {'c', NULL, DEALIAS_PROBEDEF_OPT_CSUM, SCAMPER_OPTION_TYPE_STR}, 115 {'d', NULL, DEALIAS_PROBEDEF_OPT_DPORT, SCAMPER_OPTION_TYPE_NUM}, 116 {'F', NULL, DEALIAS_PROBEDEF_OPT_SPORT, SCAMPER_OPTION_TYPE_NUM}, 117 {'i', NULL, DEALIAS_PROBEDEF_OPT_IP, SCAMPER_OPTION_TYPE_STR}, 118 {'P', NULL, DEALIAS_PROBEDEF_OPT_PROTO, SCAMPER_OPTION_TYPE_STR}, 119 {'s', NULL, DEALIAS_PROBEDEF_OPT_SIZE, SCAMPER_OPTION_TYPE_NUM}, 120 {'t', NULL, DEALIAS_PROBEDEF_OPT_TTL, SCAMPER_OPTION_TYPE_NUM}, 121 {'M', NULL, DEALIAS_PROBEDEF_OPT_MTU, SCAMPER_OPTION_TYPE_NUM}, 122 }; 123 static const int probedef_opts_cnt = SCAMPER_OPTION_COUNT(probedef_opts); 124 125 const char *scamper_do_dealias_usage(void) 126 { 127 return 128 "dealias [-d dport] [-f fudge] [-m method] [-o replyc] [-O option]\n" 129 " [-p '[-c sum] [-d dp] [-F sp] [-i ip] [-M mtu] [-P meth] [-s size] [-t ttl]']\n" 130 " [-q attempts] [-r wait-round] [-s sport] [-t ttl]\n" 131 " [-U userid] [-w wait-timeout] [-W wait-probe] [-x exclude]\n"; 132 } 133 134 typedef struct dealias_target 135 { 136 scamper_addr_t *addr; 137 dlist_t *probes; 138 uint16_t tcp_sport; 139 uint16_t udp_dport; 140 } dealias_target_t; 141 142 typedef struct dealias_probe 143 { 144 dealias_target_t *target; 145 scamper_dealias_probe_t *probe; 146 uint16_t match_field; 147 dlist_node_t *target_node; 148 } dealias_probe_t; 149 150 typedef struct dealias_prefixscan 151 { 152 scamper_dealias_probedef_t *probedefs; 153 uint32_t probedefc; 154 scamper_addr_t **aaliases; 155 int aaliasc; 156 int attempt; 157 int seq; 158 int round0; 159 int round; 160 int replyc; 161 } dealias_prefixscan_t; 162 163 typedef struct dealias_radargun 164 { 165 uint32_t *order; /* probedef order */ 166 uint32_t i; /* index into order */ 167 struct timeval next_round; 168 } dealias_radargun_t; 169 170 typedef struct dealias_bump 171 { 172 uint8_t step; 173 uint8_t attempt; 174 uint16_t bump; 175 } dealias_bump_t; 176 177 typedef struct dealias_options 178 { 179 char *addr; 180 uint8_t attempts; 181 uint8_t replyc; 182 uint8_t wait_timeout; 183 uint16_t wait_probe; 184 uint32_t wait_round; 185 uint16_t sport; 186 uint16_t dport; 187 uint8_t ttl; 188 uint16_t fudge; 189 slist_t *probedefs; 190 slist_t *xs; 191 int nobs; 192 int shuffle; 193 int inseq; 194 } dealias_options_t; 195 196 typedef struct dealias_probedef 197 { 198 scamper_dealias_probedef_t *def; 199 dealias_target_t *target; 200 uint32_t tcp_seq; 201 uint32_t tcp_ack; 202 uint16_t pktbuf_len; 203 uint8_t flags; 204 uint8_t echo; 205 } dealias_probedef_t; 206 207 typedef struct dealias_ptb 208 { 209 scamper_dealias_probedef_t *def; 210 uint8_t *quote; 211 uint16_t quote_len; 212 } dealias_ptb_t; 213 214 typedef struct dealias_state 215 { 216 uint8_t id; 217 uint8_t flags; 218 uint16_t icmpseq; 219 scamper_dealias_probedef_t *probedefs; 220 uint32_t probedefc; 221 dealias_probedef_t **pds; 222 int pdc; 223 uint32_t probe; 224 uint32_t round; 225 struct timeval last_tx; 226 struct timeval next_tx; 227 struct timeval ptb_tx; 228 splaytree_t *targets; 229 dlist_t *recent_probes; 230 void *methodstate; 231 slist_t *ptbq; 232 slist_t *discard; 233 } dealias_state_t; 234 235 #define DEALIAS_STATE_FLAG_DL 0x01 236 237 #define DEALIAS_PROBEDEF_FLAG_RX_IPID 0x01 238 #define DEALIAS_PROBEDEF_FLAG_TX_PTB 0x02 239 240 #ifdef NDEBUG 241 #define dealias_state_assert(state) ((void)0) 242 #endif 243 244 #ifndef NDEBUG 245 static void dealias_state_assert(const dealias_state_t *state) 246 247 { 248 int i; 249 for(i=0; i<state->pdc; i++) 250 { 251 assert(state->pds[i] != NULL); 252 assert(state->pds[i]->def->id == (uint32_t)i); 253 } 254 return; 255 } 256 #endif 257 258 static scamper_dealias_t *dealias_getdata(const scamper_task_t *task) 259 { 260 return scamper_task_getdata(task); 261 } 262 263 static dealias_state_t *dealias_getstate(const scamper_task_t *task) 264 { 265 dealias_state_t *state = scamper_task_getstate(task); 266 dealias_state_assert(state); 267 return state; 268 } 269 270 static int dealias_ally_queue(const scamper_dealias_t *dealias, 271 dealias_state_t *state, 272 const struct timeval *now, struct timeval *tv) 273 { 274 if(state->ptb_tx.tv_sec == 0) 275 return 0; 276 timeval_add_s(tv, &state->ptb_tx, 1); 277 if(timeval_cmp(tv, now) > 0) 278 return 1; 279 memset(&state->ptb_tx, 0, sizeof(struct timeval)); 280 return 0; 281 } 282 283 static void dealias_queue(scamper_task_t *task) 284 { 285 static int (*const func[])(const scamper_dealias_t *, dealias_state_t *, 286 const struct timeval *, struct timeval *) = { 287 NULL, 288 dealias_ally_queue, 289 NULL, 290 NULL, 291 NULL, 292 }; 293 scamper_dealias_t *dealias = dealias_getdata(task); 294 dealias_state_t *state = dealias_getstate(task); 295 struct timeval tv, now; 296 dealias_probe_t *p; 297 298 if(scamper_task_queue_isdone(task)) 299 return; 300 301 gettimeofday_wrap(&now); 302 303 for(;;) 304 { 305 if((p = dlist_head_item(state->recent_probes)) == NULL) 306 break; 307 timeval_add_s(&tv, &p->probe->tx, 10); 308 if(timeval_cmp(&now, &tv) < 0) 309 break; 310 dlist_node_pop(p->target->probes, p->target_node); 311 dlist_head_pop(state->recent_probes); 312 free(p); 313 } 314 315 if(slist_count(state->ptbq) > 0) 316 { 317 scamper_task_queue_probe(task); 318 return; 319 } 320 321 if(func[dealias->method-1] != NULL && 322 func[dealias->method-1](dealias, state, &now, &tv) != 0) 323 { 324 scamper_task_queue_wait_tv(task, &tv); 325 return; 326 } 327 328 if(timeval_cmp(&state->next_tx, &now) <= 0) 329 { 330 scamper_task_queue_probe(task); 331 return; 332 } 333 334 scamper_task_queue_wait_tv(task, &state->next_tx); 335 return; 336 } 337 338 static void dealias_handleerror(scamper_task_t *task, int error) 339 { 340 scamper_task_queue_done(task, 0); 341 return; 342 } 343 344 static void dealias_result(scamper_task_t *task, uint8_t result) 345 { 346 scamper_dealias_t *dealias = dealias_getdata(task); 347 #ifdef HAVE_SCAMPER_DEBUG 348 char buf[16]; 349 #endif 350 351 dealias->result = result; 352 353 #ifdef HAVE_SCAMPER_DEBUG 354 scamper_debug(__func__, "%s", 355 scamper_dealias_result_tostr(dealias, buf, sizeof(buf))); 356 #endif 357 358 scamper_task_queue_done(task, 0); 359 return; 360 } 361 362 static void dealias_ptb_free(dealias_ptb_t *ptb) 363 { 364 if(ptb == NULL) 365 return; 366 if(ptb->quote != NULL) 367 free(ptb->quote); 368 free(ptb); 369 return; 370 } 371 372 static int dealias_ptb_add(dealias_state_t *state, scamper_dl_rec_t *dl, 373 scamper_dealias_probedef_t *def) 374 { 375 dealias_ptb_t *ptb; 376 377 if((ptb = malloc_zero(sizeof(dealias_ptb_t))) == NULL) 378 { 379 printerror(__func__, "could not malloc ptb"); 380 goto err; 381 } 382 ptb->def = def; 383 if(dl->dl_ip_size > 1280-40-8) 384 ptb->quote_len = 1280-40-8; 385 else 386 ptb->quote_len = dl->dl_ip_size; 387 if((ptb->quote = memdup(dl->dl_net_raw, ptb->quote_len)) == NULL) 388 { 389 printerror(__func__, "could not dup ptb quote"); 390 goto err; 391 } 392 393 if(slist_tail_push(state->ptbq, ptb) == NULL) 394 { 395 printerror(__func__, "could not queue ptb"); 396 goto err; 397 } 398 399 return 0; 400 err: 401 if(ptb != NULL) dealias_ptb_free(ptb); 402 return -1; 403 } 404 405 static int dealias_target_cmp(const dealias_target_t *a, 406 const dealias_target_t *b) 407 { 408 return scamper_addr_cmp(a->addr, b->addr); 409 } 410 411 static void dealias_target_free(dealias_target_t *tgt) 412 { 413 if(tgt == NULL) 414 return; 415 if(tgt->probes != NULL) 416 dlist_free_cb(tgt->probes, free); 417 if(tgt->addr != NULL) 418 scamper_addr_free(tgt->addr); 419 free(tgt); 420 return; 421 } 422 423 static dealias_target_t *dealias_target_find(dealias_state_t *s, 424 scamper_addr_t *addr) 425 { 426 dealias_target_t fm; 427 fm.addr = addr; 428 return splaytree_find(s->targets, &fm); 429 } 430 431 static dealias_target_t *dealias_target_get(dealias_state_t *state, 432 scamper_addr_t *addr) 433 { 434 dealias_target_t *tgt; 435 if((tgt = dealias_target_find(state, addr)) != NULL) 436 return tgt; 437 if((tgt = malloc_zero(sizeof(dealias_target_t))) == NULL || 438 (tgt->probes = dlist_alloc()) == NULL) 439 { 440 printerror(__func__, "could not malloc tgt"); 441 goto err; 442 } 443 tgt->addr = scamper_addr_use(addr); 444 if(splaytree_insert(state->targets, tgt) == NULL) 445 { 446 printerror(__func__, "could not add tgt to tree"); 447 goto err; 448 } 449 return tgt; 450 451 err: 452 dealias_target_free(tgt); 453 return NULL; 454 } 455 456 static int dealias_probedef_add(dealias_state_t *state, 457 scamper_dealias_probedef_t *def) 458 { 459 dealias_probedef_t *pd = NULL; 460 461 if((pd = malloc_zero(sizeof(dealias_probedef_t))) == NULL) 462 { 463 printerror(__func__, "could not malloc pd"); 464 goto err; 465 } 466 pd->def = def; 467 if((pd->target = dealias_target_get(state, def->dst)) == NULL) 468 goto err; 469 470 if(def->size == 0) 471 pd->pktbuf_len = 2; 472 else if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_ICMP_ECHO) 473 if(SCAMPER_ADDR_TYPE_IS_IPV4(def->dst)) 474 pd->pktbuf_len = def->size - 28; 475 else 476 pd->pktbuf_len = def->size - 48; 477 else 478 goto err; 479 480 if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_TCP_ACK && 481 (random_u32(&pd->tcp_seq) != 0 || random_u32(&pd->tcp_ack) != 0)) 482 goto err; 483 484 if(array_insert((void ***)&state->pds, &state->pdc, pd, NULL) != 0) 485 { 486 printerror(__func__, "could not add pd"); 487 goto err; 488 } 489 490 return 0; 491 492 err: 493 if(pd != NULL) free(pd); 494 return -1; 495 } 496 497 static void dealias_prefixscan_array_free(scamper_addr_t **addrs, int addrc) 498 { 499 int i; 500 501 if(addrs == NULL) 502 return; 503 504 for(i=0; i<addrc; i++) 505 if(addrs[i] != NULL) 506 scamper_addr_free(addrs[i]); 507 508 free(addrs); 509 return; 510 } 511 512 static int dealias_prefixscan_array_add(scamper_dealias_t *dealias, 513 scamper_addr_t ***out, int *outc, 514 struct in_addr *addr) 515 { 516 scamper_dealias_prefixscan_t *prefixscan = dealias->data; 517 scamper_addr_t **array = *out; 518 scamper_addr_t *sa; 519 520 /* convert the in_addr into something that scamper deals with */ 521 sa = scamper_addrcache_get(addrcache, SCAMPER_ADDR_TYPE_IPV4, addr); 522 if(sa == NULL) 523 { 524 printerror(__func__, "could not get addr"); 525 return -1; 526 } 527 528 /* 529 * don't consider this address if it is the same as the address 530 * we are trying to find an alias for, or it is in the exclude list. 531 */ 532 if(scamper_addr_cmp(prefixscan->a, sa) == 0 || 533 scamper_dealias_prefixscan_xs_in(dealias, sa) != 0) 534 { 535 scamper_addr_free(sa); 536 return 0; 537 } 538 539 /* add the scamper address to the array */ 540 if(array_insert((void ***)&array, outc, sa, NULL) != 0) 541 { 542 printerror(__func__, "could not add addr"); 543 scamper_addr_free(sa); 544 return -1; 545 } 546 547 *out = array; 548 return 0; 549 } 550 551 /* 552 * dealias_prefixscan_array: 553 * 554 * figure out what the next address to scan will be, based on what the 555 * previously probed address was. below are examples of the order in which 556 * addresses should be probed given a starting address. addresses in 557 * prefixes less than /30 could be probed in random order. 558 * 559 * 00100111 39 00100010 34 00101001 41 00100000 32 560 * 00100110 38 /31 00100001 33 00101010 42 00100001 33 /31 561 * 00100101 37 00100000 32 00101000 40 00100010 34 562 * 00100100 36 /30 00100011 35 /30 00101011 43 /30 00100011 35 /30 563 * 00100011 35 00100100 36 00101100 44 564 * 00100010 34 00100101 37 00101101 45 565 * 00100001 33 00100110 38 00101110 46 566 * 00100000 32 /29 00100111 39 /29 00101111 47 /29 567 * 00101000 40 00101000 40 00100000 32 568 * 00101001 41 00101001 41 00100001 33 569 * 00101010 42 00101010 42 570 * 00101011 43 571 * 00101100 44 572 * 00101101 45 573 * 00101110 46 574 * 00101111 47 /28 575 * 576 */ 577 static int dealias_prefixscan_array(scamper_dealias_t *dealias, 578 scamper_addr_t ***out, int *outc) 579 { 580 scamper_dealias_prefixscan_t *prefixscan = dealias->data; 581 scamper_addr_t **array = NULL; 582 uint32_t hostid, netid, mask; 583 uint32_t slash30[4][3] = {{1, 2, 3}, {2, 0, 3}, {1, 0, 3}, {2, 1, 0}}; 584 uint32_t cnt[] = {4, 8, 16, 32, 64, 128}; 585 uint32_t bit; 586 struct in_addr a; 587 int pre, i; 588 589 memcpy(&a, prefixscan->b->addr, sizeof(a)); 590 *outc = 0; 591 592 /* if we've been instructed only to try /31 pair */ 593 if(prefixscan->prefix == 31) 594 { 595 netid = ntohl(a.s_addr) & ~0x1; 596 hostid = ntohl(a.s_addr) & 0x1; 597 598 if(hostid == 1) 599 a.s_addr = htonl(netid | 0); 600 else 601 a.s_addr = htonl(netid | 1); 602 603 if(dealias_prefixscan_array_add(dealias, &array, outc, &a) != 0) 604 goto err; 605 606 *out = array; 607 return 0; 608 } 609 610 /* when probing a /30 the first three probes have a particular order */ 611 mask = 0x3; 612 netid = ntohl(a.s_addr) & ~mask; 613 hostid = ntohl(a.s_addr) & mask; 614 for(i=0; i<3; i++) 615 { 616 a.s_addr = htonl(netid | slash30[hostid][i]); 617 if(dealias_prefixscan_array_add(dealias, &array, outc, &a) != 0) 618 goto err; 619 } 620 621 for(pre = 29; pre >= prefixscan->prefix; pre--) 622 { 623 bit = (0x1 << (31-pre)); 624 mask |= bit; 625 626 memcpy(&a, prefixscan->b->addr, sizeof(a)); 627 netid = ntohl(a.s_addr) & ~mask; 628 629 if((ntohl(a.s_addr) & bit) != 0) 630 bit = 0; 631 632 for(hostid=0; hostid<cnt[29-pre]; hostid++) 633 { 634 a.s_addr = htonl(netid | bit | hostid); 635 if(dealias_prefixscan_array_add(dealias, &array, outc, &a) != 0) 636 goto err; 637 } 638 } 639 640 *out = array; 641 return 0; 642 643 err: 644 dealias_prefixscan_array_free(array, *outc); 645 return -1; 646 } 647 648 static scamper_dealias_probe_t * 649 dealias_probe_udp_find(dealias_state_t *state, dealias_target_t *tgt, 650 uint16_t ipid, uint16_t sport, uint16_t dport) 651 { 652 scamper_dealias_probedef_t *def; 653 dealias_probe_t *dp; 654 dlist_node_t *n; 655 656 for(n=dlist_head_node(tgt->probes); n != NULL; n = dlist_node_next(n)) 657 { 658 dp = dlist_node_item(n); def = dp->probe->def; 659 if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_UDP(def) == 0 || 660 def->un.udp.sport != sport) 661 continue; 662 if(SCAMPER_ADDR_TYPE_IS_IPV4(tgt->addr) && dp->probe->ipid != ipid) 663 continue; 664 665 if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP) 666 { 667 if(def->un.udp.dport == dport) 668 return dp->probe; 669 } 670 else if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP_DPORT) 671 { 672 if(dp->match_field == dport) 673 return dp->probe; 674 } 675 } 676 677 return NULL; 678 } 679 680 static scamper_dealias_probe_t * 681 dealias_probe_tcp_find2(dealias_state_t *state, dealias_target_t *tgt, 682 uint16_t sport, uint16_t dport) 683 { 684 scamper_dealias_probedef_t *def; 685 dealias_probe_t *dp; 686 dlist_node_t *n; 687 688 for(n=dlist_head_node(tgt->probes); n != NULL; n = dlist_node_next(n)) 689 { 690 dp = dlist_node_item(n); def = dp->probe->def; 691 if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_TCP(def) == 0 || 692 def->un.tcp.dport != dport) 693 continue; 694 695 if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_TCP_ACK) 696 { 697 if(def->un.tcp.sport == sport) 698 return dp->probe; 699 } 700 else if(SCAMPER_DEALIAS_PROBEDEF_VARY_TCP_SPORT(def)) 701 { 702 if(dp->match_field == sport) 703 return dp->probe; 704 } 705 } 706 707 return NULL; 708 } 709 710 static scamper_dealias_probe_t * 711 dealias_probe_tcp_find(dealias_state_t *state, dealias_target_t *tgt, 712 uint16_t ipid, uint16_t sport, uint16_t dport) 713 { 714 scamper_dealias_probedef_t *def; 715 dealias_probe_t *dp; 716 dlist_node_t *n; 717 718 for(n=dlist_head_node(tgt->probes); n != NULL; n = dlist_node_next(n)) 719 { 720 dp = dlist_node_item(n); def = dp->probe->def; 721 if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_TCP(def) == 0 || 722 def->un.tcp.dport != dport) 723 continue; 724 if(SCAMPER_ADDR_TYPE_IS_IPV4(tgt->addr) && dp->probe->ipid != ipid) 725 continue; 726 727 if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_TCP_ACK) 728 { 729 if(def->un.tcp.sport == sport) 730 return dp->probe; 731 } 732 else if(SCAMPER_DEALIAS_PROBEDEF_VARY_TCP_SPORT(def)) 733 { 734 if(dp->match_field == sport) 735 return dp->probe; 736 } 737 } 738 739 return NULL; 740 } 741 742 static scamper_dealias_probe_t * 743 dealias_probe_icmp_find(dealias_state_t *state, dealias_target_t *tgt, 744 uint16_t ipid, uint8_t type, uint8_t code, 745 uint16_t id, uint16_t seq) 746 { 747 scamper_dealias_probedef_t *def; 748 dealias_probe_t *dp; 749 dlist_node_t *n; 750 uint8_t method; 751 752 if((SCAMPER_ADDR_TYPE_IS_IPV4(tgt->addr) && 753 type == ICMP_ECHO && code == 0) || 754 (SCAMPER_ADDR_TYPE_IS_IPV6(tgt->addr) && 755 type == ICMP6_ECHO_REQUEST && code == 0)) 756 method = SCAMPER_DEALIAS_PROBEDEF_METHOD_ICMP_ECHO; 757 else 758 return NULL; 759 760 for(n=dlist_head_node(tgt->probes); n != NULL; n = dlist_node_next(n)) 761 { 762 dp = dlist_node_item(n); def = dp->probe->def; 763 if(SCAMPER_ADDR_TYPE_IS_IPV4(tgt->addr) && dp->probe->ipid != ipid) 764 continue; 765 if(def->method == method && 766 def->un.icmp.id == id && dp->match_field == seq) 767 return dp->probe; 768 } 769 770 return NULL; 771 } 772 773 static scamper_dealias_probe_t * 774 dealias_probe_echoreq_find(dealias_state_t *state, dealias_target_t *tgt, 775 uint16_t id, uint16_t seq) 776 { 777 scamper_dealias_probedef_t *def; 778 dealias_probe_t *dp; 779 dlist_node_t *n; 780 781 for(n=dlist_head_node(tgt->probes); n != NULL; n = dlist_node_next(n)) 782 { 783 dp = dlist_node_item(n); def = dp->probe->def; 784 if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_ICMP_ECHO && 785 def->un.icmp.id == id && dp->match_field == seq) 786 return dp->probe; 787 } 788 789 return NULL; 790 } 791 792 static dealias_probedef_t * 793 dealias_mercator_def(scamper_dealias_t *dealias, dealias_state_t *state) 794 { 795 return state->pds[state->probe]; 796 } 797 798 static int dealias_mercator_postprobe(scamper_dealias_t *dealias, 799 dealias_state_t *state) 800 { 801 /* we just wait the specified number of seconds with mercator probes */ 802 scamper_dealias_mercator_t *mercator = dealias->data; 803 timeval_add_s(&state->next_tx, &state->last_tx, mercator->wait_timeout); 804 state->round++; 805 return 0; 806 } 807 808 static void dealias_mercator_handlereply(scamper_task_t *task, 809 scamper_dealias_probe_t *probe, 810 scamper_dealias_reply_t *reply, 811 scamper_dl_rec_t *dl) 812 { 813 if(SCAMPER_DEALIAS_REPLY_IS_ICMP_UNREACH_PORT(reply) && 814 scamper_addr_cmp(probe->def->dst, reply->src) != 0) 815 { 816 dealias_result(task, SCAMPER_DEALIAS_RESULT_ALIASES); 817 } 818 else 819 { 820 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 821 } 822 return; 823 } 824 825 static void dealias_mercator_handletimeout(scamper_task_t *task) 826 { 827 scamper_dealias_t *dealias = dealias_getdata(task); 828 scamper_dealias_mercator_t *mercator = dealias->data; 829 830 if(dealias->probec < mercator->attempts) 831 dealias_queue(task); 832 else 833 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 834 835 return; 836 } 837 838 static dealias_probedef_t * 839 dealias_ally_def(scamper_dealias_t *dealias, dealias_state_t *state) 840 { 841 return state->pds[state->probe]; 842 } 843 844 static int dealias_ally_postprobe(scamper_dealias_t *dealias, 845 dealias_state_t *state) 846 { 847 /* 848 * we wait a fixed amount of time before we send the next probe with 849 * ally. except when the last probe has been sent, where we wait for 850 * some other length of time for any final replies to come in 851 */ 852 scamper_dealias_ally_t *ally = dealias->data; 853 if(dealias->probec != ally->attempts) 854 timeval_add_ms(&state->next_tx, &state->last_tx, ally->wait_probe); 855 else 856 timeval_add_s(&state->next_tx, &state->last_tx, ally->wait_timeout); 857 if(++state->probe == 2) 858 { 859 state->probe = 0; 860 state->round++; 861 } 862 return 0; 863 } 864 865 static int dealias_ally_allzero(scamper_dealias_t *dealias) 866 { 867 uint32_t i; 868 uint16_t j; 869 870 if(dealias->probec == 0) 871 return 0; 872 if(SCAMPER_ADDR_TYPE_IS_IPV4(dealias->probes[0]->def->dst) == 0) 873 return 0; 874 875 for(i=0; i<dealias->probec; i++) 876 { 877 assert(dealias->probes[i] != NULL); 878 for(j=0; j<dealias->probes[i]->replyc; j++) 879 { 880 assert(dealias->probes[i]->replies[j] != NULL); 881 if(dealias->probes[i]->replies[j]->ipid != 0) 882 return 0; 883 } 884 } 885 886 return 1; 887 } 888 889 /* 890 * dealias_ally_handlereply_v6 891 * 892 * process the IPv6 response and signal to the caller what to do next. 893 * 894 * -1: error, stop probing now. 895 * 0: response is not useful, don't process the packet. 896 * 1: useful response, continue processing. 897 */ 898 static int dealias_ally_handlereply_v6(scamper_task_t *task, 899 scamper_dealias_probe_t *probe, 900 scamper_dealias_reply_t *reply, 901 scamper_dl_rec_t *dl) 902 { 903 scamper_dealias_t *dealias = dealias_getdata(task); 904 dealias_state_t *state = dealias_getstate(task); 905 dealias_probedef_t *pd = state->pds[probe->def->id]; 906 slist_node_t *sn; 907 int ptb = 0, discard = 0; 908 uint32_t i; 909 910 /* are we in a period where we're waiting for the receiver to get the PTB? */ 911 if(state->ptb_tx.tv_sec != 0 || slist_count(state->ptbq) > 0) 912 ptb = 1; 913 914 /* is the probe going to be discarded? */ 915 for(sn=slist_head_node(state->discard); sn != NULL; sn=slist_node_next(sn)) 916 { 917 if(slist_node_item(sn) == probe) 918 { 919 discard = 1; 920 break; 921 } 922 } 923 924 /* if the response contains an IP-ID, then we're good for this def */ 925 if((reply->flags & SCAMPER_DEALIAS_REPLY_FLAG_IPID32) != 0) 926 { 927 pd->flags |= DEALIAS_PROBEDEF_FLAG_RX_IPID; 928 return (discard == 0 && ptb == 0) ? 1 : 0; 929 } 930 931 /* should we send a packet too big for this packet? */ 932 if(probe->def->mtu != 0 && probe->def->mtu < dl->dl_ip_size && 933 (pd->flags & DEALIAS_PROBEDEF_FLAG_TX_PTB) == 0 && 934 (pd->flags & DEALIAS_PROBEDEF_FLAG_RX_IPID) == 0) 935 { 936 /* all prior probes are going to be discarded, so put them in the list */ 937 for(i=0; i<dealias->probec; i++) 938 { 939 if(slist_head_push(state->discard, dealias->probes[i]) == NULL) 940 return -1; 941 dealias->probes[i] = NULL; 942 } 943 dealias->probec = 0; 944 state->round = 0; 945 946 /* send a PTB */ 947 pd->flags |= DEALIAS_PROBEDEF_FLAG_TX_PTB; 948 if(dealias_ptb_add(state, dl, probe->def) != 0) 949 return -1; 950 dealias_queue(task); 951 return 0; 952 } 953 954 /* if we're probing for real and the response is not useful, halt */ 955 if(ptb == 0 && discard == 0) 956 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 957 958 return 0; 959 } 960 961 static void dealias_ally_handlereply(scamper_task_t *task, 962 scamper_dealias_probe_t *probe, 963 scamper_dealias_reply_t *reply, 964 scamper_dl_rec_t *dl) 965 { 966 scamper_dealias_t *dealias = dealias_getdata(task); 967 scamper_dealias_ally_t *ally = dealias->data; 968 scamper_dealias_probe_t *probes[5]; 969 uint32_t k; 970 int rc, probec = 0; 971 972 /* check to see if the response could be useful for alias resolution */ 973 if(probe->replyc != 1 || 974 !(SCAMPER_DEALIAS_REPLY_FROM_TARGET(probe, reply) || 975 (SCAMPER_DEALIAS_REPLY_IS_ICMP_TTL_EXP(reply) && 976 probe->def->ttl != 255))) 977 { 978 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 979 return; 980 } 981 982 if(SCAMPER_ADDR_TYPE_IS_IPV6(reply->src)) 983 { 984 rc = dealias_ally_handlereply_v6(task, probe, reply, dl); 985 if(rc == -1) goto err; 986 if(rc == 0) return; 987 } 988 989 /* can't make any decision unless at least two probes have been sent */ 990 if(dealias->probec < 2) 991 return; 992 993 /* find the probe in its place */ 994 for(k=0; k<dealias->probec; k++) 995 if(probe == dealias->probes[k]) 996 break; 997 if(k == dealias->probec) 998 return; 999 1000 if(k >= 1 && dealias->probes[k-1]->replyc == 1) 1001 { 1002 if(k >= 2 && dealias->probes[k-2]->replyc == 1) 1003 probes[probec++] = dealias->probes[k-2]; 1004 probes[probec++] = dealias->probes[k-1]; 1005 } 1006 probes[probec++] = dealias->probes[k]; 1007 if(k+1 < dealias->probec && dealias->probes[k+1]->replyc == 1) 1008 { 1009 probes[probec++] = dealias->probes[k+1]; 1010 if(k+2 < dealias->probec && dealias->probes[k+2]->replyc == 1) 1011 probes[probec++] = dealias->probes[k+2]; 1012 } 1013 1014 /* not enough adjacent responses to make a classification */ 1015 if(probec < 2) 1016 return; 1017 1018 /* check if the replies are in sequence */ 1019 if(SCAMPER_DEALIAS_ALLY_IS_NOBS(dealias)) 1020 rc = scamper_dealias_ipid_inseq(probes, probec, ally->fudge, 0); 1021 else 1022 rc = scamper_dealias_ipid_inseq(probes, probec, ally->fudge, 2); 1023 if(rc == 0) 1024 dealias_result(task, SCAMPER_DEALIAS_RESULT_NOTALIASES); 1025 1026 return; 1027 1028 err: 1029 dealias_handleerror(task, errno); 1030 return; 1031 } 1032 1033 static void dealias_ally_handletimeout(scamper_task_t *task) 1034 { 1035 scamper_dealias_t *dealias = dealias_getdata(task); 1036 scamper_dealias_ally_t *ally = dealias->data; 1037 uint32_t k; 1038 int rc; 1039 1040 /* do a final classification */ 1041 if(dealias->probec == ally->attempts) 1042 { 1043 for(k=0; k<dealias->probec; k++) 1044 if(dealias->probes[k]->replyc != 1) 1045 break; 1046 1047 if(k != dealias->probec) 1048 { 1049 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 1050 return; 1051 } 1052 1053 if(SCAMPER_DEALIAS_ALLY_IS_NOBS(dealias)) 1054 rc = scamper_dealias_ipid_inseq(dealias->probes, k, ally->fudge, 0); 1055 else 1056 rc = scamper_dealias_ipid_inseq(dealias->probes, k, ally->fudge, 3); 1057 1058 /* check if the replies are in sequence */ 1059 if(rc == 1) 1060 dealias_result(task, SCAMPER_DEALIAS_RESULT_ALIASES); 1061 else if(dealias_ally_allzero(dealias) != 0) 1062 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 1063 else 1064 dealias_result(task, SCAMPER_DEALIAS_RESULT_NOTALIASES); 1065 } 1066 1067 return; 1068 } 1069 1070 static dealias_probedef_t * 1071 dealias_radargun_def(scamper_dealias_t *dealias, dealias_state_t *state) 1072 { 1073 scamper_dealias_radargun_t *rg = dealias->data; 1074 dealias_radargun_t *rgstate = state->methodstate; 1075 if((rg->flags & SCAMPER_DEALIAS_RADARGUN_FLAG_SHUFFLE) == 0) 1076 return state->pds[state->probe]; 1077 return state->pds[rgstate->order[rgstate->i++]]; 1078 } 1079 1080 static int dealias_radargun_postprobe(scamper_dealias_t *dealias, 1081 dealias_state_t *state) 1082 { 1083 scamper_dealias_radargun_t *rg = dealias->data; 1084 dealias_radargun_t *rgstate = state->methodstate; 1085 struct timeval *tv = &state->last_tx; 1086 1087 if(state->probe == 0) 1088 timeval_add_ms(&rgstate->next_round, tv, rg->wait_round); 1089 1090 state->probe++; 1091 1092 if(state->probe < rg->probedefc) 1093 { 1094 timeval_add_ms(&state->next_tx, tv, rg->wait_probe); 1095 } 1096 else 1097 { 1098 state->probe = 0; 1099 state->round++; 1100 1101 if(state->round < rg->attempts) 1102 { 1103 if(timeval_cmp(tv, &rgstate->next_round) >= 0 || 1104 timeval_diff_ms(&rgstate->next_round, tv) < rg->wait_probe) 1105 { 1106 timeval_add_ms(&state->next_tx, tv, rg->wait_probe); 1107 } 1108 else 1109 { 1110 timeval_cpy(&state->next_tx, &rgstate->next_round); 1111 } 1112 1113 if((rg->flags & SCAMPER_DEALIAS_RADARGUN_FLAG_SHUFFLE) != 0) 1114 { 1115 if(shuffle32(rgstate->order, rg->probedefc) != 0) 1116 return -1; 1117 rgstate->i = 0; 1118 } 1119 } 1120 else 1121 { 1122 /* we're all finished */ 1123 timeval_add_s(&state->next_tx, tv, rg->wait_timeout); 1124 } 1125 } 1126 return 0; 1127 } 1128 1129 static void dealias_radargun_handletimeout(scamper_task_t *task) 1130 { 1131 scamper_dealias_t *dealias = dealias_getdata(task); 1132 dealias_state_t *state = dealias_getstate(task); 1133 scamper_dealias_radargun_t *radargun = dealias->data; 1134 1135 /* check to see if we are now finished */ 1136 if(state->round != radargun->attempts) 1137 dealias_queue(task); 1138 else 1139 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 1140 1141 return; 1142 } 1143 1144 static void dealias_radargun_handlereply(scamper_task_t *task, 1145 scamper_dealias_probe_t *probe, 1146 scamper_dealias_reply_t *reply, 1147 scamper_dl_rec_t *dl) 1148 { 1149 dealias_state_t *state = dealias_getstate(task); 1150 if(SCAMPER_ADDR_TYPE_IS_IPV6(probe->def->dst) && 1151 (reply->flags & SCAMPER_DEALIAS_REPLY_FLAG_IPID32) == 0 && 1152 probe->def->mtu != 0 && probe->def->mtu < dl->dl_ip_size) 1153 { 1154 if(dealias_ptb_add(state, dl, probe->def) != 0) 1155 dealias_handleerror(task, errno); 1156 else 1157 dealias_queue(task); 1158 } 1159 return; 1160 } 1161 1162 static dealias_probedef_t * 1163 dealias_prefixscan_def(scamper_dealias_t *dealias, dealias_state_t *state) 1164 { 1165 return state->pds[state->probe]; 1166 } 1167 1168 static int dealias_prefixscan_postprobe(scamper_dealias_t *dealias, 1169 dealias_state_t *state) 1170 { 1171 scamper_dealias_prefixscan_t *prefixscan = dealias->data; 1172 dealias_prefixscan_t *pfstate = state->methodstate; 1173 scamper_dealias_probedef_t *def = &state->probedefs[state->probe]; 1174 1175 if(def->id == 0) 1176 pfstate->round0++; 1177 else 1178 pfstate->round++; 1179 pfstate->attempt++; 1180 pfstate->replyc = 0; 1181 timeval_add_ms(&state->next_tx, &state->last_tx, prefixscan->wait_probe); 1182 1183 return 0; 1184 } 1185 1186 static int dealias_prefixscan_next(scamper_task_t *task) 1187 { 1188 scamper_dealias_t *dealias = dealias_getdata(task); 1189 dealias_state_t *state = dealias_getstate(task); 1190 dealias_prefixscan_t *pfstate = state->methodstate; 1191 scamper_dealias_prefixscan_t *prefixscan = dealias->data; 1192 scamper_dealias_probedef_t *def = &pfstate->probedefs[state->probedefc-1]; 1193 uint32_t *defids = NULL, p; 1194 int q; 1195 1196 /* 1197 * if the address we'd otherwise probe has been observed as an alias of 1198 * prefixscan->a, then we don't need to bother probing it. 1199 */ 1200 if(array_find((void **)pfstate->aaliases, pfstate->aaliasc, def->dst, 1201 (array_cmp_t)scamper_addr_cmp) != NULL) 1202 { 1203 prefixscan->ab = scamper_addr_use(def->dst); 1204 prefixscan->flags |= SCAMPER_DEALIAS_PREFIXSCAN_FLAG_CSA; 1205 dealias_result(task, SCAMPER_DEALIAS_RESULT_ALIASES); 1206 return 0; 1207 } 1208 1209 /* remember the probedef used with each probe */ 1210 if((defids = malloc_zero(sizeof(uint32_t) * dealias->probec)) == NULL) 1211 { 1212 printerror(__func__, "could not malloc defids"); 1213 goto err; 1214 } 1215 for(p=0; p<dealias->probec; p++) 1216 defids[p] = dealias->probes[p]->def->id; 1217 1218 /* add the probedef */ 1219 if(scamper_dealias_prefixscan_probedef_add(dealias, def) != 0) 1220 { 1221 printerror(__func__, "could not add probedef"); 1222 goto err; 1223 } 1224 1225 /* re-set the pointers to the probedefs */ 1226 for(q=0; q<state->pdc; q++) 1227 state->pds[q]->def = &prefixscan->probedefs[q]; 1228 for(p=0; p<dealias->probec; p++) 1229 dealias->probes[p]->def = &prefixscan->probedefs[defids[p]]; 1230 free(defids); defids = NULL; 1231 1232 def = &prefixscan->probedefs[prefixscan->probedefc-1]; 1233 if(dealias_probedef_add(state, def) != 0) 1234 goto err; 1235 1236 state->probedefs = prefixscan->probedefs; 1237 state->probedefc = prefixscan->probedefc; 1238 1239 return 0; 1240 1241 err: 1242 if(defids != NULL) free(defids); 1243 return -1; 1244 } 1245 1246 static void dealias_prefixscan_handlereply(scamper_task_t *task, 1247 scamper_dealias_probe_t *probe, 1248 scamper_dealias_reply_t *reply, 1249 scamper_dl_rec_t *dl) 1250 { 1251 scamper_dealias_t *dealias = dealias_getdata(task); 1252 dealias_state_t *state = dealias_getstate(task); 1253 scamper_dealias_prefixscan_t *prefixscan = dealias->data; 1254 dealias_prefixscan_t *pfstate = state->methodstate; 1255 scamper_dealias_probe_t **probes = NULL; 1256 dealias_probedef_t *pd = state->pds[probe->def->id]; 1257 uint32_t defid; 1258 int p, s, seq; 1259 1260 /* if the reply is not for the most recently sent probe */ 1261 if(probe != dealias->probes[dealias->probec-1]) 1262 return; 1263 1264 /* if the reply is not the first reply for this probe */ 1265 if(probe->replyc != 1) 1266 return; 1267 1268 if(probe->ipid == reply->ipid && ++pd->echo >= 2) 1269 { 1270 if(probe->def->id != 0) 1271 goto prefixscan_next; 1272 dealias_result(task, SCAMPER_DEALIAS_RESULT_IPIDECHO); 1273 return; 1274 } 1275 1276 /* 1277 * if we are currently waiting for our turn to probe, then for now 1278 * ignore the late response. 1279 */ 1280 if(scamper_task_queue_isprobe(task)) 1281 return; 1282 1283 /* check if we should count this reply as a valid response */ 1284 if(SCAMPER_DEALIAS_REPLY_FROM_TARGET(probe, reply)) 1285 pfstate->replyc++; 1286 else 1287 return; 1288 1289 /* 1290 * if we sent a UDP probe, and got a port unreachable message back from a 1291 * different interface, then we might be able to use that for alias 1292 * resolution. 1293 */ 1294 if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_UDP(probe->def) && 1295 SCAMPER_DEALIAS_REPLY_IS_ICMP_UNREACH_PORT(reply) && 1296 scamper_addr_cmp(probe->def->dst, reply->src) != 0) 1297 { 1298 if(probe->def->id == 0) 1299 { 1300 /* 1301 * if the reply is for prefixscan->a, then keep a record of the 1302 * address of the interface used in the response. 1303 */ 1304 if(array_find((void **)pfstate->aaliases, pfstate->aaliasc, 1305 reply->src, (array_cmp_t)scamper_addr_cmp) == NULL) 1306 { 1307 if(array_insert((void ***)&pfstate->aaliases, &pfstate->aaliasc, 1308 reply->src, (array_cmp_t)scamper_addr_cmp) != 0) 1309 { 1310 printerror(__func__, "could not add to aaliases"); 1311 goto err; 1312 } 1313 scamper_addr_use(reply->src); 1314 } 1315 } 1316 else 1317 { 1318 /* 1319 * if the address used to reply is probedef->a, or is one of the 1320 * aliases previously observed for a, then we infer aliases. 1321 */ 1322 if(scamper_addr_cmp(reply->src, prefixscan->a) == 0 || 1323 array_find((void **)pfstate->aaliases, pfstate->aaliasc, 1324 reply->src, (array_cmp_t)scamper_addr_cmp) != NULL) 1325 { 1326 prefixscan->ab = scamper_addr_use(probe->def->dst); 1327 prefixscan->flags |= SCAMPER_DEALIAS_PREFIXSCAN_FLAG_CSA; 1328 dealias_result(task, SCAMPER_DEALIAS_RESULT_ALIASES); 1329 return; 1330 } 1331 } 1332 } 1333 1334 /* 1335 * another probe received in sequence. 1336 * we will probably send another probe, so reset attempts 1337 */ 1338 seq = ++pfstate->seq; 1339 pfstate->attempt = 0; 1340 1341 assert(seq >= 1 && seq <= prefixscan->replyc); 1342 1343 /* 1344 * if we don't have a reply from each IP address yet, then keep probing. 1345 * ideally, this could be optimised to use the previous observed IP-ID 1346 * for probedef zero if we have probed other probedefs in the interim and 1347 * have just obtained a reply. 1348 */ 1349 if(seq < 2) 1350 { 1351 if(state->probe != 0) 1352 { 1353 state->probe = 0; 1354 return; 1355 } 1356 1357 if(state->probedefc == 1) 1358 { 1359 /* figure out what we're going to probe next */ 1360 if(dealias_prefixscan_next(task) != 0) 1361 goto err; 1362 1363 /* if it turns out we don't need to probe, handle that */ 1364 if(dealias->result == SCAMPER_DEALIAS_RESULT_ALIASES) 1365 return; 1366 } 1367 1368 state->probe = state->probedefc-1; 1369 dealias_queue(task); 1370 return; 1371 } 1372 1373 if((probes = malloc_zero(sizeof(scamper_dealias_probe_t *) * seq)) == NULL) 1374 { 1375 printerror(__func__, "could not malloc probes"); 1376 goto err; 1377 } 1378 probes[seq-1] = probe; 1379 1380 /* if the reply was not for the first probe, then skip over earlier probes */ 1381 p = dealias->probec-2; defid = probe->def->id; 1382 while(p >= 0 && dealias->probes[p]->def->id == defid) 1383 p--; 1384 1385 for(s=seq-1; s>0; s--) 1386 { 1387 if(p < 0) 1388 goto err; 1389 1390 if(probes[s]->def->id == 0) 1391 defid = state->probedefc - 1; 1392 else 1393 defid = 0; 1394 1395 while(p >= 0) 1396 { 1397 assert(defid == dealias->probes[p]->def->id); 1398 1399 /* skip over any unresponded to probes */ 1400 if(dealias->probes[p]->replyc == 0) 1401 { 1402 p--; 1403 continue; 1404 } 1405 1406 /* record the probe for this defid */ 1407 probes[s-1] = dealias->probes[p]; 1408 1409 /* skip over any probes that proceeded this one with same defid */ 1410 while(p >= 0 && dealias->probes[p]->def->id == defid) 1411 p--; 1412 1413 break; 1414 } 1415 } 1416 1417 /* 1418 * check to see if the sequence of replies indicates an alias. free 1419 * the probes array before we check the result, as it is easiest here. 1420 */ 1421 if(SCAMPER_DEALIAS_PREFIXSCAN_IS_NOBS(dealias)) 1422 p = scamper_dealias_ipid_inseq(probes, seq, prefixscan->fudge, 0); 1423 else 1424 p = scamper_dealias_ipid_inseq(probes, seq, prefixscan->fudge, 1425 seq < prefixscan->replyc ? 2 : 3); 1426 free(probes); probes = NULL; 1427 if(p == -1) 1428 goto err; 1429 1430 if(p == 1) 1431 { 1432 if(seq == prefixscan->replyc) 1433 { 1434 p = state->probedefc-1; 1435 prefixscan->ab = scamper_addr_use(prefixscan->probedefs[p].dst); 1436 dealias_result(task, SCAMPER_DEALIAS_RESULT_ALIASES); 1437 return; 1438 } 1439 1440 if(state->probe == 0) 1441 state->probe = state->probedefc - 1; 1442 else 1443 state->probe = 0; 1444 1445 return; 1446 } 1447 1448 prefixscan_next: 1449 /* if there are no other addresses to try, then finish */ 1450 if(state->probedefc-1 == pfstate->probedefc) 1451 { 1452 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 1453 return; 1454 } 1455 1456 if(dealias_prefixscan_next(task) != 0) 1457 goto err; 1458 if(dealias->result == SCAMPER_DEALIAS_RESULT_ALIASES) 1459 return; 1460 1461 pfstate->round = 0; 1462 pfstate->attempt = 0; 1463 state->probe = state->probedefc-1; 1464 1465 if(dealias->probes[dealias->probec-1]->def->id == 0) 1466 pfstate->seq = 1; 1467 else 1468 pfstate->seq = 0; 1469 1470 dealias_queue(task); 1471 return; 1472 1473 err: 1474 if(probes != NULL) free(probes); 1475 dealias_handleerror(task, errno); 1476 return; 1477 } 1478 1479 static void dealias_prefixscan_handletimeout(scamper_task_t *task) 1480 { 1481 scamper_dealias_t *dealias = dealias_getdata(task); 1482 dealias_state_t *state = dealias_getstate(task); 1483 dealias_prefixscan_t *pfstate = state->methodstate; 1484 scamper_dealias_prefixscan_t *prefixscan; 1485 scamper_dealias_probedef_t *def; 1486 scamper_dealias_probe_t *probe; 1487 1488 prefixscan = dealias->data; 1489 probe = dealias->probes[dealias->probec-1]; 1490 def = probe->def; 1491 1492 if(pfstate->replyc == 0) 1493 { 1494 /* if we're allowed to send another attempt, then do so */ 1495 if(pfstate->attempt < prefixscan->attempts) 1496 { 1497 goto done; 1498 } 1499 1500 /* 1501 * if the probed address is unresponsive, and it is not prefixscan->a, 1502 * and there are other addresses to try, then probe one now 1503 */ 1504 if(def->id != 0 && state->probedefc-1 < (uint32_t)pfstate->probedefc) 1505 { 1506 if(dealias_prefixscan_next(task) != 0) 1507 goto err; 1508 1509 /* if it turns out we don't need to probe, handle that */ 1510 if(dealias->result == SCAMPER_DEALIAS_RESULT_ALIASES) 1511 return; 1512 1513 pfstate->round = 0; 1514 pfstate->seq = 0; 1515 pfstate->attempt = 0; 1516 state->probe = state->probedefc-1; 1517 1518 goto done; 1519 } 1520 1521 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 1522 return; 1523 } 1524 1525 /* keep going! */ 1526 done: 1527 if(state->probe == 0) 1528 state->round = pfstate->round0; 1529 else 1530 state->round = pfstate->round; 1531 1532 return; 1533 1534 err: 1535 dealias_handleerror(task, errno); 1536 return; 1537 } 1538 1539 static dealias_probedef_t * 1540 dealias_bump_def(scamper_dealias_t *dealias, dealias_state_t *state) 1541 { 1542 return state->pds[state->probe]; 1543 } 1544 1545 static int dealias_bump_postprobe(scamper_dealias_t *dealias, 1546 dealias_state_t *state) 1547 { 1548 scamper_dealias_bump_t *bump = dealias->data; 1549 timeval_add_ms(&state->next_tx, &state->last_tx, bump->wait_probe); 1550 return 0; 1551 } 1552 1553 static void dealias_bump_handletimeout(scamper_task_t *task) 1554 { 1555 scamper_dealias_t *dealias = dealias_getdata(task); 1556 dealias_state_t *state = dealias_getstate(task); 1557 dealias_bump_t *bs = state->methodstate; 1558 scamper_dealias_bump_t *bump = dealias->data; 1559 scamper_dealias_probe_t *probes[3]; 1560 uint32_t i, x, y; 1561 1562 if(bs->step < 2) 1563 { 1564 bs->step++; 1565 } 1566 else if(bs->step == 2) 1567 { 1568 /* check if the last set of probes are in sequence */ 1569 for(i=0; i<3; i++) 1570 if(dealias->probes[dealias->probec-3+i]->replyc == 1) 1571 probes[i] = dealias->probes[dealias->probec-3+i]; 1572 else 1573 break; 1574 1575 if(i != 3) 1576 goto none; 1577 1578 if(scamper_dealias_ipid_inseq(probes, 3, 0, 0) != 1) 1579 { 1580 dealias_result(task, SCAMPER_DEALIAS_RESULT_NOTALIASES); 1581 return; 1582 } 1583 1584 if(bs->attempt > bump->attempts) 1585 { 1586 dealias_result(task, SCAMPER_DEALIAS_RESULT_ALIASES); 1587 return; 1588 } 1589 1590 x = probes[1]->replies[0]->ipid; 1591 y = probes[2]->replies[0]->ipid; 1592 if(x < y) 1593 i = y - x; 1594 else 1595 i = 0x10000 + y - x; 1596 1597 if(i * 2 > 65535) 1598 goto none; 1599 1600 bs->bump = i * 2; 1601 if(bs->bump == 2) 1602 bs->bump++; 1603 1604 if(bs->bump > bump->bump_limit) 1605 goto none; 1606 1607 bs->step++; 1608 } 1609 else if(bs->step == 3) 1610 { 1611 if(bs->bump != 0) 1612 { 1613 bs->bump--; 1614 return; 1615 } 1616 1617 bs->attempt++; 1618 bs->step = 1; 1619 } 1620 1621 if(state->probe == 1) 1622 state->probe = 0; 1623 else 1624 state->probe = 1; 1625 1626 return; 1627 1628 none: 1629 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 1630 return; 1631 } 1632 1633 static void dealias_bump_handlereply(scamper_task_t *task, 1634 scamper_dealias_probe_t *probe, 1635 scamper_dealias_reply_t *reply, 1636 scamper_dl_rec_t *dl) 1637 { 1638 /* check to see if the response could be useful for alias resolution */ 1639 if(SCAMPER_DEALIAS_REPLY_FROM_TARGET(probe,reply) == 0 || probe->replyc != 1) 1640 { 1641 dealias_result(task, SCAMPER_DEALIAS_RESULT_NONE); 1642 return; 1643 } 1644 1645 return; 1646 } 1647 1648 static void do_dealias_handle_dl(scamper_task_t *task, scamper_dl_rec_t *dl) 1649 { 1650 static void (*const func[])(scamper_task_t *, scamper_dealias_probe_t *, 1651 scamper_dealias_reply_t *, 1652 scamper_dl_rec_t *) = { 1653 dealias_mercator_handlereply, 1654 dealias_ally_handlereply, 1655 dealias_radargun_handlereply, 1656 dealias_prefixscan_handlereply, 1657 dealias_bump_handlereply, 1658 }; 1659 scamper_dealias_probe_t *probe = NULL; 1660 scamper_dealias_reply_t *reply = NULL; 1661 scamper_dealias_t *dealias = dealias_getdata(task); 1662 dealias_state_t *state = dealias_getstate(task); 1663 dealias_target_t *tgt; 1664 scamper_addr_t a; 1665 int v4 = 0; 1666 1667 /* if we haven't sent a probe yet, then we have nothing to match */ 1668 if(dealias->probec == 0) 1669 return; 1670 1671 if(dl->dl_af == AF_INET) 1672 v4 = 1; 1673 else if(dl->dl_af != AF_INET6) 1674 return; 1675 1676 if(v4 && SCAMPER_DL_IS_TCP(dl)) 1677 { 1678 if(scamper_dl_rec_src(dl, &a) != 0 || 1679 (tgt = dealias_target_find(state, &a)) == NULL) 1680 return; 1681 probe = dealias_probe_tcp_find2(state, tgt, dl->dl_tcp_dport, 1682 dl->dl_tcp_sport); 1683 scamper_dl_rec_tcp_print(dl); 1684 } 1685 else if(state->flags & DEALIAS_STATE_FLAG_DL && SCAMPER_DL_IS_ICMP(dl)) 1686 { 1687 /* if the ICMP type is not something that we care for, then drop it */ 1688 if(SCAMPER_DL_IS_ICMP_TTL_EXP(dl) || 1689 SCAMPER_DL_IS_ICMP_UNREACH(dl) || 1690 SCAMPER_DL_IS_ICMP_PACKET_TOO_BIG(dl)) 1691 { 1692 /* the IPID value used is expected to be of the form 0xabab */ 1693 if(v4 && (dl->dl_icmp_ip_id & 0xff) != (dl->dl_icmp_ip_id >> 8)) 1694 return; 1695 /* get the address to match with */ 1696 if(scamper_dl_rec_icmp_ip_dst(dl, &a) != 0 || 1697 (tgt = dealias_target_find(state, &a)) == NULL) 1698 return; 1699 1700 if(dl->dl_icmp_ip_proto == IPPROTO_UDP) 1701 probe = dealias_probe_udp_find(state, tgt, dl->dl_icmp_ip_id, 1702 dl->dl_icmp_udp_sport, 1703 dl->dl_icmp_udp_dport); 1704 else if(dl->dl_icmp_ip_proto == IPPROTO_ICMP || 1705 dl->dl_icmp_ip_proto == IPPROTO_ICMPV6) 1706 probe = dealias_probe_icmp_find(state, tgt, dl->dl_icmp_ip_id, 1707 dl->dl_icmp_icmp_type, 1708 dl->dl_icmp_icmp_code, 1709 dl->dl_icmp_icmp_id, 1710 dl->dl_icmp_icmp_seq); 1711 else if(dl->dl_icmp_ip_proto == IPPROTO_TCP) 1712 probe = dealias_probe_tcp_find(state, tgt, dl->dl_icmp_ip_id, 1713 dl->dl_icmp_tcp_sport, 1714 dl->dl_icmp_tcp_dport); 1715 } 1716 else if(SCAMPER_DL_IS_ICMP_ECHO_REPLY(dl) != 0) 1717 { 1718 if(scamper_dl_rec_src(dl, &a) != 0 || 1719 (tgt = dealias_target_find(state, &a)) == NULL) 1720 return; 1721 probe = dealias_probe_echoreq_find(state, tgt, 1722 dl->dl_icmp_id, dl->dl_icmp_seq); 1723 } 1724 else return; 1725 1726 scamper_dl_rec_icmp_print(dl); 1727 } 1728 1729 if(probe == NULL || scamper_dl_rec_src(dl, &a) != 0) 1730 return; 1731 1732 if((reply = scamper_dealias_reply_alloc()) == NULL) 1733 { 1734 scamper_debug(__func__, "could not alloc reply"); 1735 goto err; 1736 } 1737 1738 if(scamper_addr_cmp(&a, probe->def->dst) == 0) 1739 { 1740 reply->src = scamper_addr_use(probe->def->dst); 1741 } 1742 else if((reply->src=scamper_addrcache_get(addrcache,a.type,a.addr)) == NULL) 1743 { 1744 scamper_debug(__func__, "could not get address from cache"); 1745 goto err; 1746 } 1747 timeval_cpy(&reply->rx, &dl->dl_tv); 1748 reply->ttl = dl->dl_ip_ttl; 1749 reply->proto = dl->dl_ip_proto; 1750 1751 if(v4) 1752 { 1753 reply->ipid = dl->dl_ip_id; 1754 } 1755 else if(SCAMPER_DL_IS_IP_FRAG(dl)) 1756 { 1757 reply->flags |= SCAMPER_DEALIAS_REPLY_FLAG_IPID32; 1758 reply->ipid32 = dl->dl_ip6_id; 1759 } 1760 1761 if(SCAMPER_DL_IS_TCP(dl)) 1762 { 1763 reply->tcp_flags = dl->dl_tcp_flags; 1764 } 1765 else 1766 { 1767 reply->icmp_type = dl->dl_icmp_type; 1768 reply->icmp_code = dl->dl_icmp_code; 1769 reply->icmp_q_ip_ttl = dl->dl_icmp_ip_ttl; 1770 } 1771 1772 if(scamper_dealias_reply_add(probe, reply) != 0) 1773 { 1774 scamper_debug(__func__, "could not add reply to probe"); 1775 goto err; 1776 } 1777 1778 if(func[dealias->method-1] != NULL) 1779 func[dealias->method-1](task, probe, reply, dl); 1780 1781 return; 1782 1783 err: 1784 if(reply != NULL) scamper_dealias_reply_free(reply); 1785 dealias_handleerror(task, errno); 1786 return; 1787 } 1788 1789 static void do_dealias_handle_icmp(scamper_task_t *task,scamper_icmp_resp_t *ir) 1790 { 1791 static void (*const func[])(scamper_task_t *, scamper_dealias_probe_t *, 1792 scamper_dealias_reply_t *, 1793 scamper_dl_rec_t *) = { 1794 dealias_mercator_handlereply, 1795 dealias_ally_handlereply, 1796 NULL, /* radargun */ 1797 dealias_prefixscan_handlereply, 1798 dealias_bump_handlereply, 1799 }; 1800 scamper_dealias_probe_t *probe = NULL; 1801 scamper_dealias_reply_t *reply = NULL; 1802 scamper_dealias_t *dealias = dealias_getdata(task); 1803 dealias_state_t *state = dealias_getstate(task); 1804 dealias_target_t *tgt; 1805 scamper_addr_t a; 1806 1807 /* if we haven't sent a probe yet, then we have nothing to match */ 1808 if(dealias->probec == 0) 1809 return; 1810 1811 /* are we handling all responses using datalink sockets? */ 1812 if((state->flags & DEALIAS_STATE_FLAG_DL) != 0) 1813 return; 1814 1815 /* if the ICMP type is not something that we care for, then drop it */ 1816 if(SCAMPER_ICMP_RESP_IS_TTL_EXP(ir) || 1817 SCAMPER_ICMP_RESP_IS_UNREACH(ir) || 1818 SCAMPER_ICMP_RESP_IS_PACKET_TOO_BIG(ir)) 1819 { 1820 if(SCAMPER_ICMP_RESP_INNER_IS_SET(ir) == 0 || ir->ir_inner_ip_off != 0) 1821 return; 1822 1823 /* the IPID value used is expected to be of the form 0xabab */ 1824 if(ir->ir_af == AF_INET && 1825 (ir->ir_inner_ip_id & 0xff) != (ir->ir_inner_ip_id >> 8)) 1826 return; 1827 1828 if(scamper_icmp_resp_inner_dst(ir, &a) != 0 || 1829 (tgt = dealias_target_find(state, &a)) == NULL) 1830 return; 1831 1832 if(ir->ir_inner_ip_proto == IPPROTO_UDP) 1833 probe = dealias_probe_udp_find(state, tgt, ir->ir_inner_ip_id, 1834 ir->ir_inner_udp_sport, 1835 ir->ir_inner_udp_dport); 1836 else if(ir->ir_inner_ip_proto == IPPROTO_ICMP || 1837 ir->ir_inner_ip_proto == IPPROTO_ICMPV6) 1838 probe = dealias_probe_icmp_find(state, tgt, ir->ir_inner_ip_id, 1839 ir->ir_inner_icmp_type, 1840 ir->ir_inner_icmp_code, 1841 ir->ir_inner_icmp_id, 1842 ir->ir_inner_icmp_seq); 1843 else if(ir->ir_inner_ip_proto == IPPROTO_TCP) 1844 probe = dealias_probe_tcp_find(state, tgt, ir->ir_inner_ip_id, 1845 ir->ir_inner_tcp_sport, 1846 ir->ir_inner_tcp_dport); 1847 1848 if(scamper_icmp_resp_src(ir, &a) != 0) 1849 return; 1850 } 1851 else if(SCAMPER_ICMP_RESP_IS_ECHO_REPLY(ir) != 0) 1852 { 1853 if(scamper_icmp_resp_src(ir, &a) != 0 || 1854 (tgt = dealias_target_find(state, &a)) == NULL) 1855 return; 1856 probe = dealias_probe_echoreq_find(state, tgt, 1857 ir->ir_icmp_id, ir->ir_icmp_seq); 1858 } 1859 1860 if(probe == NULL) 1861 return; 1862 1863 scamper_icmp_resp_print(ir); 1864 1865 if((reply = scamper_dealias_reply_alloc()) == NULL) 1866 { 1867 scamper_debug(__func__, "could not alloc reply"); 1868 goto err; 1869 } 1870 if(scamper_addr_cmp(&a, probe->def->dst) == 0) 1871 { 1872 reply->src = scamper_addr_use(probe->def->dst); 1873 } 1874 else if((reply->src=scamper_addrcache_get(addrcache,a.type,a.addr)) == NULL) 1875 { 1876 scamper_debug(__func__, "could not get address from cache"); 1877 goto err; 1878 } 1879 timeval_cpy(&reply->rx, &ir->ir_rx); 1880 reply->ttl = (uint8_t)ir->ir_ip_ttl; 1881 reply->icmp_type = ir->ir_icmp_type; 1882 reply->icmp_code = ir->ir_icmp_code; 1883 reply->icmp_q_ip_ttl = ir->ir_inner_ip_ttl; 1884 1885 if(ir->ir_af == AF_INET) 1886 { 1887 reply->ipid = ir->ir_ip_id; 1888 reply->proto = IPPROTO_ICMP; 1889 } 1890 else 1891 { 1892 reply->proto = IPPROTO_ICMPV6; 1893 } 1894 1895 if(scamper_dealias_reply_add(probe, reply) != 0) 1896 { 1897 scamper_debug(__func__, "could not add reply to probe"); 1898 goto err; 1899 } 1900 1901 if(func[dealias->method-1] != NULL) 1902 func[dealias->method-1](task, probe, reply, NULL); 1903 return; 1904 1905 err: 1906 if(reply != NULL) scamper_dealias_reply_free(reply); 1907 dealias_handleerror(task, errno); 1908 return; 1909 } 1910 1911 static void do_dealias_handle_timeout(scamper_task_t *task) 1912 { 1913 static void (*const func[])(scamper_task_t *) = { 1914 dealias_mercator_handletimeout, 1915 dealias_ally_handletimeout, 1916 dealias_radargun_handletimeout, 1917 dealias_prefixscan_handletimeout, 1918 dealias_bump_handletimeout, 1919 }; 1920 scamper_dealias_t *dealias = dealias_getdata(task); 1921 func[dealias->method-1](task); 1922 return; 1923 } 1924 1925 /* 1926 * dealias_state_probe 1927 * 1928 * record the fact that a probe was sent 1929 */ 1930 static int dealias_state_probe(dealias_state_t *state, 1931 dealias_probedef_t *pdef, 1932 scamper_dealias_probe_t *probe, 1933 scamper_probe_t *pr) 1934 { 1935 dealias_probe_t *dp = NULL; 1936 1937 /* allocate a structure to record this probe's details */ 1938 if((dp = malloc_zero(sizeof(dealias_probe_t))) == NULL) 1939 { 1940 printerror(__func__, "could not malloc dealias_probe_t"); 1941 goto err; 1942 } 1943 if(pdef->def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP_DPORT) 1944 dp->match_field = pr->pr_udp_dport; 1945 else if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_ICMP(pdef->def)) 1946 dp->match_field = pr->pr_icmp_seq; 1947 else if(SCAMPER_DEALIAS_PROBEDEF_VARY_TCP_SPORT(pdef->def)) 1948 dp->match_field = pr->pr_tcp_sport; 1949 1950 dp->probe = probe; 1951 dp->target = pdef->target; 1952 1953 if((dp->target_node = dlist_head_push(dp->target->probes, dp)) == NULL || 1954 dlist_tail_push(state->recent_probes, dp) == NULL) 1955 { 1956 printerror(__func__, "could not push to lists"); 1957 goto err; 1958 } 1959 1960 return 0; 1961 1962 err: 1963 if(dp != NULL) free(dp); 1964 return -1; 1965 } 1966 1967 static void dealias_prefixscan_free(void *data) 1968 { 1969 dealias_prefixscan_t *pfstate = data; 1970 uint32_t j; 1971 int k; 1972 1973 if(pfstate->probedefs != NULL) 1974 { 1975 for(j=0; j<pfstate->probedefc; j++) 1976 { 1977 if(pfstate->probedefs[j].src != NULL) 1978 scamper_addr_free(pfstate->probedefs[j].src); 1979 if(pfstate->probedefs[j].dst != NULL) 1980 scamper_addr_free(pfstate->probedefs[j].dst); 1981 } 1982 free(pfstate->probedefs); 1983 } 1984 if(pfstate->aaliases != NULL) 1985 { 1986 for(k=0; k<pfstate->aaliasc; k++) 1987 if(pfstate->aaliases[k] != NULL) 1988 scamper_addr_free(pfstate->aaliases[k]); 1989 free(pfstate->aaliases); 1990 } 1991 free(pfstate); 1992 1993 return; 1994 } 1995 1996 static int dealias_prefixscan_alloc(scamper_dealias_t *dealias, 1997 dealias_state_t *state) 1998 { 1999 scamper_dealias_prefixscan_t *pfxscan = dealias->data; 2000 scamper_dealias_probedef_t pd; 2001 dealias_prefixscan_t *pfstate = NULL; 2002 scamper_addr_t **addrs = NULL; 2003 int i, addrc = 0; 2004 2005 /* figure out the addresses that will be probed */ 2006 if(dealias_prefixscan_array(dealias, &addrs, &addrc) != 0) 2007 goto err; 2008 2009 if((pfstate = malloc_zero(sizeof(dealias_prefixscan_t))) == NULL) 2010 { 2011 printerror(__func__, "could not malloc pfstate"); 2012 goto err; 2013 } 2014 state->methodstate = pfstate; 2015 2016 pfstate->probedefs = malloc_zero(addrc * sizeof(scamper_dealias_probedef_t)); 2017 if(pfstate->probedefs == NULL) 2018 { 2019 printerror(__func__, "could not malloc probedefs"); 2020 goto err; 2021 } 2022 pfstate->probedefc = addrc; 2023 2024 for(i=0; i<addrc; i++) 2025 { 2026 memcpy(&pd, &pfxscan->probedefs[0], sizeof(pd)); 2027 pd.dst = scamper_addr_use(addrs[i]); 2028 pd.src = scamper_getsrc(pd.dst, 0); 2029 memcpy(&pfstate->probedefs[i], &pd, sizeof(pd)); 2030 } 2031 2032 dealias_prefixscan_array_free(addrs, addrc); 2033 return 0; 2034 2035 err: 2036 if(addrs != NULL) dealias_prefixscan_array_free(addrs, addrc); 2037 return -1; 2038 } 2039 2040 static void dealias_radargun_free(void *data) 2041 { 2042 dealias_radargun_t *rgstate = data; 2043 if(rgstate->order != NULL) 2044 free(rgstate->order); 2045 free(rgstate); 2046 return; 2047 } 2048 2049 static int dealias_radargun_alloc(scamper_dealias_radargun_t *rg, 2050 dealias_state_t *state) 2051 { 2052 dealias_radargun_t *rgstate = NULL; 2053 uint32_t i; 2054 size_t size; 2055 2056 if((rgstate = malloc_zero(sizeof(dealias_radargun_t))) == NULL) 2057 { 2058 printerror(__func__, "could not malloc rgstate"); 2059 return -1; 2060 } 2061 state->methodstate = rgstate; 2062 2063 /* if the probe order is to be shuffled, then shuffle it */ 2064 if((rg->flags & SCAMPER_DEALIAS_RADARGUN_FLAG_SHUFFLE)) 2065 { 2066 size = sizeof(uint32_t) * rg->probedefc; 2067 if((rgstate->order = malloc_zero(size)) == NULL) 2068 { 2069 printerror(__func__, "could not malloc order"); 2070 return -1; 2071 } 2072 for(i=0; i<rg->probedefc; i++) 2073 rgstate->order[i] = i; 2074 if(shuffle32(rgstate->order, rg->probedefc) != 0) 2075 return -1; 2076 } 2077 2078 return 0; 2079 } 2080 2081 static int dealias_bump_alloc(dealias_state_t *state) 2082 { 2083 dealias_bump_t *bstate = NULL; 2084 if((bstate = malloc_zero(sizeof(dealias_bump_t))) == NULL) 2085 { 2086 printerror(__func__, "could not malloc bstate"); 2087 return -1; 2088 } 2089 state->methodstate = bstate; 2090 return 0; 2091 } 2092 2093 static void dealias_bump_free(void *data) 2094 { 2095 free(data); 2096 return; 2097 } 2098 2099 static void dealias_state_free(scamper_dealias_t *dealias, 2100 dealias_state_t *state) 2101 { 2102 int j; 2103 2104 if(state == NULL) 2105 return; 2106 2107 if(state->recent_probes != NULL) 2108 dlist_free(state->recent_probes); 2109 2110 if(state->methodstate != NULL) 2111 { 2112 if(SCAMPER_DEALIAS_METHOD_IS_PREFIXSCAN(dealias)) 2113 dealias_prefixscan_free(state->methodstate); 2114 else if(SCAMPER_DEALIAS_METHOD_IS_RADARGUN(dealias)) 2115 dealias_radargun_free(state->methodstate); 2116 else if(SCAMPER_DEALIAS_METHOD_IS_BUMP(dealias)) 2117 dealias_bump_free(state->methodstate); 2118 } 2119 2120 if(state->targets != NULL) 2121 splaytree_free(state->targets, (splaytree_free_t)dealias_target_free); 2122 2123 if(state->pds != NULL) 2124 { 2125 for(j=0; j<state->pdc; j++) 2126 if(state->pds[j] != NULL) 2127 free(state->pds[j]); 2128 free(state->pds); 2129 } 2130 2131 if(state->ptbq != NULL) 2132 slist_free_cb(state->ptbq, (slist_free_t)dealias_ptb_free); 2133 2134 if(state->discard != NULL) 2135 slist_free_cb(state->discard, (slist_free_t)scamper_dealias_probe_free); 2136 2137 free(state); 2138 return; 2139 } 2140 2141 static void do_dealias_probe(scamper_task_t *task) 2142 { 2143 static int (*const postprobe_func[])(scamper_dealias_t *, 2144 dealias_state_t *) = { 2145 dealias_mercator_postprobe, 2146 dealias_ally_postprobe, 2147 dealias_radargun_postprobe, 2148 dealias_prefixscan_postprobe, 2149 dealias_bump_postprobe, 2150 }; 2151 static dealias_probedef_t *(*const def_func[])(scamper_dealias_t *, 2152 dealias_state_t *) = { 2153 dealias_mercator_def, 2154 dealias_ally_def, 2155 dealias_radargun_def, 2156 dealias_prefixscan_def, 2157 dealias_bump_def, 2158 }; 2159 scamper_dealias_t *dealias = dealias_getdata(task); 2160 dealias_state_t *state = dealias_getstate(task); 2161 dealias_probedef_t *pdef; 2162 scamper_dealias_probedef_t *def; 2163 scamper_dealias_probe_t *dp = NULL; 2164 scamper_probe_t probe; 2165 dealias_ptb_t *ptb = NULL; 2166 uint16_t u16; 2167 2168 if(dealias->probec == 0) 2169 gettimeofday_wrap(&dealias->start); 2170 2171 memset(&probe, 0, sizeof(probe)); 2172 if((state->flags & DEALIAS_STATE_FLAG_DL) != 0) 2173 probe.pr_flags |= SCAMPER_PROBE_FLAG_DL; 2174 2175 if(slist_count(state->ptbq) > 0) 2176 { 2177 ptb = slist_head_pop(state->ptbq); def = ptb->def; 2178 probe.pr_ip_src = def->src; 2179 probe.pr_ip_dst = def->dst; 2180 probe.pr_ip_ttl = 255; 2181 SCAMPER_PROBE_ICMP_PTB(&probe, def->mtu); 2182 probe.pr_data = ptb->quote; 2183 probe.pr_len = ptb->quote_len; 2184 if(scamper_probe_task(&probe, task) != 0) 2185 { 2186 errno = probe.pr_errno; 2187 goto err; 2188 } 2189 timeval_cpy(&state->ptb_tx, &probe.pr_tx); 2190 dealias_ptb_free(ptb); 2191 dealias_queue(task); 2192 return; 2193 } 2194 2195 if((pdef = def_func[dealias->method-1](dealias, state)) == NULL) 2196 goto err; 2197 def = pdef->def; 2198 2199 if(pktbuf_len < state->pds[def->id]->pktbuf_len) 2200 { 2201 if(realloc_wrap((void **)&pktbuf, state->pds[def->id]->pktbuf_len) != 0) 2202 { 2203 printerror(__func__, "could not realloc pktbuf"); 2204 goto err; 2205 } 2206 pktbuf_len = state->pds[def->id]->pktbuf_len; 2207 } 2208 2209 probe.pr_ip_src = def->src; 2210 probe.pr_ip_dst = def->dst; 2211 probe.pr_ip_ttl = def->ttl; 2212 probe.pr_ip_tos = def->tos; 2213 probe.pr_data = pktbuf; 2214 probe.pr_len = state->pds[def->id]->pktbuf_len; 2215 2216 if(SCAMPER_ADDR_TYPE_IS_IPV4(def->dst)) 2217 { 2218 probe.pr_flags |= SCAMPER_PROBE_FLAG_IPID; 2219 probe.pr_ip_id = state->id << 8 | state->id; 2220 probe.pr_ip_off = IP_DF; 2221 } 2222 2223 if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_UDP(def)) 2224 { 2225 probe.pr_ip_proto = IPPROTO_UDP; 2226 probe.pr_udp_sport = def->un.udp.sport; 2227 2228 if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP) 2229 probe.pr_udp_dport = def->un.udp.dport; 2230 else if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP_DPORT) 2231 probe.pr_udp_dport = def->un.udp.dport + pdef->target->udp_dport++; 2232 else 2233 goto err; 2234 2235 /* hack to get the udp csum to be a particular value, and be valid */ 2236 u16 = htons(dealias->probec + 1); 2237 memcpy(probe.pr_data, &u16, 2); 2238 u16 = scamper_udp4_cksum(&probe); 2239 memcpy(probe.pr_data, &u16, 2); 2240 } 2241 else if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_ICMP(def)) 2242 { 2243 SCAMPER_PROBE_ICMP_ECHO(&probe, def->un.icmp.id, state->icmpseq++); 2244 2245 /* hack to get the icmp csum to be a particular value, and be valid */ 2246 u16 = htons(def->un.icmp.csum); 2247 memcpy(probe.pr_data, &u16, 2); 2248 u16 = scamper_icmp4_cksum(&probe); 2249 memcpy(probe.pr_data, &u16, 2); 2250 } 2251 else if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_TCP(def)) 2252 { 2253 probe.pr_ip_proto = IPPROTO_TCP; 2254 probe.pr_tcp_dport = def->un.tcp.dport; 2255 probe.pr_tcp_flags = def->un.tcp.flags; 2256 2257 if(def->method == SCAMPER_DEALIAS_PROBEDEF_METHOD_TCP_ACK) 2258 { 2259 probe.pr_tcp_sport = def->un.tcp.sport; 2260 probe.pr_tcp_seq = state->pds[def->id]->tcp_seq; 2261 probe.pr_tcp_ack = state->pds[def->id]->tcp_ack; 2262 } 2263 else if(SCAMPER_DEALIAS_PROBEDEF_VARY_TCP_SPORT(def)) 2264 { 2265 probe.pr_tcp_sport = def->un.tcp.sport + pdef->target->tcp_sport++; 2266 if(random_u32(&probe.pr_tcp_seq) != 0 || 2267 random_u32(&probe.pr_tcp_ack) != 0) 2268 goto err; 2269 } 2270 else goto err; 2271 } 2272 2273 /* 2274 * allocate a probe record before we try and send the probe as there is no 2275 * point sending something into the wild that we can't record 2276 */ 2277 if((dp = scamper_dealias_probe_alloc()) == NULL) 2278 { 2279 printerror(__func__, "could not alloc probe"); 2280 goto err; 2281 } 2282 dp->def = def; 2283 dp->ipid = probe.pr_ip_id; 2284 dp->seq = state->round; 2285 2286 if(dealias_state_probe(state, pdef, dp, &probe) != 0) 2287 goto err; 2288 2289 /* send the probe */ 2290 if(scamper_probe_task(&probe, task) != 0) 2291 { 2292 errno = probe.pr_errno; 2293 goto err; 2294 } 2295 2296 /* record details of the probe in the scamper_dealias_t data structures */ 2297 timeval_cpy(&dp->tx, &probe.pr_tx); 2298 if(scamper_dealias_probe_add(dealias, dp) != 0) 2299 { 2300 scamper_debug(__func__, "could not add probe to dealias data"); 2301 goto err; 2302 } 2303 2304 /* figure out how long to wait until sending the next probe */ 2305 timeval_cpy(&state->last_tx, &probe.pr_tx); 2306 if(postprobe_func[dealias->method-1](dealias, state) != 0) 2307 goto err; 2308 2309 assert(state->id != 0); 2310 if(--state->id == 0) 2311 state->id = 255; 2312 2313 dealias_queue(task); 2314 return; 2315 2316 err: 2317 if(ptb != NULL) dealias_ptb_free(ptb); 2318 dealias_handleerror(task, errno); 2319 return; 2320 } 2321 2322 static void do_dealias_write(scamper_file_t *sf, scamper_task_t *task) 2323 { 2324 scamper_file_write_dealias(sf, dealias_getdata(task)); 2325 return; 2326 } 2327 2328 static void do_dealias_halt(scamper_task_t *task) 2329 { 2330 dealias_result(task, SCAMPER_DEALIAS_RESULT_HALTED); 2331 return; 2332 } 2333 2334 static void do_dealias_free(scamper_task_t *task) 2335 { 2336 scamper_dealias_t *dealias = dealias_getdata(task); 2337 dealias_state_t *state = dealias_getstate(task); 2338 2339 if(state != NULL) 2340 dealias_state_free(dealias, state); 2341 2342 if(dealias != NULL) 2343 scamper_dealias_free(dealias); 2344 2345 return; 2346 } 2347 2348 static int dealias_arg_param_validate(int optid, char *param, long long *out) 2349 { 2350 long tmp; 2351 2352 switch(optid) 2353 { 2354 case DEALIAS_OPT_OPTION: 2355 case DEALIAS_OPT_PROBEDEF: 2356 case DEALIAS_OPT_EXCLUDE: 2357 tmp = 0; 2358 break; 2359 2360 case DEALIAS_OPT_DPORT: 2361 if(string_tolong(param, &tmp) != 0 || tmp < 1 || tmp > 65535) 2362 return -1; 2363 break; 2364 2365 case DEALIAS_OPT_FUDGE: 2366 if(string_tolong(param, &tmp) != 0 || tmp < 1 || tmp > 65535) 2367 return -1; 2368 break; 2369 2370 case DEALIAS_OPT_METHOD: 2371 if(strcasecmp(param, "mercator") == 0) 2372 tmp = SCAMPER_DEALIAS_METHOD_MERCATOR; 2373 else if(strcasecmp(param, "ally") == 0) 2374 tmp = SCAMPER_DEALIAS_METHOD_ALLY; 2375 else if(strcasecmp(param, "radargun") == 0) 2376 tmp = SCAMPER_DEALIAS_METHOD_RADARGUN; 2377 else if(strcasecmp(param, "prefixscan") == 0) 2378 tmp = SCAMPER_DEALIAS_METHOD_PREFIXSCAN; 2379 else if(strcasecmp(param, "bump") == 0) 2380 tmp = SCAMPER_DEALIAS_METHOD_BUMP; 2381 else 2382 return -1; 2383 break; 2384 2385 case DEALIAS_OPT_ATTEMPTS: 2386 if(string_tolong(param, &tmp) != 0 || tmp < 1 || tmp > 500) 2387 return -1; 2388 break; 2389 2390 case DEALIAS_OPT_SPORT: 2391 if(string_tolong(param, &tmp) != 0 || tmp < 1 || tmp > 65535) 2392 return -1; 2393 break; 2394 2395 case DEALIAS_OPT_TTL: 2396 if(string_tolong(param, &tmp) != 0 || tmp < 1 || tmp > 255) 2397 return -1; 2398 break; 2399 2400 case DEALIAS_OPT_USERID: 2401 if(string_tolong(param, &tmp) != 0 || tmp < 0) 2402 return -1; 2403 break; 2404 2405 case DEALIAS_OPT_WAIT_TIMEOUT: 2406 if(string_tolong(param, &tmp) != 0 || tmp < 1 || tmp > 255) 2407 return -1; 2408 break; 2409 2410 case DEALIAS_OPT_WAIT_PROBE: 2411 if(string_tolong(param, &tmp) != 0 || tmp < 1 || tmp > 65535) 2412 return -1; 2413 break; 2414 2415 case DEALIAS_OPT_WAIT_ROUND: 2416 if(string_tolong(param, &tmp) != 0 || tmp < 1 || tmp > 180000) 2417 return -1; 2418 break; 2419 2420 case DEALIAS_OPT_REPLYC: 2421 if(string_tolong(param, &tmp) != 0 || tmp < 3 || tmp > 255) 2422 return -1; 2423 break; 2424 2425 default: 2426 scamper_debug(__func__, "unhandled optid %d", optid); 2427 return -1; 2428 } 2429 2430 if(out != NULL) 2431 *out = (long long)tmp; 2432 return 0; 2433 } 2434 2435 static int dealias_probedef_args(scamper_dealias_probedef_t *def, char *str) 2436 { 2437 scamper_option_out_t *opts_out = NULL, *opt; 2438 uint16_t dport = 33435; 2439 uint16_t sport = scamper_sport_default(); 2440 uint16_t csum = 0; 2441 uint16_t options = 0; 2442 uint8_t ttl = 255; 2443 uint8_t tos = 0; 2444 uint16_t size = 0; 2445 uint16_t mtu = 0; 2446 char *end; 2447 long tmp; 2448 2449 /* try and parse the string passed in */ 2450 if(scamper_options_parse(str, probedef_opts, probedef_opts_cnt, 2451 &opts_out, &end) != 0) 2452 { 2453 scamper_debug(__func__, "could not parse options"); 2454 goto err; 2455 } 2456 2457 for(opt = opts_out; opt != NULL; opt = opt->next) 2458 { 2459 /* check for an option being used multiple times */ 2460 if(options & (1<<(opt->id-1))) 2461 { 2462 scamper_debug(__func__,"option %d specified multiple times",opt->id); 2463 goto err; 2464 } 2465 2466 options |= (1 << (opt->id-1)); 2467 2468 switch(opt->id) 2469 { 2470 case DEALIAS_PROBEDEF_OPT_CSUM: 2471 if(string_tolong(opt->str, &tmp) != 0 || tmp < 0 || tmp > 65535) 2472 { 2473 scamper_debug(__func__, "invalid csum %s", opt->str); 2474 goto err; 2475 } 2476 csum = (uint16_t)tmp; 2477 break; 2478 2479 case DEALIAS_PROBEDEF_OPT_DPORT: 2480 if(string_tolong(opt->str, &tmp) != 0 || tmp < 1 || tmp > 65535) 2481 { 2482 scamper_debug(__func__, "invalid dport %s", opt->str); 2483 goto err; 2484 } 2485 dport = (uint16_t)tmp; 2486 break; 2487 2488 case DEALIAS_PROBEDEF_OPT_IP: 2489 def->dst = scamper_addrcache_resolve(addrcache, AF_UNSPEC, opt->str); 2490 if(def->dst == NULL) 2491 { 2492 scamper_debug(__func__, "invalid dst ip %s", opt->str); 2493 goto err; 2494 } 2495 break; 2496 2497 case DEALIAS_PROBEDEF_OPT_MTU: 2498 if(string_tolong(opt->str, &tmp) != 0 || tmp < 100 || tmp > 65535) 2499 { 2500 scamper_debug(__func__, "invalid mtu size %s", opt->str); 2501 goto err; 2502 } 2503 mtu = (uint16_t)tmp; 2504 break; 2505 2506 case DEALIAS_PROBEDEF_OPT_PROTO: 2507 if(strcasecmp(opt->str, "udp") == 0) 2508 def->method = SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP; 2509 else if(strcasecmp(opt->str, "tcp-ack") == 0) 2510 def->method = SCAMPER_DEALIAS_PROBEDEF_METHOD_TCP_ACK; 2511 else if(strcasecmp(opt->str, "icmp-echo") == 0) 2512 def->method = SCAMPER_DEALIAS_PROBEDEF_METHOD_ICMP_ECHO; 2513 else if(strcasecmp(opt->str, "tcp-ack-sport") == 0) 2514 def->method = SCAMPER_DEALIAS_PROBEDEF_METHOD_TCP_ACK_SPORT; 2515 else if(strcasecmp(opt->str, "udp-dport") == 0) 2516 def->method = SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP_DPORT; 2517 else if(strcasecmp(opt->str, "tcp-syn-sport") == 0) 2518 def->method = SCAMPER_DEALIAS_PROBEDEF_METHOD_TCP_SYN_SPORT; 2519 else 2520 { 2521 scamper_debug(__func__, "invalid probe type %s", opt->str); 2522 goto err; 2523 } 2524 break; 2525 2526 case DEALIAS_PROBEDEF_OPT_SIZE: 2527 if(string_tolong(opt->str, &tmp) != 0 || tmp < 100 || tmp > 65535) 2528 { 2529 scamper_debug(__func__, "invalid probe size %s", opt->str); 2530 goto err; 2531 } 2532 size = (uint16_t)tmp; 2533 break; 2534 2535 case DEALIAS_PROBEDEF_OPT_SPORT: 2536 if(string_tolong(opt->str, &tmp) != 0 || tmp < 1 || tmp > 65535) 2537 { 2538 scamper_debug(__func__, "invalid sport %s", opt->str); 2539 goto err; 2540 } 2541 sport = (uint16_t)tmp; 2542 break; 2543 2544 case DEALIAS_PROBEDEF_OPT_TTL: 2545 if(string_tolong(opt->str, &tmp) != 0 || tmp < 1 || tmp > 255) 2546 { 2547 scamper_debug(__func__, "invalid ttl %s", opt->str); 2548 goto err; 2549 } 2550 ttl = (uint8_t)tmp; 2551 break; 2552 2553 default: 2554 scamper_debug(__func__, "unhandled optid %d", opt->id); 2555 goto err; 2556 } 2557 } 2558 2559 scamper_options_free(opts_out); opts_out = NULL; 2560 2561 /* 2562 * if there is something at the end of the option string, then this 2563 * probedef is not valid 2564 */ 2565 if(end != NULL) 2566 { 2567 scamper_debug(__func__, "invalid option string"); 2568 goto err; 2569 } 2570 2571 /* record the ttl, tos, size */ 2572 def->ttl = ttl; 2573 def->tos = tos; 2574 def->size = size; 2575 def->mtu = mtu; 2576 2577 /* if no protocol type is defined, choose UDP */ 2578 if((options & (1<<(DEALIAS_PROBEDEF_OPT_PROTO-1))) == 0) 2579 def->method = SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP; 2580 2581 if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_UDP(def)) 2582 { 2583 /* don't provide the choice of the checksum value in a UDP probe */ 2584 if(options & (1<<(DEALIAS_PROBEDEF_OPT_CSUM-1))) 2585 { 2586 scamper_debug(__func__, "csum option not permitted for udp"); 2587 goto err; 2588 } 2589 2590 def->un.udp.dport = dport; 2591 def->un.udp.sport = sport; 2592 } 2593 else if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_ICMP(def)) 2594 { 2595 /* ICMP probes don't have source or destination ports */ 2596 if(options & (1<<(DEALIAS_PROBEDEF_OPT_SPORT-1))) 2597 { 2598 scamper_debug(__func__, "sport option not permitted for icmp"); 2599 goto err; 2600 } 2601 if(options & (1<<(DEALIAS_PROBEDEF_OPT_DPORT-1))) 2602 { 2603 scamper_debug(__func__, "dport option not permitted for icmp"); 2604 goto err; 2605 } 2606 def->un.icmp.csum = csum; 2607 def->un.icmp.id = scamper_sport_default(); 2608 } 2609 else if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_TCP(def)) 2610 { 2611 /* don't provide the choice of the checksum value in a TCP probe */ 2612 if(options & (1<<(DEALIAS_PROBEDEF_OPT_CSUM-1))) 2613 { 2614 scamper_debug(__func__, "csum option not permitted for tcp"); 2615 goto err; 2616 } 2617 2618 def->un.tcp.dport = dport; 2619 def->un.tcp.sport = sport; 2620 if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_TCP_ACK(def)) 2621 def->un.tcp.flags = TH_ACK; 2622 else if(SCAMPER_DEALIAS_PROBEDEF_PROTO_IS_TCP_SYN(def)) 2623 def->un.tcp.flags = TH_SYN; 2624 else 2625 { 2626 scamper_debug(__func__,"unhandled flags for method %d",def->method); 2627 goto err; 2628 } 2629 } 2630 else 2631 { 2632 scamper_debug(__func__, "unhandled method %d", def->method); 2633 goto err; 2634 } 2635 2636 return 0; 2637 2638 err: 2639 if(opts_out != NULL) scamper_options_free(opts_out); 2640 if(def->dst != NULL) scamper_addr_free(def->dst); 2641 return -1; 2642 } 2643 2644 static int dealias_alloc_mercator(scamper_dealias_t *d, dealias_options_t *o) 2645 { 2646 scamper_dealias_mercator_t *mercator; 2647 scamper_addr_t *dst = NULL; 2648 2649 /* if there is no IP address after the options string, then stop now */ 2650 if(o->addr == NULL) 2651 { 2652 scamper_debug(__func__, "missing target address for mercator"); 2653 goto err; 2654 } 2655 if((dst = scamper_addrcache_resolve(addrcache, AF_UNSPEC, o->addr)) == NULL) 2656 { 2657 scamper_debug(__func__, "unable to resolve address for mercator"); 2658 goto err; 2659 } 2660 2661 if(o->probedefs != NULL || o->xs != NULL || o->wait_probe != 0 || 2662 o->fudge != 0 || o->attempts > 3 || o->nobs != 0 || o->replyc != 0 || 2663 o->shuffle != 0 || o->inseq != 0) 2664 { 2665 scamper_debug(__func__, "invalid parameters for mercator"); 2666 goto err; 2667 } 2668 if(o->attempts == 0) o->attempts = 3; 2669 if(o->dport == 0) o->dport = 33435; 2670 if(o->sport == 0) o->sport = scamper_sport_default(); 2671 if(o->ttl == 0) o->ttl = 255; 2672 2673 if(scamper_dealias_mercator_alloc(d) != 0) 2674 { 2675 scamper_debug(__func__, "could not alloc mercator structure"); 2676 goto err; 2677 } 2678 mercator = d->data; 2679 mercator->attempts = o->attempts; 2680 mercator->wait_timeout = o->wait_timeout; 2681 mercator->probedef.id = 0; 2682 mercator->probedef.dst = dst; dst = NULL; 2683 mercator->probedef.ttl = o->ttl; 2684 mercator->probedef.method = SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP; 2685 mercator->probedef.un.udp.sport = o->sport; 2686 mercator->probedef.un.udp.dport = o->dport; 2687 2688 return 0; 2689 2690 err: 2691 if(dst != NULL) scamper_addr_free(dst); 2692 return -1; 2693 } 2694 2695 static int dealias_alloc_ally(scamper_dealias_t *d, dealias_options_t *o) 2696 { 2697 scamper_dealias_ally_t *ally = NULL; 2698 scamper_dealias_probedef_t pd[2]; 2699 int i, probedefc = 0; 2700 slist_node_t *sn; 2701 uint8_t flags = 0; 2702 char *addr2; 2703 2704 memset(&pd, 0, sizeof(pd)); 2705 2706 if(o->probedefs != NULL) 2707 probedefc = slist_count(o->probedefs); 2708 2709 if(probedefc > 2 || o->xs != NULL || o->dport != 0 || o->sport != 0 || 2710 o->ttl != 0 || o->replyc != 0 || o->shuffle != 0 || 2711 (o->inseq != 0 && o->fudge != 0)) 2712 { 2713 scamper_debug(__func__, "invalid parameters for ally"); 2714 goto err; 2715 } 2716 2717 if(o->wait_probe == 0) o->wait_probe = 150; 2718 if(o->attempts == 0) o->attempts = 5; 2719 2720 if(o->fudge == 0 && o->inseq == 0) 2721 o->fudge = 200; 2722 2723 if(probedefc > 0) 2724 { 2725 i = 0; 2726 for(sn=slist_head_node(o->probedefs); sn != NULL; sn=slist_node_next(sn)) 2727 { 2728 if(dealias_probedef_args(&pd[i], (char *)slist_node_item(sn)) != 0) 2729 { 2730 scamper_debug(__func__, "could not read ally probedef %d", i); 2731 goto err; 2732 } 2733 i++; 2734 } 2735 } 2736 2737 if(probedefc == 0) 2738 { 2739 for(i=0; i<2; i++) 2740 { 2741 pd[i].ttl = 255; 2742 pd[i].method = SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP; 2743 pd[i].un.udp.sport = scamper_sport_default(); 2744 pd[i].un.udp.dport = 33435; 2745 } 2746 } 2747 else if(probedefc == 1) 2748 { 2749 if(pd[0].dst != NULL || o->addr == NULL) 2750 { 2751 scamper_debug(__func__, "dst IP specified incorrectly"); 2752 goto err; 2753 } 2754 memcpy(&pd[1], &pd[0], sizeof(scamper_dealias_probedef_t)); 2755 } 2756 2757 if(o->addr == NULL) 2758 { 2759 if(pd[0].dst == NULL || pd[1].dst == NULL) 2760 { 2761 scamper_debug(__func__, "missing destination IP address"); 2762 goto err; 2763 } 2764 } 2765 else 2766 { 2767 if(pd[0].dst != NULL || pd[1].dst != NULL) 2768 { 2769 scamper_debug(__func__, "dst IP specified inconsistently"); 2770 goto err; 2771 } 2772 2773 /* make sure there are two addresses specified */ 2774 if((addr2 = string_nextword(o->addr)) == NULL) 2775 { 2776 scamper_debug(__func__, "missing second address"); 2777 goto err; 2778 } 2779 2780 /* resolve each address */ 2781 pd[0].dst = scamper_addrcache_resolve(addrcache, AF_UNSPEC, o->addr); 2782 if(pd[0].dst == NULL) 2783 { 2784 printerror(__func__, "could not resolve %s", o->addr); 2785 goto err; 2786 } 2787 pd[1].dst = scamper_addrcache_resolve(addrcache, AF_UNSPEC, addr2); 2788 if(pd[1].dst == NULL) 2789 { 2790 printerror(__func__, "could not resolve %s", addr2); 2791 goto err; 2792 } 2793 } 2794 2795 if(pd[0].dst->type != pd[1].dst->type || 2796 SCAMPER_ADDR_TYPE_IS_IP(pd[0].dst) == 0 || 2797 SCAMPER_ADDR_TYPE_IS_IP(pd[1].dst) == 0) 2798 { 2799 scamper_debug(__func__, "dst IP specified incorrectly"); 2800 goto err; 2801 } 2802 2803 if(o->nobs != 0 || SCAMPER_ADDR_TYPE_IS_IPV6(pd[0].dst)) 2804 flags |= SCAMPER_DEALIAS_ALLY_FLAG_NOBS; 2805 2806 if(scamper_dealias_ally_alloc(d) != 0) 2807 { 2808 scamper_debug(__func__, "could not alloc ally structure"); 2809 goto err; 2810 } 2811 ally = d->data; 2812 2813 ally->attempts = o->attempts; 2814 ally->wait_probe = o->wait_probe; 2815 ally->wait_timeout = o->wait_timeout; 2816 ally->fudge = o->fudge; 2817 ally->flags = flags; 2818 2819 for(i=0; i<2; i++) 2820 pd[i].id = i; 2821 2822 memcpy(ally->probedefs, pd, sizeof(ally->probedefs)); 2823 2824 return 0; 2825 2826 err: 2827 if(pd[0].dst != NULL) scamper_addr_free(pd[0].dst); 2828 if(pd[1].dst != NULL) scamper_addr_free(pd[1].dst); 2829 return -1; 2830 } 2831 2832 static int dealias_alloc_radargun(scamper_dealias_t *d, dealias_options_t *o) 2833 { 2834 scamper_dealias_radargun_t *rg; 2835 scamper_dealias_probedef_t *pd = NULL, pd0; 2836 slist_t *pd_list = NULL; 2837 slist_node_t *sn; 2838 uint32_t i, probedefc; 2839 uint8_t flags = 0; 2840 char *a1, *a2; 2841 int j, pdc = 0; 2842 2843 memset(&pd0, 0, sizeof(pd0)); 2844 2845 if(o->xs != NULL || o->dport != 0 || o->sport != 0 || 2846 o->ttl != 0 || o->nobs != 0 || o->replyc != 0 || o->inseq != 0) 2847 { 2848 scamper_debug(__func__, "invalid parameters for radargun"); 2849 goto err; 2850 } 2851 2852 if(o->probedefs != NULL) 2853 pdc = slist_count(o->probedefs); 2854 if(o->wait_probe == 0) o->wait_probe = 150; 2855 if(o->attempts == 0) o->attempts = 30; 2856 if(o->wait_round == 0) o->wait_round = pdc * o->wait_probe; 2857 if(o->shuffle != 0) 2858 flags |= SCAMPER_DEALIAS_RADARGUN_FLAG_SHUFFLE; 2859 2860 if(pdc == 0) 2861 { 2862 pd0.ttl = 255; 2863 pd0.method = SCAMPER_DEALIAS_PROBEDEF_METHOD_UDP; 2864 pd0.un.udp.sport = scamper_sport_default(); 2865 pd0.un.udp.dport = 33435; 2866 } 2867 else if(pdc == 1) 2868 { 2869 if(dealias_probedef_args(&pd0, (char *)slist_head_item(o->probedefs))!=0) 2870 { 2871 scamper_debug(__func__, "could not parse radargun probedef 0"); 2872 goto err; 2873 } 2874 if(pd0.dst != NULL || o->addr == NULL) 2875 { 2876 scamper_debug(__func__, "dst addrs are specified after def"); 2877 goto err; 2878 } 2879 } 2880 2881 if(pdc >= 2 && o->addr == NULL) 2882 { 2883 if((pd = malloc_zero(pdc * sizeof(scamper_dealias_probedef_t))) == NULL) 2884 { 2885 scamper_debug(__func__, "could not malloc radargun pd"); 2886 goto err; 2887 } 2888 2889 i = 0; 2890 for(sn=slist_head_node(o->probedefs); sn != NULL; sn=slist_node_next(sn)) 2891 { 2892 if(dealias_probedef_args(&pd[i], (char *)slist_node_item(sn)) != 0 || 2893 pd[i].dst == NULL) 2894 { 2895 scamper_debug(__func__, "could not parse radargun def %d", i); 2896 goto err; 2897 } 2898 if(i != 0 && pd[0].dst->type != pd[i].dst->type) 2899 { 2900 scamper_debug(__func__, "mixed address families"); 2901 goto err; 2902 } 2903 pd[i].id = i; 2904 i++; 2905 } 2906 probedefc = i; 2907 } 2908 else if(pdc < 2 && o->addr != NULL) 2909 { 2910 if((pd_list = slist_alloc()) == NULL) 2911 { 2912 printerror(__func__, "could not alloc pd_list"); 2913 goto err; 2914 } 2915 a1 = o->addr; i = 0; 2916 for(;;) 2917 { 2918 a2 = string_nextword(a1); 2919 pd0.dst = scamper_addrcache_resolve(addrcache, AF_UNSPEC, a1); 2920 if(pd0.dst == NULL) 2921 goto err; 2922 pd0.id = i++; 2923 if((pd = memdup(&pd0, sizeof(pd0))) == NULL || 2924 slist_tail_push(pd_list, pd) == NULL) 2925 goto err; 2926 pd0.dst = NULL; 2927 if(a2 == NULL) 2928 break; 2929 a1 = a2; 2930 } 2931 probedefc = slist_count(pd_list); 2932 } 2933 else goto err; 2934 2935 if(scamper_dealias_radargun_alloc(d) != 0) 2936 { 2937 scamper_debug(__func__, "could not alloc radargun structure"); 2938 goto err; 2939 } 2940 rg = d->data; 2941 2942 if(scamper_dealias_radargun_probedefs_alloc(rg, probedefc) != 0) 2943 { 2944 scamper_debug(__func__, "could not alloc radargun probedefs"); 2945 goto err; 2946 } 2947 2948 rg->attempts = o->attempts; 2949 rg->wait_probe = o->wait_probe; 2950 rg->wait_timeout = o->wait_timeout; 2951 rg->wait_round = o->wait_round; 2952 rg->probedefc = probedefc; 2953 rg->flags = flags; 2954 2955 if(pd_list == NULL) 2956 { 2957 for(j=0; j<pdc; j++) 2958 memcpy(&rg->probedefs[j], &pd[j], sizeof(scamper_dealias_probedef_t)); 2959 } 2960 else 2961 { 2962 i=0; 2963 while((pd = slist_head_pop(pd_list)) != NULL) 2964 { 2965 memcpy(&rg->probedefs[i], pd, sizeof(scamper_dealias_probedef_t)); 2966 free(pd); 2967 i++; 2968 } 2969 slist_free(pd_list); pd_list = NULL; 2970 } 2971 2972 return 0; 2973 2974 err: 2975 if(pd != NULL) 2976 { 2977 for(j=0; j<pdc; j++) 2978 if(pd[j].dst != NULL) 2979 scamper_addr_free(pd[j].dst); 2980 free(pd); 2981 } 2982 if(pd_list != NULL) 2983 slist_free_cb(pd_list, (slist_free_t)scamper_dealias_probedef_free); 2984 if(pd0.dst != NULL) 2985 scamper_addr_free(pd0.dst); 2986 return -1; 2987 } 2988 2989 static int dealias_alloc_prefixscan(scamper_dealias_t *d, dealias_options_t *o) 2990 { 2991 scamper_dealias_prefixscan_t *prefixscan; 2992 scamper_dealias_probedef_t pd0; 2993 scamper_addr_t *dst = NULL; 2994 slist_node_t *sn; 2995 uint8_t flags = 0; 2996 uint8_t prefix; 2997 char *addr2 = NULL, *pfxstr, *xs; 2998 long tmp; 2999 int af; 3000 3001 /* check the sanity of various parameters */ 3002 if(slist_count(o->probedefs) != 1 || o->addr == NULL || o->dport != 0 || 3003 o->sport != 0 || o->ttl != 0 || o->shuffle != 0 || 3004 (o->inseq != 0 && o->fudge != 0)) 3005 { 3006 scamper_debug(__func__, "invalid parameters for prefixscan"); 3007 goto err; 3008 } 3009 3010 if(o->ttl == 0) o->ttl = 255; 3011 if(o->wait_probe == 0) o->wait_probe = 1000; 3012 if(o->attempts == 0) o->attempts = 2; 3013 if(o->replyc == 0) o->replyc = 5; 3014 3015 if(o->nobs != 0) 3016 flags |= SCAMPER_DEALIAS_PREFIXSCAN_FLAG_NOBS; 3017 3018 if(o->fudge == 0 && o->inseq == 0) 3019 o->fudge = 200; 3020 3021 /* 3022 * we need `a' and `b' to traceroute. parse the `addr' string. 3023 * start by getting the second address. 3024 * 3025 * skip over the first address until we get to whitespace. 3026 */ 3027 if((addr2 = string_nextword(o->addr)) == NULL) 3028 { 3029 scamper_debug(__func__, "missing second address"); 3030 goto err; 3031 } 3032 3033 string_nullterm_char(addr2, '/', &pfxstr); 3034 if(pfxstr == NULL) 3035 { 3036 scamper_debug(__func__, "missing prefix"); 3037 goto err; 3038 } 3039 3040 if(string_tolong(pfxstr, &tmp) != 0 || tmp < 24 || tmp >= 32) 3041 { 3042 scamper_debug(__func__, "invalid prefix %s", pfxstr); 3043 goto err; 3044 } 3045 prefix = (uint8_t)tmp; 3046 3047 /* check the sanity of the probedef */ 3048 memset(&pd0, 0, sizeof(pd0)); 3049 if(dealias_probedef_args(&pd0, (char *)slist_head_item(o->probedefs)) != 0) 3050 { 3051 scamper_debug(__func__, "could not parse prefixscan probedef"); 3052 goto err; 3053 } 3054 if(pd0.dst != NULL) 3055 { 3056 scamper_debug(__func__, "prefixscan ip address spec. in probedef"); 3057 scamper_addr_free(pd0.dst); pd0.dst = NULL; 3058 goto err; 3059 } 3060 3061 if(scamper_dealias_prefixscan_alloc(d) != 0) 3062 { 3063 scamper_debug(__func__, "could not alloc prefixscan structure"); 3064 goto err; 3065 } 3066 prefixscan = d->data; 3067 3068 prefixscan->attempts = o->attempts; 3069 prefixscan->fudge = o->fudge; 3070 prefixscan->wait_probe = o->wait_probe; 3071 prefixscan->wait_timeout = o->wait_timeout; 3072 prefixscan->replyc = o->replyc; 3073 prefixscan->prefix = prefix; 3074 prefixscan->flags = flags; 3075 3076 /* resolve the two addresses now */ 3077 prefixscan->a = scamper_addrcache_resolve(addrcache, AF_UNSPEC, o->addr); 3078 if(prefixscan->a == NULL) 3079 { 3080 scamper_debug(__func__, "could not resolve %s", o->addr); 3081 goto err; 3082 } 3083 af = scamper_addr_af(prefixscan->a); 3084 prefixscan->b = scamper_addrcache_resolve(addrcache, af, addr2); 3085 if(prefixscan->b == NULL) 3086 { 3087 scamper_debug(__func__, "could not resolve %s", addr2); 3088 goto err; 3089 } 3090 3091 /* add the first probedef */ 3092 if(scamper_dealias_prefixscan_probedefs_alloc(prefixscan, 1) != 0) 3093 { 3094 scamper_debug(__func__, "could not alloc prefixscan probedefs"); 3095 goto err; 3096 } 3097 memcpy(prefixscan->probedefs, &pd0, sizeof(pd0)); 3098 prefixscan->probedefs[0].dst = scamper_addr_use(prefixscan->a); 3099 prefixscan->probedefs[0].id = 0; 3100 prefixscan->probedefc = 1; 3101 3102 /* resolve any addresses to exclude in the scan */ 3103 if(o->xs != NULL) 3104 { 3105 for(sn = slist_head_node(o->xs); sn != NULL; sn = slist_node_next(sn)) 3106 { 3107 xs = slist_node_item(sn); 3108 if((dst = scamper_addrcache_resolve(addrcache, af, xs)) == NULL) 3109 { 3110 scamper_debug(__func__, "could not resolve %s", xs); 3111 goto err; 3112 } 3113 if(scamper_dealias_prefixscan_xs_add(d, dst) != 0) 3114 { 3115 scamper_debug(__func__, "could not add %s to xs", xs); 3116 goto err; 3117 } 3118 scamper_addr_free(dst); dst = NULL; 3119 } 3120 } 3121 3122 return 0; 3123 3124 err: 3125 return -1; 3126 } 3127 3128 static int dealias_alloc_bump(scamper_dealias_t *d, dealias_options_t *o) 3129 { 3130 scamper_dealias_bump_t *bump = NULL; 3131 scamper_dealias_probedef_t pd[2]; 3132 slist_node_t *sn; 3133 int i; 3134 3135 memset(&pd, 0, sizeof(pd)); 3136 3137 if(slist_count(o->probedefs) != 2 || o->xs != NULL || o->dport != 0 || 3138 o->sport != 0 || o->ttl != 0 || o->replyc != 0 || o->shuffle != 0 || 3139 o->addr != NULL || (o->inseq != 0 && o->fudge != 0)) 3140 { 3141 scamper_debug(__func__, "invalid parameters for bump"); 3142 goto err; 3143 } 3144 3145 if(o->wait_probe == 0) o->wait_probe = 1000; 3146 if(o->attempts == 0) o->attempts = 3; 3147 if(o->fudge == 0) o->fudge = 30; /* bump limit */ 3148 3149 i = 0; 3150 for(sn = slist_head_node(o->probedefs); sn != NULL; sn = slist_node_next(sn)) 3151 { 3152 if(dealias_probedef_args(&pd[i], (char *)slist_node_item(sn)) != 0) 3153 { 3154 scamper_debug(__func__, "could not read bump probedef %d", i); 3155 goto err; 3156 } 3157 if(pd[i].dst == NULL) 3158 { 3159 scamper_debug(__func__, "missing dst address in probedef %d", i); 3160 goto err; 3161 } 3162 if(pd[i].dst->type != SCAMPER_ADDR_TYPE_IPV4) 3163 { 3164 scamper_debug(__func__, "dst address not IPv4 in probedef %d", i); 3165 goto err; 3166 } 3167 pd[i].id = i; 3168 i++; 3169 } 3170 3171 if(scamper_dealias_bump_alloc(d) != 0) 3172 { 3173 scamper_debug(__func__, "could not alloc bump structure"); 3174 goto err; 3175 } 3176 bump = d->data; 3177 3178 bump->attempts = o->attempts; 3179 bump->wait_probe = o->wait_probe; 3180 bump->bump_limit = o->fudge; 3181 memcpy(bump->probedefs, pd, sizeof(bump->probedefs)); 3182 3183 return 0; 3184 3185 err: 3186 if(pd[0].dst != NULL) scamper_addr_free(pd[0].dst); 3187 if(pd[1].dst != NULL) scamper_addr_free(pd[1].dst); 3188 return -1; 3189 } 3190 3191 3192 /* 3193 * scamper_do_dealias_alloc 3194 * 3195 * given a string representing a dealias task, parse the parameters and 3196 * assemble a dealias. return the dealias structure so that it is all ready 3197 * to go. 3198 */ 3199 void *scamper_do_dealias_alloc(char *str) 3200 { 3201 static int (*const alloc_func[])(scamper_dealias_t *, dealias_options_t *) = { 3202 dealias_alloc_mercator, 3203 dealias_alloc_ally, 3204 dealias_alloc_radargun, 3205 dealias_alloc_prefixscan, 3206 dealias_alloc_bump, 3207 }; 3208 scamper_option_out_t *opts_out = NULL, *opt; 3209 scamper_dealias_t *dealias = NULL; 3210 dealias_options_t o; 3211 uint8_t method = SCAMPER_DEALIAS_METHOD_MERCATOR; 3212 uint32_t userid = 0; 3213 long long tmp = 0; 3214 3215 memset(&o, 0, sizeof(o)); 3216 3217 /* try and parse the string passed in */ 3218 if(scamper_options_parse(str, opts, opts_cnt, &opts_out, &o.addr) != 0) 3219 { 3220 scamper_debug(__func__, "could not parse command"); 3221 goto err; 3222 } 3223 3224 for(opt = opts_out; opt != NULL; opt = opt->next) 3225 { 3226 if(opt->type != SCAMPER_OPTION_TYPE_NULL && 3227 dealias_arg_param_validate(opt->id, opt->str, &tmp) != 0) 3228 { 3229 scamper_debug(__func__, "validation of optid %d failed", opt->id); 3230 goto err; 3231 } 3232 3233 switch(opt->id) 3234 { 3235 case DEALIAS_OPT_METHOD: 3236 method = (uint8_t)tmp; 3237 break; 3238 3239 case DEALIAS_OPT_USERID: 3240 userid = (uint32_t)tmp; 3241 break; 3242 3243 case DEALIAS_OPT_OPTION: 3244 if(strcasecmp(opt->str, "nobs") == 0) 3245 o.nobs = 1; 3246 else if(strcasecmp(opt->str, "shuffle") == 0) 3247 o.shuffle = 1; 3248 else if(strcasecmp(opt->str, "inseq") == 0) 3249 o.inseq = 1; 3250 else 3251 { 3252 scamper_debug(__func__, "unknown option %s", opt->str); 3253 goto err; 3254 } 3255 break; 3256 3257 case DEALIAS_OPT_ATTEMPTS: 3258 o.attempts = (uint8_t)tmp; 3259 break; 3260 3261 case DEALIAS_OPT_DPORT: 3262 o.dport = (uint16_t)tmp; 3263 break; 3264 3265 case DEALIAS_OPT_SPORT: 3266 o.sport = (uint16_t)tmp; 3267 break; 3268 3269 case DEALIAS_OPT_FUDGE: 3270 o.fudge = (uint16_t)tmp; 3271 break; 3272 3273 case DEALIAS_OPT_TTL: 3274 o.ttl = (uint8_t)tmp; 3275 break; 3276 3277 case DEALIAS_OPT_PROBEDEF: 3278 if(o.probedefs == NULL && (o.probedefs = slist_alloc()) == NULL) 3279 { 3280 printerror(__func__, "could not alloc probedefs"); 3281 goto err; 3282 } 3283 if(slist_tail_push(o.probedefs, opt->str) == NULL) 3284 { 3285 printerror(__func__, "could not push probedef"); 3286 goto err; 3287 } 3288 break; 3289 3290 case DEALIAS_OPT_WAIT_TIMEOUT: 3291 o.wait_timeout = (uint8_t)tmp; 3292 break; 3293 3294 case DEALIAS_OPT_WAIT_PROBE: 3295 o.wait_probe = (uint16_t)tmp; 3296 break; 3297 3298 case DEALIAS_OPT_WAIT_ROUND: 3299 o.wait_round = (uint32_t)tmp; 3300 break; 3301 3302 case DEALIAS_OPT_EXCLUDE: 3303 if(o.xs == NULL && (o.xs = slist_alloc()) == NULL) 3304 { 3305 printerror(__func__, "could not alloc xs"); 3306 goto err; 3307 } 3308 if(slist_tail_push(o.xs, opt->str) == NULL) 3309 { 3310 printerror(__func__, "could not push xs"); 3311 goto err; 3312 } 3313 break; 3314 3315 case DEALIAS_OPT_REPLYC: 3316 o.replyc = (uint8_t)tmp; 3317 break; 3318 3319 default: 3320 scamper_debug(__func__, "unhandled option %d", opt->id); 3321 goto err; 3322 } 3323 } 3324 3325 scamper_options_free(opts_out); 3326 opts_out = NULL; 3327 3328 if(o.wait_timeout == 0) 3329 o.wait_timeout = 5; 3330 3331 if((dealias = scamper_dealias_alloc()) == NULL) 3332 { 3333 scamper_debug(__func__, "could not alloc dealias structure"); 3334 goto err; 3335 } 3336 dealias->method = method; 3337 dealias->userid = userid; 3338 if(alloc_func[method-1](dealias, &o) != 0) 3339 goto err; 3340 3341 if(o.probedefs != NULL) 3342 slist_free(o.probedefs); 3343 if(o.xs != NULL) 3344 slist_free(o.xs); 3345 3346 return dealias; 3347 3348 err: 3349 if(opts_out != NULL) scamper_options_free(opts_out); 3350 if(o.probedefs != NULL) free(o.probedefs); 3351 if(dealias != NULL) scamper_dealias_free(dealias); 3352 return NULL; 3353 } 3354 3355 /* 3356 * scamper_do_dealias_arg_validate 3357 * 3358 * 3359 */ 3360 int scamper_do_dealias_arg_validate(int argc, char *argv[], int *stop) 3361 { 3362 return scamper_options_validate(opts, opts_cnt, argc, argv, stop, 3363 dealias_arg_param_validate); 3364 } 3365 3366 void scamper_do_dealias_free(void *data) 3367 { 3368 scamper_dealias_free((scamper_dealias_t *)data); 3369 return; 3370 } 3371 3372 static int probedef2sig(scamper_task_t *task, scamper_dealias_probedef_t *def) 3373 { 3374 scamper_task_sig_t *sig = NULL; 3375 char buf[32]; 3376 3377 if(def->src == NULL && (def->src = scamper_getsrc(def->dst, 0)) == NULL) 3378 { 3379 printerror(__func__, "could not get src address for %s", 3380 scamper_addr_tostr(def->dst, buf, sizeof(buf))); 3381 goto err; 3382 } 3383 3384 /* form a signature */ 3385 if((sig = scamper_task_sig_alloc(SCAMPER_TASK_SIG_TYPE_TX_IP)) == NULL) 3386 goto err; 3387 sig->sig_tx_ip_dst = scamper_addr_use(def->dst); 3388 sig->sig_tx_ip_src = scamper_addr_use(def->src); 3389 3390 /* add it to the task */ 3391 if(scamper_task_sig_add(task, sig) != 0) 3392 goto err; 3393 3394 return 0; 3395 3396 err: 3397 if(sig != NULL) scamper_task_sig_free(sig); 3398 return -1; 3399 } 3400 3401 scamper_task_t *scamper_do_dealias_alloctask(void *data, 3402 scamper_list_t *list, 3403 scamper_cycle_t *cycle) 3404 { 3405 scamper_dealias_t *dealias = (scamper_dealias_t *)data; 3406 dealias_state_t *state = NULL; 3407 scamper_task_t *task = NULL; 3408 scamper_dealias_probedef_t *def; 3409 scamper_dealias_prefixscan_t *pfxscan; 3410 scamper_dealias_mercator_t *mercator; 3411 scamper_dealias_radargun_t *radargun; 3412 scamper_dealias_ally_t *ally; 3413 scamper_dealias_bump_t *bump; 3414 dealias_prefixscan_t *pfstate; 3415 uint32_t p; 3416 int i; 3417 3418 /* allocate a task structure and store the trace with it */ 3419 if((task = scamper_task_alloc(dealias, &funcs)) == NULL) 3420 goto err; 3421 3422 if((state = malloc_zero(sizeof(dealias_state_t))) == NULL || 3423 (state->recent_probes = dlist_alloc()) == NULL || 3424 (state->ptbq = slist_alloc()) == NULL || 3425 (state->discard = slist_alloc()) == NULL || 3426 (state->targets = splaytree_alloc((splaytree_cmp_t)dealias_target_cmp)) == NULL) 3427 { 3428 printerror(__func__, "could not malloc state"); 3429 goto err; 3430 } 3431 state->id = 255; 3432 3433 if(dealias->method == SCAMPER_DEALIAS_METHOD_MERCATOR) 3434 { 3435 mercator = dealias->data; 3436 if(probedef2sig(task, &mercator->probedef) != 0) 3437 goto err; 3438 state->probedefs = &mercator->probedef; 3439 state->probedefc = 1; 3440 } 3441 else if(dealias->method == SCAMPER_DEALIAS_METHOD_ALLY) 3442 { 3443 ally = dealias->data; 3444 for(i=0; i<2; i++) 3445 if(probedef2sig(task, &ally->probedefs[i]) != 0) 3446 goto err; 3447 state->probedefs = ally->probedefs; 3448 state->probedefc = 2; 3449 } 3450 else if(dealias->method == SCAMPER_DEALIAS_METHOD_RADARGUN) 3451 { 3452 radargun = dealias->data; 3453 for(p=0; p<radargun->probedefc; p++) 3454 if(probedef2sig(task, &radargun->probedefs[p]) != 0) 3455 goto err; 3456 3457 state->probedefs = radargun->probedefs; 3458 state->probedefc = radargun->probedefc; 3459 if(dealias_radargun_alloc(radargun, state) != 0) 3460 goto err; 3461 } 3462 else if(dealias->method == SCAMPER_DEALIAS_METHOD_PREFIXSCAN) 3463 { 3464 if(dealias_prefixscan_alloc(dealias, state) != 0) 3465 goto err; 3466 pfxscan = dealias->data; 3467 if(probedef2sig(task, &pfxscan->probedefs[0]) != 0) 3468 goto err; 3469 state->probedefs = pfxscan->probedefs; 3470 state->probedefc = pfxscan->probedefc; 3471 3472 pfstate = state->methodstate; 3473 for(p=0; p<pfstate->probedefc; p++) 3474 if(probedef2sig(task, &pfstate->probedefs[p]) != 0) 3475 goto err; 3476 } 3477 else if(dealias->method == SCAMPER_DEALIAS_METHOD_BUMP) 3478 { 3479 bump = dealias->data; 3480 for(i=0; i<2; i++) 3481 if(probedef2sig(task, &bump->probedefs[i]) != 0) 3482 goto err; 3483 3484 state->probedefs = bump->probedefs; 3485 state->probedefc = 2; 3486 if(dealias_bump_alloc(state) != 0) 3487 goto err; 3488 } 3489 else goto err; 3490 3491 for(p=0; p<state->probedefc; p++) 3492 { 3493 def = &state->probedefs[p]; 3494 if(def->mtu != 0) 3495 state->flags |= DEALIAS_STATE_FLAG_DL; 3496 if(dealias_probedef_add(state, def) != 0) 3497 goto err; 3498 } 3499 3500 /* associate the list and cycle with the trace */ 3501 dealias->list = scamper_list_use(list); 3502 dealias->cycle = scamper_cycle_use(cycle); 3503 3504 scamper_task_setstate(task, state); 3505 state = NULL; 3506 3507 return task; 3508 3509 err: 3510 if(task != NULL) 3511 { 3512 scamper_task_setdatanull(task); 3513 scamper_task_free(task); 3514 } 3515 if(state != NULL) dealias_state_free(dealias, state); 3516 return NULL; 3517 } 3518 3519 void scamper_do_dealias_cleanup(void) 3520 { 3521 if(pktbuf != NULL) 3522 { 3523 free(pktbuf); 3524 pktbuf = NULL; 3525 } 3526 3527 return; 3528 } 3529 3530 int scamper_do_dealias_init(void) 3531 { 3532 funcs.probe = do_dealias_probe; 3533 funcs.handle_icmp = do_dealias_handle_icmp; 3534 funcs.handle_timeout = do_dealias_handle_timeout; 3535 funcs.handle_dl = do_dealias_handle_dl; 3536 funcs.write = do_dealias_write; 3537 funcs.task_free = do_dealias_free; 3538 funcs.halt = do_dealias_halt; 3539 3540 return 0; 3541 } 3542