Как ввести пакет в качестве входа в интерфейс?

#c #sockets #ubuntu-20.04 #raw-sockets #network-interface

Вопрос:

По какой-то причине мне нужно поместить/ввести пакет в интерфейс. Я сделал содержимое пакета на локальном компьютере. Предположим, что в сети нет другой машины, которая могла бы отправить пакет в сетевой интерфейс локальной машины. Таким образом, локальная машина должна выполнить эту работу. Если я отправлю пакет в интерфейс, он будет помещен в интерфейс для выхода из машины, и, поскольку MAC-адрес назначения пакета и IP-адрес назначения пакета принадлежат локальной машине, пакет никуда не денется. Я думаю, что такой пакет называется исходящим пакетом, в то время как мне нужно, чтобы тот же пакет был получен интерфейсом или притворялся для ядра, что он был получен интерфейсом. Я думаю, что такой пакет называется входным пакетом. Операционная система ubuntu 20.04, а код написан на C. Ниже приведен пример такого кода. Я проверил его между двумя виртуальными машинами, и он отлично работает, но что я могу сделать, если хочу сделать это только с одной машиной?

В следующем примере я отвечаю на пакеты ping (ICMP). Когда я запускаю его между двумя виртуальными машинами, он работает правильно, но когда я отправляю сгенерированный ответ на единственный интерфейс на одной машине, ping не может получить ответ.

 int main(int argc, const char *argv[])
{
    u8 buf[1000], *dest = NULL;
    int len, destLen = 0;

    int sdRaw = OpenRawSocket(argv[1], NULL, NULL);
    while (true)
    {
        len = recv(sdRaw, buf, sizeof(buf), 0);
        CHECK(len > 0, "%s", strerror(errno));
        if (*(u16 *)(buf   0x0c) == 8 amp;amp;
            buf[0x17] == 1)
        {
            if (destLen < len)
            {
                printf("destLen: %d --> %dn", destLen, len);
                dest = realloc(dest, len);
                destLen = len;
            }
            memcpy(dest   12, buf   12, len - 12);
            memcpy(dest, buf   6, 6);
            memcpy(dest   6, buf, 6);
            *(u16 *)(dest   0x14) = 0;
            *(u32 *)(dest   0x1a) = *(u32 *)(buf   0x1e);
            *(u32 *)(dest   0x1e) = *(u32 *)(buf   0x1a);
            //dest[0x22] = 0;  // no need
            FixChecksums(dest, len);
            CHECK(send(sdRaw, dest, len, 0) == len, "%s", strerror(errno));
        }
    }
}
 

Пожалуйста, не спрашивайте о полезности кода. Я собираюсь упростить проблему с помощью простого кода, но проблема будет решена, если эта простая проблема будет преодолена.