Quantcast
Channel: Active questions tagged ubuntu - Stack Overflow
Viewing all articles
Browse latest Browse all 6101

Capture Encrypt Forward Packet on Ubuntu

$
0
0

I am working on C project where I have to capture the packets,encrypt and forward it. Scenario is client A (windows) sends data to client B(windows) and in between there is a server (ubuntu) where my application runs as LAN (encrypt)& WAN(decrypt). For testing purpose (only ecrypt part LAN)I am running it on a single system (unbuntu) sending text from one terminal to another terminal using netcat. Now I able to capture the text and encrypts it as well but it does not forward the encrypted data instead it forwards the actual text to other terminal. When I put debugging points I found out that the moment I send the text from source it instantly receives at the destination while my code which also capture the text is still in processing mode. It seems like that it creates a copy of it, one which forwards it directly to other terminal and other one which my application captures. Can anyone please guide me how I can I stop it sending to the destination and force it to forward the encrypted data. I want the packet to go through my application encrypts it and then forward the encrypted data. I took help from chatgpt and it is telling me that it is related with iptables, now I am not familiar with it so I followed the examples given by chatgpt but that doesnot worked.I have remove few part due the word count.LAN code that capture data encrypts it and forward it.

#define LOG_ERROR(format, ...) fprintf(logFile, (format), ##__VA_ARGS__); fflush(logFile)#define BUFF_SIZE 65536void calculate_transport_checksum(unsigned char* transport_segment, struct iphdr* iph, int segment_len);int total_len = 0, send_len;static const unsigned char aes_key[] = "0123456789abcdef0123456789abcdef"; unsigned char aes_iv[] = "abcdef9876543210";struct pseudo_header {    u_int32_t source_address;    u_int32_t dest_address;    u_int8_t placeholder;    u_int8_t protocol;    u_int16_t tcp_length;};void debug_print_packet_size(unsigned int packet_size, int buffer_size) {    printf("Reported IP packet size: %u bytes, Buffer size: %d bytes\n", packet_size, buffer_size);}int set_promiscuous_mode(char *interface_name, int sock, int enable) {    struct ifreq ifr;    memset(&ifr, 0, sizeof(ifr));    strncpy(ifr.ifr_name, interface_name, IFNAMSIZ - 1);    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {        LOG_ERROR("Error in SIOCGIFFLAGS for %s: %s\n", interface_name, strerror(errno));        return -1;    }    if (enable) {        ifr.ifr_flags |= IFF_PROMISC;    } else {         ifr.ifr_flags &= ~IFF_PROMISC;    }    if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {        LOG_ERROR("Error in SIOCSIFFLAGS for %s: %s\n", interface_name, strerror(errno));        return -1;    }    LOG_ERROR("Promiscuous mode %s on interface %s\n", enable ? "enabled" : "disabled", interface_name);    fflush(logFile);    return 0;}void get_eth_index() {    struct ifreq if_idx;    memset(&if_idx, 0, sizeof(if_idx));     strncpy(if_idx.ifr_name, "enp0s31f6", IFNAMSIZ - 1);      int temp_sock = socket(AF_INET, SOCK_DGRAM, 0);     if(temp_sock < 0) {        perror("Error opening socket for getting interface index");        return;    }    if (ioctl(temp_sock, SIOCGIFINDEX, &if_idx) < 0){        LOG_ERROR("Error in SIOCGIFINDEX: %s\n", strerror(errno));     }else{    printf("Interface index: %d\n", if_idx.ifr_ifindex);    }    close(temp_sock); }void get_mac() {    int fd;    struct ifreq ifr;    memset(&ifr, 0, sizeof(ifr));    strncpy(ifr.ifr_name, "enp0s31f6", IFNAMSIZ-1);    fd = socket(AF_INET, SOCK_DGRAM, 0);    if (fd < 0) {        perror("socket(AF_INET, SOCK_DGRAM, 0) failed");        return;    }    if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {        perror("SIOCGIFHWADDR ioctl error");        close(fd);        return;    }    close(fd);    printf("MAC = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n",           (unsigned char)ifr.ifr_hwaddr.sa_data[0],           (unsigned char)ifr.ifr_hwaddr.sa_data[1],           (unsigned char)ifr.ifr_hwaddr.sa_data[2],           (unsigned char)ifr.ifr_hwaddr.sa_data[3],           (unsigned char)ifr.ifr_hwaddr.sa_data[4],           (unsigned char)ifr.ifr_hwaddr.sa_data[5]);    printf("ethernet packaging start ... \n");    struct ethhdr *eth = (struct ethhdr *)(sendbuff);    eth->h_dest[0] = WAN_MAC0;    eth->h_dest[1] = WAN_MAC1;    eth->h_dest[2] = WAN_MAC2;    eth->h_dest[3] = WAN_MAC3;    eth->h_dest[4] = WAN_MAC4;    eth->h_dest[5] = WAN_MAC5;    eth->h_source[0] = CLIENT_A_MAC0;     eth->h_source[1] = CLIENT_A_MAC1;    eth->h_source[2] = CLIENT_A_MAC2;    eth->h_source[3] = CLIENT_A_MAC3;    eth->h_source[4] = CLIENT_A_MAC4;    eth->h_source[5] = CLIENT_A_MAC5;    eth->h_proto = htons(ETH_P_IP);     printf("ethernet packaging done.\n");    total_len += sizeof(struct ethhdr);}void get_icmp() {    struct icmphdr *icmp = (struct icmphdr *)(sendbuff + sizeof(struct iphdr) + sizeof(struct ethhdr));    icmp->type = ICMP_ECHO;    icmp->code = 0;    icmp->un.echo.id = htons(1234);     icmp->un.echo.sequence = htons(1);    icmp->checksum = 0;    total_len += sizeof(struct icmphdr);}unsigned short calculate_checksum(unsigned short* ptr, int nbytes) {    long sum;    unsigned short oddbyte;    short answer;    sum = 0;    while (nbytes > 1) {        sum += *ptr++;        nbytes -= 2;    }    if (nbytes == 1) {        oddbyte = 0;        *((u_char*)&oddbyte) = *(u_char*)ptr;        sum += oddbyte;    }    sum = (sum >> 16) + (sum & 0xffff);    sum = sum + (sum >> 16);    answer = (short)~sum;    return answer;}void get_ip() {    int temp_sock = socket(AF_INET, SOCK_DGRAM, 0);    if (temp_sock < 0) {        perror("Error opening temp socket for getting IP address");        return;    }    memset(&ifreq_ip, 0, sizeof(ifreq_ip));    strncpy(ifreq_ip.ifr_name, "enp0s31f6", IFNAMSIZ-1);    if (ioctl(temp_sock, SIOCGIFADDR, &ifreq_ip) < 0) {        perror("SIOCGIFADDR ioctl error");    } else {        printf("%s\n", inet_ntoa(((struct sockaddr_in *)&(ifreq_ip.ifr_addr))->sin_addr));    }    close(temp_sock);    struct iphdr *iph = (struct iphdr *)(sendbuff + sizeof(struct ethhdr));    iph->ihl = 5;    iph->version = 4;    iph->tos = 16;    iph->id = htons(10201);    iph->ttl = 64;    iph->protocol = IPPROTO_ICMP;    iph->saddr = inet_addr(inet_ntoa((((struct sockaddr_in *)&(ifreq_ip.ifr_addr))->sin_addr)));    iph->daddr = inet_addr("192.168.10.16");    unsigned short checksum = calculate_checksum((unsigned short *)(sendbuff + sizeof(struct ethhdr)), (sizeof(struct iphdr) / 2));    fprintf(logFile, "Calculated IP checksum: 0x%04x\n", checksum);    fflush(logFile);    total_len += sizeof(struct iphdr);    get_icmp();    iph->tot_len = htons(total_len - sizeof(struct ethhdr));    iph->check = htons(calculate_checksum((unsigned short *)(sendbuff + sizeof(struct ethhdr)), sizeof(struct iphdr) / 2));}void enable_iptables_rules() {    system("sudo iptables -t nat -A POSTROUTING -o enp0s31f6 -j MASQUERADE");    system("sudo iptables -A FORWARD -i enp0s31f6 -o enp0s31f6 -m state --state RELATED,ESTABLISHED -j ACCEPT");    system("sudo iptables -A FORWARD -i enp0s31f6 -o enp0s31f6 -j ACCEPT");  }void enable_ip_forwarding() {    int fd;    char path[] = "/proc/sys/net/ipv4/ip_forward";    fd = open(path, O_WRONLY);    if (fd == -1) {        perror("Error opening /proc/sys/net/ipv4/ip_forward");    }    if (write(fd, "1", 1) == -1) {        perror("Error writing to /proc/sys/net/ipv4/ip_forward");        exit(EXIT_FAILURE);    }    close(fd);    printf("IP forwarding enabled.\n");}void remove_iptables_drop_rule() {    system("sudo iptables -D OUTPUT -p icmp --icmp-type echo-request -d 192.168.10.16 -j DROP");    system("sudo iptables -D OUTPUT -p tcp --dport 1234 -d 192.168.10.16 -j DROP");    system("sudo iptables -D OUTPUT -p udp --dport 1234 -d 192.168.10.16 -j DROP");}void setup_iptables_drop_rule() {    system("sudo iptables -A OUTPUT -p icmp --icmp-type echo-request -d 192.168.10.16 -j DROP");    system("sudo iptables -A OUTPUT -p tcp --dport 1234 -j DROP");    system("sudo iptables -A OUTPUT -p udp --dport 1234 -j DROP");}void handle_signal(int signal) {    printf("Signal received: %d\n", signal);    remove_iptables_drop_rule();    if (set_promiscuous_mode("enp0s31f6", sock_raw, 0) < 0) {        fprintf(stderr, "Failed to disable promiscuous mode for interface %s\n", "enp0s31f6");    } else {        printf("Promiscuous mode disabled on interface %s\n", "enp0s31f6");    }    fclose(logFile);    close(sock_raw);    free(sendbuff);    exit(signal);}void setup_signal_handling() {    struct sigaction sa;    memset(&sa, 0, sizeof(sa));    sa.sa_handler = handle_signal;    sigaction(SIGINT, &sa, NULL);    sigaction(SIGTERM, &sa, NULL);    sigaction(SIGQUIT, &sa, NULL);}int main() {    setup_signal_handling();    enable_iptables_rules();    enable_ip_forwarding();     setup_iptables_drop_rule();     logFile = fopen("logfile.txt", "w");     if (logFile == NULL) {    perror("Failed to open log file");    exit(EXIT_FAILURE);        }    int raw_socket;    ssize_t data_size;    unsigned char *buffer = (unsigned char *)malloc(BUFF_SIZE);    char *interface_name = "enp0s31f6";    if (buffer == NULL) {    perror("Failed to allocate memory for buffer");    exit(EXIT_FAILURE);    }    raw_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));    if(raw_socket < 0) {        printf("Error: %s\n", strerror(errno));        fclose(logFile);        exit(EXIT_FAILURE);    }    if (set_promiscuous_mode(interface_name, raw_socket, 1) < 0) {        close(raw_socket);        fclose(logFile);        exit(EXIT_FAILURE);    }    printf("Promiscuous mode enabled on interface %s\n", interface_name);    if (!buffer) {        perror("Memory allocation failed for buffer");        set_promiscuous_mode("enp0s31f6", raw_socket, 0);        close(raw_socket);        fclose(logFile);        exit(EXIT_FAILURE);    }    sendbuff = (unsigned char *)malloc(4096);     if (sendbuff == NULL) {    perror("Failed to allocate memory for sendbuff");    close(raw_socket);    free(buffer);    return 1;    }    memset(sendbuff, 0, 4096);    get_eth_index();    get_mac();    get_ip();    struct sockaddr_ll sadr_ll;    sadr_ll.sll_ifindex = ifreq_i.ifr_ifindex;    sadr_ll.sll_halen = ETH_ALEN;    sadr_ll.sll_addr[0] = CLIENT_B_MAC0;    sadr_ll.sll_addr[1] = CLIENT_B_MAC1;    sadr_ll.sll_addr[2] = CLIENT_B_MAC2;    sadr_ll.sll_addr[3] = CLIENT_B_MAC3;    sadr_ll.sll_addr[4] = CLIENT_B_MAC4;    sadr_ll.sll_addr[5] = CLIENT_B_MAC5;    printf("Packet capture started...\n");    while(1) {        data_size = recvfrom(raw_socket, buffer, 65536, 0, NULL, NULL);         if(data_size < 0) {            LOG_ERROR("Recvfrom error, code: %s\n", strerror(errno));            break;                    }        LOG_ERROR("Received packet size: %zd bytes\n", data_size);        process_packet(buffer, data_size);    }    if (set_promiscuous_mode(interface_name, raw_socket, 0) < 0) {        fprintf(stderr, "Failed to disable promiscuous mode for interface %s\n", interface_name);    } else {        printf("Promiscuous mode disabled on interface %s\n", interface_name);    }    fclose(logFile);    close(raw_socket);    free(buffer);    free(sendbuff);    return 0;}void handle_packet(int protocol, unsigned char* buffer, int size) {    struct iphdr* iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));    int ip_header_len = iph->ihl * 4;    printf("Handling packet with protocol: %d\n", protocol);    switch (protocol) {        case IPPROTO_ICMP:            {                printf("ICMP packet processing\n");                struct icmphdr* icmph = (struct icmphdr*)(buffer + sizeof(struct ethhdr) + ip_header_len);                printf("ICMP Type: %d, Code: %d\n", icmph->type, icmph->code);                break;            }        case IPPROTO_TCP:            {                printf("TCP packet processing\n");                struct tcphdr* tcph = (struct tcphdr*)(buffer + sizeof(struct ethhdr) + ip_header_len);                printf("TCP Source Port: %u, Destination Port: %u\n", ntohs(tcph->source), ntohs(tcph->dest));                break;            }        case IPPROTO_UDP:            {                printf("UDP packet processing\n");                struct udphdr* udph = (struct udphdr*)(buffer + sizeof(struct ethhdr) + ip_header_len);                printf("UDP Source Port: %u, Destination Port: %u\n", ntohs(udph->source), ntohs(udph->dest));                break;            }        default:            printf("Other protocol: %d\n", protocol);            break;    }}void process_packet(unsigned char* buffer, int size) {     printf("Size of packet received: %d\n", size);      if (size < sizeof(struct ethhdr)) {        printf("Packet too small to contain Ethernet header\n");        return;    }        struct ethhdr *eth = (struct ethhdr*)buffer;        if (ntohs(eth->h_proto) != ETH_P_IP) {            printf("Non-IP packet received, protocol: 0x%04x\n", ntohs(eth->h_proto));            return;        }    struct iphdr* iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));    int ip_header_len = iph->ihl * 4;    printf("IP header length: %d\n", ip_header_len);    if (size < sizeof(struct ethhdr) + sizeof(struct iphdr)) {        printf("Packet too small to contain IP header\n");        return;    }    printf("Packet protocol: %u\n", iph->protocol);    switch (iph->protocol) {        case IPPROTO_ICMP:            handle_icmp_packet(buffer, size);            break;        case IPPROTO_TCP:            handle_tcp_packet(buffer, size);            break;        case IPPROTO_UDP:            handle_udp_packet(buffer, size);            break;        default:            printf("Non-ICMP/TCP/UDP packet, protocol: %d\n", iph->protocol);            break;    }    int protocol = iph->protocol;    printf("Packet protocol: %d\n", protocol);    printf("Packet captured, size: %d bytes, protocol: %d\n", size, iph->protocol);    unsigned int transport_header_len = 0;     if (iph->ihl < 5 || ip_header_len > size - sizeof(struct ethhdr)) {        printf("Invalid IP header length: %d\n", iph->ihl);        return;    }     int total_length = ntohs(iph->tot_len);    if (total_length > size- sizeof(struct ethhdr)) {        printf("Error: IP total length (%u) is greater than the actual packet size (%d).\n", total_length, size - sizeof(struct ethhdr));        return;     }    if (ip_header_len > total_length) {        printf("Error: IP header length is greater than the total length reported in the IP header. Possible error in packet formation.\n");        return;     }      printf("Packet captured, size: %d bytes, protocol: %d\n", size, iph->protocol);    if ((ntohs(iph->frag_off) & 0x1FFF) != 0) {        LOG_ERROR("Fragmented packet received, skipping.\n");        printf("Fragmented packet received, skipping.\n");        return;    }    if (size < (int)sizeof(struct iphdr)) {        printf("Received packet size too small to contain an IP header\n");        return;    }    if (iph->protocol == IPPROTO_ICMP || iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP) {        printf("Packet captured, Protocol: %d, Size: %d bytes\n", iph->protocol, size);    } else {        printf("Non-ICMP/TCP/UDP packet. Protocol number: %d\n", iph->protocol);        return;    }    int payload_len = 0;    unsigned char* payload = NULL;    unsigned char* encrypted_payload = NULL;    unsigned char* new_packet;    int new_packet_size;    if (!RAND_bytes(aes_iv, sizeof(aes_iv))) {        LOG_ERROR("Failed to generate IV\n");        //fprintf(stderr, "Failed to generate IV\n");        return;    }     if (!filter_packet(buffer, size)) {        printf("Packet filtered out.\n");        return;    }     if (iph->protocol == IPPROTO_TCP) {        struct tcphdr *tcph = (struct tcphdr *)(buffer + sizeof(struct ethhdr) + iph->ihl * 4);        if (ntohs(tcph->source) != 1234 && ntohs(tcph->dest) != 1234) return;        transport_header_len = tcph->doff * 4;    } else if (iph->protocol == IPPROTO_UDP) {        struct udphdr *udph = (struct udphdr *)(buffer + sizeof(struct ethhdr) + iph->ihl * 4);        transport_header_len = sizeof(struct udphdr);    } else if (iph->protocol == IPPROTO_ICMP) {        struct icmphdr *icmph = (struct icmphdr *)(buffer + sizeof(struct ethhdr) + iph->ihl * 4);        transport_header_len = sizeof(struct icmphdr);     }    struct tcphdr *tcph = (struct tcphdr *)(buffer + sizeof(struct ethhdr) + iph->ihl * 4);      if (ntohs(tcph->source) != 1234 && ntohs(tcph->dest) != 1234) return;      printf("Netcat packet captured, size: %d bytes\n", size);        if (extract_payload(buffer, size, &payload, &payload_len) != 0) {        printf("Failed to extract payload\n");        return;    }    printf("Original payload (text received by netcat):\n");    for (int i = 0; i < payload_len; i++) {        printf("%c", payload[i]);    }    printf("\n");    encrypted_payload = (unsigned char*)malloc(payload_len);    if (!encrypted_payload) {        printf("Failed to allocate memory for encrypted payload");        return;    }    int encrypted_payload_len = encrypt_payload(payload, payload_len, encrypted_payload);    if (encrypted_payload_len < 0) {         printf("Encryption failed\n");         free(encrypted_payload);        return;    }      printf("Encrypted payload:\n");      for (int i = 0; i < encrypted_payload_len; i++) {          printf("%02x ", encrypted_payload[i]);      }      printf("\n");        memcpy(buffer + sizeof(struct ethhdr) + ip_header_len + transport_header_len, encrypted_payload, encrypted_payload_len);      free(encrypted_payload);       encrypted_payload = NULL;       iph->tot_len = htons(ip_header_len + transport_header_len + encrypted_payload_len);      iph->check = 0;       iph->check = calculate_checksum((unsigned short*)iph, iph->ihl * 4);      if (iph->protocol == IPPROTO_TCP) {          struct tcphdr *tcph = (struct tcphdr *)(buffer + sizeof(struct ethhdr) + iph->ihl * 4);          tcph->check = 0;           calculate_transport_checksum((unsigned char*)tcph, iph, transport_header_len + encrypted_payload_len);      } else if (iph->protocol == IPPROTO_UDP) {          struct udphdr *udph = (struct udphdr *)(buffer + sizeof(struct ethhdr) + ip_header_len);          udph->check = 0;            calculate_transport_checksum((unsigned char*)udph, iph, sizeof(struct udphdr) + encrypted_payload_len);      } else if (iph->protocol == IPPROTO_ICMP) {                  struct icmphdr *icmph = (struct icmphdr *)(buffer + ip_header_len);                  memcpy(icmph + 1, encrypted_payload, encrypted_payload_len);                   iph->tot_len = htons(ip_header_len + sizeof(struct icmphdr) + encrypted_payload_len);              }    printf("Payload encrypted: New size %d\n", encrypted_payload_len);     LOG_ERROR("Encrypted payload length: %d\n", encrypted_payload_len);     reconstruct_packet(buffer, size);    LOG_ERROR("Packet reconstructed with new total length: %d\n", ntohs(iph->tot_len));    printf("Buffer content before forwarding:\n");    for (int i = 0; i < 20; i++) {         printf("%02x ", buffer[i]);    }    printf("\n");    remove_iptables_drop_rule();    printf("IPTables rules removed, forwarding packet...\n");    forward_packet(buffer, ntohs(iph->tot_len) + sizeof(struct ethhdr));    free(encrypted_payload);    encrypted_payload = NULL;}int filter_packet(const unsigned char *buffer, int bufsize) {    struct iphdr *ip_header = (struct iphdr *)(buffer + sizeof(struct ethhdr));     printf("Received packet with protocol: %d\n", ip_header->protocol);     int ip_header_length = ip_header->ihl * 4;    printf("Packet protocol: %u\n", ip_header->protocol);    printf("IPPROTO_ICMP: %u\n", IPPROTO_ICMP);    if (ip_header->protocol == IPPROTO_ICMP) {        printf("ICMP packet accepted.\n");        return 1;     }   else if (ip_header->protocol == IPPROTO_TCP) {        printf("TCP packet accepted.\n");        struct tcphdr *tcp_header = (struct tcphdr *)(buffer + ip_header_length);        if (ntohs(tcp_header->source) == 80 || ntohs(tcp_header->dest) == 80) {            printf("HTTP packet\n");            return 1;         }        if (ntohs(tcp_header->source) == 1234 || ntohs(tcp_header->dest) == 1234) {            printf("netcat packet\n");                    }    }    else if (ip_header->protocol == IPPROTO_UDP) {        printf("UDP packet accepted.\n");        struct udphdr *udp_header = (struct udphdr *)(buffer + ip_header_length);        if (ntohs(udp_header->source) == 53 || ntohs(udp_header->dest) == 53) {            printf("DNS packet\n");            return 1;         }    }    else {        printf("Non-ICMP/TCP/UDP packet. Protocol number: %d\n", ip_header->protocol);        return 0;     }    int accepted = (ip_header->protocol == IPPROTO_ICMP || ip_header->protocol == IPPROTO_TCP || ip_header->protocol == IPPROTO_UDP);    printf("Filtering: Protocol %d, %s\n", ip_header->protocol, (accepted ? "Accepted" : "Rejected"));    return accepted ? 1 : 0;}int extract_payload(unsigned char* buffer, int size, unsigned char** payload, int* payload_size) {    if (buffer == NULL || size <= 0 || payload == NULL || payload_size == NULL) {        printf("Invalid parameters for payload extraction.\n");        return -1;    }    struct iphdr *ip_header = (struct iphdr *)(buffer + sizeof(struct ethhdr));    *payload_size = 0;    unsigned int ip_header_len = ip_header->ihl * 4;     printf("Extracting payload: Original packet size %d, IP header length %u\n", size, ip_header_len);    if (size < sizeof(struct iphdr)) {        fprintf(stderr, "Packet too small for IP header.\n");        return -1;    }    if (ip_header_len < sizeof(struct iphdr)) {        fprintf(stderr, "Invalid IP header length: %u\n", ip_header_len);        return -1;    }    unsigned int total_length = ntohs(ip_header->tot_len);    printf("IP Header Length: %u bytes\n", ip_header_len);    printf("Total Length from IP header: %u bytes\n", total_length);    printf("Received buffer size: %d bytes\n", size);    if (total_length <= ip_header_len || total_length > size - sizeof(struct ethhdr)) {            printf("Invalid total length in IP header: %u bytes, buffer size: %d bytes\n", total_length, size);            return -1;        }    unsigned int transport_header_len = 0;    unsigned int total_packet_size = ntohs(ip_header->tot_len);    printf("total_packet_size: %u, buffer size: %d, ip_header_len: %u\n", total_packet_size, size, ip_header_len);    if (total_packet_size > size || total_packet_size < ip_header_len) {        printf("Invalid packet size: %u bytes (total packet size) is larger than buffer size: %d bytes or smaller than IP header size: %u bytes.\n", total_packet_size, size, ip_header_len);        return -1;    }   printf("Valid packet size: %u bytes, Buffer size: %d bytes, IP header size: %u bytes\n", total_packet_size, size, ip_header_len);    unsigned int packet_size = ntohs(ip_header->tot_len);    debug_print_packet_size(packet_size, size);    if (size < sizeof(struct iphdr) || packet_size > size) {        printf("Packet size is larger than the buffer size or too small to be valid.\n");        return -1;    }    if (ip_header->protocol == IPPROTO_TCP) {        struct tcphdr *tcp_header = (struct tcphdr *)(buffer + sizeof(struct ethhdr) + ip_header_len);        transport_header_len = tcp_header->doff * 4;    } else if (ip_header->protocol == IPPROTO_UDP) {        transport_header_len = sizeof(struct udphdr);    } else if (ip_header->protocol == IPPROTO_ICMP) {        transport_header_len = sizeof(struct icmphdr);    }    if (total_length <= ip_header_len + transport_header_len) {            printf("Total length is less than the combined length of IP and transport headers.\n");            return -1;        }        *payload = buffer + sizeof(struct ethhdr) + ip_header_len + transport_header_len;        *payload_size = total_length - ip_header_len - transport_header_len;        if (*payload_size <= 0) {        printf("Negative payload size calculated. This should not happen.\n");        return -1;    }    printf("Payload extracted: Size %d\n", *payload_size);     return 0; }int encrypt_payload(unsigned char* buffer, int size, unsigned char* encrypted_payload) {    if (buffer == NULL || size <= 0 || encrypted_payload == NULL) {        return -1;    }    printf("Encrypting payload: Original size %d\n", size);    printf("Original data: ");    for (int i = 0; i < size && i < 16; i++) {        printf("%02x ", buffer[i]);    }    printf("\n");    if (size <= 0 || encrypted_payload == NULL) return -1;    printf("Encrypting payload: Original size %d\n", size);    printf("Original data: ");    for (int i = 0; i < size && i < 16; i++) {        printf("%02x ", buffer[i]);    }    printf("\n");    printf("Encrypting payload...\n");    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();    if (!ctx) {        LOG_ERROR("EVP_CIPHER_CTX_new failed\n");        return -1;    }    if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, aes_key, aes_iv)) {        EVP_CIPHER_CTX_free(ctx);        return -2;    }    int len;    if (1 != EVP_EncryptUpdate(ctx, encrypted_payload, &len, buffer, size)) {        EVP_CIPHER_CTX_free(ctx);        return -3;    }    int final_len;    if (1 != EVP_EncryptFinal_ex(ctx, encrypted_payload + len, &final_len)) {        EVP_CIPHER_CTX_free(ctx);        return -4;    }    printf("Encrypted data: ");    for (int i = 0; i < len && i < 16; i++) {        printf("%02x ", (encrypted_payload)[i]);    }    printf("\n");    printf("Encryption successful, len: %d, final_len: %d\n", len, final_len);    EVP_CIPHER_CTX_free(ctx);    return len + final_len; }    void reconstruct_packet(unsigned char* buffer, int size) {    struct iphdr* iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));    int ip_header_len = iph->ihl * 4;    if (size < ip_header_len) {        LOG_ERROR("Packet size is too small to reconstruct\n");        return;    }    int payload_size = ntohs(iph->tot_len) - ip_header_len;    int new_total_length = ip_header_len + payload_size;    iph->tot_len = htons(new_total_length);    iph->check = 0;     iph->check = calculate_checksum((unsigned short*)iph, ip_header_len);    if (iph->protocol == IPPROTO_TCP) {        struct tcphdr* tcph = (struct tcphdr*)(buffer + sizeof(struct ethhdr) + ip_header_len);        tcph->check = 0;          calculate_transport_checksum(buffer + sizeof(struct ethhdr), iph, payload_size + ip_header_len);    } else if (iph->protocol == IPPROTO_UDP) {        struct udphdr* udph = (struct udphdr*)(buffer + sizeof(struct ethhdr) + ip_header_len);        udph->check = 0;         calculate_transport_checksum(buffer + sizeof(struct ethhdr), iph, payload_size + ip_header_len);    }    LOG_ERROR("Packet reconstructed: New total length %d\n", ntohs(iph->tot_len));}void calculate_transport_checksum(unsigned char* transport_segment, struct iphdr* iph, int segment_len) {    unsigned short *src_addr = (unsigned short *)&iph->saddr;    unsigned short *dest_addr = (unsigned short *)&iph->daddr;    struct pseudo_header psh = {0};    psh.source_address = iph->saddr;    psh.dest_address = iph->daddr;    psh.placeholder = 0;    psh.protocol = iph->protocol;    psh.tcp_length = htons(segment_len);    int psize = sizeof(struct pseudo_header) + segment_len;    unsigned char* pseudogram = malloc(psize);    if (pseudogram == NULL) {        fprintf(stderr, "Failed to allocate memory for pseudogram\n");        return;    }    memcpy(pseudogram, &psh, sizeof(struct pseudo_header));    memcpy(pseudogram + sizeof(struct pseudo_header), transport_segment, segment_len);    if (iph->protocol == IPPROTO_TCP) {        struct tcphdr* tcph = (struct tcphdr*)transport_segment;        tcph->check = 0;         tcph->check = calculate_checksum((unsigned short*)pseudogram, psize);    } else if (iph->protocol == IPPROTO_UDP) {        struct udphdr* udph = (struct udphdr*)transport_segment;        udph->check = 0;         udph->check = calculate_checksum((unsigned short*)pseudogram, psize);    }    free(pseudogram);}void forward_packet(unsigned char* buffer, int size) {    printf("Forwarding packet: Size %d\n", size);    if (sendto(sock_raw, buffer, size, 0, (struct sockaddr*)&sadr_ll, sizeof(sadr_ll)) < 0) {        LOG_ERROR("sendto failed: %s\n", strerror(errno));        fflush(logFile);    }}

I entered text abc from one terminal and it instantly receive text abc to another terminal. The output of my applicationOUTPUTabc

Encrypting payload: Original size 4Original data: 61 62 63 0aEncrypting payload: Original size 4Original data: 61 62 63 0aEncrypting payload...Encrypted data: 47 5b 0d bfEncryption successful,


Viewing all articles
Browse latest Browse all 6101

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>