diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2017-12-14 19:28:13 +0100 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2017-12-14 19:28:13 +0100 |
commit | ab9e4f90c0dc4d95698bb7f4a62ea709e0cdea9d (patch) | |
tree | ddc48c7a9e6a0994e35c6b26ae1de810249490af | |
parent | e49c629b22cc1eea89be4dbf6ef039706c143ab9 (diff) |
ptunnel-ng:
* source refactoring
-rw-r--r-- | challenge.h | 18 | ||||
-rw-r--r-- | options.h | 3 | ||||
-rw-r--r-- | pconfig.h | 91 | ||||
-rw-r--r-- | pdesc.h | 115 | ||||
-rw-r--r-- | ptunnel.h | 205 |
5 files changed, 227 insertions, 205 deletions
diff --git a/challenge.h b/challenge.h new file mode 100644 index 0000000..7bfd68c --- /dev/null +++ b/challenge.h @@ -0,0 +1,18 @@ +#ifndef CHALLENGE_H +#define CHALLENGE_H 1 + +#include <stdint.h> + +/** challenge_t: This structure contains the pseudo-random challenge used for + * authentication. + */ +typedef struct challenge_t { + /** tv_sec as returned by gettimeofday */ + uint32_t sec; + /** tv_usec as returned by gettimeofday + random value */ + uint32_t usec_rnd; + /** random values */ + uint32_t random[6]; +} __attribute__ ((packed)) challenge_t; + +#endif @@ -10,9 +10,8 @@ #include <selinux/selinux.h> #endif -#include "ptunnel.h" #include "md5.h" - +#include "pconfig.h" struct options { /** user defined magic value (prevent Cisco WSA/IronPort fingerprint scan) */ diff --git a/pconfig.h b/pconfig.h new file mode 100644 index 0000000..4adabc9 --- /dev/null +++ b/pconfig.h @@ -0,0 +1,91 @@ +#ifndef PCONFIG_H +#define PCONFIG_H 1 + +enum { + /** Ping tunnel's operating mode (client) */ + kMode_forward = 0, + /** Ping tunnel's operating mode (server) */ + kMode_proxy, + /** Set this constant to the number of + * concurrent connections you wish to handle by default. + */ + kMax_tunnels = 10, + /** Different verbosity levels. */ + kNo_log = -1, + kLog_error = 0, + kLog_info, + kLog_event, + kLog_verbose, + kLog_debug, + kLog_sendrecv, + /** Major (0.xx) and minor (x.70) version */ + kMajor_version = 0, + /** numbers */ + kMinor_version = 72, + kIP_packet_max_size = 576, + /** In bytes, mind you */ + kIP_header_size = 20, + kIP_actual_size = (kIP_packet_max_size - kIP_header_size) - ((kIP_packet_max_size - kIP_header_size) % 8), + /** Also in bytes */ + kICMP_header_size = 8, + /** 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! + */ + kDefault_buf_size = 1024, + /** Type code for echo request and replies */ + kICMP_echo_request = 8, + kICMP_echo_reply = 0, + /** number of packets we can have in our send/receive ring */ + kPing_window_size = 64, + /** 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! + /** size of md5 digest in bytes */ + kMD5_digest_size = 16, + /** 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 + * to identify the session (and thus the relevant sockets). + * - The seq-no of the ping packet is used in a sliding-window-esque + * way, and to identify the order of data. + * + * The protocol can be in any of the following states: + * 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. + * 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. + * 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 + * 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 + * proxies running in unprivileged mode. + */ + kProxy_start = 0, + kProto_ack, + kProto_data, + kProto_close, + kProto_authenticate, + kNum_proto_types, + /** set when packet comes from a user */ + kUser_flag = 1 << 30, + /** set when packet comes from the proxy */ + kProxy_flag = 1 << 31, + kFlag_mask = kUser_flag | kProxy_flag, + kDNS_port = 53 +}; + +#endif @@ -0,0 +1,115 @@ +#ifndef PDESC_H +#define PDESC_H 1 + +#include <stdint.h> + +#include "pkt.h" +#include "challenge.h" +#include "pconfig.h" + +/** 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 { + /** ping_tunnel_pkt_t seq_no */ + int seq_no; + /** length of data */ + int length; + /** amount of data not yet transferred */ + int remaining; + char data[0]; +} forward_desc_t; + +/** icmp_desc_t: This structure is used to track the ICMP packets sent by either + * the client or proxy. The last_resend variable is used to prevent resending + * the packet too often. Once the packet is acknowledged by the remote end, + * it will be removed from the send-ring, freeing up space for more outgoing + * ICMP packets. + */ +typedef struct { + /** total length of ICMP packet, including ICMP header and ptunnel data. */ + int pkt_len; + double last_resend; + int resend_count; + uint16_t seq_no; + uint16_t icmp_id; + icmp_echo_packet_t *pkt; +} icmp_desc_t; + +/** xfer_stats_t: Various transfer statistics, such as bytes sent and received, + * number of ping packets sent/received, etc. + */ +typedef struct xfer_stats_t { + double bytes_in; + double bytes_out; + uint32_t icmp_in; + uint32_t icmp_out; + uint32_t icmp_resent; + uint32_t icmp_ack_out; +} xfer_stats_t; + +/** proxy_desc_t: This massive structure describes a tunnel instance. + */ +typedef struct proxy_desc_t { + /** ICMP or UDP socket */ + int sock; + /** number of bytes in receive buffer */ + int bytes; + /** set to true once this instance should be removed */ + int should_remove; + /** data buffer, used to receive ping and pong packets */ + char *buf; + uint16_t id_no; + uint16_t my_seq; + uint16_t ping_seq; + uint16_t next_remote_seq; + uint16_t pkt_type; + uint16_t remote_ack_val; + uint16_t icmp_id; + /** first available slot in recv ring */ + int recv_idx; + /** current slot in recv ring being transferred */ + int recv_xfer_idx; + /** first available slot in send ring */ + int send_idx; + /** first packet in send ring not yet acked */ + int send_first_ack; + /** number of items in recv ring awaiting send */ + int recv_wait_send; + /** number of items in send ring awaiting ack */ + int send_wait_ack; + int next_resend_start; + int authenticated; + /** Contains the challenge, if used. */ + challenge_t *challenge; + /** Protocol state */ + uint32_t state; + /** Either kProxy_flag or kUser_flag */ + uint32_t type_flag; + /** IP and port to which data should be forwarded. */ + uint32_t dst_ip; + uint32_t dst_port; + /** Same as above */ + struct sockaddr_in dest_addr; + /** Time when last ack packet was sent. */ + double last_ack; + /** Time when a packet was last received. */ + double last_activity; + 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; + +#endif @@ -71,93 +71,8 @@ #include <pcap.h> #include "pkt.h" - -enum { - kMode_forward = 0, // Ping tunnel's operating mode (client) - kMode_proxy, // Ping tunnel's operating mode (server) - - /** Set this constant to the number of - * concurrent connections you wish to handle by default. - */ - kMax_tunnels = 10, - - 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 - - /** 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! - */ - kDefault_buf_size = 1024, - - 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 - to identify the session (and thus the relevant sockets). - - The seq-no of the ping packet is used in a sliding-window-esque - way, and to identify the order of data. - - The protocol can be in any of the following states: - 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. - 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. - 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 - 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 - proxies running in unprivileged mode. - */ - kProxy_start = 0, - kProto_ack, - kProto_data, - 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, -}; +#include "pdesc.h" +#include "challenge.h" /* pt_thread_info_t: A simple (very simple, in fact) structure that allows us to pass an arbitrary number of params to the threads we create. Currently, @@ -169,122 +84,6 @@ typedef struct { 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]; -} forward_desc_t; - - -/* icmp_desc_t: This structure is used to track the ICMP packets sent by either - the client or proxy. The last_resend variable is used to prevent resending - the packet too often. Once the packet is acknowledged by the remote end, - it will be removed from the send-ring, freeing up space for more outgoing - 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; - icmp_echo_packet_t *pkt; -} icmp_desc_t; - - -/* challenge_t: This structure contains the pseudo-random challenge used for - 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 -} __attribute__ ((packed)) challenge_t; - - -/* xfer_stats_t: Various transfer statistics, such as bytes sent and received, - 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; -} 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; -} proxy_desc_t; - - /* pqueue_elem_t: An queue element in the pqueue structure (below). */ typedef struct pqueue_elem_t { |