diff options
author | Erik Simon <simon.erik@fmx.net> | 2020-02-20 12:55:13 +0100 |
---|---|---|
committer | Erik Simon <simon.erik@fmx.net> | 2020-02-20 12:55:13 +0100 |
commit | 0ee4b6536234c99a4828ae9b15ebdf504424e12e (patch) | |
tree | 5a14eda18e82548e307b890aa6acb4101b3a5e1d | |
parent | 5edf3ce72d68b8b65fecd44003af6d011b93185d (diff) |
Run clang-format on old ptk.c/.h files
-rw-r--r-- | src/pkt.c | 817 | ||||
-rw-r--r-- | src/pkt.h | 89 |
2 files changed, 459 insertions, 447 deletions
@@ -62,437 +62,450 @@ * 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; - struct in_addr in_addr; +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; + struct in_addr in_addr; + + proxy_flag = kProxy_flag; - 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: %lu+%lu = %lu ; Got: %u\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 || opts.unprivileged) { + 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 (bytes < sizeof(icmp_echo_packet_t)+sizeof(ping_tunnel_pkt_t)) - pt_log(kLog_verbose, "Skipping this packet - too short. " - "Expect: %lu+%lu = %lu ; Got: %u\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 || opts.unprivileged) { - 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); + pkt->seq = ntohs(pkt->seq); + 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); - if (ntohl(pt_pkt->magic) == opts.magic) { - pt_pkt->state = ntohl(pt_pkt->state); - pkt->identifier = ntohs(pkt->identifier); - pkt->seq = ntohs(pkt->seq); - 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; + cur->ping_seq = pkt->seq; + } + if (!is_pcap) + cur->xfer.icmp_in++; + } else { + type_flag = kProxy_flag; + } - /* 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; - cur->ping_seq = pkt->seq; - } - if (!is_pcap) - cur->xfer.icmp_in++; - } - else { - type_flag = kProxy_flag; - } - - pkt_flag = pt_pkt->state & kFlag_mask; - pt_pkt->state &= ~kFlag_mask; - if (pt_pkt->state > (kNum_proto_types-1)) { - pt_log(kLog_error, "Dropping packet with invalid state.\n"); - return; - } - pt_log(kLog_sendrecv, "Recv: %4d [%4d] bytes " - "[id = 0x%04X] [seq = %d] " - "[seq_no = %d] [type = %s] " - "[ack = %d] [icmp = %d] " - "[user = %s] [pcap = %d]\n", - bytes, ntohl(pt_pkt->data_len), - pkt->identifier, ntohs(pkt->seq), - 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); + pkt_flag = pt_pkt->state & kFlag_mask; + pt_pkt->state &= ~kFlag_mask; + if (pt_pkt->state > (kNum_proto_types - 1)) { + pt_log(kLog_error, "Dropping packet with invalid state.\n"); + return; + } + pt_log(kLog_sendrecv, + "Recv: %4d [%4d] bytes " + "[id = 0x%04X] [seq = %d] " + "[seq_no = %d] [type = %s] " + "[ack = %d] [icmp = %d] " + "[user = %s] [pcap = %d]\n", + bytes, + ntohl(pt_pkt->data_len), + pkt->identifier, + ntohs(pkt->seq), + 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; - } - in_addr.s_addr = pt_pkt->dst_ip; - pt_log(kLog_info, "Starting new session to %s:%d with ID %d\n", - inet_ntoa(in_addr), - ntohl(pt_pkt->dst_port), pt_pkt->id_no); - if ((opts.restrict_dst_ip && opts.given_dst_ip && - opts.given_dst_ip != pt_pkt->dst_ip) || - (opts.restrict_dst_port && (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; - } + /* 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; + } + in_addr.s_addr = pt_pkt->dst_ip; + pt_log(kLog_info, + "Starting new session to %s:%d with ID %d\n", + inet_ntoa(in_addr), + ntohl(pt_pkt->dst_port), + pt_pkt->id_no); + if ((opts.restrict_dst_ip && opts.given_dst_ip && opts.given_dst_ip != pt_pkt->dst_ip) || + (opts.restrict_dst_port && (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; + if (opts.password) + init_state = kProto_authenticate; + else + init_state = kProto_data; - cur = (proxy_desc_t *) 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 (!cur) { - /* if failed, abort. Logging is done in create_insert_proxy_desc */ - pt_log(kLog_error, "Failed to create proxy descriptor!\n"); - return; - } - if (pt_pkt->data_len > 0) { - handle_data(pkt, bytes, cur, 1); - if (!opts.password) { - handle_extended_options(cur); - } - } - 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, cur->buf, sizeof(challenge_t), 0, 0, - kProto_authenticate | cur->type_flag); - } - } - 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 " - "with ID %d and seq %d.\n", - pt_pkt->id_no, pt_pkt->seq_no); - } - 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: %u Expected: %lu\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; - } + cur = (proxy_desc_t *)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 (!cur) { + /* if failed, abort. Logging is done in create_insert_proxy_desc */ + pt_log(kLog_error, "Failed to create proxy descriptor!\n"); + return; + } + if (pt_pkt->data_len > 0) { + handle_data(pkt, bytes, cur, 1); + if (!opts.password) { + handle_extended_options(cur); + } + } + 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, + cur->buf, + sizeof(challenge_t), + 0, + 0, + kProto_authenticate | cur->type_flag); + } + } 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 " + "with ID %d and seq %d.\n", + pt_pkt->id_no, + pt_pkt->seq_no); + } 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: %u Expected: %lu\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; + } #ifdef ENABLE_SHA512 - if (opts.force_sha512) { - pt_log(kLog_debug, "Got authentication challenge - sending SHA512 response\n"); - generate_response_sha512(&challenge->plain, &challenge->digest); - } else + if (opts.force_sha512) { + pt_log(kLog_debug, "Got authentication challenge - sending SHA512 response\n"); + generate_response_sha512(&challenge->plain, &challenge->digest); + } else #endif - { - pt_log(kLog_debug, "Got authentication challenge - sending MD5 response\n"); - generate_response_md5(&challenge->plain, &challenge->digest); - } + { + pt_log(kLog_debug, "Got authentication challenge - sending MD5 response\n"); + generate_response_md5(&challenge->plain, &challenge->digest); + } - memcpy(cur->buf, challenge, sizeof(challenge_t)); - queue_packet(icmp_sock, cur, cur->buf, sizeof(challenge_t), 0, 0, - kProto_authenticate | cur->type_flag); - /* 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, 0); - return; - } - /* If proxy: Handle client's response to challenge */ - else if (type_flag == proxy_flag) { - pt_log(kLog_debug, "Received remote %s challenge response.\n", - (challenge->digest.hash_type == HT_SHA512 ? - "SHA512" : "MD5")); - if ((!opts.force_sha512 && challenge->digest.hash_type == HT_MD5 && - validate_challenge_md5(cur->challenge, &challenge->digest)) || + memcpy(cur->buf, challenge, sizeof(challenge_t)); + queue_packet( + icmp_sock, cur, cur->buf, sizeof(challenge_t), 0, 0, kProto_authenticate | cur->type_flag); + /* 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, 0); + return; + } + /* If proxy: Handle client's response to challenge */ + else if (type_flag == proxy_flag) { + pt_log(kLog_debug, + "Received remote %s challenge response.\n", + (challenge->digest.hash_type == HT_SHA512 ? "SHA512" : "MD5")); + if ((!opts.force_sha512 && challenge->digest.hash_type == HT_MD5 && + validate_challenge_md5(cur->challenge, &challenge->digest)) || #ifdef ENABLE_SHA512 - (challenge->digest.hash_type == HT_SHA512 && - validate_challenge_sha512(cur->challenge, &challenge->digest)) || + (challenge->digest.hash_type == HT_SHA512 && + validate_challenge_sha512(cur->challenge, &challenge->digest)) || #endif - cur->authenticated) - { - pt_log(kLog_verbose, "Remote end authenticated successfully.\n"); - handle_extended_options(cur); - /* 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, 0); - } - 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; - } + cur->authenticated) { + pt_log(kLog_verbose, "Remote end authenticated successfully.\n"); + handle_extended_options(cur); + /* 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, 0); + } 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) { - double now = time_as_double(); - if (pt_pkt->state != kProto_ack) { - cur->last_data_activity = now; - } - if (pt_pkt->state == kProto_data || pt_pkt->state == kProxy_start || - pt_pkt->state == kProto_ack) - { - if (pt_pkt->state == kProxy_start) { - pt_pkt->data_len = 0; - } - handle_data(pkt, bytes, cur, 0); - } - handle_ack(pt_pkt->ack, cur); - cur->last_activity = now; - } - } - } - else - pt_log(kLog_verbose, "Ignored incoming packet.\n"); - } + if (cur && cur->sock) { + double now = time_as_double(); + if (pt_pkt->state != kProto_ack) { + cur->last_data_activity = now; + } + if (pt_pkt->state == kProto_data || pt_pkt->state == kProxy_start || pt_pkt->state == kProto_ack) { + if (pt_pkt->state == kProxy_start) { + pt_pkt->data_len = 0; + } + handle_data(pkt, bytes, cur, 0); + } + handle_ack(pt_pkt->ack, cur); + cur->last_activity = now; + } + } + } else + pt_log(kLog_verbose, "Ignored incoming packet.\n"); + } } /* handle_data: * Utility function for handling kProto_data packets, and place the data it contains * onto the passed-in receive ring. */ -void handle_data(icmp_echo_packet_t *pkt, int total_len, proxy_desc_t *cur, int handle_extended_options) +void handle_data(icmp_echo_packet_t * pkt, int total_len, proxy_desc_t * cur, int handle_extended_options) { - ping_tunnel_pkt_t *pt_pkt = (ping_tunnel_pkt_t*)pkt->data; - int expected_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) + - sizeof(ping_tunnel_pkt_t); /* 20+8+28 */ - /* Place packet in the receive ring, in its proper place. - * This works as follows: - * -1. Packet == ack packet? Perform ack, and continue. - * 0. seq_no < next_remote_seq, and absolute difference is bigger than w size => discard - * 1. If seq_no == next_remote_seq, we have no problems; just put it in the ring. - * 2. If seq_no > next_remote_seq + remaining window size, discard packet. - * Send resend request for missing packets. - * 3. Else, put packet in the proper place in the ring - * (don't overwrite if one is already there), but don't increment next_remote_seq_no - * 4. If packed was not discarded, process ack info in packet. - */ - expected_len += pt_pkt->data_len; - expected_len += expected_len % 2; - if (opts.udp || opts.unprivileged) - expected_len -= sizeof(ip_packet_t); - if (total_len < expected_len) { - pt_log(kLog_error, "Packet not completely received: %d Should be: %d. " - "For some reason, this error is fatal.\n", total_len, expected_len); - pt_log(kLog_debug, "Data length: %d Total length: %d\n", pt_pkt->data_len, total_len); - /* TODO: This error isn't fatal, so it should definitely be handled in some way. - * We could simply discard it. - */ - exit(0); - } + ping_tunnel_pkt_t * pt_pkt = (ping_tunnel_pkt_t *)pkt->data; + int expected_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) + sizeof(ping_tunnel_pkt_t); /* 20+8+28 */ + /* Place packet in the receive ring, in its proper place. + * This works as follows: + * -1. Packet == ack packet? Perform ack, and continue. + * 0. seq_no < next_remote_seq, and absolute difference is bigger than w size => discard + * 1. If seq_no == next_remote_seq, we have no problems; just put it in the ring. + * 2. If seq_no > next_remote_seq + remaining window size, discard packet. + * Send resend request for missing packets. + * 3. Else, put packet in the proper place in the ring + * (don't overwrite if one is already there), but don't increment next_remote_seq_no + * 4. If packed was not discarded, process ack info in packet. + */ + expected_len += pt_pkt->data_len; + expected_len += expected_len % 2; + if (opts.udp || opts.unprivileged) + expected_len -= sizeof(ip_packet_t); + if (total_len < expected_len) { + pt_log(kLog_error, + "Packet not completely received: %d Should be: %d. " + "For some reason, this error is fatal.\n", + total_len, + expected_len); + pt_log(kLog_debug, "Data length: %d Total length: %d\n", pt_pkt->data_len, total_len); + /* TODO: This error isn't fatal, so it should definitely be handled in some way. + * We could simply discard it. + */ + exit(0); + } - if (handle_extended_options) { - uint16_t *extended_options = (uint16_t *)pt_pkt->data; - if (pt_pkt->data_len >= 2) { - cur->extended_options[0] = ntohs(extended_options[0]); - } - if (pt_pkt->data_len >= 4) { - cur->extended_options[1] = ntohs(extended_options[1]); - } - if (pt_pkt->data_len >= 6) { - cur->extended_options[2] = ntohs(extended_options[2]); - } - if (pt_pkt->data_len >= 8) { - cur->extended_options[3] = ntohs(extended_options[3]); - } - return; - } + if (handle_extended_options) { + uint16_t * extended_options = (uint16_t *)pt_pkt->data; + if (pt_pkt->data_len >= 2) { + cur->extended_options[0] = ntohs(extended_options[0]); + } + if (pt_pkt->data_len >= 4) { + cur->extended_options[1] = ntohs(extended_options[1]); + } + if (pt_pkt->data_len >= 6) { + cur->extended_options[2] = ntohs(extended_options[2]); + } + if (pt_pkt->data_len >= 8) { + cur->extended_options[3] = ntohs(extended_options[3]); + } + return; + } - if (pt_pkt->seq_no == cur->next_remote_seq) { - /* hmm, what happens if this test is true? */ - if (!cur->recv_ring[cur->recv_idx]) { /* && pt_pkt->state == kProto_data */ - /* pt_log(kLog_debug, "Queing data packet: %d\n", pt_pkt->seq_no); */ - cur->recv_ring[cur->recv_idx] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); - cur->recv_wait_send++; - cur->recv_idx++; - } - else { - pt_log(kLog_debug, "Dup packet?\n"); - } + if (pt_pkt->seq_no == cur->next_remote_seq) { + /* hmm, what happens if this test is true? */ + if (!cur->recv_ring[cur->recv_idx]) { /* && pt_pkt->state == kProto_data */ + /* pt_log(kLog_debug, "Queing data packet: %d\n", pt_pkt->seq_no); */ + cur->recv_ring[cur->recv_idx] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); + cur->recv_wait_send++; + cur->recv_idx++; + } else { + pt_log(kLog_debug, "Dup packet?\n"); + } - cur->next_remote_seq++; - if (cur->recv_idx >= cur->window_size) - cur->recv_idx = 0; - /* Check if we have already received some of the next packets */ - while (cur->recv_ring[cur->recv_idx]) { - if (cur->recv_ring[cur->recv_idx]->seq_no == cur->next_remote_seq) { - cur->next_remote_seq++; - cur->recv_idx++; - if (cur->recv_idx >= cur->window_size) - cur->recv_idx = 0; - } - else - break; - } - } - else { - int r, s, d, pos; - pos = -1; /* If pos ends up staying -1, packet is discarded. */ - r = cur->next_remote_seq; - s = pt_pkt->seq_no; - d = s - r; - if (d < 0) { /* This packet _may_ be old, or seq_no may have wrapped around */ - d = (s+0xFFFF) - r; - if (cur->window_size && d < cur->window_size) { - /* Counter has wrapped, so we should add this packet to the recv ring */ - pos = (cur->recv_idx + d) % cur->window_size; - } - } - else if (cur->window_size && d < cur->window_size) { - pos = (cur->recv_idx + d) % cur->window_size; - } + cur->next_remote_seq++; + if (cur->recv_idx >= cur->window_size) + cur->recv_idx = 0; + /* Check if we have already received some of the next packets */ + while (cur->recv_ring[cur->recv_idx]) { + if (cur->recv_ring[cur->recv_idx]->seq_no == cur->next_remote_seq) { + cur->next_remote_seq++; + cur->recv_idx++; + if (cur->recv_idx >= cur->window_size) + cur->recv_idx = 0; + } else + break; + } + } else { + int r, s, d, pos; + pos = -1; /* If pos ends up staying -1, packet is discarded. */ + r = cur->next_remote_seq; + s = pt_pkt->seq_no; + d = s - r; + if (d < 0) { /* This packet _may_ be old, or seq_no may have wrapped around */ + d = (s + 0xFFFF) - r; + if (cur->window_size && d < cur->window_size) { + /* Counter has wrapped, so we should add this packet to the recv ring */ + pos = (cur->recv_idx + d) % cur->window_size; + } + } else if (cur->window_size && d < cur->window_size) { + pos = (cur->recv_idx + d) % cur->window_size; + } - if (pos != -1) { - if (!cur->recv_ring[pos]) { - pt_log(kLog_verbose, "Out of order. Expected: %d Got: %d Inserted: %d " - "(cur = %d)\n", cur->next_remote_seq, pt_pkt->seq_no, pos, - cur->recv_idx); - cur->recv_ring[pos] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); - cur->recv_wait_send++; - } - } - else { - pt_log(kLog_info, "Packet discarded - outside receive window.\n"); - } - } + if (pos != -1) { + if (!cur->recv_ring[pos]) { + pt_log(kLog_verbose, + "Out of order. Expected: %d Got: %d Inserted: %d " + "(cur = %d)\n", + cur->next_remote_seq, + pt_pkt->seq_no, + pos, + cur->recv_idx); + cur->recv_ring[pos] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); + cur->recv_wait_send++; + } + } else { + pt_log(kLog_info, "Packet discarded - outside receive window.\n"); + } + } } -void handle_extended_options(proxy_desc_t *cur) +void handle_extended_options(proxy_desc_t * cur) { - if (cur->extended_options[0] > 0) { - if (cur->extended_options[0] > cur->window_size) { - size_t extend = cur->extended_options[0] - cur->window_size; - cur->send_ring = (icmp_desc_t *) realloc(cur->send_ring, cur->extended_options[0] * sizeof(icmp_desc_t)); - cur->recv_ring = (forward_desc_t **) realloc(cur->recv_ring, cur->extended_options[0] * sizeof(forward_desc_t *)); - memset(cur->send_ring + cur->window_size, 0, extend * sizeof(icmp_desc_t)); - memset(cur->recv_ring + cur->window_size, 0, extend * sizeof(forward_desc_t *)); - } - cur->window_size = cur->extended_options[0]; - pt_log(kLog_verbose, "Received extended option for window size %d \n", cur->window_size); - } - if (cur->extended_options[1] > 0) { - cur->ack_interval = cur->extended_options[1] / 1000.0; - pt_log(kLog_verbose, "Received extended option for ack interval %f \n", cur->ack_interval); - } - if (cur->extended_options[2] > 0) { - cur->resend_interval = cur->extended_options[2] / 1000.0; - pt_log(kLog_verbose, "Received extended option for resend interval %f \n", cur->resend_interval); - } - if (cur->extended_options[3] > 0) { - cur->payload_size = cur->extended_options[3]; - pt_log(kLog_verbose, "Received extended option for payload size %d \n", cur->payload_size); - } + if (cur->extended_options[0] > 0) { + if (cur->extended_options[0] > cur->window_size) { + size_t extend = cur->extended_options[0] - cur->window_size; + cur->send_ring = (icmp_desc_t *)realloc(cur->send_ring, cur->extended_options[0] * sizeof(icmp_desc_t)); + cur->recv_ring = + (forward_desc_t **)realloc(cur->recv_ring, cur->extended_options[0] * sizeof(forward_desc_t *)); + memset(cur->send_ring + cur->window_size, 0, extend * sizeof(icmp_desc_t)); + memset(cur->recv_ring + cur->window_size, 0, extend * sizeof(forward_desc_t *)); + } + cur->window_size = cur->extended_options[0]; + pt_log(kLog_verbose, "Received extended option for window size %d \n", cur->window_size); + } + if (cur->extended_options[1] > 0) { + cur->ack_interval = cur->extended_options[1] / 1000.0; + pt_log(kLog_verbose, "Received extended option for ack interval %f \n", cur->ack_interval); + } + if (cur->extended_options[2] > 0) { + cur->resend_interval = cur->extended_options[2] / 1000.0; + pt_log(kLog_verbose, "Received extended option for resend interval %f \n", cur->resend_interval); + } + if (cur->extended_options[3] > 0) { + cur->payload_size = cur->extended_options[3]; + pt_log(kLog_verbose, "Received extended option for payload size %d \n", cur->payload_size); + } } -void handle_ack(uint32_t seq_no, proxy_desc_t *cur) +void handle_ack(uint32_t seq_no, proxy_desc_t * cur) { - if (cur->send_wait_ack > 0) { - int i, can_ack = 0, count = 0; - i = cur->send_idx - 1; - if (i < 0) - i = cur->window_size - 1; + if (cur->send_wait_ack > 0) { + int i, can_ack = 0, count = 0; + i = cur->send_idx - 1; + if (i < 0) + i = cur->window_size - 1; - pt_log(kLog_debug, "Received ack-series starting at seq %d\n", seq_no); - while (count < cur->window_size) { - if (!cur->send_ring[i].pkt) - break; - if (cur->send_ring[i].seq_no == seq_no) - can_ack = 1; - else if (!can_ack) - cur->send_first_ack = i; - if (can_ack) { - free(cur->send_ring[i].pkt); - cur->send_ring[i].pkt = 0; - cur->send_ring[i].pkt_len = 0; - cur->send_wait_ack--; - } - i--; - if (i < 0) - i = cur->window_size - 1; - count++; - } - } - else { - pt_log(kLog_verbose, "Dropping superfluous acknowledgement for seq %d " - "(no outstanding packets needing ack.)\n", seq_no); - } + pt_log(kLog_debug, "Received ack-series starting at seq %d\n", seq_no); + while (count < cur->window_size) { + if (!cur->send_ring[i].pkt) + break; + if (cur->send_ring[i].seq_no == seq_no) + can_ack = 1; + else if (!can_ack) + cur->send_first_ack = i; + if (can_ack) { + free(cur->send_ring[i].pkt); + cur->send_ring[i].pkt = 0; + cur->send_ring[i].pkt_len = 0; + cur->send_wait_ack--; + } + i--; + if (i < 0) + i = cur->window_size - 1; + count++; + } + } else { + pt_log(kLog_verbose, + "Dropping superfluous acknowledgement for seq %d " + "(no outstanding packets needing ack.)\n", + seq_no); + } } @@ -49,9 +49,9 @@ #include <stdint.h> #ifndef __MINGW32__ -#define __PTATTR__ __attribute__ ((packed)) +#define __PTATTR__ __attribute__((packed)) #else -#define __PTATTR__ __attribute__ ((packed, gcc_struct)) +#define __PTATTR__ __attribute__((packed, gcc_struct)) #endif #ifdef WIN32 @@ -60,9 +60,9 @@ typedef int socklen_t; typedef uint32_t in_addr_t; #define ETH_ALEN 6 /* Octets in one ethernet addr */ struct ether_header { - uint8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ - uint8_t ether_shost[ETH_ALEN]; /* source ether addr */ - uint16_t ether_type; /* packet type ID field */ + uint8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ + uint8_t ether_shost[ETH_ALEN]; /* source ether addr */ + uint16_t ether_type; /* packet type ID field */ } __PTATTR__; #endif /* WIN32 */ @@ -75,24 +75,24 @@ struct ether_header { * in packets from the client to the proxy. */ typedef struct { - /** magic number, used to identify ptunnel packets. */ - uint32_t magic; - /** destination IP and port (used by proxy to figure */ - uint32_t dst_ip; - /** out where to tunnel to) */ - uint32_t dst_port; - /** current connection state; see constants above. */ - uint32_t state; - /** sequence number of last packet received from other end */ - uint32_t ack; - /** length of data buffer */ - uint32_t data_len; - /** sequence number of this packet */ - uint16_t seq_no; - /** id number, used to separate different tunnels from each other */ - uint16_t id_no; - /** optional data buffer */ - char data[0]; + /** magic number, used to identify ptunnel packets. */ + uint32_t magic; + /** destination IP and port (used by proxy to figure */ + uint32_t dst_ip; + /** out where to tunnel to) */ + uint32_t dst_port; + /** current connection state; see constants above. */ + uint32_t state; + /** sequence number of last packet received from other end */ + uint32_t ack; + /** length of data buffer */ + uint32_t data_len; + /** sequence number of this packet */ + uint16_t seq_no; + /** id number, used to separate different tunnels from each other */ + uint16_t id_no; + /** optional data buffer */ + char data[0]; } __PTATTR__ ping_tunnel_pkt_t; /** ip_packet_t: This is basically my own definition of the IP packet, which @@ -100,17 +100,17 @@ typedef struct { * (or even the RFC) for info on the contents of this packet. */ typedef struct { - uint8_t vers_ihl; - uint8_t tos; - uint16_t pkt_len; - uint16_t id; - uint16_t flags_frag_offset; - uint8_t ttl; - uint8_t proto; // 1 for ICMP - uint16_t checksum; - uint32_t src_ip; - uint32_t dst_ip; - char data[0]; + uint8_t vers_ihl; + uint8_t tos; + uint16_t pkt_len; + uint16_t id; + uint16_t flags_frag_offset; + uint8_t ttl; + uint8_t proto; // 1 for ICMP + uint16_t checksum; + uint32_t src_ip; + uint32_t dst_ip; + char data[0]; } __PTATTR__ ip_packet_t; /** icmp_echo_packet_t: This is the definition of a standard ICMP header. The @@ -123,25 +123,24 @@ typedef struct { * taken care of by the OS. */ typedef struct { - uint8_t type; - uint8_t code; - uint16_t checksum; - uint16_t identifier; - uint16_t seq; - char data[0]; + uint8_t type; + uint8_t code; + uint16_t checksum; + uint16_t identifier; + uint16_t seq; + char data[0]; } __PTATTR__ icmp_echo_packet_t; typedef struct forward_desc_t forward_desc_t; typedef struct icmp_desc_t icmp_desc_t; typedef struct proxy_desc_t proxy_desc_t; +void handle_packet(char * buf, unsigned bytes, int is_pcap, struct sockaddr_in * addr, int icmp_sock); -void handle_packet(char *buf, unsigned bytes, int is_pcap, struct sockaddr_in *addr, int icmp_sock); +void handle_data(icmp_echo_packet_t * pkt, int total_len, proxy_desc_t * cur, int handle_extended_options); -void handle_data(icmp_echo_packet_t *pkt, int total_len, proxy_desc_t *cur, int handle_extended_options); +void handle_extended_options(proxy_desc_t * cur); -void handle_extended_options(proxy_desc_t *cur); - -void handle_ack(uint32_t seq_no, proxy_desc_t *cur); +void handle_ack(uint32_t seq_no, proxy_desc_t * cur); #endif |