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