Advertisement
Guest User

rotmg.c

a guest
Apr 26th, 2014
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.15 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 <arpa/inet.h>
  7. #include <unistd.h>
  8. #include <errno.h>
  9. #include <string.h>
  10. #include "rc4.c"
  11.  
  12. typedef struct conn
  13. {
  14.     int client_socket;
  15.     int remote_port;
  16.     char* remote_address;
  17.  
  18.     long rc4_receive_length;
  19.     char* rc4_receive;
  20.     long rc4_send_length;
  21.     char* rc4_send;
  22. } conn;
  23.  
  24. typedef struct message
  25. {
  26.     long length;
  27.     char* payload;
  28. } message;
  29.  
  30. //predeclare functions
  31. //exported
  32. conn*    rotmg_connect        (char* server, int port);
  33. void     rotmg_disconnect     (conn* client);
  34. message* rotmg_receive_message(conn* client);
  35. void     rotmg_send_message   (conn* client, message* msg);
  36. //unexported
  37. char* reverse_endian(char* buffer);
  38. char* ltoc(long num);
  39.  
  40. conn* rotmg_connect(char* server, int port)
  41. {
  42.     conn* cli = malloc(sizeof(conn));
  43.     char* srv = malloc(strlen(server)+1);
  44.     strcpy(srv, server);
  45.     cli->remote_address = srv;
  46.     cli->remote_port = port;
  47.     //open socket
  48.     if ((cli->client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  49.     {
  50.         perror("rotmg_connect: socket error");
  51.         exit(1);
  52.     }
  53.     //prepare socket
  54.     struct sockaddr_in server_addr;
  55.     server_addr.sin_family = AF_INET;
  56.     server_addr.sin_port = htons(port);
  57.     server_addr.sin_addr.s_addr = inet_addr(server);
  58.     //connect socket
  59.     if ((connect(cli->client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))) == -1)
  60.     {
  61.         perror("rotmg_connect: connect error");
  62.         exit(1);
  63.     }
  64.     //now connected
  65.     printf("rotmg_connect: connected to %s\n", server);
  66.     return cli;
  67. }
  68.  
  69. void rotmg_disconnect(conn* client)
  70. {
  71.     //stop both receiving and transmitting
  72.     errno = 0;
  73.     shutdown(client->client_socket, 2);
  74.     switch(errno)
  75.     {
  76.         case EBADF:
  77.             perror("rotmg_disconnect: invalid socket descriptor");
  78.             return;
  79.         case ENOTSOCK:
  80.             perror("rotmg_disconnect: invalid socket");
  81.             return;
  82.         case ENOTCONN:
  83.             perror("rotmg_disconnect: socket not connected");
  84.             return;
  85.     }
  86.     //close the socket
  87.     errno = 0;
  88.     close(client->client_socket);
  89.     switch(errno)
  90.     {
  91.         case EBADF:
  92.             perror("rotmg_disconnect: invalid socket descriptor");
  93.             return;
  94.         case EINTR:
  95.             perror("rotmg_disconnect: interrupted by signal");
  96.             return;
  97.         case EIO:
  98.             perror("rotmg_disconnect: i/o error");
  99.             return;
  100.     }
  101.     //free connection memory
  102.     free(client->remote_address);
  103.     free(client);
  104. }
  105.  
  106. message* rotmg_receive_message(conn* client)
  107. {
  108.     //prepare message struct
  109.     message* msg;
  110.  
  111.     //allocate buffer for server packet length (4 bytes)
  112.     char* buffer_length = malloc(sizeof(char) * 4);
  113.     //read 4 bytes into buffer_length
  114.     int r = 0;
  115.     errno = 0;
  116.     while (r < 4 && errno == 0)
  117.     {
  118.         r += read(client->client_socket, buffer_length, 4 - r);
  119.     }
  120.     switch(errno)
  121.     {
  122.         case EBADF:
  123.             if (write(client->client_socket, buffer_length, 0) == -1)
  124.             {
  125.                 perror("rotmg_receive: invalid socket descriptor");
  126.                 return NULL;
  127.             } break;       
  128.         case ECONNRESET:
  129.             if (write(client->client_socket, buffer_length, 0) == -1)
  130.             {
  131.                 perror("rotmg_receive: connection reset");
  132.                 return NULL;
  133.             } break;
  134.         case ENOTCONN:
  135.             if (write(client->client_socket, buffer_length, 0) == -1)
  136.             {
  137.                 perror("rotmg_receive: socket not connected");
  138.                 return NULL;
  139.             } break;
  140.         case ETIMEDOUT:
  141.             if (write(client->client_socket, buffer_length, 0) == -1)
  142.             {
  143.                 perror("rotmg_receive: timed out");
  144.                 return NULL;
  145.             } break;
  146.     }
  147.     //convert packet length from bytes to long
  148.     //char* reversed_length = reverse_endian(buffer_length);
  149.     long payload_length = (long)buffer_length;
  150.     free(buffer_length);
  151.     //free(reversed_length);
  152.     msg->length = (payload_length);
  153.  
  154.     //allocate buffer for server packet payload
  155.     char* buffer_payload = malloc(sizeof(char) * (payload_length));
  156.     //read payload into buffer_payload
  157.     r = 0;
  158.     errno = 0;
  159.     while(r < (payload_length) && errno == 0)
  160.     {
  161.         int h = read(client->client_socket, buffer_payload, (payload_length) - r);
  162.         if (h == -1) { break; }
  163.         r = r + h;
  164.     }
  165.     switch(errno)
  166.     {
  167.         case EBADF:
  168.             if (write(client->client_socket, buffer_length, 0) == -1)
  169.             {
  170.                 perror("rotmg_receive: invalid socket descriptor");
  171.                 return NULL;
  172.             } break;       
  173.         case ECONNRESET:
  174.             if (write(client->client_socket, buffer_length, 0) == -1)
  175.             {
  176.                 perror("rotmg_receive: connection reset");
  177.                 return NULL;
  178.             } break;
  179.         case ENOTCONN:
  180.             if (write(client->client_socket, buffer_length, 0) == -1)
  181.             {
  182.                 perror("rotmg_receive: socket not connected");
  183.                 return NULL;
  184.             } break;
  185.         case ETIMEDOUT:
  186.             if (write(client->client_socket, buffer_length, 0) == -1)
  187.             {
  188.                 perror("rotmg_receive: timed out");
  189.                 return NULL;
  190.             } break;
  191.     }
  192.     //char* reversed_payload = reverse_endian(buffer_payload);
  193.     msg->payload = malloc(sizeof(buffer_payload));
  194.     strcpy(msg->payload, buffer_payload);
  195.     free(buffer_payload);
  196.     //msg->payload = reversed_payload;
  197.  
  198.     return msg;
  199. }
  200.  
  201. void rotmg_send_message(conn* client, message* msg)
  202. {
  203.     errno = 0;
  204.     //prepare buffer to send
  205.     char* payload = malloc(sizeof(char) * msg->length + 4);
  206.     //convert length to bytes
  207.     long paylen = (long)sizeof(payload);
  208.     char* payload_length = ltoc(paylen);
  209.     memcpy(payload, payload_length, 4);
  210.     //encrypt payload using rc4 key
  211.     char* encrypted = rc4_crypt((long)msg->length, msg->payload, client->rc4_send_length, client->rc4_send);
  212.     //copy payload
  213.     memcpy(&payload[4], encrypted, msg->length);
  214.     //write to socket
  215.     write(client->client_socket, payload, msg->length + 4);
  216.     //free memory
  217.     free(payload);
  218.     free(encrypted);
  219.     switch(errno)
  220.     {
  221.         case EBADF:
  222.             perror("rotmg_receive: invalid socket descriptor");
  223.             return;
  224.         case ECONNRESET:
  225.             perror("rotmg_receive: connection reset");
  226.             return;
  227.         case ENOTCONN:
  228.             perror("rotmg_receive: socket not connected");
  229.             return;
  230.         case ETIMEDOUT:
  231.             perror("rotmg_receive: timed out");
  232.             return;
  233.     }
  234. }
  235.  
  236. char* reverse_endian(char* buffer)
  237. {
  238.     char* temp = malloc(sizeof(buffer));
  239.     int h = 0;
  240.     for (int i = sizeof(buffer); i > 0; i--)
  241.     {
  242.         temp[h] = buffer[i];
  243.         h++;
  244.     }
  245.     return temp;
  246. }
  247.  
  248. char* ltoc(long num)
  249. {
  250.     char* temp = malloc(sizeof(char)*4);
  251.     temp[3] = num;
  252.     temp[2] = num >> 8;
  253.     temp[1] = num >> 16;
  254.     temp[0] = num >> 24;
  255.     return temp;
  256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement