Alberto Lara
Alberto Lara

Reputation: 31

Problem with tcpreplay in docker to inject data in ethernet interface of host pc

I'm trying to use tcpreplay to inject UDP packets in another ethernet interface in same pc. For that reason I created a dummy interface.

sudo modprobe dummy
sudo ip link add eth0 type dummy
ip link show eth0
sudo ifconfig eth0 hw ether 02:5d:6c:e8:8d:b2
sudo ip addr add 192.168.50.50/24 broadcast 192.168.50.255 dev eth0
sudo ip link set dev eth0 arp on
sudo ip link set eth0 promisc off
sudo ip link set eth0 multicast on
sudo ip link set dev eth0 up

Resulting in:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.50.50  netmask 255.255.255.0  broadcast 192.168.50.255
        inet6 fe80::5d:6cff:fee8:8db2  prefixlen 64  scopeid 0x20<link>
        ether 02:5d:6c:e8:8d:b2  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 935342  bytes 1167225106 (1.1 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Once eth0 is created, I run tcprewrite to fit ip addresses and mac orig/dest in .pcap file for my interface:

sudo tcprewrite --srcipmap=192.168.50.51:192.168.50.50 --dstipmap=192.168.50.50:192.168.50.50 --infile=my.pcap --enet-dmac=ff:ff:ff:ff:ff:ff,02:5d:6c:e8:8d:b2 --enet-smac=60:76:88:00:00:00,02:5d:6c:e8:8d:b2 --outfile=out.pcap

and then inject UDP traffic:

sudo tcpreplay -l 0 -v --intf1=eth0 out.pcap

If I sniff traffic in wireshark, it seems all packets are being injected in eth0.

33312 20.472560871 192.168.50.50 192.168.50.50 UDP 1248 2368 → 2368 Len=1206

when I use tcpdump the outcome is somehow different because is pointing to <my_machine_name> (Why? if wireshark yields 192.168.50.50 ? ) 09:39:10.168498 IP <my_machine_name>.2368 > <my_machine_name>.2368: UDP, length 1206

But still arrives packets.

Is in my standard socket C program Binding is ok but is being stacked for good in recvfrom().

#include <iostream>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <sys/ioctl.h>  

#define PORT 2368
#define BUFFER_SIZE 2048

int main() {
    int udp_socket;
    struct sockaddr_in server_address, client_address;
    socklen_t client_address_len = sizeof(client_address);
    char buffer[BUFFER_SIZE];

    // Create UDP socket
    udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (udp_socket < 0) {
        perror("Error creating socket");
        exit(EXIT_FAILURE);
    }

    // Bind the socket to a specific address and port
    memset(&server_address, 0, sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(PORT);
    server_address.sin_addr.s_addr = INADDR_ANY;

    if (bind(udp_socket, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
        perror("Bind error");
        close(udp_socket);
        exit(EXIT_FAILURE);
    }

    printf("Listening for UDP packets on port %d...\n", PORT);

    // Receive and process UDP packets
    while (1) {
        int bytes_received = recvfrom(udp_socket, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&client_address, &client_address_len);
        if (bytes_received < 0) {
            perror("recvfrom error");
            close(udp_socket);
            exit(EXIT_FAILURE);
        }

        // Process the received packet (contained in 'buffer')
        printf("Received UDP packet from %s:%d with length: %d\n",
               inet_ntoa(client_address.sin_addr), ntohs(client_address.sin_port), bytes_received);

        // Print the packet contents
        for (int i = 0; i < bytes_received; ++i) {
            printf("%02x ", buffer[i]);
        }
        printf("\n");
    }

    // Close the UDP socket (not reached in this example)
    close(udp_socket);

    return 0;
}

Also checked in docker (Using https://hub.docker.com/r/dgarros/tcpreplay) , and still doesn't work.

docker run --net host --rm -t -v /home/myhostFolder:/data -i dgarros/tcpreplay /usr/bin/tcpreplay --intf1=eth0 docker.pcap

In my local docker interface I can see the packets published by tcpreplay, but my C socket program above continues stacked at recvfrom

Please, any ideas why it's not working? Maybe, some limitations in tcpreplay for injecting in same pc?

Cheers

Upvotes: 1

Views: 194

Answers (0)

Related Questions