1 /*	ptunnel.h
2 	ptunnel is licensed under the BSD license:
3 
4 	Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>,
5 	Yellow Lemon Software. All rights reserved.
6 
7 	Redistribution and use in source and binary forms, with or without
8 	modification, are permitted provided that the following conditions are met:
9 
10 	- Redistributions of source code must retain the above copyright notice,
11 	  this list of conditions and the following disclaimer.
12 
13 	- Redistributions in binary form must reproduce the above copyright notice,
14 	  this list of conditions and the following disclaimer in the documentation
15 	  and/or other materials provided with the distribution.
16 
17 	- Neither the name of the Yellow Lemon Software nor the names of its
18 	  contributors may be used to endorse or promote products derived from this
19 	  software without specific prior written permission.
20 
21 	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 	POSSIBILITY OF SUCH DAMAGE.
32 
33 	Contacting the author:
34 	You can get in touch with me, Daniel St�dle (that's the Norwegian letter oe,
35 	in case your text editor didn't realize), here: <daniels@cs.uit.no>
36 
37 	The official ptunnel website is here:
38 	<http://www.cs.uit.no/~daniels/PingTunnel/>
39 
40 	Note that the source code is best viewed with tabs set to 4 spaces.
41 */
42 
43 #ifndef PING_TUNNEL_H
44 	#define PING_TUNNEL_H
45 
46 //	Includes
47 #ifndef WIN32
48   	#include	<sys/unistd.h>
49   	#include	<sys/types.h>
50   	#include	<sys/socket.h>
51   	#include	<netinet/in.h>
52   	#include	<arpa/inet.h>
53   	#include	<netdb.h>
54 	#include	<pthread.h>
55 	#include	<errno.h>
56 	#include	<net/ethernet.h>
57 	#include	<syslog.h>
58 	#include	<pwd.h>
59 	#include	<grp.h>
60 #endif /* !WIN32 */
61 	#include	<stdarg.h>
62 	#include	<unistd.h>
63   	#include	<stdio.h>
64   	#include	<stdlib.h>
65   	#include	<string.h>
66   	#include	<time.h>
67   	#include	<sys/time.h>
68   	#include	<signal.h>
69   	#include	<inttypes.h>
70   	#include	<pcap.h>
71 
72 #ifdef WIN32
73 	#include    <winsock2.h>
74 	typedef int socklen_t;
75 	typedef uint32_t in_addr_t;
76 	#define ETH_ALEN        6               /* Octets in one ethernet addr   */
77 	struct ether_header
78 	{
79 		u_int8_t  ether_dhost[ETH_ALEN];      /* destination eth addr */
80 		u_int8_t  ether_shost[ETH_ALEN];      /* source ether addr    */
81 		u_int16_t ether_type;                 /* packet type ID field */
82 	};
83 #endif /* WIN32 */
84 
85 //	Constants
86 #define	false		0
87 #define	true		1
88 #define	bool		char
89 
90 enum {
91 	kOpt_undefined			= 0,		//	Constants for parsing options
92 	kOpt_set_proxy_addr,
93 	kOpt_set_mode,
94 	kOpt_set_password,
95 	kOpt_set_tcp_port,
96 	kOpt_set_tcp_dest_addr,
97 	kOpt_set_tcp_dest_port,
98 	kOpt_set_verbosity,
99 	kOpt_set_max_tunnels,
100 	kOpt_set_non_privileged,
101 	kOpt_set_pcap_device,
102 	kOpt_set_log_file,
103 	kOpt_set_unpriv_user,
104 	kOpt_set_unpriv_group,
105 	kOpt_set_root_dir,
106 	kOpt_set_selinux_context,
107 	kOpt_daemonize,
108 
109 	kMode_forward			= 0,	//	Ping tunnel's operating mode (client or
110 	kMode_proxy,					//	proxy)
111 
112 	kMax_tunnels			= 10,/*	Set this constant to the number of concurrent
113 									connections you wish to handle by default. */
114 
115 	kNo_log					= -1,	//	Different verbosity levels.
116 	kLog_error				= 0,
117 	kLog_info,
118 	kLog_event,
119 	kLog_verbose,
120 	kLog_debug,
121 	kLog_sendrecv,
122 
123 	kMajor_version			= 0,	//	Major (0.xx) and minor (x.70) version
124 	kMinor_version			= 72,	//	numbers.
125 
126 	kIP_packet_max_size		= 576,
127 	kIP_header_size			= 20,	//	In bytes, mind you
128 	kIP_actual_size			= (kIP_packet_max_size - kIP_header_size) - ((kIP_packet_max_size - kIP_header_size) % 8),
129 	kICMP_header_size		= 8,	//	Also in bytes
130 
131 	kDefault_buf_size		= 1024,	/*	This constant control the maximum size of
132 										the payload-portion of the ICMP packets
133 										we send. Note that this does not include
134 										the IP or ICMP headers!	*/
135 
136 	kICMP_echo_request		= 8,	//	Type code for echo request and replies
137 	kICMP_echo_reply		= 0,
138 
139 	kPing_window_size		= 64,	// number of packets we can have in our send/receive ring
140 
141 	/*	Tunnels are automatically closed after one minute of inactivity. Since
142 		we continously send acknowledgements between the two peers, this mechanism
143 		won't disconnect "valid" connections.
144 	*/
145 	kAutomatic_close_timeout	= 60,	//	Seconds!
146 
147 	kMD5_digest_size		= 16,	//	size of md5 digest in bytes
148 
149 	/*	These constants are used to indicate the protocol state. The protocol
150 		works as follows:
151 		- The identifier is used by both the proxy and the forwarder
152 		to identify the session (and thus the relevant sockets).
153 		- The seq-no of the ping packet is used in a sliding-window-esque
154 		way, and to identify the order of data.
155 
156 		The protocol can be in any of the following states:
157 		kProxy_start		Causes the proxy to open a connection to the given
158 							host and port, associating the ID with the socket,
159 							before the data on the socket are transmitted.
160 		kProxy_data			Indicates that the packet contains data from the proxy.
161 							Data ordering is indicated by the seq-no, which will start
162 							at 0. (The proxy and forwarder maintain different seq-nos.)
163 		kUser_data			This packet contains user data.
164 		kConnection_close	Indicates that the connection is being closed.
165 		kProxy_ack and		Acknowledges the packet (and all packets before it) with seq_no = ack.
166 		kUser_ack			This is used if there are no implicit acknowledgements due to data
167 							being sent.
168 
169 		Acknowledgements work by the remote peer acknowledging the last
170 		continuous seq no it has received.
171 
172 		Note: A proxy receiving a kProxy_data packet, or a user receiving a
173 		kUser_data packet, should ignore it, as it is the host operating system
174 		actually returning the ping. This is mostly relevant for users, and for
175 		proxies running in unprivileged mode.
176 	*/
177 	kProxy_start			= 0,
178 	kProto_ack,
179 	kProto_data,
180 	kProto_close,
181 	kProto_authenticate,
182 	kNum_proto_types,
183 
184 	kUser_flag				= 1 << 30,	//	set when packet comes from a user
185 	kProxy_flag				= 1 << 31,	//	set when packet comes from the proxy
186 	kFlag_mask				= kUser_flag | kProxy_flag,
187 
188 	kDNS_port				= 53,
189 };
190 
191 #define	kPing_tunnel_magic		0xD5200880
192 //	Resend packets after this interval (in seconds)
193 #define	kResend_interval		1.5
194 
195 /*	ping_tunnel_pkt_t: This data structure represents the header of a ptunnel
196 	packet, consisting of a magic number, the tunnel's destination IP and port,
197 	as well as some other fields. Note that the dest IP and port is only valid
198 	in packets from the client to the proxy.
199 */
200 typedef struct {
201 	uint32_t	magic,		//	magic number, used to identify ptunnel packets.
202 				dst_ip,		//	destination IP and port (used by proxy to figure
203 				dst_port,	//	out where to tunnel to)
204 				state,		//	current connection state; see constants above.
205 				ack,		//	sequence number of last packet received from other end
206 				data_len;	//	length of data buffer
207 	uint16_t	seq_no,		//	sequence number of this packet
208 				id_no;		//	id number, used to separate different tunnels from each other
209 	char		data[0];	//	optional data buffer
210 } __attribute__ ((packed)) ping_tunnel_pkt_t;
211 
212 
213 /*	ip_packet_t: This is basically my own definition of the IP packet, which
214 	of course complies with the official definition ;) See any good book on IP
215 	(or even the RFC) for info on the contents of this packet.
216 */
217 typedef struct {
218 	uint8_t			vers_ihl,
219 					tos;
220 	uint16_t		pkt_len,
221 					id,
222 					flags_frag_offset;
223 	uint8_t			ttl,
224 					proto;	// 1 for ICMP
225 	uint16_t		checksum;
226 	uint32_t		src_ip,
227 					dst_ip;
228 	char			data[0];
229 } __attribute__ ((packed)) ip_packet_t;
230 
231 
232 /*	icmp_echo_packet_t: This is the definition of a standard ICMP header. The
233 	ptunnel packets are constructed as follows:
234 	[    ip header (20 bytes)   ]
235 	[   icmp header (8 bytes)   ]
236 	[ ptunnel header (28 bytes) ]
237 
238 	We actually only create the ICMP and ptunnel headers, the IP header is
239 	taken care of by the OS.
240 */
241 typedef struct {
242 	uint8_t			type,
243 					code;
244 	uint16_t		checksum,
245 					identifier,
246 					seq;
247 	char			data[0];
248 } __attribute__ ((packed)) icmp_echo_packet_t;
249 
250 
251 /*	pt_thread_info_t: A simple (very simple, in fact) structure that allows us
252 	to pass an arbitrary number of params to the threads we create. Currently,
253 	that's just one single parameter: The socket which the thread should listen
254 	to.
255 */
256 typedef struct {
257 	int			sock;
258 } pt_thread_info_t;
259 
260 
261 /*	forward_desc_t: Describes a piece of that needs to be forwarded. This
262 	structure is used for receiving data from the network, and for subsequent
263 	forwarding over TCP:
264 
265 	1. Client sends data to proxy over ICMP
266 	2. Proxy receives the data, and puts it into a forward_desc_t
267 	3. The proxy starts send()-ing the data over the TCP socket to the destination,
268 	   decreasing forward_desc_t->remaining with the number of bytes transferred.
269 	4. Once remaining reaches 0, the forward_desc_t is removed from the receive
270 	   ring.
271 
272 	The same procedure is followed in proxy-to-client communication. Just replace
273 	proxy with client and vice versa in the list above.
274 */
275 typedef struct {
276 	int			seq_no,		//	ping_tunnel_pkt_t seq_no
277 				length,		//	length of data
278 				remaining;	//	amount of data not yet transferred
279 	char		data[0];
280 } forward_desc_t;
281 
282 
283 /*	icmp_desc_t: This structure is used to track the ICMP packets sent by either
284 	the client or proxy. The last_resend variable is used to prevent resending
285 	the packet too often. Once the packet is acknowledged by the remote end,
286 	it will be removed from the send-ring, freeing up space for more outgoing
287 	ICMP packets.
288 */
289 typedef struct {
290 	int					pkt_len;		// total length of ICMP packet, including ICMP header and ptunnel data.
291 	double				last_resend;
292 	int					resend_count;
293 	uint16_t			seq_no,
294 						icmp_id;
295 	icmp_echo_packet_t	*pkt;
296 } icmp_desc_t;
297 
298 
299 /*	challenge_t: This structure contains the pseudo-random challenge used for
300 	authentication.
301 */
302 typedef struct challenge_t {
303 	uint32_t			sec,		//	tv_sec as returned by gettimeofday
304 						usec_rnd,	//	tv_usec as returned by gettimeofday + random value
305 						random[6];	//	random values
306 } __attribute__ ((packed)) challenge_t;
307 
308 
309 /*	xfer_stats_t: Various transfer statistics, such as bytes sent and received,
310 	number of ping packets sent/received, etc.
311 */
312 typedef struct xfer_stats_t {
313 	double				bytes_in,
314 						bytes_out;
315 	uint32_t			icmp_in,
316 						icmp_out,
317 						icmp_resent,
318 						icmp_ack_out;
319 } xfer_stats_t;
320 
321 
322 /*	proxy_desc_t: This massive structure describes a tunnel instance.
323 */
324 typedef struct proxy_desc_t {
325 	int					sock,			//	ICMP or UDP socket
326 						bytes,			//	number of bytes in receive buffer
327 						should_remove;	//	set to true once this instance should be removed
328 	char				*buf;			//	data buffer, used to receive ping and pong packets
329 	uint16_t			id_no,
330 						my_seq,
331 						ping_seq,
332 						next_remote_seq,
333 						pkt_type,
334 						remote_ack_val,
335 						icmp_id;
336 	int					recv_idx,		//	first available slot in recv ring
337 						recv_xfer_idx,	//	current slot in recv ring being transferred
338 						send_idx,		//	first available slot in send ring
339 						send_first_ack,	//	first packet in send ring not yet acked
340 						recv_wait_send,	//	number of items in recv ring awaiting send
341 						send_wait_ack,	//	number of items in send ring awaiting ack
342 						next_resend_start,
343 						authenticated;
344 	challenge_t			*challenge;		//	Contains the challenge, if used.
345 	uint32_t			state,			//	Protocol state
346 						type_flag,		//	Either kProxy_flag or kUser_flag
347 						dst_ip,			//	IP and port to which data should be forwarded.
348 						dst_port;
349 	struct sockaddr_in	dest_addr;		//	Same as above
350 	double				last_ack,		//	Time when last ack packet was sent.
351 						last_activity;	//	Time when a packet was last received.
352 	icmp_desc_t			send_ring[kPing_window_size];
353 	forward_desc_t		*recv_ring[kPing_window_size];
354 	xfer_stats_t		xfer;
355 	struct proxy_desc_t	*next;
356 } proxy_desc_t;
357 
358 
359 /*	pqueue_elem_t: An queue element in the pqueue structure (below).
360 */
361 typedef struct pqueue_elem_t {
362 	int						bytes;		// size of data buffer
363 	struct pqueue_elem_t	*next;		// next queue element (if any)
364 	char					data[0];	// data (duh!)
365 } pqueue_elem_t;
366 
367 
368 /*	pqueue_t: A simple queue strucutre.
369 */
370 typedef struct {
371 	pqueue_elem_t	*head,
372 					*tail;
373 	int				elems;
374 } pqueue_t;
375 
376 /*	pcap_info_t: Structure to hold information related to packet capturing.
377 */
378 typedef struct {
379 	pcap_t				*pcap_desc;
380 	struct bpf_program	fp;		//	Compiled filter program
381 	uint32_t			netp,
382 						netmask;
383 	char				*pcap_err_buf,	//	Buffers for error and packet info
384 						*pcap_data_buf;
385 	pqueue_t			pkt_q;			//	Queue of packets to process
386 } pcap_info_t;
387 
388 
389 //	Prototypes (sorry about the long lines..)
390 	void		usage(char *exec_name);
391 	void*		pt_proxy(void *args);
392 	void		pcap_packet_handler(u_char *refcon, const struct pcap_pkthdr *hdr, const u_char* pkt);
393 	void		handle_packet(char *buf, int bytes, int is_pcap, struct sockaddr_in *addr, int icmp_sock);
394 
395 	proxy_desc_t*	create_and_insert_proxy_desc(uint16_t id_no, uint16_t icmp_id, int sock, struct sockaddr_in *addr, uint32_t dst_ip, uint32_t dst_port, uint32_t init_state, uint32_t type);
396 	void		remove_proxy_desc(proxy_desc_t *cur, proxy_desc_t *prev);
397 
398 	void		pt_forwarder(void);
399 
400 	void		print_statistics(xfer_stats_t *xfer, int is_continuous);
401 	int			queue_packet(int icmp_sock, uint8_t type, char *buf, int num_bytes, uint16_t id_no, uint16_t icmp_id, uint16_t *seq, icmp_desc_t ring[], int *insert_idx, int *await_send, uint32_t ip, uint32_t port, uint32_t state, struct sockaddr_in *dest_addr, uint16_t next_expected_seq, int *first_ack, uint16_t *ping_seq);
402 	uint32_t	send_packets(forward_desc_t *ring[], int *xfer_idx, int *await_send, int *sock);
403 	void		handle_data(icmp_echo_packet_t *pkt, int total_len, forward_desc_t *ring[], int *await_send, int *insert_idx, uint16_t *next_expected_seq);
404 	void		handle_ack(uint16_t seq_no, icmp_desc_t ring[], int *packets_awaiting_ack, int one_ack_only, int insert_idx, int *first_ack, uint16_t *remote_ack, int is_pcap);
405 	forward_desc_t*	create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data);
406 	void		init_ip_packet(ip_packet_t *packet, uint16_t id, uint16_t frag_offset, uint16_t pkt_len, uint8_t ttl, uint32_t src_ip, uint32_t dst_ip, bool is_last_frag, bool dont_frag);
407 	uint16_t	calc_ip_checksum(ip_packet_t *pkt);
408 	uint16_t	calc_icmp_checksum(uint16_t *data, int bytes);
409 
410 	challenge_t*	generate_challenge(void);
411 	void			generate_response(challenge_t *challenge);
412 	int				validate_challenge(challenge_t *local, challenge_t *remote);
413 
414 	void		send_termination_msg(proxy_desc_t *cur, int icmp_sock);
415 
416 	char*	f_inet_ntoa(uint32_t ip);
417 	void	pt_log(int level, char *fmt, ...);
418 	double	time_as_double(void);
419 #endif
420