N0PasteRecent pastes

Description

Linux RCON commandline tool
Syntax:
Created: 17.07.2015 | Expires: Never | Hits: 925
Hide line NumbersSelect allDownload as text fileParsed in 0.036 seconds
  1. /*
  2. # This is a simple linux command line utility to execute rcon commands
  3. # Just change the YOUR_PASSWORD_HERE to your rcon password (unless
  4. # you want to enter it every time) and possibly change the default
  5. # IP address from 127.0.0.1 (localhost)
  6. #
  7. # once downloaded on your linux system, compile it with:
  8. #
  9. #   gcc -o rcon rcon.c
  10. #
  11. # note, it should work on non-linux too, but may require changing the
  12. # socket stuff (i.e. windows will definitely need to add the winsock
  13. # initialization line)
  14. #
  15. # written by [ASY]Zyrain
  16. #
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <sys/socket.h>
  21. #include <sys/types.h>
  22. #include <netinet/in.h>
  23. #include <arpa/inet.h>
  24. #include <errno.h>
  25. #include <string.h>
  26.  
  27. #define DEBUG 0
  28.  
  29. #define SERVERDATA_EXECCOMMAND 2
  30. #define SERVERDATA_AUTH 3
  31. #define SERVERDATA_RESPONSE_VALUE 0
  32. #define SERVERDATA_AUTH_RESPONSE 2
  33.  
  34. int send_rcon(int sock, int id, int command, char *string1, char *string2) {
  35.   int size, ret;
  36.   size = 10+strlen(string1)+strlen(string2);
  37.  
  38.   ret = send(sock,&size,sizeof(int),0);
  39.   if(ret == -1) {
  40.     perror("send() failed:");
  41.     return -1;
  42.   }
  43.   ret = send(sock,&id,sizeof(int),0);
  44.   if(ret == -1) {
  45.     perror("send() failed:");
  46.     return -1;
  47.   }
  48.   ret = send(sock,&command,sizeof(int),0);
  49.   if(ret == -1) {
  50.     perror("send() failed:");
  51.     return -1;
  52.   }
  53.   ret = send(sock,string1,strlen(string1)+1,0);
  54.   if(ret == -1) {
  55.     perror("send() failed:");
  56.     return -1;
  57.   }
  58.   ret = send(sock,string2,strlen(string2)+1,0);
  59.   if(ret == -1) {
  60.     perror("send() failed:");
  61.     return -1;
  62.   }
  63.   if(DEBUG) printf("Sent %d bytes\n",size+4);
  64.   return 0;
  65. }
  66.  
  67. int recv_rcon(int sock, int timeout, int *id, int *command, char *string1,
  68.               char *string2) {
  69.   struct timeval tv;
  70.   fd_set readfds;
  71.   int size;
  72.   char *ptr;
  73.   int ret;
  74.   char buf[8192];
  75.  
  76.   size=0xDEADBEEF;
  77.   *id=0xDEADBEEF;
  78.   *command=0xDEADBEEF;
  79.   string1[0]=0;
  80.   string2[0]=0;
  81.  
  82.   tv.tv_sec = timeout;
  83.   tv.tv_usec = 0;
  84.  
  85.   FD_ZERO(&readfds);
  86.   FD_SET(sock, &readfds);
  87.  
  88.   /* don't care about writefds and exceptfds: */
  89.   select(sock+1, &readfds, NULL, NULL, &tv);
  90.  
  91.   if (!FD_ISSET(sock, &readfds)) {
  92.     if(DEBUG) {
  93.       printf("recv timeout\n");
  94.     }
  95.     return -1; // timeout
  96.   }
  97.   if(DEBUG) printf("Got a response\n");
  98.   ret = recv(sock, &size, sizeof(int), 0);
  99.   if(ret == -1) {
  100.     perror("recv() failed:");
  101.     return -1;
  102.   }
  103.   if((size<10) || (size>8192)) {
  104.     printf("Illegal size %d\n",size);
  105.     exit(-1);
  106.   }
  107.   ret = recv(sock, id, sizeof(int),0);
  108.   if(ret == -1) {
  109.     perror("recv() failed:");
  110.     return -1;
  111.   }
  112.   size-=ret;
  113.   ret = recv(sock, command, sizeof(int),0);
  114.   if(ret == -1) {
  115.     perror("recv() failed:");
  116.     return -1;
  117.   }
  118.   size-=ret;
  119.  
  120.   ptr = buf;
  121.   while(size) {
  122.     ret = recv(sock, ptr, size, 0);
  123.     if(ret == -1) {
  124.       perror("recv() failed:");
  125.       return -1;
  126.     }
  127.     size -= ret;
  128.     ptr += ret;
  129.   }
  130.   buf[8190] = 0;
  131.   buf[8191] = 0;
  132.  
  133.   strncpy(string1, buf, 4095);
  134.   string1[4095] = 0;
  135.   strncpy(string2, buf+strlen(string1)+1, 4095);
  136.  
  137.   return 0;
  138. }
  139.  
  140. /* This is set to 1 when we've been authorized */
  141. int auth = 0;
  142. char string1[4096];
  143. char string2[4096];
  144.  
  145. int process_response(int sock) {
  146.   int ret;
  147.   int id;
  148.   int command;
  149.  
  150.   ret=recv_rcon(sock, 1, &id, &command, string1, string2);
  151.   if(DEBUG) printf("Received = %d : id=%d, command=%d, s1=%s, s2=%s\n",
  152.                    ret, id, command, string1, string2);
  153.   if(ret==-1) {
  154.     return -1;
  155.   }
  156.  
  157.   switch(command) {
  158.   case SERVERDATA_AUTH_RESPONSE:
  159.     switch(id) {
  160.     case 20:
  161.       auth = 1;
  162.       break;
  163.     case -1:
  164.       printf("Password Refused\n");
  165.       return -1;
  166.     default:
  167.       printf("Bad Auth Response ID = %d\n",id);
  168.       exit(-1);
  169.     };
  170.     break;
  171.   case SERVERDATA_RESPONSE_VALUE:
  172.     printf("%s",string1);
  173.     break;
  174.   default:
  175.     printf("Unexpected command: %d",command);
  176.     break;
  177.   };
  178. }
  179.  
  180. int main(int argc, char **argv)
  181. {
  182.   struct sockaddr_in a;
  183.   int sock;
  184.   int ret, i;
  185.   char password[512]="YOUR_PASSWORD_HERE";
  186.   short port = 32330;
  187.   char address[512] = "127.0.0.1";
  188.  
  189.   int arg;
  190.  
  191.   auth = 0;
  192.  
  193.   if(argc<2)
  194.     {
  195.       printf("Syntax: rcon [-P\"rcon_password\"] [-a127.0.0.1] [-p32330] command\n");
  196.       return 0;
  197.     }
  198.  
  199.   for(arg = 1;arg<argc;arg++) {
  200.     if(argv[arg][0] != '-')
  201.       break; /* done with args */
  202.     switch(argv[arg][1]) {
  203.     case 'a':
  204.       strncpy(address, argv[arg]+2, 512);
  205.       break;
  206.     case 'p':
  207.       port = atoi(argv[arg]+2);
  208.       break;
  209.     case 'P':
  210.       strncpy(password, argv[arg]+2, 512);
  211.       break;
  212.     default:
  213.       fprintf(stderr, "Unknown option -%c\n",argv[arg][1]);
  214.       return 0;
  215.     }
  216.   }
  217.  
  218.   a.sin_family = AF_INET;
  219.   a.sin_addr.s_addr = inet_addr(address);
  220.   a.sin_port = htons(port);
  221.  
  222.   sock = socket(AF_INET, SOCK_STREAM,0); // TCP socket
  223.  
  224.   ret = 0;
  225.   ret = connect(sock,(struct sockaddr *)&a,sizeof(a));
  226.  
  227.   if(ret == -1) {
  228.     perror("connect() failed.");
  229.     return -1;
  230.   } else {
  231.     if(DEBUG) printf("Connected to Server\n");
  232.   }
  233.  
  234.   if(DEBUG) printf("Sending RCON Password\n");
  235.   ret=send_rcon(sock, 20, SERVERDATA_AUTH, password, "");
  236.  
  237.   if(ret == -1) {
  238.     perror("Sending password");
  239.     return -1;
  240.   };
  241.  
  242.   while(auth==0) {
  243.     if(process_response(sock)==-1) {
  244.       printf("Couldn't Authenticate\n");
  245.       exit(-1);
  246.     }
  247.   }
  248.  
  249.   if(DEBUG) printf("Password Accepted\n");
  250.   /* Now we're authorized, send command */
  251.  
  252.   /* built command */
  253.   ret = 0;
  254.   while(arg < argc) {
  255.     if(strlen(argv[arg]) + ret < 4096) {
  256.       strcpy(string1+ret, argv[arg]);
  257.       ret += strlen(argv[arg]);
  258.       string1[ret] = ' ';
  259.       ret++;
  260.       arg++;
  261.     } else {
  262.       fprintf(stderr, "cmd too long to send\n");
  263.       return -1;
  264.     }
  265.   }
  266.   //  string1[ret] = '\n';
  267.   //ret++;
  268.   ret--;
  269.   string1[ret]=0;
  270.  
  271.   if(DEBUG) printf("Sending Command: \"%s\"\n", string1);
  272.  
  273.   ret=send_rcon(sock, 20, SERVERDATA_EXECCOMMAND, string1, "");
  274.  
  275.   if(ret == -1) {
  276.     perror("cmd send");
  277.     return -1;
  278.   }
  279.  
  280.   // process responses until a timeout
  281.   while(process_response(sock) != -1);
  282.  
  283.   return 0;
  284. }
  285.