1 /*
2  * scamper_task.h
3  *
4  * $Id: scamper_task.h,v 1.43 2020/03/17 05:28:16 mjl Exp $
5  *
6  * Copyright (C) 2005-2006 Matthew Luckie
7  * Copyright (C) 2006-2011 The University of Waikato
8  * Copyright (C) 2013      The Regents of the University of California
9  * Copyright (C) 2018-2020 Matthew Luckie
10  * Author: Matthew Luckie
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, version 2.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  *
25  */
26 
27 #ifndef __SCAMPER_TASK_H
28 #define __SCAMPER_TASK_H
29 
30 struct scamper_addr;
31 struct scamper_queue;
32 struct scamper_task;
33 struct scamper_dl_rec;
34 struct scamper_icmp_resp;
35 struct scamper_cyclemon;
36 struct scamper_file;
37 struct scamper_sourcetask;
38 
39 #define SCAMPER_TASK_SIG_TYPE_TX_IP 1
40 #define SCAMPER_TASK_SIG_TYPE_TX_ND 2
41 #define SCAMPER_TASK_SIG_TYPE_SNIFF 3
42 #define SCAMPER_TASK_SIG_TYPE_HOST  4
43 
44 typedef struct scamper_task scamper_task_t;
45 typedef struct scamper_task_anc scamper_task_anc_t;
46 
47 typedef struct scamper_task_sig
48 {
49   uint8_t sig_type;
50   union
51   {
52     struct tx_ip
53     {
54       struct scamper_addr *dst;
55       struct scamper_addr *src;
56     } ip;
57     struct tx_nd
58     {
59       struct scamper_addr *ip;
60     } nd;
61     struct sniff
62     {
63       struct scamper_addr *src;
64       uint16_t             icmpid;
65     } sniff;
66     struct host
67     {
68       char                *name;
69       uint16_t             type;
70     } host;
71   } un;
72 } scamper_task_sig_t;
73 
74 #define sig_tx_ip_dst     un.ip.dst
75 #define sig_tx_ip_src     un.ip.src
76 #define sig_tx_nd_ip      un.nd.ip
77 #define sig_sniff_src     un.sniff.src
78 #define sig_sniff_icmp_id un.sniff.icmpid
79 #define sig_host_name     un.host.name
80 #define sig_host_type     un.host.type
81 
82 typedef struct scamper_task_funcs
83 {
84   /* probe the destination */
85   void (*probe)(struct scamper_task *task);
86 
87   /* handle some ICMP packet */
88   void (*handle_icmp)(struct scamper_task *task,
89 		      struct scamper_icmp_resp *icmp);
90 
91   /* handle some information from the datalink */
92   void (*handle_dl)(struct scamper_task *task, struct scamper_dl_rec *dl_rec);
93 
94   /* handle the task timing out on the wait queue */
95   void (*handle_timeout)(struct scamper_task *task);
96 
97   void (*halt)(struct scamper_task *task);
98 
99   /* write the task's data object out */
100   void (*write)(struct scamper_file *file, struct scamper_task *task);
101 
102   /* free the task's data and state */
103   void (*task_free)(struct scamper_task *task);
104 
105 } scamper_task_funcs_t;
106 
107 scamper_task_t *scamper_task_alloc(void *data, scamper_task_funcs_t *funcs);
108 void scamper_task_free(scamper_task_t *task);
109 
110 /* get various items of the task */
111 void *scamper_task_getdata(const scamper_task_t *task);
112 void *scamper_task_getstate(const scamper_task_t *task);
113 struct scamper_source *scamper_task_getsource(scamper_task_t *task);
114 
115 /* set various items on the task */
116 void scamper_task_setdatanull(scamper_task_t *task);
117 void scamper_task_setstate(scamper_task_t *task, void *state);
118 void scamper_task_setsourcetask(scamper_task_t *task,
119 				struct scamper_sourcetask *st);
120 void scamper_task_setcyclemon(scamper_task_t *t, struct scamper_cyclemon *cm);
121 
122 /* access the various functions registered with the task */
123 void scamper_task_write(scamper_task_t *task, struct scamper_file *file);
124 void scamper_task_probe(scamper_task_t *task);
125 void scamper_task_handleicmp(scamper_task_t *task,struct scamper_icmp_resp *r);
126 void scamper_task_handletimeout(scamper_task_t *task);
127 void scamper_task_halt(scamper_task_t *task);
128 
129 /* pass the datalink record to all appropriate tasks */
130 void scamper_task_handledl(struct scamper_dl_rec *dl);
131 
132 /* access the queue structre the task holds */
133 int scamper_task_queue_probe(scamper_task_t *task);
134 int scamper_task_queue_probe_head(scamper_task_t *task);
135 int scamper_task_queue_wait(scamper_task_t *task, int ms);
136 int scamper_task_queue_wait_tv(scamper_task_t *task, struct timeval *tv);
137 int scamper_task_queue_done(scamper_task_t *task, int ms);
138 int scamper_task_queue_isprobe(scamper_task_t *task);
139 int scamper_task_queue_isdone(scamper_task_t *task);
140 
141 /* access the file descriptors the task holds */
142 #ifdef __SCAMPER_FD_H
143 scamper_fd_t *scamper_task_fd_icmp4(scamper_task_t *task, void *addr);
144 scamper_fd_t *scamper_task_fd_icmp6(scamper_task_t *task, void *addr);
145 scamper_fd_t *scamper_task_fd_udp4(scamper_task_t *task, void *a, uint16_t sp);
146 scamper_fd_t *scamper_task_fd_udp6(scamper_task_t *task, void *a, uint16_t sp);
147 scamper_fd_t *scamper_task_fd_tcp4(scamper_task_t *task, void *a, uint16_t sp);
148 scamper_fd_t *scamper_task_fd_tcp6(scamper_task_t *task, void *a, uint16_t sp);
149 scamper_fd_t *scamper_task_fd_dl(scamper_task_t *task, int ifindex);
150 scamper_fd_t *scamper_task_fd_ip4(scamper_task_t *task);
151 #endif
152 
153 #if defined(__SCAMPER_FD_H) && !defined(_WIN32)
154 scamper_fd_t *scamper_task_fd_rtsock(scamper_task_t *task);
155 #endif
156 
157 /* define and use the task's probe signatures */
158 scamper_task_sig_t *scamper_task_sig_alloc(uint8_t type);
159 void scamper_task_sig_free(scamper_task_sig_t *sig);
160 int scamper_task_sig_add(scamper_task_t *task, scamper_task_sig_t *sig);
161 scamper_task_t *scamper_task_sig_block(scamper_task_t *task);
162 int scamper_task_sig_install(scamper_task_t *task);
163 void scamper_task_sig_deinstall(scamper_task_t *task);
164 scamper_task_t *scamper_task_find(scamper_task_sig_t *sig);
165 char *scamper_task_sig_tostr(scamper_task_sig_t *sig, char *buf, size_t len);
166 
167 /* manage ancillary data attached to the task */
168 scamper_task_anc_t *scamper_task_anc_add(scamper_task_t *task, void *data,
169 					 void (*freedata)(void *));
170 void scamper_task_anc_del(scamper_task_t *task, scamper_task_anc_t *anc);
171 
172 /*
173  * scamper_task_onhold
174  *
175  * given a task that another is blocked on, register the fact.
176  * when the task is free'd, the unhold function will be called.
177  *
178  * returns a cookie, so the dehold function can cancel the task
179  * from  being on hold at a later point.
180  */
181 void *scamper_task_onhold(scamper_task_t *task, void *param,
182 			  void (*unhold)(void *param));
183 
184 /*
185  * scamper_task_dehold
186  *
187  * given a task and a cookie returned from putting another task on hold,
188  * de-hold the task with this cookie.
189  */
190 int scamper_task_dehold(scamper_task_t *task, void *cookie);
191 
192 int scamper_task_init(void);
193 void scamper_task_cleanup(void);
194 
195 #endif /* __SCAMPER_TASK_H */
196