aboutsummaryrefslogtreecommitdiff
path: root/ptunnel.h
diff options
context:
space:
mode:
Diffstat (limited to 'ptunnel.h')
-rwxr-xr-xptunnel.h299
1 files changed, 170 insertions, 129 deletions
diff --git a/ptunnel.h b/ptunnel.h
index 70b673b..57fb170 100755
--- a/ptunnel.h
+++ b/ptunnel.h
@@ -89,6 +89,7 @@
enum {
kOpt_undefined = 0, // Constants for parsing options
+ kOpt_set_magic,
kOpt_set_proxy_addr,
kOpt_set_mode,
kOpt_set_password,
@@ -105,47 +106,47 @@ enum {
kOpt_set_root_dir,
kOpt_set_selinux_context,
kOpt_daemonize,
-
+
kMode_forward = 0, // Ping tunnel's operating mode (client or
- kMode_proxy, // proxy)
-
+ kMode_proxy, // proxy)
+
kMax_tunnels = 10,/* Set this constant to the number of concurrent
- connections you wish to handle by default. */
-
- kNo_log = -1, // Different verbosity levels.
- kLog_error = 0,
+ connections you wish to handle by default. */
+
+ kNo_log = -1, // Different verbosity levels.
+ kLog_error = 0,
kLog_info,
kLog_event,
kLog_verbose,
kLog_debug,
kLog_sendrecv,
-
+
kMajor_version = 0, // Major (0.xx) and minor (x.70) version
kMinor_version = 72, // numbers.
-
+
kIP_packet_max_size = 576,
kIP_header_size = 20, // In bytes, mind you
kIP_actual_size = (kIP_packet_max_size - kIP_header_size) - ((kIP_packet_max_size - kIP_header_size) % 8),
kICMP_header_size = 8, // Also in bytes
-
+
kDefault_buf_size = 1024, /* This constant control the maximum size of
- the payload-portion of the ICMP packets
- we send. Note that this does not include
- the IP or ICMP headers! */
-
+ the payload-portion of the ICMP packets
+ we send. Note that this does not include
+ the IP or ICMP headers! */
+
kICMP_echo_request = 8, // Type code for echo request and replies
kICMP_echo_reply = 0,
-
+
kPing_window_size = 64, // number of packets we can have in our send/receive ring
-
+
/* Tunnels are automatically closed after one minute of inactivity. Since
we continously send acknowledgements between the two peers, this mechanism
won't disconnect "valid" connections.
*/
kAutomatic_close_timeout = 60, // Seconds!
-
+
kMD5_digest_size = 16, // size of md5 digest in bytes
-
+
/* These constants are used to indicate the protocol state. The protocol
works as follows:
- The identifier is used by both the proxy and the forwarder
@@ -157,18 +158,18 @@ enum {
kProxy_start Causes the proxy to open a connection to the given
host and port, associating the ID with the socket,
before the data on the socket are transmitted.
- kProxy_data Indicates that the packet contains data from the proxy.
+ kProxy_data Indicates that the packet contains data from the proxy.
Data ordering is indicated by the seq-no, which will start
at 0. (The proxy and forwarder maintain different seq-nos.)
- kUser_data This packet contains user data.
+ kUser_data This packet contains user data.
kConnection_close Indicates that the connection is being closed.
kProxy_ack and Acknowledges the packet (and all packets before it) with seq_no = ack.
- kUser_ack This is used if there are no implicit acknowledgements due to data
+ kUser_ack This is used if there are no implicit acknowledgements due to data
being sent.
-
+
Acknowledgements work by the remote peer acknowledging the last
continuous seq no it has received.
-
+
Note: A proxy receiving a kProxy_data packet, or a user receiving a
kUser_data packet, should ignore it, as it is the host operating system
actually returning the ping. This is mostly relevant for users, and for
@@ -180,15 +181,15 @@ enum {
kProto_close,
kProto_authenticate,
kNum_proto_types,
-
- kUser_flag = 1 << 30, // set when packet comes from a user
- kProxy_flag = 1 << 31, // set when packet comes from the proxy
- kFlag_mask = kUser_flag | kProxy_flag,
-
- kDNS_port = 53,
+
+ kUser_flag = 1 << 30, // set when packet comes from a user
+ kProxy_flag = 1 << 31, // set when packet comes from the proxy
+ kFlag_mask = kUser_flag | kProxy_flag,
+
+ kDNS_port = 53,
};
-#define kPing_tunnel_magic 0xD5200880
+#define kPing_tunnel_magic 0xDEADC0DE
// Resend packets after this interval (in seconds)
#define kResend_interval 1.5
@@ -198,15 +199,18 @@ enum {
in packets from the client to the proxy.
*/
typedef struct {
- uint32_t magic, // magic number, used to identify ptunnel packets.
- dst_ip, // destination IP and port (used by proxy to figure
- dst_port, // out where to tunnel to)
- state, // current connection state; see constants above.
- ack, // sequence number of last packet received from other end
- data_len; // length of data buffer
- uint16_t seq_no, // sequence number of this packet
- id_no; // id number, used to separate different tunnels from each other
- char data[0]; // optional data buffer
+ uint32_t
+ magic, // magic number, used to identify ptunnel packets.
+ dst_ip, // destination IP and port (used by proxy to figure
+ dst_port, // out where to tunnel to)
+ state, // current connection state; see constants above.
+ ack, // sequence number of last packet received from other end
+ data_len; // length of data buffer
+ uint16_t
+ seq_no, // sequence number of this packet
+ id_no; // id number, used to separate different tunnels from each other
+ char
+ data[0]; // optional data buffer
} __attribute__ ((packed)) ping_tunnel_pkt_t;
@@ -215,17 +219,23 @@ typedef struct {
(or even the RFC) for info on the contents of this packet.
*/
typedef struct {
- uint8_t vers_ihl,
- tos;
- uint16_t pkt_len,
- id,
- flags_frag_offset;
- uint8_t ttl,
- proto; // 1 for ICMP
- uint16_t checksum;
- uint32_t src_ip,
- dst_ip;
- char data[0];
+ uint8_t
+ vers_ihl,
+ tos;
+ uint16_t
+ pkt_len,
+ id,
+ flags_frag_offset;
+ uint8_t
+ ttl,
+ proto; // 1 for ICMP
+ uint16_t
+ checksum;
+ uint32_t
+ src_ip,
+ dst_ip;
+ char
+ data[0];
} __attribute__ ((packed)) ip_packet_t;
@@ -239,12 +249,15 @@ typedef struct {
taken care of by the OS.
*/
typedef struct {
- uint8_t type,
- code;
- uint16_t checksum,
- identifier,
- seq;
- char data[0];
+ uint8_t
+ type,
+ code;
+ uint16_t
+ checksum,
+ identifier,
+ seq;
+ char
+ data[0];
} __attribute__ ((packed)) icmp_echo_packet_t;
@@ -254,29 +267,32 @@ typedef struct {
to.
*/
typedef struct {
- int sock;
+ int
+ sock;
} pt_thread_info_t;
/* forward_desc_t: Describes a piece of that needs to be forwarded. This
structure is used for receiving data from the network, and for subsequent
forwarding over TCP:
-
+
1. Client sends data to proxy over ICMP
2. Proxy receives the data, and puts it into a forward_desc_t
3. The proxy starts send()-ing the data over the TCP socket to the destination,
decreasing forward_desc_t->remaining with the number of bytes transferred.
4. Once remaining reaches 0, the forward_desc_t is removed from the receive
ring.
-
+
The same procedure is followed in proxy-to-client communication. Just replace
proxy with client and vice versa in the list above.
*/
typedef struct {
- int seq_no, // ping_tunnel_pkt_t seq_no
- length, // length of data
- remaining; // amount of data not yet transferred
- char data[0];
+ int
+ seq_no, // ping_tunnel_pkt_t seq_no
+ length, // length of data
+ remaining; // amount of data not yet transferred
+ char
+ data[0];
} forward_desc_t;
@@ -287,11 +303,12 @@ typedef struct {
ICMP packets.
*/
typedef struct {
- int pkt_len; // total length of ICMP packet, including ICMP header and ptunnel data.
- double last_resend;
- int resend_count;
- uint16_t seq_no,
- icmp_id;
+ int pkt_len; // total length of ICMP packet, including ICMP header and ptunnel data.
+ double last_resend;
+ int resend_count;
+ uint16_t
+ seq_no,
+ icmp_id;
icmp_echo_packet_t *pkt;
} icmp_desc_t;
@@ -300,9 +317,10 @@ typedef struct {
authentication.
*/
typedef struct challenge_t {
- uint32_t sec, // tv_sec as returned by gettimeofday
- usec_rnd, // tv_usec as returned by gettimeofday + random value
- random[6]; // random values
+ uint32_t
+ sec, // tv_sec as returned by gettimeofday
+ usec_rnd, // tv_usec as returned by gettimeofday + random value
+ random[6]; // random values
} __attribute__ ((packed)) challenge_t;
@@ -310,79 +328,102 @@ typedef struct challenge_t {
number of ping packets sent/received, etc.
*/
typedef struct xfer_stats_t {
- double bytes_in,
- bytes_out;
- uint32_t icmp_in,
- icmp_out,
- icmp_resent,
- icmp_ack_out;
+ double
+ bytes_in,
+ bytes_out;
+ uint32_t
+ icmp_in,
+ icmp_out,
+ icmp_resent,
+ icmp_ack_out;
} xfer_stats_t;
/* proxy_desc_t: This massive structure describes a tunnel instance.
*/
typedef struct proxy_desc_t {
- int sock, // ICMP or UDP socket
- bytes, // number of bytes in receive buffer
- should_remove; // set to true once this instance should be removed
- char *buf; // data buffer, used to receive ping and pong packets
- uint16_t id_no,
- my_seq,
- ping_seq,
- next_remote_seq,
- pkt_type,
- remote_ack_val,
- icmp_id;
- int recv_idx, // first available slot in recv ring
- recv_xfer_idx, // current slot in recv ring being transferred
- send_idx, // first available slot in send ring
- send_first_ack, // first packet in send ring not yet acked
- recv_wait_send, // number of items in recv ring awaiting send
- send_wait_ack, // number of items in send ring awaiting ack
- next_resend_start,
- authenticated;
- challenge_t *challenge; // Contains the challenge, if used.
- uint32_t state, // Protocol state
- type_flag, // Either kProxy_flag or kUser_flag
- dst_ip, // IP and port to which data should be forwarded.
- dst_port;
- struct sockaddr_in dest_addr; // Same as above
- double last_ack, // Time when last ack packet was sent.
- last_activity; // Time when a packet was last received.
- icmp_desc_t send_ring[kPing_window_size];
- forward_desc_t *recv_ring[kPing_window_size];
- xfer_stats_t xfer;
- struct proxy_desc_t *next;
+ int
+ sock, // ICMP or UDP socket
+ bytes, // number of bytes in receive buffer
+ should_remove; // set to true once this instance should be removed
+ char *buf; // data buffer, used to receive ping and pong packets
+ uint16_t
+ id_no,
+ my_seq,
+ ping_seq,
+ next_remote_seq,
+ pkt_type,
+ remote_ack_val,
+ icmp_id;
+ int
+ recv_idx, // first available slot in recv ring
+ recv_xfer_idx, // current slot in recv ring being transferred
+ send_idx, // first available slot in send ring
+ send_first_ack, // first packet in send ring not yet acked
+ recv_wait_send, // number of items in recv ring awaiting send
+ send_wait_ack, // number of items in send ring awaiting ack
+ next_resend_start,
+ authenticated;
+ challenge_t
+ *challenge; // Contains the challenge, if used.
+ uint32_t
+ state, // Protocol state
+ type_flag, // Either kProxy_flag or kUser_flag
+ dst_ip, // IP and port to which data should be forwarded.
+ dst_port;
+ struct sockaddr_in
+ dest_addr; // Same as above
+ double
+ last_ack, // Time when last ack packet was sent.
+ last_activity; // Time when a packet was last received.
+ icmp_desc_t
+ send_ring[kPing_window_size];
+ forward_desc_t
+ *recv_ring[kPing_window_size];
+ xfer_stats_t
+ xfer;
+ struct proxy_desc_t
+ *next;
} proxy_desc_t;
/* pqueue_elem_t: An queue element in the pqueue structure (below).
*/
typedef struct pqueue_elem_t {
- int bytes; // size of data buffer
- struct pqueue_elem_t *next; // next queue element (if any)
- char data[0]; // data (duh!)
+ int
+ bytes; // size of data buffer
+ struct pqueue_elem_t
+ *next; // next queue element (if any)
+ char
+ data[0]; // data (duh!)
} pqueue_elem_t;
/* pqueue_t: A simple queue strucutre.
*/
typedef struct {
- pqueue_elem_t *head,
- *tail;
- int elems;
+ pqueue_elem_t
+ *head,
+ *tail;
+ int
+ elems;
} pqueue_t;
/* pcap_info_t: Structure to hold information related to packet capturing.
*/
typedef struct {
- pcap_t *pcap_desc;
- struct bpf_program fp; // Compiled filter program
- uint32_t netp,
- netmask;
- char *pcap_err_buf, // Buffers for error and packet info
- *pcap_data_buf;
- pqueue_t pkt_q; // Queue of packets to process
+ pcap_t
+ *pcap_desc;
+ struct bpf_program
+ fp; // Compiled filter program
+ uint32_t
+ netp,
+ netmask;
+ char
+ *pcap_err_buf, // Buffers for error and packet info
+ *pcap_data_buf;
+ pqueue_t
+ pkt_q; // Queue of packets to process
} pcap_info_t;
@@ -391,12 +432,12 @@ typedef struct {
void* pt_proxy(void *args);
void pcap_packet_handler(u_char *refcon, const struct pcap_pkthdr *hdr, const u_char* pkt);
void handle_packet(char *buf, int bytes, int is_pcap, struct sockaddr_in *addr, int icmp_sock);
-
+
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);
void remove_proxy_desc(proxy_desc_t *cur, proxy_desc_t *prev);
-
+
void pt_forwarder(void);
-
+
void print_statistics(xfer_stats_t *xfer, int is_continuous);
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);
uint32_t send_packets(forward_desc_t *ring[], int *xfer_idx, int *await_send, int *sock);
@@ -406,13 +447,13 @@ typedef struct {
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);
uint16_t calc_ip_checksum(ip_packet_t *pkt);
uint16_t calc_icmp_checksum(uint16_t *data, int bytes);
-
+
challenge_t* generate_challenge(void);
- void generate_response(challenge_t *challenge);
- int validate_challenge(challenge_t *local, challenge_t *remote);
-
+ void generate_response(challenge_t *challenge);
+ int validate_challenge(challenge_t *local, challenge_t *remote);
+
void send_termination_msg(proxy_desc_t *cur, int icmp_sock);
-
+
char* f_inet_ntoa(uint32_t ip);
void pt_log(int level, char *fmt, ...);
double time_as_double(void);