-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathn2n.h
346 lines (279 loc) · 10.9 KB
/
n2n.h
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
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/**
* (C) 2007-18 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not see see <http://www.gnu.org/licenses/>
*
*/
#ifndef _N2N_H_
#define _N2N_H_
/*
tunctl -t tun0
tunctl -t tun1
ifconfig tun0 1.2.3.4 up
ifconfig tun1 1.2.3.5 up
./edge -d tun0 -l 2000 -r 127.0.0.1:3000 -c hello
./edge -d tun1 -l 3000 -r 127.0.0.1:2000 -c hello
tunctl -u UID -t tunX
*/
/* #define N2N_CAN_NAME_IFACE */
/* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */
#ifdef WIN32
#include "win32/n2n_win32.h"
#undef N2N_HAVE_DAEMON
#undef N2N_HAVE_SETUID
#endif
#include <time.h>
#include <ctype.h>
#include <stdlib.h>
#ifndef WIN32
#include <netdb.h>
#endif
#ifndef _MSC_VER
#include <getopt.h>
#endif /* #ifndef _MSC_VER */
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#ifndef WIN32
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <pthread.h>
#ifdef __linux__
#include <linux/if.h>
#include <linux/if_tun.h>
#define N2N_CAN_NAME_IFACE 1
#endif /* #ifdef __linux__ */
#ifdef __FreeBSD__
#include <netinet/in_systm.h>
#endif /* #ifdef __FreeBSD__ */
#include <syslog.h>
#include <sys/wait.h>
#define ETH_ADDR_LEN 6
struct ether_hdr
{
uint8_t dhost[ETH_ADDR_LEN];
uint8_t shost[ETH_ADDR_LEN];
uint16_t type; /* higher layer protocol encapsulated */
} __attribute__ ((__packed__));
typedef struct ether_hdr ether_hdr_t;
#ifdef __ANDROID_NDK__
#undef N2N_HAVE_DAEMON
#undef N2N_HAVE_SETUID
#undef N2N_CAN_NAME_IFACE
#endif /* #ifdef __ANDROID_NDK__ */
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
#include <sys/stat.h>
#include "minilzo.h"
#define closesocket(a) close(a)
#endif /* #ifndef WIN32 */
#include <string.h>
#include <stdarg.h>
#ifdef WIN32
#include "win32/wintap.h"
#endif /* #ifdef WIN32 */
#include "n2n_wire.h"
#include "n2n_transforms.h"
/* N2N_IFNAMSIZ is needed on win32 even if dev_name is not used after declaration */
#define N2N_IFNAMSIZ 16 /* 15 chars * NULL */
#ifndef WIN32
typedef struct tuntap_dev {
int fd;
uint8_t mac_addr[6];
uint32_t ip_addr, device_mask;
uint16_t mtu;
char dev_name[N2N_IFNAMSIZ];
} tuntap_dev;
#define SOCKET int
#endif /* #ifndef WIN32 */
#define QUICKLZ 1
/* N2N packet header indicators. */
#define MSG_TYPE_REGISTER 1
#define MSG_TYPE_DEREGISTER 2
#define MSG_TYPE_PACKET 3
#define MSG_TYPE_REGISTER_ACK 4
#define MSG_TYPE_REGISTER_SUPER 5
#define MSG_TYPE_REGISTER_SUPER_ACK 6
#define MSG_TYPE_REGISTER_SUPER_NAK 7
#define MSG_TYPE_FEDERATION 8
/* Set N2N_COMPRESSION_ENABLED to 0 to disable lzo1x compression of ethernet
* frames. Doing this will break compatibility with the standard n2n packet
* format so do it only for experimentation. All edges must be built with the
* same value if they are to understand each other. */
#define N2N_COMPRESSION_ENABLED 1
#define DEFAULT_MTU 1400
/** Common type used to hold stringified IP addresses. */
typedef char ipstr_t[32];
/** Common type used to hold stringified MAC addresses. */
#define N2N_MACSTR_SIZE 32
typedef char macstr_t[N2N_MACSTR_SIZE];
struct peer_info {
struct peer_info * next;
n2n_community_t community_name;
n2n_mac_t mac_addr;
n2n_sock_t sock;
time_t last_seen;
};
struct n2n_edge; /* defined in edge.c */
typedef struct n2n_edge n2n_edge_t;
#define N2N_EDGE_SN_HOST_SIZE 48
#define N2N_EDGE_NUM_SUPERNODES 2
#define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */
#define N2N_PATHNAME_MAXLEN 256
#define N2N_MAX_TRANSFORMS 16
#define N2N_EDGE_MGMT_PORT 5644
typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE];
struct n2n_edge {
int daemon; /**< Non-zero if edge should detach and run in the background. */
uint8_t re_resolve_supernode_ip;
n2n_sock_t supernode;
size_t sn_idx; /**< Currently active supernode. */
size_t sn_num; /**< Number of supernode addresses defined. */
n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES];
int sn_wait; /**< Whether we are waiting for a supernode response. */
n2n_community_t community_name; /**< The community. 16 full octets. */
char keyschedule[N2N_PATHNAME_MAXLEN];
int null_transop; /**< Only allowed if no key sources defined. */
int udp_sock;
int udp_mgmt_sock; /**< socket for status info. */
tuntap_dev device; /**< All about the TUNTAP device */
int dyn_ip_mode; /**< Interface IP address is dynamically allocated, eg. DHCP. */
int allow_routing; /**< Accept packet no to interface address. */
int drop_multicast; /**< Multicast ethernet addresses. */
n2n_trans_op_t transop[N2N_MAX_TRANSFORMS]; /* one for each transform at fixed positions */
size_t tx_transop_idx; /**< The transop to use when encoding. */
struct peer_info * known_peers; /**< Edges we are connected to. */
struct peer_info * pending_peers; /**< Edges we have tried to register with. */
time_t last_register_req; /**< Check if time to re-register with super*/
size_t register_lifetime; /**< Time distance after last_register_req at which to re-register. */
time_t last_p2p; /**< Last time p2p traffic was received. */
time_t last_sup; /**< Last time a packet arrived from supernode. */
size_t sup_attempts; /**< Number of remaining attempts to this supernode. */
n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */
time_t start_time; /**< For calculating uptime */
/* Statistics */
size_t tx_p2p;
size_t rx_p2p;
size_t tx_sup;
size_t rx_sup;
};
/* ************************************** */
#ifdef __ANDROID_NDK__
#include <android/log.h>
#endif /* #ifdef __ANDROID_NDK__ */
#ifndef TRACE_ERROR
#define TRACE_ERROR 0, __FILE__, __LINE__
#define TRACE_WARNING 1, __FILE__, __LINE__
#define TRACE_NORMAL 2, __FILE__, __LINE__
#define TRACE_INFO 3, __FILE__, __LINE__
#define TRACE_DEBUG 4, __FILE__, __LINE__
#endif
/* ************************************** */
#define SUPERNODE_IP "127.0.0.1"
#define SUPERNODE_PORT 1234
/* ************************************** */
#ifndef max
#define max(a, b) ((a < b) ? b : a)
#endif
#ifndef min
#define min(a, b) ((a > b) ? b : a)
#endif
/* ************************************** */
/* Variables */
/* extern TWOFISH *tf; */
extern int traceLevel;
extern int useSyslog;
extern const uint8_t broadcast_addr[6];
extern const uint8_t multicast_addr[6];
/* Functions */
extern void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...);
extern int tuntap_open(tuntap_dev *device, char *dev, const char *address_mode, char *device_ip,
char *device_mask, const char * device_mac, int mtu);
extern int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len);
extern int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len);
extern void tuntap_close(struct tuntap_dev *tuntap);
extern void tuntap_get_address(struct tuntap_dev *tuntap);
extern SOCKET open_socket(int local_port, int bind_any);
extern char* intoa(uint32_t addr, char* buf, uint16_t buf_len);
extern char* macaddr_str(macstr_t buf, const n2n_mac_t mac);
extern int str2mac( uint8_t * outmac /* 6 bytes */, const char * s );
extern char * sock_to_cstr( n2n_sock_str_t out,
const n2n_sock_t * sock );
extern int sock_equal( const n2n_sock_t * a,
const n2n_sock_t * b );
extern uint8_t is_multi_broadcast(const uint8_t * dest_mac);
extern char* msg_type2str(uint16_t msg_type);
extern void hexdump(const uint8_t * buf, size_t len);
void print_n2n_version();
/* Operations on peer_info lists. */
struct peer_info * find_peer_by_mac( struct peer_info * list,
const n2n_mac_t mac );
void peer_list_add( struct peer_info * * list,
struct peer_info * newp );
size_t peer_list_size( const struct peer_info * list );
size_t purge_peer_list( struct peer_info ** peer_list,
time_t purge_before );
size_t clear_peer_list( struct peer_info ** peer_list );
size_t purge_expired_registrations( struct peer_info ** peer_list );
/* version.c */
extern char *n2n_sw_version, *n2n_sw_osName, *n2n_sw_buildDate;
/* egde_utils.c */
int edge_init(n2n_edge_t * eee);
void supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn);
void update_supernode_reg(n2n_edge_t * eee, time_t nowTime);
int is_empty_ip_address(const n2n_sock_t * sock);
void update_peer_address(n2n_edge_t * eee,
uint8_t from_supernode,
const n2n_mac_t mac,
const n2n_sock_t * peer,
time_t when);
int transop_enum_to_index(n2n_transform_t id);
int edge_init_keyschedule(n2n_edge_t * eee);
void update_peer_address(n2n_edge_t * eee,
uint8_t from_supernode,
const n2n_mac_t mac,
const n2n_sock_t * peer,
time_t when);
int is_empty_ip_address(const n2n_sock_t * sock);
void send_register(n2n_edge_t * eee,
const n2n_sock_t * remote_peer);
void send_packet2net(n2n_edge_t * eee,
uint8_t *tap_pkt, size_t len);
void check_peer(n2n_edge_t * eee,
uint8_t from_supernode,
const n2n_mac_t mac,
const n2n_sock_t * peer);
void set_peer_operational(n2n_edge_t * eee,
const n2n_mac_t mac,
const n2n_sock_t * peer);
const char * supernode_ip(const n2n_edge_t * eee);
int edge_init_twofish(n2n_edge_t * eee, uint8_t *encrypt_pwd,
uint32_t encrypt_pwd_len);
int run_edge_loop(n2n_edge_t * eee, int *keep_running);
void edge_term(n2n_edge_t * eee);
const char *random_device_mac(void);
int quick_edge_init(char *device_name, char *community_name,
char *encrypt_key, char *device_mac,
char *local_ip_address,
char *supernode_ip_address_port,
int *keep_on_running);
#endif /* _N2N_H_ */