Jump to content

Half Life based games - Sever view


Daersun

Recommended Posts

gcc -o rcon rcon.c

 


#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>

#define DEBUG 0

#define SERVERDATA_EXECCOMMAND 2
#define SERVERDATA_AUTH 3
#define SERVERDATA_RESPONSE_VALUE 0
#define SERVERDATA_AUTH_RESPONSE 2

int send_rcon(int sock, int id, int command, char *string1, char *string2) {
 int size, ret;
 size = 10+strlen(string1)+strlen(string2);

 ret = send(sock,&size,sizeof(int),0);
 if(ret == -1) {
   perror("send() failed:");
   return -1;
 }
 ret = send(sock,&id,sizeof(int),0);
 if(ret == -1) {
   perror("send() failed:");
   return -1;
 }
 ret = send(sock,&command,sizeof(int),0);
 if(ret == -1) {
   perror("send() failed:");
   return -1;
 }
 ret = send(sock,string1,strlen(string1)+1,0);
 if(ret == -1) {
   perror("send() failed:");
   return -1;
 }
 ret = send(sock,string2,strlen(string2)+1,0);
 if(ret == -1) {
   perror("send() failed:");
   return -1;
 }
 if(DEBUG) printf("Sent %d bytes\n",size+4);
 return 0;
}

int recv_rcon(int sock, int timeout, int *id, int *command, char *string1,
             char *string2) {
 struct timeval tv;
 fd_set readfds;
 int size;
 char *ptr;
 int ret;
 char buf[8192];

 size=0xDEADBEEF;
 *id=0xDEADBEEF;
 *command=0xDEADBEEF;
 string1[0]=0;
 string2[0]=0;

 tv.tv_sec = timeout;
 tv.tv_usec = 0;

 FD_ZERO(&readfds);
 FD_SET(sock, &readfds);

 /* don't care about writefds and exceptfds: */
 select(sock+1, &readfds, NULL, NULL, &tv);

 if (!FD_ISSET(sock, &readfds)) {
   if(DEBUG) { 
     printf("recv timeout\n");
   }
   return -1; // timeout
 }
 if(DEBUG) printf("Got a response\n");
 ret = recv(sock, &size, sizeof(int), 0);
 if(ret == -1) {
   perror("recv() failed:");
   return -1;
 }
 if((size<10) || (size>8192)) {
   printf("Illegal size %d\n",size);
   exit(-1);
 }
 ret = recv(sock, id, sizeof(int),0);
 if(ret == -1) {
   perror("recv() failed:");
   return -1;
 }
 size-=ret;
 ret = recv(sock, command, sizeof(int),0);
 if(ret == -1) {
   perror("recv() failed:");
   return -1;
 }
 size-=ret;

 ptr = buf;
 while(size) {
   ret = recv(sock, ptr, size, 0);
   if(ret == -1) {
     perror("recv() failed:");
     return -1;
   }
   size -= ret; 
   ptr += ret;
 }
 buf[8190] = 0;
 buf[8191] = 0;

 strncpy(string1, buf, 4095);
 string1[4095] = 0;
 strncpy(string2, buf+strlen(string1)+1, 4095);
 
 return 0;
}

/* This is set to 1 when we've been authorized */
int auth = 0;
char string1[4096];
char string2[4096];

int process_response(int sock) {
 int ret;
 int id;
 int command;

 ret=recv_rcon(sock, 1, &id, &command, string1, string2);
 if(DEBUG) printf("Received = %d : id=%d, command=%d, s1=%s, s2=%s\n",
                  ret, id, command, string1, string2);
 if(ret==-1) {
   return -1;
 }
 
 switch(command) {
 case SERVERDATA_AUTH_RESPONSE:
   switch(id) {
   case 20: 
     auth = 1;
     break;
   case -1:
     printf("Password Refused\n");
     return -1;
   default:
     printf("Bad Auth Response ID = %d\n",id);
     exit(-1);
   };
   break;
 case SERVERDATA_RESPONSE_VALUE:
   printf("%s",string1);
   break;
 default:
   printf("Unexpected command: %d",command);
   break;
 };
return 0;

}

int main(int argc, char **argv)
{
 struct sockaddr_in a;
 int sock;
 int ret;
 char password[512]="YOUR_PASSWORD_HERE";
 short port = 27015;
 char address[512] = "127.0.0.1";

 int arg;

 auth = 0;

 if(argc<2)
   {
     printf("Syntax: rcon [-P\"rcon_password\"] [-a127.0.0.1] [-p27015] command\n");
     return 0;
   }
 
 for(arg = 1;arg<argc;arg++) {
   if(argv[arg][0] != '-')
     break; /* done with args */
   switch(argv[arg][1]) {
   case 'a':
     strncpy(address, argv[arg]+2, 512);
     break;
   case 'p':
     port = atoi(argv[arg]+2);
     break;
   case 'P':
     strncpy(password, argv[arg]+2, 512);
     break;
   default:
     fprintf(stderr, "Unknown option -%c\n",argv[arg][1]);
     return 0;
   }
 }
 
 a.sin_family = AF_INET;
 a.sin_addr.s_addr = inet_addr(address);
 a.sin_port = htons(port);
 
 sock = socket(AF_INET, SOCK_STREAM,0); // TCP socket
 
 ret = 0;
 ret = connect(sock,(struct sockaddr *)&a,sizeof(a));
 
 if(ret == -1) {
   perror("connect() failed.");
   return -1;
 } else {
   if(DEBUG) printf("Connected to Server\n");
 }
 
 if(DEBUG) printf("Sending RCON Password\n");
 ret=send_rcon(sock, 20, SERVERDATA_AUTH, password, "");

 if(ret == -1) {
   perror("Sending password");
   return -1;
 };

 while(auth==0) {
   if(process_response(sock)==-1) {
     printf("Couldn't Authenticate\n");
     exit(-1);
   }
 }

 if(DEBUG) printf("Password Accepted\n");
 /* Now we're authorized, send command */

 /* built command */
 ret = 0;
 while(arg < argc) {
   if(strlen(argv[arg]) + ret < 4096) {
     strcpy(string1+ret, argv[arg]);
     ret += strlen(argv[arg]);
     string1[ret] = ' ';
     ret++;
     arg++;
   } else {
     fprintf(stderr, "cmd too long to send\n");
     return -1;
   }
 }
 //  string1[ret] = '\n';
 //ret++;
 ret--;
 string1[ret]=0;

 if(DEBUG) printf("Sending Command: \"%s\"\n", string1);

 ret=send_rcon(sock, 20, SERVERDATA_EXECCOMMAND, string1, "");

 if(ret == -1) {
   perror("cmd send");
   return -1;
 }

 // process responses until a timeout
 while(process_response(sock) != -1);
 
 return 0;
}

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Terms of Use