static void dns_send(void) { struct header *header; int n, name_len; uchar *p, *pkt; const char *s; const char *name; enum dns_query_type qtype = DNS_A_RECORD; name = net_dns_resolve; pkt = (uchar *)(net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE); p = pkt; /* Prepare DNS packet header */ header = (struct header *)pkt; header->tid = 1; header->flags = htons(0x100); /* standard query */ header->nqueries = htons(1); /* Just one query */ header->nanswers = 0; header->nauth = 0; header->nother = 0; /* Encode DNS name */ name_len = strlen(name); p = (uchar *)&header->data; /* For encoding host name into packet */ do { s = strchr(name, '.'); if (!s) s = name + name_len; n = s - name; /* Chunk length */ *p++ = n; /* Copy length */ memcpy(p, name, n); /* Copy chunk */ p += n; if (*s == '.') n++; name += n; name_len -= n; } while (*s != '\0'); *p++ = 0; /* Mark end of host name */ *p++ = 0; /* Some servers require double null */ *p++ = (unsigned char) qtype; /* Query Type */ *p++ = 0; *p++ = 1; /* Class: inet, 0x0001 */ n = p - pkt; /* Total packet length */ debug("Packet size %d\n", n); dns_our_port = random_port(); net_send_udp_packet(net_server_ethaddr, net_dns_server, DNS_SERVICE_PORT, dns_our_port, n); debug("DNS packet sent\n"); }
struct p2p *p2p_init(const char *rpc_srv, const char *stun_srv) { char ip[64]; struct skt_addr tmpaddr; static stun_addr _mapped; struct p2p *p2p = CALLOC(1, struct p2p); if (!p2p) { loge("malloc failed: %d\n", errno); return NULL; } p2p->rpc = rpc_create(rpc_srv, _rpc_port); if (!p2p->rpc) { loge("rpc_create failed\n"); return NULL; } RPC_REGISTER_MSG_MAP(BASIC_RPC_API_RESP); rpc_set_cb(p2p->rpc, on_rpc_read, on_rpc_write, on_rpc_error, p2p); skt_getaddr_by_fd(p2p->rpc->fd, &tmpaddr); skt_addr_ntop(_local_ip, tmpaddr.ip); //_local_port = tmpaddr.port; //logi("_local_port = %d\n", _local_port); stun_init(stun_srv); p2p->nat.type = stun_nat_type(); p2p->nat.uuid = p2p->rpc->send_pkt.header.uuid_src; p2p->nat.local.ip = skt_addr_pton(_local_ip); _local_port = random_port(); p2p->nat.local.port = _local_port; p2p->nat.fd = stun_socket(_local_ip, _local_port, &_mapped); _mapped.addr = ntohl(_mapped.addr); skt_addr_ntop(ip, _mapped.addr); p2p->nat.reflect.ip = _mapped.addr; p2p->nat.reflect.port = _mapped.port; logi("get nat info from local\n"); logi("nat.type = %d\n", p2p->nat.type); logi("nat.local_addr %s:%d\n", _local_ip, p2p->nat.local.port); logi("nat.reflect_addr %s:%d\n", ip, p2p->nat.reflect.port); p2p->rpc_state = P2P_RPC_INIT; _p2p = p2p; return p2p; }
/** * This is the main function of the program that handles calling other * functions to implemented the needed operations of the replay functionaily. */ int main(int argc, char **argv) { unsigned int k; unsigned int num_packets=0; char port_mode[10]; /* does user specify random port generation?*/ char random_strg[7] = "random"; char* iface = argv[1]; char* new_rmac_ptr; char* new_rip_ptr; in_addr new_remoteip; struct mac_addr new_remotemac; in_addr myip; struct mac_addr mymac; /*temporary packet buffers*/ unsigned int new_src_port = 0; unsigned int retransmissions = 0; pcap_t *local_handle; char errbuf[PCAP_ERRBUF_SIZE]; char ebuf[SENDPACKET_ERRBUF_SIZE]; optionProcess(&tcpliveplayOptions, argc, argv); /*Process AutoOpts for manpage options*/ if((argc < 5) || (argv[1]==NULL) || (argv[2]==NULL) || (argv[3]==NULL) || (argv[4]==NULL) || (argv[5]==NULL)) { printf("ERROR: Incorrect Usage!\n"); printf("Usage: tcpliveplay <eth0/eth1> <file.pcap> <Destinatin IP [1.2.3.4]> <Destination mac [0a:1b:2c:3d:4e:5f]> <specify 'random' or specific port#>\n"); printf("Example:\n yhsiam@yhsiam-VirtualBox:~$ sudo tcpliveplay eth0 test1.pcap 192.168.1.4 52:57:01:11:31:92 random\n\n"); exit(0); } iface_addrs(iface, &myip, &mymac); /* Extract MAC of interface replay is being request on */ /* open send function socket*/ if ((sp = sendpacket_open(iface, ebuf, TCPR_DIR_C2S, SP_TYPE_NONE)) == NULL) errx(-1, "Can't open %s: %s", argv[1], ebuf); /* random dport vs. specified dport operation*/ strcpy(port_mode, argv[5]); /*for(int i = 0; i<10; i++) tolower(port_mode[i]);*/ if(strcmp(port_mode, random_strg)==0) { new_src_port = random_port(); } else new_src_port = atoi(argv[5]); /*else { printf("Port specification error. Please specify 'random' for random source port generation between 49152 and 65535 OR specifiy a specific source port number.\n"); return; }*/ printf("new source port:: %d\n", new_src_port); /* Establish a handler for SIGALRM signals. */ /* This is used as timeout for unresponsive remote hosts */ signal (SIGALRM, catch_alarm); /* Extract new Remote MAC & IP inputted at command line */ new_rmac_ptr= argv[4]; new_rip_ptr = argv[3]; /* These function setup the MAC & IP addresses in the mac_addr & in_addr structs */ extmac(new_rmac_ptr, &new_remotemac); extip(new_rip_ptr, &new_remoteip); /* Rewrites the given "*.pcap" file with all the new parameters and returns the number of packets */ /* that need to be replayed */ num_packets = rewrite(&new_remoteip, &new_remotemac, &myip, &mymac, argv[2], new_src_port); /* create schedule & set it up */ sched = (struct tcp_sched*) malloc(num_packets*sizeof(struct tcp_sched)); pkts_scheduled = setup_sched(sched); /* Returns number of packets in schedule*/ /* Set up the schedule struct to be relative numbers rather than absolute*/ relative_sched(sched, sched[1].exp_rseq, num_packets); printf("Packets Scheduled %d\n", pkts_scheduled); /* Open socket for savedfile traffic to be sent*/ local_handle = pcap_open_offline("newfile.pcap", errbuf); /*call pcap library function*/ if (local_handle == NULL) { fprintf(stderr,"Couldn't open pcap file %s: %s\n", "newfile.pcap", errbuf); return(2); } /* Open socket for live traffic to be listed to*/ live_handle = set_live_filter(iface, &myip, new_src_port); /* returns a pcap_t that filters out traffic other than TCP*/ if (live_handle == NULL) { fprintf(stderr,"Error occured while listing on traffic: %s\n", errbuf); return(2); } /* Printout when no packets are scheduled */ if(pkts_scheduled==0) { printf("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("+ ERROR:: There are no TCP packets to sent +\n"); printf("+ Closing replay... +\n"); printf("+ Thank you for Playing, Play again! +\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); return ERROR; } /* Start replay by sending the first packet, the SYN, from the schedule */ else if(sched[0].local) { /* Send first packet*/ sendpacket(sp, sched[sched_index].packet_ptr, sched[sched_index].pkthdr.len, &sched[sched_index].pkthdr); printf("Sending Local Packet............... [%d]\n",sched_index+1); sched_index++; /* Proceed in the schedule */ } /* Main while loop that handles the decision making and the replay oprations */ while(sched_index<pkts_scheduled) { if(!keep_going) { /*Check the timeout variable */ printf("\n======================================================================\n"); printf("= TIMEOUT:: Remote host is not responding. You may have crashed =\n"); printf("= the host you replayed these packets against OR the packet sequence =\n"); printf("= changed since the capture was taken resulting in differing =\n"); printf("= expectations. Closing replay... =\n"); printf("======================================================================\n\n"); break; } /* tcphdr_rprev carries the last remote tcp header */ if(tcphdr_rprev == NULL) { //printf("FIRST PASS!\n"); } /* Check if received RST or RST-ACK flagged packets*/ else if((tcphdr_rprev->th_flags==TH_RST) || (tcphdr_rprev->th_flags==(TH_RST|TH_ACK))) { printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("+ ERROR:: Remote host has requested to RESET the connection. +\n"); printf("+ Closing replay... +\n"); printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); break; } /*Check if received earlier FIN-ACK than expected else if((sched_index-1 < finack_rindex) && (tcphdr_rprev->th_flags==(TH_FIN|TH_ACK))){ printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("+ ERROR:: Remote host sent an earlier FIN-ACK than expected. +\n"); printf("+ Closing replay... +\n"); printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); return; } */ /* Do the following if we receive a packet that ACKs for the same ACKing of next packet */ else if((tcphdr_rprev->th_seq==htonl(sched[sched_index].exp_rseq)) && (tcphdr_rprev->th_ack==htonl(sched[sched_index].exp_rack)) && (size_payload_prev>0)) { printf("Received Remote Packet............... [%d]\n",sched_index+1); printf("Skipping Packet...................... [%d] to Packet [%d]\n",sched_index+1, sched_index+2); printf("Next Remote Packet Expectation met.\nProceeding in replay...\n"); sched_index++; } /* Do the following if payload does not meet expectation and re-attempt with the remote host for 3 tries*/ else if(different_payload) { printf("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("+ WARNING: Remote host is not meeting packet size expectations. +\n"); printf("+ for packet %-d. Application layer data differs from capture being replayed. +\n", diff_payload_index+1); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); printf("Requesting retransmission.\n Proceeding...\n"); different_payload = false; } /* Local Packets */ if(sched[sched_index].local) { /*Reset alarm timeout*/ alarm (ALARM_TIMEOUT); printf("Sending Local Packet............... [%d]\n",sched_index+1); /* edit each packet tcphdr before sending based on the schedule*/ if(sched_index>0) { sched[sched_index].tcphdr->th_ack = htonl(sched[sched_index].curr_lack); fix_all_checksum_liveplay(sched[sched_index].iphdr); } /* If 3 attempts of resending was made, then error out to the user */ if(sched[sched_index].sent_counter==3) { printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("+ ERROR: Re-sent packet [%-d] 3 times, but remote host is not +\n", sched_index+1); printf("+ responding as expected. 3 resend attempts are a maximum. +\n"); printf("+ Closing replay... +\n"); printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); break; } /* If nothing goes wrong, then send the packet scheduled to be sent, then proceed in the schedule */ sendpacket(sp, sched[sched_index].packet_ptr, sched[sched_index].pkthdr.len, &sched[sched_index].pkthdr); sched[sched_index].sent_counter++; /* Keep track of how many times this specific packet was attempted */ sched_index++; /* proceed */ } /* Remote Packets */ else if(sched[sched_index].remote) { alarm (ALARM_TIMEOUT); printf("Receiving Packets from remote host...\n"); pcap_dispatch(live_handle, 1, got_packet, NULL); /* Listen in on NIC for tcp packets */ //printf("pcap_loop returned\n"); } } /* end of main while loop*/ pcap_breakloop(live_handle); pcap_close(live_handle); sendpacket_close(sp); /* Close Send socket*/ remove("newfile.pcap"); /* Remote the rewritten file that was created*/ for(k=0; k<pkts_scheduled; k++) { retransmissions+=sched[k].sent_counter; } /* User Debug Result Printouts*/ if(sched_index==pkts_scheduled) { printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("~ CONGRATS!!! You have successfully Replayed your pcap file '%s' \n", argv[2]); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"); } else { printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("~ Unfortunately an error has occurred halting the replay of \n"); printf("~ the pcap file '%s'. Please see error above for details... \n", argv[2]); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"); } printf("----------------TCP Live Play Summary----------------\n"); printf("- Packets Scheduled to be Sent & Received: %-d \n", pkts_scheduled); printf("- Actual Packets Sent & Received: %-d \n", sched_index); printf("- Total Local Packet Re-Transmissions due to packet \n"); printf("- loss and/or differing payload size than expected: %-d \n", retransmissions); printf("- Thank you for Playing, Play again! \n"); printf("----------------------------------------------------------\n\n"); return 0; }