nsa.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <arpa/inet.h>
  5. #include <sys/socket.h>
  6. #include <unistd.h>
  7. #include <sys/stat.h>
  8. /// Prints usage message
  9. void usage(char* filename) {
  10. printf("\tNSA - yet another CIA network installer for FBI 2.0 or"
  11. "greater.\n"
  12. "\tUsage: %s ip-address 1st.cia [2nd.cia 3rd.cia ...]\n", filename);
  13. }
  14. int main(int argc, char* argv[]) {
  15. // Print usage message if too few args are given.
  16. if(argc < 3) {
  17. usage(argv[0]);
  18. return EXIT_FAILURE;
  19. }
  20. // Check the files first.
  21. // Keep each file name with its size, which we'll need when sending the
  22. // file.
  23. struct file_w_size {
  24. char * file;
  25. unsigned long int size;
  26. };
  27. struct file_w_size filelist[argc-2];
  28. for( int i=2; i<argc; i++) {
  29. // Check that the file is readable
  30. if(access(argv[i], R_OK) == -1) {
  31. fprintf(stderr, "Cannot read file %s\n", argv[i]);
  32. return EXIT_FAILURE;
  33. }
  34. // Get the size and store it
  35. struct stat st;
  36. stat(argv[i], &st);
  37. filelist[i-2].size = st.st_size;
  38. filelist[i-2].file = argv[i];
  39. }
  40. // Create a TCP/IP socket
  41. int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  42. if(sock == -1) {
  43. fprintf(stderr, "Failed to create socket\n");
  44. return EXIT_FAILURE;
  45. }
  46. // Parse the 3DS's IP address as an unsigned long
  47. struct sockaddr_in serv_addr;
  48. if( inet_pton(AF_INET, argv[1], &serv_addr.sin_addr.s_addr) != 1) {
  49. fprintf(stderr, "Invalid IP\n");
  50. return EXIT_FAILURE;
  51. }
  52. // Set the rest of sockaddr_in
  53. serv_addr.sin_family = AF_INET;
  54. serv_addr.sin_port = htons(5000); // Port 5000
  55. memset(serv_addr.sin_zero, 0, sizeof(serv_addr.sin_zero));
  56. // Connect to the 3DS
  57. if(connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) {
  58. fprintf(stderr, "Failed to connect to socket\n");
  59. return EXIT_FAILURE;
  60. }
  61. // FBI first accepts the # of files being sent as a big endian uint
  62. unsigned int numfiles = argc-2;
  63. printf("Telling FBI we have %u files to send...\n", numfiles);
  64. // Swap to big endian
  65. numfiles = htonl(numfiles);
  66. send(sock, &numfiles, sizeof(unsigned int), 0);
  67. // Send each file
  68. // Allocate a 16MB buffer to hold what's read of the file
  69. char * buf = malloc(16000000 * sizeof(char));
  70. for(int i=0; i< argc-2; i++) {
  71. // Recieve 1 byte ACK from FBI
  72. recv(sock, NULL, 1, 0);
  73. // Send the file size as a big endian ulong int
  74. filelist[i].size = (filelist[i].size & 0x00000000FFFFFFFF) << 32 |
  75. (filelist[i].size & 0xFFFFFFFF00000000) >> 32;
  76. filelist[i].size = (filelist[i].size & 0x0000FFFF0000FFFF) << 16 |
  77. (filelist[i].size & 0xFFFF0000FFFF0000) >> 16;
  78. filelist[i].size = (filelist[i].size & 0x00FF00FF00FF00FF) << 8 |
  79. (filelist[i].size & 0xFF00FF00FF00FF00) >> 8;
  80. printf("Sending size of %s...\n", filelist[i].file);
  81. send(sock, &filelist[i].size, sizeof(unsigned long int), 0);
  82. // Open and send the file
  83. printf("Sending %s...\n", filelist[i].file);
  84. FILE *fp = fopen(filelist[i].file, "r");
  85. size_t bytes_read;
  86. do {
  87. bytes_read = fread(buf, 1, 16000000, fp);
  88. send(sock, buf, bytes_read, 0);
  89. }while(bytes_read);
  90. printf("Sent %s!\n", filelist[i].file);
  91. fclose(fp);
  92. }
  93. free(buf);
  94. close(sock);
  95. return EXIT_SUCCESS;
  96. }