示例#1
0
int handle_response(){
		struct TCP_header* ptcph = (struct TCP_header *)(buf + sizeof(struct iphdr));
		int rcvlen = 0;	
		struct TCP_header * tcph = (struct TCP_header *) (datagram + sizeof(struct ip));
	int expected_ack = (htonl(ntohl(seqNum) + 1));
	// not correct ack number
	if(not_correct_seq(buf,tcph->ack_seq)){
		perror("packet not in order, gonna quit!");
		iph->tot_len = sizeof(struct iphdr) + sizeof(struct TCP_header) ;
		tcph->seq = ptcph->ack_seq;
		tcph->ack_seq = htonl(ntohl(ptcph->seq) + 1); 
		tcph->psh = 0;
		tcph->doff = 5;
		tcph->ack = 1;
		tcph->fin = 0;
		tcph->rst = 1;
		/* Check sum */
		tcph->check = 0;
		tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
		if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
		{
			perror("sendto failed");
		} 
		exit(0);
	}
	// got fin signal
	else if(recv_flag_contains(FIN,buf)) {
		perror("got fin flag, goes to close\n");
		tcph->seq = htonl(ntohl(ptcph->ack));
		tcph->ack_seq = htonl(ntohl(ptcph->seq) + 1); 
		tcph->rst = 0;
		tcph->syn = 0;
		tcph->fin = 0;
		tcph->ack = 1;
		tcph->psh = 0;
		/* Check sum */
		tcph->check = 0;
		tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
		if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
		{
			perror("sendto failed");
		} 
		if((rcvlen = recv(sock2recv,buf,iph->tot_len,0)) < 0){
			perror("recv failed");
		}
		exit(0);
	
	}
	// got rst signal
	else if(recv_flag_contains(RST,buf)){
		perror("got rst flag, goes to close\n");
		exit(0);
	};
}
示例#2
0
int Close() {
	int rcvlen = 0;	
	struct TCP_header * tcph = (struct TCP_header *) (datagram + sizeof(struct ip));
	iph->tot_len = sizeof(struct iphdr) + sizeof(struct TCP_header) ;
	printf("Goes in Close()\n");
	tcph->seq = seqNum;
	tcph->ack_seq = ackNum; 
	tcph->psh = 0;
	tcph->fin = 1;
	tcph->ack = 1;
	tcph->syn = 0;
	/* Check sum */
	tcph->check = 0;
	tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
	if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
	{
		perror("sendto failed");
	} 
	if((rcvlen = recv(sock2recv,buf,iph->tot_len,0)) < 0){
		perror("recv failed");
	}
	if(ptcph->fin){
		tcph->seq = htonl(ntohl(ptcph->ack));
		tcph->ack_seq = htonl(ntohl(ptcph->seq) + 1); 
		tcph->ack = 1;
		tcph->psh = 0;
		tcph->fin = 0;
		tcph->check = 0;		
		tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
		if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
		{
			perror("sendto failed");
		} 
	
	}	 
	printf("Close succeed!");
}
示例#3
0
int Write(char* msg,int size){
//	printf("Goes in write function\n");
	struct TCP_header * tcph = (struct TCP_header *) (datagram + sizeof(struct ip));
	char* data = datagram + sizeof(struct iphdr) + sizeof(struct TCP_header);	
	int sendbytes = 0;
	int rcvlen,count = 0;
	tcph->offset = 0;
	tcph->doff = 5;
	tcph->fin = 0;
	tcph->syn = 0;
	tcph->rst = 0;
	tcph->psh = 1;
	tcph->ack = 1;
	tcph->urg = 0;
	tcph->ece = 0;
	tcph->cwr = 0;
	tcph->urg_ptr = 0;
	memcpy(data,msg,size);
	sendbytes = strlen(data);
//	printf("data is \n%s\n,data size is %d\n",data,sendbytes);
	sendbytes = sizeof(struct TCP_header);
//	strcpy(data,buf);
	iph->tot_len = sizeof(struct iphdr) + sizeof(struct TCP_header)  + size;
	tcph->seq = seqNum;
	tcph->ack_seq = ackNum; 
	tcph->check = 0;
	tcph->check = tcp_csum(send_addr,tcph,size,srcaddr);
	do{
	count++;
	if(count > 5){
		perror("duplicate ACKs, program gonna quit\n");
		exit(0);
	}	
	if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
	{
		perror("sendto failed");
	}
	if((rcvlen = recv(sock2recv,buf,iph->tot_len,0)) < 0){
		perror("recv failed");
	} else 
	{
		handle_response();
//		printf("Write successfully\n"); 
	}
	}while(not_correct_seq(buf,ackNum) || !recv_flag_contains(ACK,buf));
	seqNum = htonl(ntohl(seqNum) + size);

}
示例#4
0
// retransmit a ACK to re psh packet
int retransmit(char* buf)
{
	u_int16_t datasize;
	struct TCP_header* ptcph = (struct TCP_header *)(buf + sizeof(struct iphdr));
	struct iphdr* iph = (struct iphdr*) buf;
	datasize = ntohs(iph->tot_len) - (sizeof(struct iphdr) + 4 * ptcph->doff);
        iph->tot_len = sizeof(struct iphdr) + sizeof(struct TCP_header) ;
	tcph->seq = ptcph->ack_seq;
 	tcph->ack_seq = htonl(ntohl(ptcph->seq) + datasize); 
	tcph->psh = 0;
	tcph->doff = 5;
	tcph->ack = 1;
	tcph->fin = 0;
 	tcph->rst = 0;
	/* Check sum */
	tcph->check = 0;
	tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
	if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
	{
		perror("sendto failed");
	} 
	printf("Send succss\n");
}
示例#5
0
文件: tcp.c 项目: DavidGarriou/RIOT
void tcp_packet_handler(void)
{
    msg_t m_recv_ip, m_send_ip;
    ipv6_hdr_t *ipv6_header;
    tcp_hdr_t *tcp_header;
    uint8_t *payload;
    socket_internal_t *tcp_socket = NULL;
    uint16_t chksum;

    while (1) {
        msg_receive(&m_recv_ip);

        ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr);
        tcp_header = ((tcp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN));
#ifdef TCP_HC
        tcp_socket = decompress_tcp_packet(ipv6_header);
#else
        switch_tcp_packet_byte_order(tcp_header);
        tcp_socket = get_tcp_socket(ipv6_header, tcp_header);
#endif
        chksum = tcp_csum(ipv6_header, tcp_header);

        payload = (uint8_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN + tcp_header->data_offset * 4);

        if ((chksum == 0xffff) && (tcp_socket != NULL)) {
#ifdef TCP_HC
            update_tcp_hc_context(true, tcp_socket, tcp_header);
#endif
            /* Remove reserved bits from tcp flags field */
            uint8_t tcp_flags = tcp_header->reserved_flags;

            switch (tcp_flags) {
                case TCP_ACK: {
                    /* only ACK Bit set */
                    uint8_t tcp_payload_len = NTOHS(ipv6_header->length) - TCP_HDR_LEN;
                    uint8_t state = tcp_socket->socket_values.tcp_control.state;

                    if ((tcp_payload_len > 0) && (state == TCP_ESTABLISHED)) {
                        /* handle data segments only when the connection was established successfully */
                        handle_tcp_no_flags_packet(ipv6_header, tcp_header, tcp_socket, payload, tcp_payload_len);
                    }
                    else if (tcp_payload_len == 0
                            && (state == TCP_ESTABLISHED || state == TCP_SYN_RCVD
                                || state == TCP_CLOSING || state == TCP_LAST_ACK)) {
                        /* no payload, acknowledging data only */
                        handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket);
                    }
                    break;
                }

                case TCP_RST: {
                    printf("RST Bit set!\n");
                    /* only RST Bit set */
                    handle_tcp_rst_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                case TCP_SYN: {
                    /* only SYN Bit set, look for matching, listening socket
                     * and request new queued socket */
                    printf("SYN Bit set!\n");
                    handle_tcp_syn_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                case TCP_SYN_ACK: {
                    /* only SYN and ACK Bit set, complete three way handshake
                     * when socket in state TCP_SYN_SENT */
                    handle_tcp_syn_ack_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                case TCP_FIN_ACK: {
                    if (tcp_socket->socket_values.tcp_control.state == TCP_ESTABLISHED) {
                        /* this is the first FIN */
                        printf("FIN ACK Bit set!\n");
                        handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket);
                    }
                    else {
                        /* this is the response to FIN */
                        handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket);
                    }
                    break;
                }

                default: {
                    printf("Unable to process the incoming segment!\n");
                }
            }
        }
        else {
            printf("Wrong checksum (%x) or no corresponding socket found!\n",
                   chksum);
            printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN +
                            NTOHS(ipv6_header->length), "Incoming");
            print_tcp_status(INC_PACKET, ipv6_header, tcp_header,
                             &tcp_socket->socket_values);
        }

        msg_reply(&m_recv_ip, &m_send_ip);
    }
}
示例#6
0
int three_hand_shake(int sock2send,int sock2recv,char* datagram,struct sockaddr_in send_addr)
{
	int one = 1,i = 0;
	const int *val = &one;
	int rcvlen = 0;
	struct TCP_header * tcph = (struct TCP_header *) (datagram + sizeof(struct ip));
	// tcp head
	tcph->source = htons(srcPort);
	tcph->dest = htons(destPort);
	tcph->seq = random();;
	tcph->ack_seq = 0;
	seqNum = tcph->seq;
	tcph->doff = 5;
	tcph->fin = 0;
	tcph->syn = 1;
	tcph->rst = 0;
	tcph->psh = 0;
	tcph->ack = 0;
	tcph->urg = 0;
	tcph->window = htons(adv_window);
	tcph->urg_ptr = 0;
	tcph->offset = 0;
	tcph->check = 0;
	tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
	if(setsockopt(sock2send, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0){
		perror("Error setting IP_HDRINCL");
		exit(0);
	}
	do{
	static int count = 0;
	count++;
	if(count == 10){
		perror("Can not connect to host\n");
		exit(0);
	}
	// first hand shake	
	if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
	{
		perror("sendto failed");
	}
	printf("first hand shake done\n"); 
	// second hand shake
	if((rcvlen = recv(sock2recv,buf,iph->tot_len,0)) < 0){
		perror("recv failed");
	} else 
	{
		printf("second hand shake done\n"); 
	}
	if(!recv_flag_contains(SYN,buf))
		 handle_response();
	} while(!(recv_flag_contains(SYN,buf) && recv_flag_contains(ACK,buf)));

	// third hand shake

	{
	ptcph = (struct TCP_header *)(buf + sizeof(struct iphdr));

	tcph->source = htons(srcPort);
	tcph->dest = htons(destPort);
	tcph->seq = htonl(ntohl(tcph->seq) + 1);
	tcph->ack_seq = htonl(ntohl(ptcph->seq) + 1); 
	tcph->ack = 1;
	tcph->syn = 0;
	tcph->fin = 0;
	tcph->rst = 0;
	tcph->psh = 0;
	tcph->urg = 0;
	tcph->window = htons(adv_window);
	tcph->urg_ptr = 0;
	tcph->offset = 0;
	/* Check sum */
	tcph->check = 0;
	tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
	if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
	{
		perror("sendto failed");
	} 
	}
	relative_first_seq = ntohl(ptcph->seq); 
	printf("third hand shake done\n"); 
	seqNum = tcph->seq;
	ackNum = tcph->ack_seq;
	return 0;
}
示例#7
0
char* Read(char* filename){
	FILE* fp = fopen(filename,"w");
	printf("goes in read function\n**************************************************************************************\n\n\n");
	int data_len = 0;
	int count = 0;
	u_int32_t previousSeq = 1;
	struct TCP_header * tcph = (struct TCP_header *) (datagram + sizeof(struct ip));
	int rcvlen = 0;	
	char* msg = NULL;
	u_int16_t datasize = 0;
	int contentlength = 50000;
	int first_http_pack = 1;
	char* http_buf = NULL;
	char buf[1024];
	struct TCP_header* ptcph = (struct TCP_header *)(buf + sizeof(struct iphdr));
	struct iphdr* iph = (struct iphdr*) buf;
	do{
	  printf("\n\n");
	  memset(buf,0,1024);
	  // Receive packet
   	  if((rcvlen = recv(sock2recv,buf,1024,0)) < 0){
		perror("recv failed");
		exit(0);
	  } 
          if(recv_flag_contains(FIN,buf))
	   {
	     printf("Packet signal SYN, gonna quit\n");
	     break;
	    }

 	  msg = buf + sizeof(struct iphdr) + 4 * ptcph->doff;
//	  printf("\n****************************************\n********************** msg is\n%s\n**********************************\n***************************************\n",msg);
	  printf("recvlen is %d\tseq num is: %d\n",rcvlen,(ntohl(ptcph->seq) - relative_first_seq));
	  if(rcvlen == 0){
		continue;
	  };
	  datasize = ntohs(iph->tot_len) - (sizeof(struct iphdr) + 4 * ptcph->doff);
 	  // if data size greater than zero
	  if(datasize > 0){
		printf("datasize is %d\n",datasize);
		if(previousSeq >= ntohl(ptcph->seq)|| not_correct_seq(buf,ackNum)){
			printf("Got duplicate packet previousSeq is\t%u now seq is \t%u\tdatasize is\t%d\n",(previousSeq - relative_first_seq),(ntohl(ptcph->seq) - relative_first_seq),datasize);
			retransmit(buf);
			continue;
		}
		msg = buf + sizeof(struct iphdr) + 4 * ptcph->doff;
		count = strlen(msg);
		// handle http header
		if(first_http_pack){
			data_len = datasize;
			char* slen = NULL;
//			printf("\nFirst time\n");
//			printf("msg is :\n%s\n",msg);
			first_http_pack = 0;
			if(!(contain_substr(msg,"HTTP/") && contain_substr(msg, "200") && contain_substr(msg,"OK")) )
			{
				printf("HTTP header code is not \"200 OK\", gonna quit!\n");
//				printf("Msg is\n%s\n",msg);
				exit(0);
			}
			slen = indexOfString(msg,"Content-Length");
			if(slen != NULL){
				slen = strchr(slen,':');
				slen++;
				contentlength = atoi(slen);
				printf("Content-Length is :\t %d\n",contentlength);
			} else {
				printf("\ndid not find Content-Length\n\n");
				exit(0);
			}
			printf("First time\n");
			http_buf = malloc(contentlength + 1000);
			memset(http_buf,0,contentlength + 1000);
		}
		strcat(http_buf,msg);
//		printf("BODY\n%s\n",msg);
		previousSeq = ntohl(ptcph->seq);
		printf("previousSeq is %d\n",(previousSeq - relative_first_seq));
	  } else {
		if(ntohl(ackNum) > contentlength){
			printf("got all data from packets: %u bytes, gonna quit\n",(ntohl(ackNum) - relative_first_seq));
			break;
		}
		printf("Received rubbish, go on\n");
		continue;
	  }
	  // Respond ACK
	  iph->tot_len = sizeof(struct iphdr) + sizeof(struct TCP_header) ;
	  tcph->seq = ptcph->ack_seq;
 	  tcph->ack_seq = htonl(ntohl(ptcph->seq) + datasize); 
	  tcph->psh = 0;
	  tcph->doff = 5;
	  tcph->ack = 1;
	  tcph->fin = 0;
 	  tcph->rst = 0;
	  /* Check sum */
	  tcph->check = 0;
	  tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
	  if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
	  {
		perror("sendto failed");
	 } 
	 printf("Send succss\n");
 	ackNum = htonl((ntohl(ackNum) + datasize));	
      }while((!recv_flag_contains(FIN,buf)));
//	printf("receive size is %d\n",count);
//	printf("%s\n",http_buf);
	printf("Read done!\n");
	fwrite(http_buf,1,(contentlength + 1000),fp);
	return http_buf; 
}
示例#8
0
文件: tcp.c 项目: fjrk/RIOT
void tcp_packet_handler(void)
{
    msg_t m_recv_ip, m_send_ip;
    ipv6_hdr_t *ipv6_header;
    tcp_hdr_t *tcp_header;
    uint8_t *payload;
    socket_internal_t *tcp_socket = NULL;
    uint16_t chksum;

    while (1) {
        msg_receive(&m_recv_ip);

        ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr);
        tcp_header = ((tcp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN));
#ifdef TCP_HC
        tcp_socket = decompress_tcp_packet(ipv6_header);
#else
        switch_tcp_packet_byte_order(tcp_header);
        tcp_socket = get_tcp_socket(ipv6_header, tcp_header);
#endif
        chksum = tcp_csum(ipv6_header, tcp_header);

        payload = (uint8_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN +
                tcp_header->dataOffset_reserved * 4);

        if ((chksum == 0xffff) && (tcp_socket != NULL)) {
#ifdef TCP_HC
            update_tcp_hc_context(true, tcp_socket, tcp_header);
#endif
            /* Remove reserved bits from tcp flags field */
            uint8_t tcp_flags = tcp_header->reserved_flags & REMOVE_RESERVED;

            switch(tcp_flags) {
                case TCP_ACK: {
                    /* only ACK Bit set */
                    handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                case TCP_RST: {
                    printf("RST Bit set!\n");
                    /* only RST Bit set */
                    handle_tcp_rst_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                case TCP_SYN: {
                    /* only SYN Bit set, look for matching, listening socket
                     * and request new queued socket */
                    printf("SYN Bit set!\n");
                    handle_tcp_syn_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                case TCP_SYN_ACK: {
                    /* only SYN and ACK Bit set, complete three way handshake
                     * when socket in state SYN_SENT */
                    handle_tcp_syn_ack_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                case TCP_FIN: {
                    printf("FIN Bit set!\n");
                    /* only FIN Bit set */
                    handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                case TCP_FIN_ACK: {
                    printf("FIN ACK Bit set!\n");
                    /* only FIN and ACK Bit set */
                    handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket);
                    break;
                }

                default: {
                    handle_tcp_no_flags_packet(ipv6_header, tcp_header,
                                               tcp_socket, payload);
                }
            }
        }
        else {
            printf("Wrong checksum (%x) or no corresponding socket found!\n",
                   chksum);
            printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN +
                            ipv6_header->length, "Incoming");
            print_tcp_status(INC_PACKET, ipv6_header, tcp_header,
                             &tcp_socket->socket_values);
        }

        msg_reply(&m_recv_ip, &m_send_ip);
    }
}