www.pudn.com > win控制台程序(可以发送,但接受还需要完善)776.zip > RawTcp.h
// rawtcp.h #include#include #include #include #include //#include //#include #include //#include #include //#include #include #include #include //#include //#include //#include #define CMD_FILE_READ 0x01 #define CMD_FILE_WRITE 0x02 //#define TURE 0x01 //#define FALSE 0x02 /* no use temperarily, for tcp :)*/ #define DESTPORT 80 #define LOCALPORT 8888 /* -------my protocol type----- */ #define IPPROTO_LDJ 100 /*100*/ /* ---------------------------- */ #define MAX_FILENAME_SIZE 256 #define MAX_DATASECTION_SIZE 56000 #define MAXHEADSIZE 1000 #define ADDING 20 /* 20 */ #define MAX (MAXHEADSIZE+MAX_DATASECTION_SIZE) #define IP_HDRINCL 2 /* header is included with data */ #define IPVERSION 4 #define bzero ZeroMemory #pragma comment(lib,"ws2_32.lib") #define hstrerror(x) (TransErrorMessage(x)) /* + ADDING */ struct file_info{ char file_name[MAX_FILENAME_SIZE]; int file_bytes; int ip_packet_number; int start_place; int datasection_bytes_length; /* usage: memset(XXXX.file_name, '\0', MAX_FILENAME_SIZE); strcat(char *, char*); front<-behind */ }; struct ip { unsigned int ip_hl:4; // Length of the header unsigned int ip_v:4; // Version of IP unsigned char ip_tos; // Type of service unsigned short ip_len; // Total length of the packet unsigned short ip_id; // Unique identifier unsigned short ip_off;//frag_and_flags; // Flags unsigned char ip_ttl; // Time to live unsigned char ip_p; // Protocol (TCP, UDP etc) unsigned short ip_sum; // IP checksum struct in_addr ip_src; struct in_addr ip_dst; } ; /* TCP header */ struct tcphdr { u_short source; /* source port */ u_short dest; /* destination port */ u_int seq; /* sequence number */ u_int ack_seq; /* acknowledgement number */ #if BYTE_ORDER == LITTLE_ENDIAN u_int th_x2:4; /* (unused) */ u_int doff:4; /* data offset */ #elif BYTE_ORDER == BIG_ENDIAN u_int doff:4; /* data offset */ u_int th_x2:4; /* (unused) */ #endif u_char syn; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) u_short th_win; /* window */ u_short check; /* checksum */ u_short th_urp; /* urgent pointer */ }; int mssleep=10; /* ----------declaration of functions -----------*/ int get_file_size(char *file_name); void send_ip(int sockfd, struct sockaddr_in *addr, CFile& local_fd, struct file_info *local_file_info); void receive_ip(int sockfd, struct sockaddr_in *their_addr, CFile& local_fd); void send_read_command(void); int do_file_write_transfer(char *hostname, char *local_filename); int do_file_read_transfer(char *hostname, char *local_filename); int inet_aton( LPSTR lpszAscii, struct in_addr* paddr ); CString TransErrorMessage( DWORD ErrorCode); CString TransErrorMessage( DWORD ErrorCode) { LPVOID lpMsgBuf; DWORD n; CString szBuf; n = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); if (n) { szBuf.Format("%s",(LPTSTR)lpMsgBuf); LocalFree( lpMsgBuf ); } return szBuf; } int inet_aton( LPSTR lpszAscii, struct in_addr* paddr ) { if (lpszAscii == NULL) (paddr->S_un).S_addr = htonl(INADDR_ANY); else { DWORD lResult = inet_addr(lpszAscii); if (lResult == INADDR_NONE) { WSASetLastError(WSAEINVAL); return 0; } (paddr->S_un).S_addr = lResult; } return 1; } /* -------------------------- 1 -------------------------------- */ int get_file_size(char *file_name) { struct stat statbuf; if(stat(file_name,&statbuf) == -1) { fprintf(stderr,"Could not get stat on file %s: %s\n",\ file_name, strerror(errno)); return -1; } else return (int)statbuf.st_size; } /* -------------------------- 2 -------------------------------- */ void send_ip(int sockfd, struct sockaddr_in *addr, CFile& local_fd, struct file_info *local_file_info) { //int i; extern int mssleep; char buffer[MAX]; /**** used to store ip packet ****/ struct ip *ip; struct tcphdr *tcp; /* for future use */ struct file_info *file_information; void *file_data; int ip_length, ip_packets, file_bytes_to_send, data_startplace, datasection_length ; /* for geting source ip address */ struct hostent *src_host; struct sockaddr_in src_addr; char src_hostname[MAX_FILENAME_SIZE]; /*** begin of geting source ip address from configure file FILE *fp; if((fp=fopen("localhost.conf","r"))==NULL) { printf("can't open src configure file %s\n", "localhost.conf"); exit(-1); } memset(src_hostname, '\0', MAX_FILENAME_SIZE); fscanf(fp,"%s",src_hostname); fclose(fp); ***/ if( gethostname( src_hostname, MAX_FILENAME_SIZE ) != 0 ) { printf("can't to get host name"); exit(-1); } // if(inet_aton(src_hostname, &src_addr.sin_addr)==0) { /* ==0, failed, not ip format, do translation */ if( (src_host=gethostbyname(src_hostname)) == NULL) { fprintf(stderr,"HostName Error:%s\n\a", hstrerror(h_errno)); exit(1); } src_addr.sin_addr = *(struct in_addr *)(src_host->h_addr); } /*** end of geting source ip address ***/ ip_packets = local_file_info->ip_packet_number; file_bytes_to_send = local_file_info->file_bytes; data_startplace = 0; datasection_length = 0; #ifdef DEBUG printf("totally %d ip packets need to be sent\n", ip_packets); printf("totally %d bytes need to send\n", file_bytes_to_send); #endif while( ip_packets > 0) { data_startplace += datasection_length; if(ip_packets > 1) /* not the last packet? */ { /* no, not the last packet */ datasection_length = MAX_DATASECTION_SIZE; file_bytes_to_send -= MAX_DATASECTION_SIZE; } else /* yes, is the last packet */ { datasection_length = file_bytes_to_send; file_bytes_to_send = 0; } bzero(buffer,MAX); /** the byte length of IP packet **/ ip_length = sizeof(struct ip) + sizeof(struct tcphdr) + sizeof(struct file_info) + datasection_length; /******** set IP packet header ******/ ip=(struct ip *)buffer; ip->ip_v=IPVERSION; /** general is 4 **/ ip->ip_hl=sizeof(struct ip)>>2; /** IP header length, unit: 32 bits**/ ip->ip_tos=0; /** service type **/ ip->ip_len=htons(ip_length); /** IP packet length **/ #ifdef DEBUG_SENDIP_2 printf("the ip length is %d\n", ntohs(ip->ip_len)); #endif ip->ip_id=0; /** let kernel to fill it **/ ip->ip_off=0; /** let kernel to fill it **/ ip->ip_ttl=2; /** do not go out of local net, or MAXTTL,the longest =255 **/ ip->ip_p=IPPROTO_LDJ; /** ==0,we need to send raw ip packet; or IPPROTO_TCP**/ ip->ip_sum=0; /** let kernel to calculate the check sum **/ ip->ip_src.s_addr = src_addr.sin_addr.s_addr; /* fill in soure ip addr */ ip->ip_dst=addr->sin_addr; /** the destination to go **/ /******* fill in TCP packet, not reailze yet ****/ tcp=(struct tcphdr *)(buffer +sizeof(struct ip)); tcp->source=htons(LOCALPORT); tcp->dest=addr->sin_port; /** destination port **/ tcp->seq=rand(); tcp->ack_seq=0; tcp->doff=5; tcp->syn=0; /*if =1, means I want to construct link*/ tcp->check=0; /******** set file_information ******/ file_information = (struct file_info *)(buffer + sizeof(struct ip) + sizeof(struct tcphdr)); /* steady part */ memset(file_information->file_name, '\0', MAX_FILENAME_SIZE); strcat(file_information->file_name, local_file_info->file_name); file_information->file_bytes =htonl(local_file_info->file_bytes); file_information->ip_packet_number =htonl(local_file_info->ip_packet_number); /* changing part */ file_information->start_place =htonl(data_startplace); file_information->datasection_bytes_length = htonl(datasection_length); printf(" the start place is %d\n",ntohl(file_information->start_place)); #ifdef DEBUG_SENDIP_1 printf(" the file bytes is %d\n",ntohl(file_information->file_bytes)); printf(" the start placeis %d\n",ntohl(file_information->start_place)); printf(" the datasection length is %d\n",ntohl(file_information->datasection_bytes_length)); #endif /******** set data_section ******/ file_data =(void *)( buffer + sizeof(struct ip) + sizeof(struct tcphdr) + sizeof(struct file_info )); // fread( file_data , datasection_length, datasection_length,local_fd); local_fd.Read( file_data, datasection_length); /***** all ready, send ip packet now ^_^ *****/ sendto(sockfd, buffer, ip_length, 0, (struct sockaddr *)addr, sizeof(struct sockaddr)); ip_packets--; Sleep(mssleep*10); }/* end of while */ } /* -------------------------- 3 -------------------------------- */ void receive_ip(int sockfd, struct sockaddr_in *their_addr, CFile& local_fd) { int i; // struct file_info *local_file_info; char buffer[MAX]; /**** used to store ip packet ****/ struct sockaddr_in inaddr; int inaddrlen; int first_ip, ip_min_length = ADDING + sizeof(struct ip) +sizeof(struct tcphdr) + sizeof(struct file_info); struct ip *ip=(struct ip *)(buffer+ ADDING); struct tcphdr *tcp=(struct tcphdr *)(buffer + ADDING +sizeof(struct ip)); /* for future use */ struct file_info *file_information=(struct file_info *)(void *)( buffer + ADDING + sizeof(struct ip) + sizeof(struct tcphdr) ); void *file_data=(void *)( buffer + ADDING + sizeof(struct ip) + sizeof(struct tcphdr) + sizeof(struct file_info) ); int total_ip_packets, file_bytes_to_receive, data_startplace, datasection_length; /* get first ip packet */ first_ip = 0; i= 0; do{ if(recvfrom(sockfd, buffer, MAX, 0, (struct sockaddr *)&inaddr, &inaddrlen) < ip_min_length) continue; /* the ip packet is not long enough, discard it */ /* is this the 1st packet FROM THE ROUTER ? */ if(ip->ip_src.s_addr == their_addr->sin_addr.s_addr) { first_ip = 1; /* yes, change the flag value */ #ifdef DEBUG_RECEIVEIP_1 /* printf("the min ip length is %20d\n", ip_min_length); printf("the actual ip length is %17d\n", ntohs(((struct ip *)buffer)->ip_len)); printf("after move right,the ip length is %7d\n\n", ntohs(ip->ip_len)); printf(" the file bytes is %22d\n",ntohl(file_information->file_bytes)); printf(" need %33d ip packet \n", ntohl(file_information->ip_packet_number)); */ printf(" the start place is %19d\n",ntohl(file_information->start_place)); printf(" the datasection length is %14d\n",ntohl(file_information->datasection_bytes_length)); #endif /* get file information */ /* steady part */ file_bytes_to_receive = ntohl(file_information->file_bytes); total_ip_packets = ntohl(file_information->ip_packet_number); /* changing part */ data_startplace = ntohl(file_information->start_place); datasection_length = ntohl(file_information->datasection_bytes_length); /* write ip packet data into the right place of file signified by local_fd */ local_fd.Seek( data_startplace , CFile::begin ); #ifdef DEBUG_RECEIVEIP_2 printf("receive %d packets ",++i); printf("data start place is %d bytes ", data_startplace); printf("data length is %d bytes \n", datasection_length); #endif local_fd.Write(file_data ,datasection_length); /* do modification according to ip packet receipt processing*/ file_bytes_to_receive -= datasection_length; total_ip_packets--; } }while(first_ip == 0); /* receive the 2nd, 3rd packets if there are any */ while(total_ip_packets > 0) { /* yes, there are more packets to receive */ if(recvfrom(sockfd, buffer, MAX, 0, (struct sockaddr *)&inaddr, &inaddrlen) < ip_min_length) continue; /* the ip packet is not long enough, discard it */ /* is this the packet FROM THE ROUTER ? */ /* if(inaddr.sin_addr.s_addr == their_addr->sin_addr.s_addr)*/ if(ip->ip_src.s_addr == their_addr->sin_addr.s_addr) { /* yes */ /* get file information */ /* changing part */ data_startplace = ntohl(file_information->start_place); datasection_length = ntohl(file_information->datasection_bytes_length); /* write ip packet data into the right place of file signified by local_fd */ local_fd.Seek( data_startplace , CFile::begin);//SEEK_SET); #ifdef DEBUG_RECEIVEIP_2 printf("receive %d packets ",++i); printf("data start place is %d bytes ", data_startplace); printf("data length is %d bytes\n", datasection_length); #endif local_fd.Write( file_data ,datasection_length); /* do modification according to ip packet receipt processing*/ file_bytes_to_receive -= datasection_length; total_ip_packets--; } }/* while */ if(file_bytes_to_receive != 0) printf("Wrong in receive ip\n"); } /* -------------------------- 4 -------------------------------- */ void send_read_command(void) { /* socket description */ int sockfd, on=1; char buffer[100]; /**** used to store read_command_ip****/ struct ip *ip; int ip_length; /* for geting read command ip address */ struct hostent *command_host; /*attention : struct hostent *src_host; defined in this function */ struct sockaddr_in command_addr; char command_hostname[MAX_FILENAME_SIZE]; /* for geting source ip address */ struct hostent *src_host; struct sockaddr_in src_addr; char src_hostname[MAX_FILENAME_SIZE]; FILE *fp; /*** begin of geting source ip address from configure file if((fp=fopen("localhost.conf","r"))==NULL) { printf("can't open src configure file %s\n", "localhost.conf"); exit(-1); } memset(src_hostname, '\0', MAX_FILENAME_SIZE); fscanf(fp,"%s",src_hostname); fclose(fp); /***********************************************************************/ bzero(&src_addr,sizeof(struct sockaddr_in)); if( gethostname( src_hostname, MAX_FILENAME_SIZE ) != 0 ) { printf("can't to get host name"); exit(-1); } // if(inet_aton(src_hostname, &src_addr.sin_addr)==0) { /* ==0, failed, not ip format, do translation */ if( (src_host=gethostbyname(src_hostname)) == NULL) { fprintf(stderr,"HostName Error:%s\n\a", hstrerror(h_errno)); exit(1); } src_addr.sin_addr = *(struct in_addr *)(src_host->h_addr); } /*** end of geting source ip address ***/ /*** begin of geting command ip address from configure file ***/ if((fp=fopen("readcommand.conf","r"))==NULL) { printf("can't open src configure file %s\n", "readcommand.conf"); exit(-1); } memset(command_hostname, '\0', MAX_FILENAME_SIZE); fscanf(fp,"%s",command_hostname); fclose(fp); /*** end of geting command ip address from configure file ***/ /** begin of initializing command_addr (struct sockaddr_in) **/ bzero(&command_addr,sizeof(struct sockaddr_in)); command_addr.sin_family = AF_INET; command_addr.sin_port = htons(DESTPORT); /* for future use */ if(inet_aton(command_hostname, &command_addr.sin_addr)==0) { /* ==0, failed, not ip format, do translation */ if( (command_host=gethostbyname(command_hostname)) == NULL) { fprintf(stderr,"HostName Error:%s\n\a", hstrerror(h_errno)); exit(1); } command_addr.sin_addr = *(struct in_addr *)(command_host->h_addr); } /** end of initializing command_addr (struct sockaddr_in) **/ /***** use IPPROTO_LDJ to create a raw socket *****/ if((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_LDJ)) < 0) { fprintf(stderr,"Socket Error:%s\n\a",strerror(errno)); exit(1); } /* set IP package format, tell kernel I will fill it myself */ setsockopt(sockfd,IPPROTO_LDJ,IP_HDRINCL ,(char*)&on,sizeof(on)); /* set the right of this program as normal user setuid(getpid()); */ /** the byte length of IP packet, an empty ip packet **/ ip_length = sizeof(struct ip); /******** set IP packet header ******/ ip=(struct ip *)buffer; ip->ip_v=IPVERSION; /** general is 4 **/ ip->ip_hl=sizeof(struct ip)>>2; /** IP header length, unit: 32 bits**/ ip->ip_tos=0; /** service type **/ ip->ip_len=htons((short)ip_length); /** IP packet length **/ ip->ip_id=0; /** let kernel to fill it **/ ip->ip_off=0; /** let kernel to fill it **/ ip->ip_ttl=2; /** do not go out of local net, or MAXTTL,the longest =255 **/ ip->ip_p=IPPROTO_LDJ; /** ==0,we need to send raw ip packet; or IPPROTO_LDJ**/ ip->ip_sum=0; /** let kernel to calculate the check sum **/ ip->ip_src.s_addr = src_addr.sin_addr.s_addr ; /* fill in soure ip addr */ ip->ip_dst=command_addr.sin_addr; /** the destination to go **/ /********* send read command ip****/ sendto(sockfd,buffer,ip_length,0,(struct sockaddr *) &command_addr,sizeof(struct sockaddr)); printf("read command send to %s!!\n\n",command_hostname); closesocket(sockfd); } /* -------------------------- 5 -------------------------------- */ int do_file_write_transfer(char *hostname, char *local_filename) { /* socket description */ int sockfd, on=1; struct hostent *host; struct sockaddr_in their_addr; /* file description */ CFile local_fd; int file_bytes; int IP_packet_number; struct file_info local_file_info; /*** begin of file processing part ***/ /* get file fd */ if(!(local_fd.Open(local_filename, CFile::modeRead))) { perror("opening local file to read from"); goto end_0; } /* get file size */ if((file_bytes = get_file_size(local_filename)) == -1) goto end_1; /* calculate IP package that need to be send */ IP_packet_number = (file_bytes / MAX_DATASECTION_SIZE) + (((file_bytes % MAX_DATASECTION_SIZE)!= 0)?1:0); /* fill in local_file_info (struct file_info) */ memset(local_file_info.file_name, '\0', MAX_FILENAME_SIZE); strcat(local_file_info.file_name, local_filename); local_file_info.file_bytes = file_bytes; local_file_info.ip_packet_number = IP_packet_number; /*** end of file processing part ***/ /*** begin of initializing their_addr (struct sockaddr_in) ***/ bzero(&their_addr,sizeof(struct sockaddr_in)); their_addr.sin_family = AF_INET; their_addr.sin_port = htons(DESTPORT); /* for future use */ if(inet_aton(hostname, &their_addr.sin_addr)==0) { /* ==0, failed, not ip format, do translation */ if( (host=gethostbyname(hostname)) == NULL) { fprintf(stderr,"HostName Error:%s\n\a", hstrerror(h_errno)); exit(1); } their_addr.sin_addr = *(struct in_addr *)(host->h_addr); } /*** end of initializing their_addr (struct sockaddr_in) ***/ /***** use IPPROTO_LDJ to create a raw socket *****/ if((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_LDJ)) < 0) { fprintf(stderr,"Socket Error:%s\n\a",strerror(errno)); exit(1); } /* set IP package format, tell kernel I will fill it myself */ setsockopt(sockfd,IPPROTO_LDJ,IP_HDRINCL,(char*)&on,sizeof(on)); /* set the right of this program as normal user setuid(getpid()); */ /********* send file ****/ send_ip(sockfd,&their_addr,local_fd, &local_file_info); closesocket(sockfd); /* Tidy up open files */ end_1: local_fd.Close(); end_0: return 1; } /* -------------------------- 6 -------------------------------- */ int do_file_read_transfer(char *hostname, char *local_filename) { /* socket description */ int sockfd, on=1; struct hostent *host; struct sockaddr_in their_addr; /* file description */ CFile local_fd; // long file_bytes; // int IP_packet_number; // struct file_info local_file_info; int ip_no=0; if( !local_fd.Open(local_filename,CFile::modeCreate|CFile::modeReadWrite|CFile::typeBinary) )//O_WRONLY|O_CREAT|O_EXCL,\ // S_IRUSR|S_IWUSR))==-1) { perror("opening local file to write to"); goto end_0; } /*** begin of initializing their_addr (struct sockaddr_in) ***/ bzero(&their_addr,sizeof(struct sockaddr_in)); their_addr.sin_family = AF_INET; their_addr.sin_port = htons(DESTPORT); /* for future use */ if(inet_aton(hostname, &their_addr.sin_addr)==0) { /* ==0, failed, not ip format, do translation */ if( (host=gethostbyname(hostname)) == NULL) { fprintf(stderr,"HostName Error:%s\n\a", hstrerror(h_errno)); exit(1); } their_addr.sin_addr = *(struct in_addr *)(host->h_addr); } /*** end of initializing their_addr (struct sockaddr_in) ***/ /***** use IPPROTO_LDJ to create a raw socket *****/ if((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_LDJ)) < 0) { fprintf(stderr,"Socket Error:%s\n\a",strerror(errno)); exit(1); } /* set IP package format, tell kernel I will fill it myself */ setsockopt(sockfd,IPPROTO_LDJ,IP_HDRINCL,(char*)&on,sizeof(on)); /* set the right of this program as normal user setuid(getpid()); */ /* send read command, order router to send back packets */ send_read_command(); /* read first ip packet */ receive_ip(sockfd, &their_addr, local_fd); closesocket(sockfd); /* Tidy up open files */ //end_1: local_fd.Close(); end_0: return 1; }