Advertisement
Guest User

Untitled

a guest
Oct 1st, 2016
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.62 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/socket.h>
  4. #include <sys/types.h>
  5. #include <netinet/in.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include <unistd.h>
  9. #include <netinet/in.h>
  10. #include <arpa/inet.h>
  11.  
  12. void sendErrorPacket(int errorCode, int sockfd, struct sockaddr_in client){
  13. char error_packet[200];
  14. error_packet[0] = 0;
  15. error_packet[1] = 5;
  16. error_packet[2] = 0;
  17. error_packet[3] = errorCode;
  18. switch(errorCode){
  19. case 0:
  20. strcpy(error_packet+4, "Undefined error");
  21. break;
  22. case 1:
  23. strcpy(error_packet+4, "File or directory not found");
  24. break;
  25. case 2:
  26. strcpy(error_packet+4, "Access violation");
  27. break;
  28. case 3:
  29. strcpy(error_packet+4, "Disk full or allocation exceeded");
  30. break;
  31. case 4:
  32. strcpy(error_packet+4, "Illegal TFTP operation");
  33. break;
  34. case 5:
  35. strcpy(error_packet+4, "Unknown transfer ID");
  36. break;
  37. case 6:
  38. strcpy(error_packet+4, "File already exists");
  39. break;
  40. case 7:
  41. strcpy(error_packet+4, "No such user");
  42. break;
  43. }
  44. sendto(sockfd, error_packet, sizeof(error_packet), 0, (struct sockaddr *) &client, sizeof(client));
  45. }
  46.  
  47. void sendPacket(int opCode, int sockfd, int blockcount, char* file_buffer, int size, struct sockaddr_in client){
  48. char packet_buffer[516];
  49. packet_buffer[0] = 0;
  50. packet_buffer[1] = opCode;
  51. packet_buffer[2] = (blockcount >> 8) & 0xFF;
  52. packet_buffer[3] = (blockcount)&0xFF;
  53. memcpy(packet_buffer+4, file_buffer, size);
  54. sendto(sockfd, packet_buffer, size+4, 0, (struct sockaddr *) &client, sizeof(client));
  55. }
  56.  
  57. void serve_client(int sockfd, char *filename, struct sockaddr_in client)
  58. {
  59. char file_buffer[512];
  60. char reply_buffer[512];
  61. unsigned short blockcount = 0;
  62. FILE *fp;
  63. if((fp = fopen(filename, "r")) == NULL){
  64. sendErrorPacket(1, sockfd, client);
  65. exit(1);
  66. }
  67. socklen_t len = (socklen_t) sizeof(client);
  68. memset(file_buffer, 0, sizeof(file_buffer));
  69. int size;
  70. do{
  71. blockcount++;
  72. size = fread(file_buffer, 1, 512, fp);
  73. //Send data packet
  74. sendPacket(3, sockfd, blockcount, file_buffer, size, client);
  75. memset(reply_buffer, 0, sizeof(reply_buffer));
  76. //Wait for acknowledgement packet
  77. recvfrom(sockfd, reply_buffer, sizeof(reply_buffer)-1, 0, (struct sockaddr *) &client, &len);
  78. if(reply_buffer[1] != 4){
  79. /*send error package if the client doesn't reply with an acknowledgement packet
  80. something has gone wrong*/
  81. sendErrorPacket(4, sockfd, client);
  82. exit(1);
  83. }
  84. }
  85. while(size == 512);
  86. printf("file delivered\n");
  87. fclose(fp);
  88. }
  89.  
  90. int main(int argc, char *argv[])
  91. {
  92. // 2 arguments have to be entered for correct execution
  93. if ( argc != 3 )
  94. {
  95. printf( "Please insert arguments PORT and DATA DIRECTORY to execute %s", argv[0] );
  96. exit(1);
  97. }
  98. if((chdir(argv[2])) == -1){
  99. printf("Directory not found!");
  100. exit(1);
  101. }
  102. unsigned short port = atoi(argv[1]);
  103. int sockfd;
  104. struct sockaddr_in server, client;
  105. char message[512];
  106. char filename[255];
  107. sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  108. memset(&server, 0, sizeof(server));
  109.  
  110. //IPv4 address
  111. server.sin_family = AF_INET;
  112. server.sin_addr.s_addr = htonl(INADDR_ANY);
  113. server.sin_port = htons(port);
  114. bind(sockfd, (struct sockaddr *) &server, (socklen_t) sizeof(server));
  115. while(1){
  116. memset(filename, 0, sizeof(filename));
  117. memset(message, 0, sizeof(message));
  118. socklen_t len = (socklen_t) sizeof(client);
  119. //client address gets filled in by the recvfrom request
  120. recvfrom(sockfd, message, sizeof(message)-1, 0, (struct sockaddr *) &client, &len);
  121. //serve the client if it's a RRQ.
  122. if(message[1] != 1){
  123. sendErrorPacket(4, sockfd, client);
  124. continue;
  125. }
  126. else{
  127. //the amateur way of retrieving the filename from the read request
  128. int index = 2;
  129. while(message[index] != '\0'){
  130. strncat(filename, &message[index], 1);
  131. index++;
  132. }
  133. char *ip = inet_ntoa(client.sin_addr);
  134. printf("file \"%s\" requested from %s:%s\n", filename, ip, argv[1]);
  135. serve_client(sockfd, filename, client);
  136. }
  137. fflush(stdout);
  138. }
  139. return 0;
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement