使用 C 语言中的套接字编程进行代理服务器数据包嗅探和请求转发

Proxy server packet sniffing and request forwarding using Socket Programming in C

提问人:MT 16 提问时间:11/12/2023 更新时间:11/12/2023 访问量:25

问:

我是网络初学者。我正在寻找为在代理服务器上运行的数据包嗅探器编写代码。我的目标是获取 IP 地址并过滤掉任何列入黑名单的 IP 地址。现在,我不知道为什么在打印存储请求数据包的变量时没有打印出来。我需要如何打字才能打印它,或者我做错了什么?buffer

此外,我还面临着与主机服务器建立连接和接收响应的问题。如何解决问题?另外,这是正确的做事方式,还是我错过了任何标准做法?谢谢。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#define BUFFER_SIZE 65536
#define BLACKLISTED_IP "142.251.42.36"

int main() {
    int raw_socket;
    struct sockaddr saddr;
    int saddr_len;

    unsigned char *buffer = (unsigned char *)malloc(BUFFER_SIZE);

    // Create a raw socket to read IP packets
    raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
    if (raw_socket < 0) {
        perror("Socket creation error");
        return 1;
    }

    while (1) {
        saddr_len = sizeof(saddr);
        // Receive packets
        int data_size = recvfrom(raw_socket, buffer, BUFFER_SIZE, 0, &saddr, (socklen_t*)&saddr_len);
        if (data_size < 0) {
            perror("Packet receive error");
            return 1;
        }


        // Extracting IP header information
        struct iphdr *ip_header = (struct iphdr*)(buffer);
        printf("Destination IP: %d.%d.%d.%d\n",
               (unsigned int)(ip_header->saddr & 0xFF),
               (unsigned int)((ip_header->saddr >> 8) & 0xFF),
               (unsigned int)((ip_header->saddr >> 16) & 0xFF),
               (unsigned int)((ip_header->saddr >> 24) & 0xFF));

        printf("Source IP: %d.%d.%d.%d\n",
               (unsigned int)(ip_header->daddr & 0xFF),
               (unsigned int)((ip_header->daddr >> 8) & 0xFF),
               (unsigned int)((ip_header->daddr >> 16) & 0xFF),
               (unsigned int)((ip_header->daddr >> 24) & 0xFF));

        // Construct destination IP address and store in dest_ip as character array
        char src_ip[16];
        sprintf(src_ip, "%d.%d.%d.%d",
                (unsigned int)(ip_header->daddr & 0xFF),
                (unsigned int)((ip_header->daddr >> 8) & 0xFF),
                (unsigned int)((ip_header->daddr >> 16) & 0xFF),
                (unsigned int)((ip_header->daddr >> 24) & 0xFF));

        // Construct sender IP address and store in src_ip as character array
        char dest_ip[16];
        sprintf(dest_ip, "%d.%d.%d.%d",
                (unsigned int)(ip_header->saddr & 0xFF),
                (unsigned int)((ip_header->saddr >> 8) & 0xFF),
                (unsigned int)((ip_header->saddr >> 16) & 0xFF),
                (unsigned int)((ip_header->saddr >> 24) & 0xFF));
        
        unsigned short dest_port = 0;
        memcpy(&dest_port, buffer + sizeof(struct iphdr) + sizeof(struct tcphdr) + 2, sizeof(dest_port));

        // Check if the destination IP is in the blacklist and if in blacklist then respond the client with 403 forbidden
        if (strstr(dest_ip, BLACKLISTED_IP) != NULL) {
            printf("URL blocked: %s\n", BLACKLISTED_IP);
            const char* response = "HTTP/1.1 403 Forbidden\r\nContent-Length: 19\r\n\r\nAccess Denied: URL blocked\r\n";
            sendto(raw_socket, response, strlen(response), 0, &saddr, saddr_len);
            close(raw_socket);
            return 1;
        }
    
        // The following code is to forward the packet to the destination IP and port
        int hostSocket;
        if ((hostSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            perror("Error opening host socket");
            return 1;
        }

        struct sockaddr_in hostAddr;
        hostAddr.sin_family = AF_INET;
        hostAddr.sin_addr.s_addr = inet_addr(dest_ip);
        hostAddr.sin_port = htons(dest_port);

        printf("Forwarding request to the target server: %s \n", buffer);

        // Connect to the host server
        if (connect(hostSocket, (struct sockaddr *)&hostAddr, sizeof(hostAddr)) == -1) {
            perror("Connection to host server failed");
            return 1;
        }        

        // Forward the body of the request to the host server
        if (write(hostSocket, buffer, data_size) == -1) {
            perror("Error writing to host server");
            return 1;
        }

        // Read the host server's response
        if (read(hostSocket, buffer, BUFFER_SIZE) == -1) {
            perror("Error reading from host server");
            return 1;
        }

        printf("Received response from host server: %s\n", buffer);

        // Forward the response to the client
        if (write(raw_socket, buffer, strlen(buffer)) == -1) {
            perror("Error writing to client");
            return 1;
        }
    
    }
    
    // Close the sockets
    close(raw_socket);
    free(buffer);
    return 0;
}
C 套接字接 网络编程 IP

评论


答: 暂无答案