diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | pdesc.c | 56 | ||||
-rw-r--r-- | pkt.c | 244 | ||||
-rw-r--r-- | pkt.h | 3 | ||||
-rw-r--r-- | ptunnel.c | 280 | ||||
-rw-r--r-- | ptunnel.h | 6 | ||||
-rw-r--r-- | utils.c | 51 | ||||
-rw-r--r-- | utils.h | 4 |
9 files changed, 372 insertions, 286 deletions
@@ -3,14 +3,14 @@ # ptunnel.exe target added by Mike Miller, mike@mikeage.net CC = gcc -CFLAGS = -Wall -g -fstrict-aliasing +CFLAGS = -Wall -g -fstrict-aliasing -Os LDOPTS = -lpthread -lpcap -PT_OBJS = options.o pdesc.o ptunnel.o md5.o base64.o +PT_OBJS = utils.o options.o pkt.o pdesc.o ptunnel.o md5.o base64.o WIN32_CC = mingw32-gcc WIN32_CFLAGS = -g -Wall -DWIN32 -I"c:\Program Files\WpdPack\Include" WIN32_LDOPTS = -lwpcap -lwsock32 -L"c:\Program Files\WpdPack\Lib" -WIN32_PT_OBJS = options.obj pdesc.obj ptunnel.obj md5.obj base64.obj +WIN32_PT_OBJS = utils.obj options.obj pkt.obj pdesc.obj ptunnel.obj md5.obj base64.obj prefix = $(DESTDIR)/usr bindir = $(prefix)/sbin @@ -1,11 +1,13 @@ -PingTunnel Read Me +PingTunnel-ng Read Me ================== -What is ptunnel? +What is ptunnel-ng? ---------------- Ptunnel is an application that allows you to reliably tunnel TCP connections to a remote host using ICMP echo request and reply packets, commonly known as ping requests and replies. +Ptunnel-ng is a bugfixed and refactored version of Ptunnel with some additional +features e.g. change the magic value without recompiling (bypass Cisco IPS). Contact details @@ -16,6 +18,8 @@ The official ptunnel website is located here: <http://www.cs.uit.no/~daniels/PingTunnel/> The Windows port was created by Mike Miller: <mike@mikeage.net> +The ng fork was done by Toni Uhlig: + <matzeton@googlemail.com> Compiling @@ -1,3 +1,5 @@ +#include <stdlib.h> + #include "pdesc.h" #include "options.h" #include "ptunnel.h" @@ -25,7 +27,7 @@ proxy_desc_t* create_and_insert_proxy_desc(uint16_t id_no, uint16_t icmp_id, pthread_mutex_unlock(&chain_lock); pt_log(kLog_debug, "Adding proxy desc to run loop. Type is %s. Will create socket: %s\n", (type == kUser_flag ? "user" : "proxy"), (sock ? "No" : "Yes")); - cur = calloc(1, sizeof(proxy_desc_t)); + cur = (proxy_desc_t *) calloc(1, sizeof(proxy_desc_t)); cur->id_no = id_no; cur->dest_addr = *addr; cur->dst_ip = dst_ip; @@ -50,7 +52,7 @@ proxy_desc_t* create_and_insert_proxy_desc(uint16_t id_no, uint16_t icmp_id, cur->pkt_type = kICMP_echo_request; else cur->pkt_type = (opts.unprivileged ? kICMP_echo_request : kICMP_echo_reply); - cur->buf = malloc(icmp_receive_buf_len); + cur->buf = (char *) malloc(icmp_receive_buf_len); cur->last_activity = time_as_double(); cur->authenticated = 0; @@ -62,3 +64,53 @@ proxy_desc_t* create_and_insert_proxy_desc(uint16_t id_no, uint16_t icmp_id, cur->xfer.bytes_out = 0.0; return cur; } + +/* remove_proxy_desc: Removes the given proxy desc, freeing its resources. + * Assumes that we hold the chain_lock. + */ +void remove_proxy_desc(proxy_desc_t *cur, proxy_desc_t *prev) { + int i; + struct timeval tt; + + pt_log(kLog_debug, "Removing proxy descriptor.\n"); + /* Get a timestamp, for making an entry in the seq_expiry_tbl */ + gettimeofday(&tt, 0); + seq_expiry_tbl[cur->id_no] = tt.tv_sec+(2*kAutomatic_close_timeout); + + /* Free resources associated with connection */ + if (cur->buf) + free(cur->buf); + cur->buf = 0; + for (i=0;i<kPing_window_size;i++) { + if (cur->send_ring[i].pkt) + free(cur->send_ring[i].pkt); + cur->send_ring[i].pkt = 0; + if (cur->recv_ring[i]) + free(cur->recv_ring[i]); + cur->recv_ring[i] = 0; + } + close(cur->sock); + cur->sock = 0; + + /* Keep list up-to-date */ + if (prev) + prev->next = cur->next; + else + chain = cur->next; + if (cur->challenge) + free(cur->challenge); + free(cur); + num_tunnels--; +} + +forward_desc_t* create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data) { + forward_desc_t *fwd_desc; + fwd_desc = (forward_desc_t *) malloc(sizeof(forward_desc_t)+data_len); + fwd_desc->seq_no = seq_no; + fwd_desc->length = data_len; + fwd_desc->remaining = data_len; + if (data_len > 0) + memcpy(fwd_desc->data, data, data_len); + return fwd_desc; +} + @@ -0,0 +1,244 @@ +#ifndef WIN32 +#include <netinet/in.h> +#include <arpa/inet.h> +#include <pthread.h> +#endif +#include <sys/time.h> + +#include "ptunnel.h" +#include "pkt.h" +#include "pdesc.h" +#include "options.h" +#include "utils.h" + +/* handle_proxy_packet: + * Processes incoming ICMP packets for the proxy. The packet can come either from the + * packet capture lib, or from the actual socket or both. + * Input: A buffer pointing at the start of an IP header, the buffer length and the proxy + * descriptor chain. + */ +void handle_packet(char *buf, unsigned bytes, int is_pcap, struct sockaddr_in *addr, int icmp_sock) { + ip_packet_t *ip_pkt; + icmp_echo_packet_t *pkt; + ping_tunnel_pkt_t *pt_pkt; + proxy_desc_t *cur; + uint32_t type_flag, pkt_flag, init_state, proxy_flag; + challenge_t *challenge; + struct timeval tt; + + proxy_flag = kProxy_flag; + + if (bytes < sizeof(icmp_echo_packet_t)+sizeof(ping_tunnel_pkt_t)) + pt_log(kLog_verbose, "Skipping this packet - too short. " + "Expect: %d+%d = %d ; Got: %d\n", + sizeof(icmp_echo_packet_t), + sizeof(ping_tunnel_pkt_t), + sizeof(icmp_echo_packet_t) + + sizeof(ping_tunnel_pkt_t), bytes); + else { + if (opts.udp) { + ip_pkt = 0; + pkt = (icmp_echo_packet_t*)buf; + pt_pkt = (ping_tunnel_pkt_t*)pkt->data; + } + else { + ip_pkt = (ip_packet_t*)buf; + pkt = (icmp_echo_packet_t*)ip_pkt->data; + pt_pkt = (ping_tunnel_pkt_t*)pkt->data; + } + + if (ntohl(pt_pkt->magic) == opts.magic) { + pt_pkt->state = ntohl(pt_pkt->state); + pkt->identifier = ntohs(pkt->identifier); + pt_pkt->id_no = ntohs(pt_pkt->id_no); + pt_pkt->seq_no = ntohs(pt_pkt->seq_no); + /* Find the relevant connection, if it exists */ + pthread_mutex_lock(&chain_lock); + for (cur=chain;cur;cur=cur->next) { + if (cur->id_no == pt_pkt->id_no) + break; + } + pthread_mutex_unlock(&chain_lock); + + /* Handle the packet if it comes from "the other end." This is a bit tricky + * to get right, since we receive both our own and the other end's packets. + * Basically, a proxy will accept any packet from a user, regardless if it + * has a valid connection or not. A user will only accept the packet if there + * exists a connection to handle it. + */ + if (cur) { + type_flag = cur->type_flag; + if (type_flag == (uint32_t)kProxy_flag) + cur->icmp_id = pkt->identifier; + if (!is_pcap) + cur->xfer.icmp_in++; + } + else + type_flag = kProxy_flag; + + pkt_flag = pt_pkt->state & kFlag_mask; + pt_pkt->state &= ~kFlag_mask; + pt_log(kLog_sendrecv, "Recv: %d [%d] bytes " + "[seq = %d] [type = %s] " + "[ack = %d] [icmp = %d] " + "[user = %s] [pcap = %d]\n", + bytes, ntohl(pt_pkt->data_len), + pt_pkt->seq_no, state_name[pt_pkt->state & (~kFlag_mask)], + ntohl(pt_pkt->ack), pkt->type, + (pkt_flag == kUser_flag ? "yes" : "no"), is_pcap); + + /* This test essentially verifies that the packet comes from someone who isn't us. */ + if ((pkt_flag == kUser_flag && type_flag == proxy_flag) || + (pkt_flag == proxy_flag && type_flag == kUser_flag)) + { + pt_pkt->data_len = ntohl(pt_pkt->data_len); + pt_pkt->ack = ntohl(pt_pkt->ack); + if (pt_pkt->state == kProxy_start) { + if (!cur && type_flag == proxy_flag) { + pt_log(kLog_info, "Incoming tunnel request from %s.\n", + inet_ntoa(*(struct in_addr *)&addr->sin_addr)); + gettimeofday(&tt, 0); + if (tt.tv_sec < seq_expiry_tbl[pt_pkt->id_no]) { + pt_log(kLog_verbose, "Dropping request: ID was recently in use.\n"); + return; + } + pt_log(kLog_info, "Starting new session to %s:%d with ID %d\n", + inet_ntoa(*(struct in_addr *)&pt_pkt->dst_ip), + ntohl(pt_pkt->dst_port), pt_pkt->id_no); + if ((opts.given_dst_ip && opts.given_dst_ip != pt_pkt->dst_ip) || + ((uint32_t)-1 != opts.given_dst_port && opts.given_dst_port != ntohl(pt_pkt->dst_port))) + { + pt_log(kLog_info, "Destination administratively prohibited!\n"); + return; + } + + if (opts.password) + init_state = kProto_authenticate; + else + init_state = kProto_data; + + cur = create_and_insert_proxy_desc(pt_pkt->id_no, pkt->identifier, 0, + addr, pt_pkt->dst_ip, + ntohl(pt_pkt->dst_port), + init_state, kProxy_flag); + if (init_state == kProto_authenticate) { + pt_log(kLog_debug, "Sending authentication challenge..\n"); + /* Send challenge */ + cur->challenge = generate_challenge(); + memcpy(cur->buf, cur->challenge, sizeof(challenge_t)); + queue_packet(icmp_sock, cur->pkt_type, cur->buf, + sizeof(challenge_t), cur->id_no, + cur->icmp_id, &cur->my_seq, cur->send_ring, + &cur->send_idx, &cur->send_wait_ack, 0, 0, + kProto_authenticate | cur->type_flag, + &cur->dest_addr, cur->next_remote_seq, + &cur->send_first_ack, &cur->ping_seq); + } + } + else if (type_flag == kUser_flag) { + pt_log(kLog_error, "Dropping proxy session request - we are not a proxy!\n"); + return; + } + else + pt_log(kLog_error, "Dropping duplicate proxy session request.\n"); + } + else if (cur && pt_pkt->state == kProto_authenticate) { + /* Sanity check packet length, and make sure it matches what we expect */ + if (pt_pkt->data_len != sizeof(challenge_t)) { + pt_log(kLog_error, "Received challenge packet, but data length " + "is not as expected.\n"); + pt_log(kLog_debug, "Data length: %d Expected: %d\n", + pt_pkt->data_len, sizeof (challenge_t)); + cur->should_remove = 1; + return; + } + /* Prevent packet data from being forwarded over TCP! */ + pt_pkt->data_len = 0; + challenge = (challenge_t*)pt_pkt->data; + /* If client: Compute response to challenge */ + if (type_flag == kUser_flag) { + if (!opts.password) { + pt_log(kLog_error, "This proxy requires a password! " + "Please supply one usin g the -x switch.\n"); + send_termination_msg(cur, icmp_sock); + cur->should_remove = 1; + return; + } + pt_log(kLog_debug, "Got authentication challenge - sending response\n"); + generate_response(challenge); + queue_packet(icmp_sock, cur->pkt_type, (char*)challenge, + sizeof(challenge_t), cur->id_no, cur->icmp_id, + &cur->my_seq, cur->send_ring, &cur->send_idx, + &cur->send_wait_ack, 0, 0, + kProto_authenticate | cur->type_flag, &cur->dest_addr, + cur->next_remote_seq, &cur->send_first_ack, &cur-> ping_seq); + /* We have authenticated locally. + * It's up to the proxy now if it accepts our response or not.. + */ + cur->authenticated = 1; + handle_data(pkt, bytes, cur->recv_ring, &cur->recv_wait_send, + &cur->recv_idx, &cur->next_remote_seq); + return; + } + /* If proxy: Handle client's response to challenge */ + else if (type_flag == proxy_flag) { + pt_log(kLog_debug, "Received remote challenge response.\n"); + if (validate_challenge(cur->challenge, challenge) || + cur->authenticated) + { + pt_log(kLog_verbose, "Remote end authenticated successfully.\n"); + /* Authentication has succeeded, so now we can proceed + * to handle incoming TCP data. + */ + cur->authenticated = 1; + cur->state = kProto_data; + /* Insert the packet into the receive ring, to avoid + * confusing the reliab ility mechanism. + */ + handle_data(pkt, bytes, cur->recv_ring, &cur->recv_wait_send, + &cur->recv_idx, &cur->next_remote_seq); + } + else { + pt_log(kLog_info, "Remote end failed authentication.\n"); + send_termination_msg(cur, icmp_sock); + cur->should_remove = 1; + } + return; + } + } + /* Handle close-messages for connections we know about */ + if (cur && pt_pkt->state == kProto_close) { + pt_log(kLog_info, "Received session close from remote peer.\n"); + cur->should_remove = 1; + return; + } + /* The proxy will ignore any other packets from the client + * until it has been authenticated. The packet resend mechanism + * insures that this isn't problematic. + */ + if (type_flag == proxy_flag && opts.password && + cur && !cur->authenticated) + { + pt_log(kLog_debug, "Ignoring packet with seq-no %d " + "- not authenticated yet.\n", pt_pkt->seq_no); + return; + } + + if (cur && cur->sock) { + if (pt_pkt->state == kProto_data || pt_pkt->state == kProxy_start || + pt_pkt->state == kProto_ack) + { + handle_data(pkt, bytes, cur->recv_ring, &cur->recv_wait_send, + &cur->recv_idx, &cur->next_remote_seq); + } + handle_ack((uint16_t)pt_pkt->ack, cur->send_ring, &cur->send_wait_ack, + 0, cur->send_idx, &cur->send_first_ack, &cur->remote_ack_val, + is_pcap); + cur->last_activity = time_as_double(); + } + } + } + else + pt_log(kLog_verbose, "Ignored incoming packet.\n"); + } +} @@ -80,4 +80,7 @@ typedef struct { char data[0]; } __attribute__ ((packed)) icmp_echo_packet_t; + +void handle_packet(char *buf, unsigned bytes, int is_pcap, struct sockaddr_in *addr, int icmp_sock); + #endif @@ -83,10 +83,10 @@ pthread_mutex_t chain_lock, // Lock protecting the chain of connections num_threads_lock; // Lock protecting the num_threads variable int - num_threads = 0, // Current thread count - num_tunnels = 0; // Current tunnel count -uint32_t - *seq_expiry_tbl = 0; // Table indicating when a connection ID is allowable (used by proxy) + num_threads = 0; // Current thread count +uint32_t num_tunnels = 0; // Current tunnel count +/** Table indicating when a connection ID is allowable (used by proxy) */ +uint32_t *seq_expiry_tbl = NULL; // Some buffer constants const int @@ -716,219 +716,6 @@ void pcap_packet_handler(u_char *refcon, const struct pcap_pkthdr *hdr, const u } - -/* handle_proxy_packet: - Processes incoming ICMP packets for the proxy. The packet can come either from the - packet capture lib, or from the actual socket or both. - Input: A buffer pointing at the start of an IP header, the buffer length and the proxy - descriptor chain. -*/ -void handle_packet(char *buf, int bytes, int is_pcap, struct sockaddr_in *addr, int icmp_sock) { - ip_packet_t *ip_pkt; - icmp_echo_packet_t *pkt; - ping_tunnel_pkt_t *pt_pkt; - proxy_desc_t *cur; - uint32_t type_flag, pkt_flag, init_state; - challenge_t *challenge; - struct timeval tt; - - if (bytes < sizeof(icmp_echo_packet_t)+sizeof(ping_tunnel_pkt_t)) - pt_log(kLog_verbose, "Skipping this packet - too short. Expect: %d+%d = %d ; Got: %d\n", sizeof(icmp_echo_packet_t), sizeof(ping_tunnel_pkt_t), sizeof(icmp_echo_packet_t)+sizeof(ping_tunnel_pkt_t), bytes); - else { - if (opts.udp) { - ip_pkt = 0; - pkt = (icmp_echo_packet_t*)buf; - pt_pkt = (ping_tunnel_pkt_t*)pkt->data; - } - else { - ip_pkt = (ip_packet_t*)buf; - pkt = (icmp_echo_packet_t*)ip_pkt->data; - pt_pkt = (ping_tunnel_pkt_t*)pkt->data; - } - if (ntohl(pt_pkt->magic) == opts.magic) { - pt_pkt->state = ntohl(pt_pkt->state); - pkt->identifier = ntohs(pkt->identifier); - pt_pkt->id_no = ntohs(pt_pkt->id_no); - pt_pkt->seq_no = ntohs(pt_pkt->seq_no); - // Find the relevant connection, if it exists - pthread_mutex_lock(&chain_lock); - for (cur=chain;cur;cur=cur->next) { - if (cur->id_no == pt_pkt->id_no) - break; - } - pthread_mutex_unlock(&chain_lock); - - /* Handle the packet if it comes from "the other end." This is a bit tricky - to get right, since we receive both our own and the other end's packets. - Basically, a proxy will accept any packet from a user, regardless if it - has a valid connection or not. A user will only accept the packet if there - exists a connection to handle it. - */ - if (cur) { - type_flag = cur->type_flag; - if (type_flag == kProxy_flag) - cur->icmp_id = pkt->identifier; - - if (!is_pcap) - cur->xfer.icmp_in++; - } - else - type_flag = kProxy_flag; - - pkt_flag = pt_pkt->state & kFlag_mask; - pt_pkt->state &= ~kFlag_mask; - pt_log(kLog_sendrecv, "Recv: %d [%d] bytes [seq = %d] [type = %s] [ack = %d] [icmp = %d] [user = %s] [pcap = %d]\n", - bytes, ntohl(pt_pkt->data_len), pt_pkt->seq_no, state_name[pt_pkt->state & (~kFlag_mask)], - ntohl(pt_pkt->ack), pkt->type, (pkt_flag == kUser_flag ? "yes" : "no"), is_pcap); - - // This test essentially verifies that the packet comes from someone who isn't us. - if ((pkt_flag == kUser_flag && type_flag == kProxy_flag) || (pkt_flag == kProxy_flag && type_flag == kUser_flag)) { - pt_pkt->data_len = ntohl(pt_pkt->data_len); - pt_pkt->ack = ntohl(pt_pkt->ack); - if (pt_pkt->state == kProxy_start) { - if (!cur && type_flag == kProxy_flag) { - pt_log(kLog_info, "Incoming tunnel request from %s.\n", inet_ntoa(*(struct in_addr*)&addr->sin_addr)); - gettimeofday(&tt, 0); - if (tt.tv_sec < seq_expiry_tbl[pt_pkt->id_no]) { - pt_log(kLog_verbose, "Dropping request: ID was recently in use.\n"); - return; - } - pt_log(kLog_info, "Starting new session to %s:%d with ID %d\n", inet_ntoa(*(struct in_addr*)&pt_pkt->dst_ip), ntohl(pt_pkt->dst_port), pt_pkt->id_no); - if ((opts.given_dst_ip && opts.given_dst_ip != pt_pkt->dst_ip) || (-1 != opts.given_dst_port && opts.given_dst_port != ntohl(pt_pkt->dst_port))) { - pt_log(kLog_info, "Destination administratively prohibited!\n"); - return; - } - if (opts.password) - init_state = kProto_authenticate; - else - init_state = kProto_data; - cur = create_and_insert_proxy_desc(pt_pkt->id_no, pkt->identifier, 0, addr, pt_pkt->dst_ip, ntohl(pt_pkt->dst_port), init_state, kProxy_flag); - if (init_state == kProto_authenticate) { - pt_log(kLog_debug, "Sending authentication challenge..\n"); - // Send challenge - cur->challenge = generate_challenge(); - memcpy(cur->buf, cur->challenge, sizeof(challenge_t)); - queue_packet(icmp_sock, cur->pkt_type, cur->buf, sizeof(challenge_t), cur->id_no, cur->icmp_id, &cur->my_seq, cur->send_ring, &cur->send_idx, &cur->send_wait_ack, 0, 0, kProto_authenticate | cur->type_flag, &cur->dest_addr, cur->next_remote_seq, &cur->send_first_ack, &cur->ping_seq); - } - } - else if (type_flag == kUser_flag) { - pt_log(kLog_error, "Dropping proxy session request - we are not a proxy!\n"); - return; - } - else - pt_log(kLog_error, "Dropping duplicate proxy session request.\n"); - } - else if (cur && pt_pkt->state == kProto_authenticate) { - // Sanity check packet length, and make sure it matches what we expect - if (pt_pkt->data_len != sizeof(challenge_t)) { - pt_log(kLog_error, "Received challenge packet, but data length is not as expected.\n"); - pt_log(kLog_debug, "Data length: %d Expected: %d\n", pt_pkt->data_len, sizeof(challenge_t)); - cur->should_remove = 1; - return; - } - // Prevent packet data from being forwarded over TCP! - pt_pkt->data_len = 0; - challenge = (challenge_t*)pt_pkt->data; - // If client: Compute response to challenge - if (type_flag == kUser_flag) { - if (!opts.password) { - pt_log(kLog_error, "This proxy requires a password! Please supply one using the -x switch.\n"); - send_termination_msg(cur, icmp_sock); - cur->should_remove = 1; - return; - } - pt_log(kLog_debug, "Got authentication challenge - sending response\n"); - generate_response(challenge); - queue_packet(icmp_sock, cur->pkt_type, (char*)challenge, sizeof(challenge_t), cur->id_no, cur->icmp_id, &cur->my_seq, cur->send_ring, &cur->send_idx, &cur->send_wait_ack, 0, 0, kProto_authenticate | cur->type_flag, &cur->dest_addr, cur->next_remote_seq, &cur->send_first_ack, &cur->ping_seq); - // We have authenticated locally. It's up to the proxy now if it accepts our response or not.. - cur->authenticated = 1; - handle_data(pkt, bytes, cur->recv_ring, &cur->recv_wait_send, &cur->recv_idx, &cur->next_remote_seq); - return; - } - // If proxy: Handle client's response to challenge - else if (type_flag == kProxy_flag) { - pt_log(kLog_debug, "Received remote challenge response.\n"); - if (validate_challenge(cur->challenge, challenge) || cur->authenticated) { - pt_log(kLog_verbose, "Remote end authenticated successfully.\n"); - // Authentication has succeeded, so now we can proceed to handle incoming TCP data. - cur->authenticated = 1; - cur->state = kProto_data; - // Insert the packet into the receive ring, to avoid confusing the reliability mechanism. - handle_data(pkt, bytes, cur->recv_ring, &cur->recv_wait_send, &cur->recv_idx, &cur->next_remote_seq); - } - else { - pt_log(kLog_info, "Remote end failed authentication.\n"); - send_termination_msg(cur, icmp_sock); - cur->should_remove = 1; - } - return; - } - } - // Handle close-messages for connections we know about - if (cur && pt_pkt->state == kProto_close) { - pt_log(kLog_info, "Received session close from remote peer.\n"); - cur->should_remove = 1; - return; - } - // The proxy will ignore any other packets from the client - // until it has been authenticated. The packet resend mechanism - // insures that this isn't problematic. - if (type_flag == kProxy_flag && opts.password && cur && !cur->authenticated) { - pt_log(kLog_debug, "Ignoring packet with seq-no %d - not authenticated yet.\n", pt_pkt->seq_no); - return; - } - - if (cur && cur->sock) { - if (pt_pkt->state == kProto_data || pt_pkt->state == kProxy_start || pt_pkt->state == kProto_ack) - handle_data(pkt, bytes, cur->recv_ring, &cur->recv_wait_send, &cur->recv_idx, &cur->next_remote_seq); - handle_ack((uint16_t)pt_pkt->ack, cur->send_ring, &cur->send_wait_ack, 0, cur->send_idx, &cur->send_first_ack, &cur->remote_ack_val, is_pcap); - cur->last_activity = time_as_double(); - } - } - } - else - pt_log(kLog_verbose, "Ignored incoming packet.\n"); - } -} - -/* remove_proxy_desc: Removes the given proxy desc, freeing its resources. - Assumes that we hold the chain_lock. -*/ -void remove_proxy_desc(proxy_desc_t *cur, proxy_desc_t *prev) { - int i; - struct timeval tt; - - pt_log(kLog_debug, "Removing proxy descriptor.\n"); - // Get a timestamp, for making an entry in the seq_expiry_tbl - gettimeofday(&tt, 0); - seq_expiry_tbl[cur->id_no] = tt.tv_sec+(2*kAutomatic_close_timeout); - - // Free resources associated with connection - if (cur->buf) - free(cur->buf); - cur->buf = 0; - for (i=0;i<kPing_window_size;i++) { - if (cur->send_ring[i].pkt) - free(cur->send_ring[i].pkt); - cur->send_ring[i].pkt = 0; - if (cur->recv_ring[i]) - free(cur->recv_ring[i]); - cur->recv_ring[i] = 0; - } - close(cur->sock); - cur->sock = 0; - - // Keep list up-to-date - if (prev) - prev->next = cur->next; - else - chain = cur->next; - if (cur->challenge) - free(cur->challenge); - free(cur); - num_tunnels--; -} - #if kPT_add_iphdr static int ip_id_counter = 1; #endif @@ -1218,19 +1005,6 @@ void handle_ack(uint16_t seq_no, icmp_desc_t ring[], int *packets_awaiting_ack, } - -forward_desc_t* create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data) { - forward_desc_t *fwd_desc; - fwd_desc = malloc(sizeof(forward_desc_t)+data_len); - fwd_desc->seq_no = seq_no; - fwd_desc->length = data_len; - fwd_desc->remaining = data_len; - if (data_len > 0) - memcpy(fwd_desc->data, data, data_len); - return fwd_desc; -} - - uint16_t calc_icmp_checksum(uint16_t *data, int bytes) { uint32_t sum; int i; @@ -1308,49 +1082,3 @@ void send_termination_msg(proxy_desc_t *cur, int icmp_sock) { queue_packet(icmp_sock, cur->pkt_type, 0, 0, cur->id_no, cur->icmp_id, &cur->my_seq, cur->send_ring, &cur->send_idx, &cur->send_wait_ack, 0, 0, kProto_close | cur->type_flag, &cur->dest_addr, cur->next_remote_seq, &cur->send_first_ack, &cur->ping_seq); cur->xfer.icmp_out += 2; } - - -void pt_log(int level, const char *fmt, ...) { - va_list args; - const char *header[] = { "[err]: ", - "[inf]: ", - "[evt]: ", - "[vbs]: ", - "[dbg]: ", - "[xfr]: " }; -#ifndef WIN32 - int syslog_levels[] = {LOG_ERR, LOG_NOTICE, LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_DEBUG}; -#endif /* !WIN32 */ - - if (level <= opts.log_level) { - va_start(args, fmt); -#ifndef WIN32 - if (opts.use_syslog) { - char log[255]; - int header_len; - header_len = snprintf(log,sizeof(log),"%s",header[level]); - vsnprintf(log+header_len,sizeof(log)-header_len,fmt,args); - syslog(syslog_levels[level], "%s", log); - } - else -#endif /* !WIN32 */ - fprintf(opts.log_file, "%s", header[level]), vfprintf(opts.log_file, fmt, args); - va_end(args); -#ifndef WIN32 - if (opts.log_file != stdout && !opts.use_syslog) -#else - if (opts.log_file != stdout) -#endif - fflush(opts.log_file); - } -} - - -double time_as_double(void) { - double result; - struct timeval tt; - - gettimeofday(&tt, 0); - result = (double)tt.tv_sec + ((double)tt.tv_usec / (double)10e5); - return result; -} @@ -64,7 +64,6 @@ #include <stdlib.h> #include <string.h> #include <time.h> -#include <sys/time.h> #include <signal.h> #include <stdint.h> #include <stdbool.h> @@ -75,9 +74,11 @@ #include "challenge.h" extern pthread_mutex_t chain_lock; -extern int num_tunnels; +extern uint32_t num_tunnels; extern const int icmp_receive_buf_len; extern proxy_desc_t *chain; +extern uint32_t *seq_expiry_tbl; +extern const char *state_name[kNum_proto_types]; /* 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, @@ -132,7 +133,6 @@ typedef struct { // Prototypes (sorry about the long lines..) 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); void pt_forwarder(void); @@ -0,0 +1,51 @@ +#ifndef WIN32 +#include <syslog.h> +#endif +#include <sys/time.h> + +#include "utils.h" +#include "options.h" + +void pt_log(int level, const char *fmt, ...) { + va_list args; + const char *header[] = { "[err]: ", + "[inf]: ", + "[evt]: ", + "[vbs]: ", + "[dbg]: ", + "[xfr]: " }; +#ifndef WIN32 + int syslog_levels[] = {LOG_ERR, LOG_NOTICE, LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_DEBUG}; +#endif /* !WIN32 */ + + if (level <= opts.log_level) { + va_start(args, fmt); +#ifndef WIN32 + if (opts.use_syslog) { + char log[255]; + int header_len; + header_len = snprintf(log,sizeof(log),"%s",header[level]); + vsnprintf(log+header_len,sizeof(log)-header_len,fmt,args); + syslog(syslog_levels[level], "%s", log); + } + else +#endif /* !WIN32 */ + fprintf(opts.log_file, "%s", header[level]), vfprintf(opts.log_file, fmt, args); + va_end(args); +#ifndef WIN32 + if (opts.log_file != stdout && !opts.use_syslog) +#else + if (opts.log_file != stdout) +#endif + fflush(opts.log_file); + } +} + +double time_as_double(void) { + double result; + struct timeval tt; + + gettimeofday(&tt, 0); + result = (double)tt.tv_sec + ((double)tt.tv_usec / (double)10e5); + return result; +} @@ -3,4 +3,8 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +void pt_log(int level, const char *fmt, ...); + +double time_as_double(void); + #endif |