diff options
-rw-r--r-- | pdesc.c | 120 | ||||
-rw-r--r-- | pdesc.h | 10 | ||||
-rw-r--r-- | pkt.c | 159 | ||||
-rw-r--r-- | pkt.h | 10 | ||||
-rw-r--r-- | ptunnel.c | 279 | ||||
-rw-r--r-- | ptunnel.h | 14 |
6 files changed, 297 insertions, 295 deletions
@@ -115,6 +115,126 @@ forward_desc_t* create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data) return fwd_desc; } +/* queue_packet: + * Creates an ICMP packet descriptor, and sends it. The packet descriptor is added + * to the given send ring, for potential resends later on. + */ +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) +{ +#if kPT_add_iphdr + ip_packet_t *ip_pkt = 0; + int pkt_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) + + sizeof(ping_tunnel_pkt_t) + num_bytes; +#else + int pkt_len = sizeof(icmp_echo_packet_t) + + sizeof(ping_tunnel_pkt_t) + num_bytes; +#endif + int err = 0; + icmp_echo_packet_t *pkt = 0; + ping_tunnel_pkt_t *pt_pkt = 0; + uint16_t ack_val = next_expected_seq - 1; + + if (pkt_len % 2) + pkt_len++; + +#if kPT_add_iphdr + printf("add header\n"); + ip_pkt = (ip_packet_t *) malloc(pkt_len); + pkt = (icmp_echo_packet_t *) ip_pkt->data; + memset(ip_pkt, 0, sizeof(ip_packet_t)); + /* |(pkt_len>>2);//5;//(IPVERSION << 4) | (sizeof(ip_packet_t) >> 2); */ + ip_pkt->vers_ihl = 0x45; + ip_pkt->tos = IPTOS_LOWDELAY; + ip_pkt->pkt_len = pkt_len; + /* kernel sets proper value htons(ip_id_counter); */ + ip_pkt->id = 0; + ip_pkt->flags_frag_offset = 0; + /* default time to live (64) */ + ip_pkt->ttl = IPDEFTTL; + /* ICMP */ + ip_pkt->proto = 1; + /* maybe the kernel helps us out..? */ + ip_pkt->checksum = 0; + /* insert source IP address here */ + ip_pkt->src_ip = htonl(0x0); + /* htonl(0x7f000001); -> localhost.. */ + ip_pkt->dst_ip = dest_addr->sin_addr.s_addr; +#else + pkt = (icmp_echo_packet_t *) calloc(1, pkt_len); +#endif + + /* ICMP Echo request or reply */ + pkt->type = type; + /* Must be zero (non-zero requires root) */ + pkt->code = 0; + pkt->identifier = htons(icmp_id); + pkt->seq = htons(*ping_seq); + pkt->checksum = 0; + (*ping_seq)++; + /* Add our information */ + pt_pkt = (ping_tunnel_pkt_t*)pkt->data; + pt_pkt->magic = htonl(opts.magic); + pt_pkt->dst_ip = ip; + pt_pkt->dst_port = htonl(port); + pt_pkt->ack = htonl(ack_val); + pt_pkt->data_len = htonl(num_bytes); + pt_pkt->state = htonl(state); + pt_pkt->seq_no = htons(*seq); + pt_pkt->id_no = htons(id_no); + /* Copy user data */ + if (buf && num_bytes > 0) + memcpy(pt_pkt->data, buf, num_bytes); +#if kPT_add_iphdr + pkt->checksum = htons(calc_icmp_checksum((uint16_t*)pkt, pkt_len-sizeof(ip_packet_t))); + ip_pkt->checksum = htons(calc_icmp_checksum((uint16_t*)ip_pkt, sizeof(ip_packet_t))); +#else + pkt->checksum = htons(calc_icmp_checksum((uint16_t*)pkt, pkt_len)); +#endif + + /* Send it! */ + pt_log(kLog_sendrecv, "Send: %d [%d] bytes [seq = %d] " + "[type = %s] [ack = %d] [icmp = %d] [user = %s]\n", + pkt_len, num_bytes, *seq, state_name[state & (~kFlag_mask)], + ack_val, type, ((state & kUser_flag) == kUser_flag ? "yes" : "no")); +#if kPT_add_iphdr + err = sendto(icmp_sock, (const void*)ip_pkt, pkt_len, 0, + (struct sockaddr*)dest_addr, sizeof(struct sockaddr)); +#else + err = sendto(icmp_sock, (const void*)pkt, pkt_len, 0, + (struct sockaddr*)dest_addr, sizeof(struct sockaddr)); +#endif + if (err < 0) { + pt_log(kLog_error, "Failed to send ICMP packet: %s\n", strerror(errno)); + return -1; + } + else if (err != pkt_len) + pt_log(kLog_error, "WARNING WARNING, didn't send entire packet\n"); + + /* Update sequence no's and so on */ +#if kPT_add_iphdr + /* NOTE: Retry mechanism needs update for PT_add_ip_hdr */ + ring[*insert_idx].pkt = ip_pkt; +#else + ring[*insert_idx].pkt = pkt; +#endif + ring[*insert_idx].pkt_len = pkt_len; + ring[*insert_idx].last_resend = time_as_double(); + ring[*insert_idx].seq_no = *seq; + ring[*insert_idx].icmp_id = icmp_id; + (*seq)++; + if (!ring[*first_ack].pkt) + *first_ack = *insert_idx; + (*await_send)++; + (*insert_idx)++; + if (*insert_idx >= kPing_window_size) + *insert_idx = 0; + return 0; +} + /* send_packets: * Examines the passed-in ring, and forwards data in it over TCP. */ @@ -24,7 +24,7 @@ * The same procedure is followed in proxy-to-client communication. Just replace * proxy with client and vice versa in the list above. */ -typedef struct { +typedef struct forward_desc_t { /** ping_tunnel_pkt_t seq_no */ int seq_no; /** length of data */ @@ -40,7 +40,7 @@ typedef struct { * it will be removed from the send-ring, freeing up space for more outgoing * ICMP packets. */ -typedef struct { +typedef struct icmp_desc_t { /** total length of ICMP packet, including ICMP header and ptunnel data. */ int pkt_len; double last_resend; @@ -125,6 +125,12 @@ void remove_proxy_desc(proxy_desc_t *cur, proxy_desc_t *prev); forward_desc_t* create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data); +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); #endif @@ -242,3 +242,162 @@ void handle_packet(char *buf, unsigned bytes, int is_pcap, struct sockaddr_in *a 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, forward_desc_t *ring[], + int *await_send, int *insert_idx, uint16_t *next_expected_seq) +{ + 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) + 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 (pt_pkt->seq_no == *next_expected_seq) { + /* hmm, what happens if this test is true? */ + if (!ring[*insert_idx]) { /* && pt_pkt->state == kProto_data */ + /* pt_log(kLog_debug, "Queing data packet: %d\n", pt_pkt->seq_no); */ + ring[*insert_idx] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); + (*await_send)++; + (*insert_idx)++; + } + else if (ring[*insert_idx]) + pt_log(kLog_debug, "Dup packet?\n"); + + (*next_expected_seq)++; + if (*insert_idx >= kPing_window_size) + *insert_idx = 0; + /* Check if we have already received some of the next packets */ + while (ring[*insert_idx]) { + if (ring[*insert_idx]->seq_no == *next_expected_seq) { + (*next_expected_seq)++; + (*insert_idx)++; + if (*insert_idx >= kPing_window_size) + *insert_idx = 0; + } + else + break; + } + } + else { + int r, s, d, pos; + pos = -1; /* If pos ends up staying -1, packet is discarded. */ + r = *next_expected_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 (d < kPing_window_size) { + /* Counter has wrapped, so we should add this packet to the recv ring */ + pos = ((*insert_idx)+d) % kPing_window_size; + } + } + else if (d < kPing_window_size) + pos = ((*insert_idx)+d) % kPing_window_size; + + if (pos != -1) { + if (!ring[pos]) { + pt_log(kLog_verbose, "Out of order. Expected: %d Got: %d Inserted: %d " + "(cur = %d)\n", *next_expected_seq, pt_pkt->seq_no, pos, + (*insert_idx)); + ring[pos] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); + (*await_send)++; + } + } + /* else + * pt_log(kLog_debug, "Packet discarded - outside receive window.\n"); + */ + } +} + +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) +{ + int i, j, k; + ping_tunnel_pkt_t *pt_pkt; + + if (*packets_awaiting_ack > 0) { + if (one_ack_only) { + for (i = 0; i < kPing_window_size; i++) { + if (ring[i].pkt && ring[i].seq_no == seq_no && !is_pcap) { + pt_log(kLog_debug, "Received ack for only seq %d\n", seq_no); + pt_pkt = (ping_tunnel_pkt_t*)ring[i].pkt->data; + /* WARNING: We make the dangerous assumption here that packets arrive in order! */ + *remote_ack = (uint16_t)ntohl(pt_pkt->ack); + free(ring[i].pkt); + ring[i].pkt = 0; + (*packets_awaiting_ack)--; + if (i == *first_ack) { + for (j=1;j<kPing_window_size;j++) { + k = (i+j)%kPing_window_size; + if (ring[k].pkt) { + *first_ack = k; + break; + } + /* we have looped through everything */ + if (k == i) + *first_ack = insert_idx; + j++; + } + } + return; + } + } + } + else { + int i, can_ack = 0, count = 0; + i = insert_idx-1; + if (i < 0) + i = kPing_window_size - 1; + + pt_log(kLog_debug, "Received ack-series starting at seq %d\n", seq_no); + while (count < kPing_window_size) { + if (!ring[i].pkt) + break; + + if (ring[i].seq_no == seq_no) + can_ack = 1; + else if (!can_ack) + *first_ack = i; + + if (can_ack) { + free(ring[i].pkt); + ring[i].pkt = 0; + (*packets_awaiting_ack)--; + } + i--; + if (i < 0) + i = kPing_window_size - 1; + count++; + } + } + } +/* else + * pt_log(kLog_verbose, "Dropping superfluous acknowledgement (no outstanding packets needing ack.)\n"); + */ +} @@ -80,7 +80,17 @@ typedef struct { char data[0]; } __attribute__ ((packed)) icmp_echo_packet_t; +typedef struct forward_desc_t forward_desc_t; +typedef struct icmp_desc_t icmp_desc_t; + 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, forward_desc_t **ring, + int *await_send, int *insert_idx, uint16_t *next_expected_seq); + +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); + #endif @@ -754,285 +754,6 @@ void pcap_packet_handler(u_char *refcon, const struct pcap_pkthdr *hdr, const u_ static int ip_id_counter = 1; #endif -/* queue_packet: - * Creates an ICMP packet descriptor, and sends it. The packet descriptor is added - * to the given send ring, for potential resends later on. - */ -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) -{ -#if kPT_add_iphdr - ip_packet_t *ip_pkt = 0; - int pkt_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) + - sizeof(ping_tunnel_pkt_t) + num_bytes; -#else - int pkt_len = sizeof(icmp_echo_packet_t) + - sizeof(ping_tunnel_pkt_t) + num_bytes; -#endif - int err = 0; - icmp_echo_packet_t *pkt = 0; - ping_tunnel_pkt_t *pt_pkt = 0; - uint16_t ack_val = next_expected_seq - 1; - - if (pkt_len % 2) - pkt_len++; - -#if kPT_add_iphdr - printf("add header\n"); - ip_pkt = (ip_packet_t *) malloc(pkt_len); - pkt = (icmp_echo_packet_t *) ip_pkt->data; - memset(ip_pkt, 0, sizeof(ip_packet_t)); - /* |(pkt_len>>2);//5;//(IPVERSION << 4) | (sizeof(ip_packet_t) >> 2); */ - ip_pkt->vers_ihl = 0x45; - ip_pkt->tos = IPTOS_LOWDELAY; - ip_pkt->pkt_len = pkt_len; - /* kernel sets proper value htons(ip_id_counter); */ - ip_pkt->id = 0; - ip_pkt->flags_frag_offset = 0; - /* default time to live (64) */ - ip_pkt->ttl = IPDEFTTL; - /* ICMP */ - ip_pkt->proto = 1; - /* maybe the kernel helps us out..? */ - ip_pkt->checksum = 0; - /* insert source IP address here */ - ip_pkt->src_ip = htonl(0x0); - /* htonl(0x7f000001); -> localhost.. */ - ip_pkt->dst_ip = dest_addr->sin_addr.s_addr; -#else - pkt = (icmp_echo_packet_t *) calloc(1, pkt_len); -#endif - - /* ICMP Echo request or reply */ - pkt->type = type; - /* Must be zero (non-zero requires root) */ - pkt->code = 0; - pkt->identifier = htons(icmp_id); - pkt->seq = htons(*ping_seq); - pkt->checksum = 0; - (*ping_seq)++; - /* Add our information */ - pt_pkt = (ping_tunnel_pkt_t*)pkt->data; - pt_pkt->magic = htonl(opts.magic); - pt_pkt->dst_ip = ip; - pt_pkt->dst_port = htonl(port); - pt_pkt->ack = htonl(ack_val); - pt_pkt->data_len = htonl(num_bytes); - pt_pkt->state = htonl(state); - pt_pkt->seq_no = htons(*seq); - pt_pkt->id_no = htons(id_no); - /* Copy user data */ - if (buf && num_bytes > 0) - memcpy(pt_pkt->data, buf, num_bytes); -#if kPT_add_iphdr - pkt->checksum = htons(calc_icmp_checksum((uint16_t*)pkt, pkt_len-sizeof(ip_packet_t))); - ip_pkt->checksum = htons(calc_icmp_checksum((uint16_t*)ip_pkt, sizeof(ip_packet_t))); -#else - pkt->checksum = htons(calc_icmp_checksum((uint16_t*)pkt, pkt_len)); -#endif - - /* Send it! */ - pt_log(kLog_sendrecv, "Send: %d [%d] bytes [seq = %d] " - "[type = %s] [ack = %d] [icmp = %d] [user = %s]\n", - pkt_len, num_bytes, *seq, state_name[state & (~kFlag_mask)], - ack_val, type, ((state & kUser_flag) == kUser_flag ? "yes" : "no")); -#if kPT_add_iphdr - err = sendto(icmp_sock, (const void*)ip_pkt, pkt_len, 0, - (struct sockaddr*)dest_addr, sizeof(struct sockaddr)); -#else - err = sendto(icmp_sock, (const void*)pkt, pkt_len, 0, - (struct sockaddr*)dest_addr, sizeof(struct sockaddr)); -#endif - if (err < 0) { - pt_log(kLog_error, "Failed to send ICMP packet: %s\n", strerror(errno)); - return -1; - } - else if (err != pkt_len) - pt_log(kLog_error, "WARNING WARNING, didn't send entire packet\n"); - - /* Update sequence no's and so on */ -#if kPT_add_iphdr - /* NOTE: Retry mechanism needs update for PT_add_ip_hdr */ - ring[*insert_idx].pkt = ip_pkt; -#else - ring[*insert_idx].pkt = pkt; -#endif - ring[*insert_idx].pkt_len = pkt_len; - ring[*insert_idx].last_resend = time_as_double(); - ring[*insert_idx].seq_no = *seq; - ring[*insert_idx].icmp_id = icmp_id; - (*seq)++; - if (!ring[*first_ack].pkt) - *first_ack = *insert_idx; - (*await_send)++; - (*insert_idx)++; - if (*insert_idx >= kPing_window_size) - *insert_idx = 0; - return 0; -} - -/* 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, forward_desc_t *ring[], - int *await_send, int *insert_idx, uint16_t *next_expected_seq) -{ - 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) - 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 (pt_pkt->seq_no == *next_expected_seq) { - /* hmm, what happens if this test is true? */ - if (!ring[*insert_idx]) { /* && pt_pkt->state == kProto_data */ - /* pt_log(kLog_debug, "Queing data packet: %d\n", pt_pkt->seq_no); */ - ring[*insert_idx] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); - (*await_send)++; - (*insert_idx)++; - } - else if (ring[*insert_idx]) - pt_log(kLog_debug, "Dup packet?\n"); - - (*next_expected_seq)++; - if (*insert_idx >= kPing_window_size) - *insert_idx = 0; - /* Check if we have already received some of the next packets */ - while (ring[*insert_idx]) { - if (ring[*insert_idx]->seq_no == *next_expected_seq) { - (*next_expected_seq)++; - (*insert_idx)++; - if (*insert_idx >= kPing_window_size) - *insert_idx = 0; - } - else - break; - } - } - else { - int r, s, d, pos; - pos = -1; /* If pos ends up staying -1, packet is discarded. */ - r = *next_expected_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 (d < kPing_window_size) { - /* Counter has wrapped, so we should add this packet to the recv ring */ - pos = ((*insert_idx)+d) % kPing_window_size; - } - } - else if (d < kPing_window_size) - pos = ((*insert_idx)+d) % kPing_window_size; - - if (pos != -1) { - if (!ring[pos]) { - pt_log(kLog_verbose, "Out of order. Expected: %d Got: %d Inserted: %d " - "(cur = %d)\n", *next_expected_seq, pt_pkt->seq_no, pos, - (*insert_idx)); - ring[pos] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); - (*await_send)++; - } - } - /* else - * pt_log(kLog_debug, "Packet discarded - outside receive window.\n"); - */ - } -} - -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) -{ - int i, j, k; - ping_tunnel_pkt_t *pt_pkt; - - if (*packets_awaiting_ack > 0) { - if (one_ack_only) { - for (i = 0; i < kPing_window_size; i++) { - if (ring[i].pkt && ring[i].seq_no == seq_no && !is_pcap) { - pt_log(kLog_debug, "Received ack for only seq %d\n", seq_no); - pt_pkt = (ping_tunnel_pkt_t*)ring[i].pkt->data; - /* WARNING: We make the dangerous assumption here that packets arrive in order! */ - *remote_ack = (uint16_t)ntohl(pt_pkt->ack); - free(ring[i].pkt); - ring[i].pkt = 0; - (*packets_awaiting_ack)--; - if (i == *first_ack) { - for (j=1;j<kPing_window_size;j++) { - k = (i+j)%kPing_window_size; - if (ring[k].pkt) { - *first_ack = k; - break; - } - /* we have looped through everything */ - if (k == i) - *first_ack = insert_idx; - j++; - } - } - return; - } - } - } - else { - int i, can_ack = 0, count = 0; - i = insert_idx-1; - if (i < 0) - i = kPing_window_size - 1; - - pt_log(kLog_debug, "Received ack-series starting at seq %d\n", seq_no); - while (count < kPing_window_size) { - if (!ring[i].pkt) - break; - - if (ring[i].seq_no == seq_no) - can_ack = 1; - else if (!can_ack) - *first_ack = i; - - if (can_ack) { - free(ring[i].pkt); - ring[i].pkt = 0; - (*packets_awaiting_ack)--; - } - i--; - if (i < 0) - i = kPing_window_size - 1; - count++; - } - } - } -/* else - * pt_log(kLog_verbose, "Dropping superfluous acknowledgement (no outstanding packets needing ack.)\n"); - */ -} - uint16_t calc_icmp_checksum(uint16_t *data, int bytes) { uint32_t sum; int i; @@ -133,24 +133,10 @@ 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); - -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); - -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); - 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); void send_termination_msg(proxy_desc_t *cur, int icmp_sock); |