aboutsummaryrefslogtreecommitdiff
path: root/ptunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'ptunnel.c')
-rw-r--r--ptunnel.c279
1 files changed, 0 insertions, 279 deletions
diff --git a/ptunnel.c b/ptunnel.c
index c672a04..b2ab310 100644
--- a/ptunnel.c
+++ b/ptunnel.c
@@ -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;