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