~wkenzie/invizible/master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/**
 * @file invizible.h
 * @project invizible
 * @author Wesley Kenzie (wkenzie@gmail.com PGP 4c945266)
 * @created April 20, 2011
 * @modified June 19, 2011
 * @version 0.95
 * @copyright 2011. Arthur (Wesley) Kenzie. All Rights Reserved.
 * @license 3-clause BSD License. See accompanying LICENSE file.
 */

#ifndef _INVIZIBLE_H
#define	_INVIZIBLE_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <errno.h>
#include <error.h>
#include <netdb.h>
#include <time.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <linux/ip.h>
#include <sys/socket.h>
#include "libevwrap.h"
#include "pkcommon.h"

#define INVIZ_MAJOR_VERSION "0.25"
#define INVIZ_MINOR_VERSION "6d"
#define INVIZ_VERSION INVIZ_MAJOR_VERSION"."INVIZ_MINOR_VERSION
#define INVIZ_USING_HPING 1
#define INVIZ_USING_SIGNALS 0
#define HAVE_CTYPE_H 1
//
// /dev/random is blocking and so may be very slow
// /dev/urandom is non-blocking but not as high quality randomness
// can be user-defined with --devrandom= parameter
//
#define INVIZ_DEFAULT_DEVRANDOM "/dev/urandom"
//
#define INVIZ_DEFAULT_SEED_CONSTANT 10253
#define INVIZ_MAX_SEED_CONSTANT 10249000
#define INVIZ_PROTOCOL_SOCKS_PROXY 202 // why this?
#define INVIZ_PROTOCOL_HTTP_PROXY 203 // aribitrary
#define INVIZ_PROTOCOL_UNKNOWN 204 // also arbitrary
#define INVIZ_PROTOCOL_UNKNOWN_PROXY 205 // and this
#define MAX_PROTOCOL_DESC_LEN 16
#define IPPROTO_UDP_DESC "udp"
#define IPPROTO_TCP_DESC "tcp"
#define IPPROTO_ICMP_DESC "icmp"
#define IPPROTO_IP_DESC "ip"
#define IPPROTO_SCTP_DESC "sctp"
#define IPPROTO_RAW_DESC "raw"
#define IPPROTO_HTTPPROXY_DESC "http"
#define IPPROTO_HTTPPROXY_DESC_UPPER "HTTP"
#define IPPROTO_SOCKSPROXY_DESC "socks"
#define IPPROTO_SOCKSPROXY_DESC_UPPER "SOCKS"
#define IPPROTO_PROXY_DESC "proxy"
#define INVIZ_PROTOCOL_UNKNOWN_DESC "unknown"
#define DNS_QUERY_HOSTNAME_SEPARATOR "+"
#define HOST_COM_COUNT 144
#define HOST_ORG_COUNT 12
#define HOST_NET_COUNT 16
#define HOST_OTHER_COUNT 118
#define PK_BUFFER_LEN 512
#define MAX_HOSTNAME_EXT_LEN 16
#define MAX_FILENAME_LEN 512
#define MAX_IP4_LEN 16
#define MAX_IP6_LEN 64
#define MAX_MAC_ADDRESS_LEN 512
#define MAX_IFNAME_LEN 128
#define MIN_IFNAME_LEN 2
#define MAX_PACKETFILTER_LEN 128
#define RECEIVE_PACKET_SIZE 10240
#define UDP_HDR_LEN 8
#define INVIZ_TCP_SYN_WINDOW_SIZE 512
#define IP_TTL_DEFAULT 64
/** DNS error codes 0-5 are as described in RFC 1035. */
#define DNS_ERR_NONE 0
/** The name server was unable to interpret the query */
#define DNS_ERR_FORMAT 1
/** The name server was unable to process this query due to a problem with the name server */
#define DNS_ERR_SERVERFAILED 2
/** The domain name does not exist */
#define DNS_ERR_NOTEXIST 3
/** The name server does not support the requested kind of query */
#define DNS_ERR_NOTIMPL 4
/** The name server refuses to reform the specified operation for policy reasons */
#define DNS_ERR_REFUSED 5
/** The reply was truncated or ill-formatted */
#define DNS_ERR_TRUNCATED 65
/** An unknown error occurred */
#define DNS_ERR_UNKNOWN 66
/** Communication with the server timed out */
#define DNS_ERR_TIMEOUT 67
/** The request was canceled because the DNS subsystem was shut down. */
#define DNS_ERR_SHUTDOWN 68
/** The request was canceled via a call to evdns_cancel_request */
#define DNS_ERR_CANCEL 69
#define DNS_IP4_A 1
#define DNS_PTR 2
#define DNS_IP6_AAAA 3
#define DNS_QUERY_NO_SEARCH 1
#define DNS_OPTION_SEARCH 1
#define DNS_OPTION_NAMESERVERS 2
#define DNS_OPTION_MISC 4
#define DNS_OPTION_HOSTSFILE 8
#define DNS_OPTIONS_ALL 15
#define DNS_ANSWER_SECTION 0
#define DNS_AUTHORITY_SECTION 1
#define DNS_ADDITIONAL_SECTION 2
#define DNS_TYPE_A 1
#define DNS_TYPE_NS 2
#define DNS_TYPE_CNAME 5
#define DNS_TYPE_SOA 6
#define DNS_TYPE_PTR 12
#define DNS_TYPE_MX 15
#define DNS_TYPE_TXT 16
#define DNS_TYPE_AAAA 28
#define DNS_QTYPE_AXFR 252
#define DNS_QTYPE_ALL 255
#define DNS_CLASS_INET 1
#define DNS_FLAGS_AA 0x400
#define DNS_FLAGS_RD 0x080
#define DNS_MAX_IP4_ADDRS 32
#define DNS_MAX_IP6_ADDRS 32
//
// global variables
//
char * hostcoms[HOST_COM_COUNT];
char * hostorgs[HOST_ORG_COUNT];
char * hostnets[HOST_NET_COUNT];
char * hostothers[HOST_OTHER_COUNT];
struct ev_loop * loop;
struct ev_signal signal_watcher;
struct ev_io io_watcher;
struct ev_stat stat_watcher;
struct ev_timer timer_watcher;
struct ev_periodic periodic_watcher;
//
//
//
struct send_tcp {
    struct iphdr ip;
    struct tcphdr tcp;
};
struct recv_tcp {
    struct iphdr ip;
    struct tcphdr tcp;
    char buffer[RECEIVE_PACKET_SIZE];
};
//
// based on libevent dns_struct.h
//
struct dns_server_question {
    int type;
    int dns_question_class;
    char name[1];
};
struct dns_server_request {
    int flags;
    int nquestions;
    struct dns_server_question **questions;
};
struct nameserver {
    int socket;	 /* a connected UDP socket */
    struct sockaddr_storage address;
    socklen_t addrlen;
    int failed_times;  /* number of times which we have given this server a chance */
    int timedout;  /* number of times in a row a request has timed out */
    /* these objects are kept in a circular list */
    struct nameserver *next, *prev;
    /* Outstanding probe request for this nameserver, if any */
    struct request *probe_request;
    char state;  /* zero if we think that this server is down */
    char choked;  /* true if we have an EAGAIN from this server's socket */
    char write_waiting;  /* true if we are waiting for EV_WRITE events */
};
struct request {
    uint8_t *request;  /* the dns packet data */
    uint8_t request_type; /* TYPE_PTR or TYPE_A or TYPE_AAAA */
    unsigned int request_len;
    int reissue_count;
    int tx_count;  /* the number of times that this packet has been sent */
    void *user_pointer;  /* the pointer given to us for this request */
    struct nameserver *ns;	/* the server which we last sent it */
    /* these objects are kept in a circular list */
    struct request *next, *prev;
    uint16_t trans_id;  /* the transaction id */
    unsigned request_appended :1;	/* true if the request pointer is data which follows this struct */
    unsigned transmit_me :1;  /* needs to be transmitted */
    /* XXXX This is a horrible hack. */
    char **put_cname_in_ptr; /* store the cname here if we get one. */
};
struct reply {
    unsigned int type;
    unsigned int have_answer : 1;
    union {
        struct {
            uint32_t addrcount;
            uint32_t addresses[DNS_MAX_IP4_ADDRS];
        } a;
	struct {
            uint32_t addrcount;
            struct in6_addr addresses[DNS_MAX_IP6_ADDRS];
	} aaaa;
	struct {
            char name[NI_MAXHOST];
	} ptr;
    } data;
};
struct udpdata_part1 {
    uint16_t trans_id; // __be16?
    uint16_t flags;
    uint16_t questions;
    uint16_t answers;
    uint16_t authorities;
    uint16_t additionals;
};
struct udpdata_part2 {
    char query_hostname[NI_MAXHOST];
    uint16_t query_type;
    uint16_t query_class;
};
struct udpdata {
    struct udpdata_part1 hdr;
    struct udpdata_part2 qry;
};

struct send_udp {
    struct iphdr ip;
    struct udphdr udp;
    struct udpdata dns;
    char * nextlookuphost;
};
struct recv_udp {
    struct iphdr ip;
    struct udphdr udp;
    char buffer[RECEIVE_PACKET_SIZE];
};
//
/* From synhose.c by knight */
//
struct pseudo_header_tcp {
    unsigned int source_address;
    unsigned int dest_address;
    unsigned char placeholder;
    unsigned char protocol;
    unsigned short tcp_length;
    struct tcphdr tcp;
};
struct pseudo_header_udp {
    unsigned int source_address;
    unsigned int dest_address;
    unsigned char placeholder;
    unsigned char protocol;
    unsigned short udp_length;
    struct udphdr udp;
    struct udpdata dns;
};
//
// courtesy of libevent2/evdns.c
/* Represents part of a reply being built.	(That is, a single RR.) */
//
struct server_reply_item {
	struct server_reply_item *next; /* next item in sequence. */
	char *name; /* name part of the RR */
	uint16_t dns_type; /* The RR type */
	uint16_t dns_class; /* The RR class (usually CLASS_INET) */
	uint32_t ttl; /* The RR TTL */
	char is_name; /* True iff data is a label */
	uint16_t datalen; /* Length of data; -1 if data is a label */
	void *data; /* The contents of the RR */
};
//
// courtesy of libevent2/evdns.c
/* Represents a request that we've received as a DNS server, and holds */
/* the components of the reply as we're constructing it. */
//
struct server_request {
	/* Pointers to the next and previous entries on the list of replies */
	/* that we're waiting to write.	 Only set if we have tried to respond */
	/* and gotten EAGAIN. */
	struct server_request *next_pending;
	struct server_request *prev_pending;

	uint16_t trans_id; /* Transaction id. */
	struct sockaddr_storage addr; /* Where to send the response */
	socklen_t addrlen; /* length of addr */

	int n_answer; /* how many answer RRs have been set? */
	int n_authority; /* how many authority RRs have been set? */
	int n_additional; /* how many additional RRs have been set? */

	struct server_reply_item *answer; /* linked list of answer RRs */
	struct server_reply_item *authority; /* linked list of authority RRs */
	struct server_reply_item *additional; /* linked list of additional RRs */

	/* Constructed response.  Only set once we're ready to send a reply. */
	/* Once this is set, the RR fields are cleared, and no more should be set. */
	char *response;
	size_t response_len;

        struct dns_server_request base;
};
//
// function prototypes
//
void doinvizible(unsigned int, unsigned int, const char *, int, int, int, int);
void usage(char *);
char * get_lookuphost(const int, char[(int)MAX_HOSTNAME_EXT_LEN]);
char get_lookupchar(char[NI_MAXHOST], int);
void set_socket_recv_buff_size();
//
// callback function(s) for signals
//
#ifdef LIBEV
void sigint_cb(EV_P_ struct ev_signal *, int);
#endif

#ifdef	__cplusplus
}
#endif

#endif	/* _INVIZIBLE_H */