QEMU сеть: различия между версиями

Материал из test
Нет описания правки
Нет описания правки
Строка 71: Строка 71:
sudo dhcpcd enp59s0
sudo dhcpcd enp59s0
</pre>
</pre>
== Tun интерфейс ==
<pre>
sudo ip tuntap add dev tun0 mode tun
sudo ip link set tun0 up
sudo ip addr add 10.0.0.1/24 dev tun0
</pre>
Читает пакеты из tun-интерфейса
<syntaxhighlight lang="с" line>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <errno.h>
void print_hex(const unsigned char *buf, size_t len) {
    for(size_t i = 0; i < len; i++) {
printf("%02x ", buf[i]);
    }
    printf("\n");
}
int main(void) {
    printf("hi\n");
    int tun_fd;
    const char *iface_name = "tun0";
    struct ifreq ifr;
    int ret = 0;
    tun_fd = open("/dev/net/tun", O_RDWR);
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, iface_name, IFNAMSIZ - 1);
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
    ret = ioctl(tun_fd, TUNSETIFF, (void*)&ifr);
   
    unsigned char buffer[2048];
    ssize_t bytes_read;
    while(1) {
bytes_read = read(tun_fd, buffer, sizeof(buffer));
printf("read %zd bytes\n", bytes_read);
print_hex(buffer, bytes_read);
    }
   
    close(tun_fd);
    return 0;
}
</syntaxhighlight>

Версия от 18:43, 29 июня 2026

Две машины, связанные сетью

Связанные между собой, изолированные от хоста.

На хосте нужно создать два tap-интерфейса и бридж:

sudo ip tuntap add dev tap0 mode tap
sudo ip tuntap add dev tap1 mode tap

sudo ip link set tap0 up
sudo ip link set tap1 up

sudo ip link add name br0 type bridge

sudo ip link set tap0 master br0
sudo ip link set tap1 master br0

sudo ip link set dev br0 up

Параметры запуска QEMU для сети:

-netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device e1000,netdev=net0,mac=52:55:00:d1:55:01

Запуск может выглядеть например так (для разных машин нужно выбрать разный mac-адрес):

qemu-system-x86_64 -m 2048 -smp 2 -drive file=my_disk.qcow2,format=qcow2 -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device e1000,netdev=net0,mac=52:55:00:d1:55:01

В самих машинах нужно настроить статический ip-адрес.

В /etc/network/interfaces прописать, например:

iface ens3 inet static
    address 192.168.0.1
    netmask 255.255.255.0

Виртуалка в подсети хоста, получает адрес от роутера

sudo ip link add name br0 type bridge
sudo ip link set br0 up
sudo ip link set enp59s0 master br0
sudo ip link set enp59s0 up
sudo dhcpcd br0
sudo ip tuntap add tap0 mode tap
sudo ip link set tap0 master br0
sudo ip link set tap0 up

sudo ip r del default via 192.168.1.1 dev enp59s0
sudo ip r del 192.168.1.0/24 dev enp59s0 proto kernel scope link src 192.168.1.13 metric 100

Запуск qemu:

qemu-system-x86_64 -m 2048 -smp 4 -drive file=test.qcow2,format=qcow2 -accel kvm -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device e1000,netdev=net0,mac=52:54:00:11:22:33

Вернуть обратно:

sudo ip link set tap0 nomaster
sudo ip link delete tap0
sudo ip link set enp59s0 nomaster
sudo ip link set br0 down
sudo ip link delete br0
sudo dhcpcd enp59s0


Tun интерфейс

sudo ip tuntap add dev tun0 mode tun
sudo ip link set tun0 up
sudo ip addr add 10.0.0.1/24 dev tun0

Читает пакеты из tun-интерфейса

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <errno.h>

void print_hex(const unsigned char *buf, size_t len) {
    for(size_t i = 0; i < len; i++) {
	printf("%02x ", buf[i]);
    }
    printf("\n");
}

int main(void) {
    printf("hi\n");
    int tun_fd;
    const char *iface_name = "tun0";
    struct ifreq ifr;
    int ret = 0;

    tun_fd = open("/dev/net/tun", O_RDWR);
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, iface_name, IFNAMSIZ - 1);
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
    ret = ioctl(tun_fd, TUNSETIFF, (void*)&ifr);
    
    unsigned char buffer[2048];
    ssize_t bytes_read;
    while(1) {
	bytes_read = read(tun_fd, buffer, sizeof(buffer));
	printf("read %zd bytes\n", bytes_read);
	print_hex(buffer, bytes_read);
	
    }
    

    close(tun_fd);
    return 0;
}