Прежде всего, извините, если мой заголовок не очень хороший.Не могу придумать хорошего названия.Итак, я попытался создать приложение, которое прослушивает все пакеты на порту 27080. Затем оно отправляет эти пакеты на другой порт (где есть сервер, который отвечает), а затем отправляет этот ответ пользователю.Теперь с помощью iptables я перенаправил определенный тип пакетов (пакетов запросов) с основного порта в это приложение.Теперь, так как ответ получает пользователь, главный сервер должен быть в моем списке онлайн.Однако, как только я начинаю перенаправлять пакеты в это приложение, это не так.
Код:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <string.h> // memset()
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <linux/ip.h> // For ipv4 header.
#include <linux/udp.h> // For udp header.
#define PORT 27080
#define BUFF_LEN 512
void die(char * error);
void QueryServer(char * ServerIP, char * ServerPort, char * Query, int QueryLen, char * Response, int ResponseSize, int *ResponseLen);
int main() {
// Create a UDP socket.
int iSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (iSocket == -1) {
die((char *) "Unable to create socket");
}
struct sockaddr_in sock_structure;
memset((char *) &sock_structure, 0, sizeof(sock_structure)); // Zero out the structure.
sock_structure.sin_family = AF_INET;
sock_structure.sin_port = htons(PORT);
sock_structure.sin_addr.s_addr = INADDR_ANY;
// Bind socket to port.
if (bind(iSocket, (struct sockaddr *) &sock_structure, sizeof(sock_structure)) == -1) {
die((char *) "Error binding to port");
}
// Keep listening for data.
struct sockaddr_in recvsock_structure;
socklen_t recvsock_len = sizeof(recvsock_structure);
// Declare variables for send socket.
int send_socket;
struct sockaddr_in send_socket_structure;
int recv_len = 0;
char recv_data[BUFF_LEN];
while (true) {
recv_len = recvfrom(iSocket, recv_data, BUFF_LEN, 0, (struct sockaddr *) &recvsock_structure, &recvsock_len);
if (recv_len == -1) {
die((char *) "Error recieving data");
}
// Query server.
char send_data[BUFF_LEN];
int send_data_len;
QueryServer((char *) "SERVERIP", (char *) "SERVERPORT", recv_data, recv_len, send_data, BUFF_LEN, &send_data_len);
//printf("Sending response to %s:%d : %s\n", inet_ntoa(recvsock_structure.sin_addr), ntohs(recvsock_structure.sin_port), send_data);
// Send the response.
if (sendto(iSocket, send_data, send_data_len, 0, (struct sockaddr *) &recvsock_structure, recvsock_len) == -1) {
die((char *) "Error sending response");
}
/*
if (recv_len > 4) {
switch(recv_data[4]) {
case 'T' : { // Info query, check cache.
// Query server.
char send_data[BUFF_LEN];
int send_data_len;
QueryServer((char *) "SERVERIP", (char *) "SERVERPORT", recv_data, recv_len, send_data, BUFF_LEN, &send_data_len);
printf("Recieved data : %s\n", send_data);
// Send the response.
if (sendto(iSocket, send_data, send_data_len, 0, (struct sockaddr *) &recvsock_structure, recvsock_len) == -1) {
die((char *)"Error sending response");
}
break;
}
// Further : not an info query.
case 'U' : { // PlayerList.
break;
}
case 'V' : { // Rules
break;
}
case 'W' : { // GetChallenge
break;
}
default : { // Other.
}
}
}*/
//printf("Received packet from %s:%d\n", inet_ntoa(recvsock_structure.sin_addr), ntohs(recvsock_structure.sin_port));
//printf("Data: %s\n" , recv_data);
}
close(iSocket);
}
void QueryServer(char * ServerIP, char * ServerPort, char * Query, int QueryLen, char * Response, int ResponseSize, int *ResponseLen) {
// Create socket.
int iSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (iSocket == -1) {
die((char *) "Unable to create socket");
}
// Bind socket to any port.
struct sockaddr_in sock_structure;
sock_structure.sin_family = AF_INET;
sock_structure.sin_addr.s_addr = htonl(INADDR_ANY);
sock_structure.sin_port = htons(0);
socklen_t sock_structure_len = sizeof(sock_structure);
if (bind(iSocket, (struct sockaddr *) &sock_structure, sock_structure_len) == -1) {
die((char *) "Error binding to port");
}
// Query server.
struct hostent * host;
host = gethostbyname(ServerIP); // Get server ip address.
struct sockaddr_in send_sock_structure;
send_sock_structure.sin_family = host->h_addrtype;
memcpy((char *) &send_sock_structure.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
send_sock_structure.sin_port = htons(atoi(ServerPort));
if (sendto(iSocket, Query, QueryLen, 0, (struct sockaddr *) &send_sock_structure, sizeof(send_sock_structure)) == -1) {
die((char *) "Error sending data to remote server");
}
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
setsockopt(iSocket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *) &timeout, sizeof(timeout));
(*ResponseLen) = recvfrom(iSocket, Response, ResponseSize, 0, (struct sockaddr *) &sock_structure, &sock_structure_len);
if (*ResponseLen == -1) {
die((char *) "Error recieving data");
}
//printf("%s\n", Response);
close(iSocket);
}
void die(char * error) {
perror(error);
exit(1);
}
Может ли кто-нибудь указать мне, что я делаю неправильно?