Redeemer, как-то криво ты сокет открываешь для записи сырых данных в него. Какой код ошибки возвращается 'errno'?
Если ты открываешь RAW сокет а функцию маршрутизации пакетов полностью перекладываешь на ядро, то там есть какие то тонкости, в IP_HDR по моему src-ip указывать не надо, и crc в ip-hdr то же формировать не надо. Сейчас соответствующей документации у меня нет под рукой.
Вот посмотри пример, программа читает pcap-dump и выкидывает его содержимое в интерфейс (eth0, ...). Pcap-dump можно записать 'tcpdump'-ом или 'Wireshark'-ом. Обрати внимание на функцию 'open_eth_dev', она открывает интерфейс для записи в него пакетов из pcapdump-а:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <arpa/inet.h>
#include "gentraf.h"
/**
 * Формат PCAP файла имеет следующий вид:
 * +-------------+-------------+-----------+-------------+-----------+---+
 * |Global Header|Packet Header|Packet Data|Packet Header|Packet Data|...|
 * +-------------+-------------+-----------+-------------+-----------+---+
 */
/* Pcap Global Header */
struct pcap_global_head {
        uint32_t magic;           /* магический номер */
        uint16_t version_major;   /* старший номер версии */
        uint16_t version_minor;   /* младший номер версии */
        uint32_t thiszone;        /* корекция времени GMT (временная зона) */
        uint32_t sigfigs;         /* временная погрешность (всегда 0) */
        uint32_t snaplen;         /* длина кадра */
        uint32_t linktype;        /* тип канального уровня (Ethernet, PPP, ...) */
};
/* Pcap Packet Header */
struct pcap_packet_head {
        uint32_t tv_sec;          /* время захвата пакета */
        uint32_t tv_usec;         /* микросекунд от tv_sec захвата пакета */
        uint32_t caplen;          /* колличество байт в блоке данных пакета */
        uint32_t len;             /* размер блока данных пакета */
};
/* Pcap Packet Data */
struct pcap_packet_data {
        struct pcap_packet_head p_head;  /* заголовок пакета */
        unsigned char *packet_data;        /* данные пакета */
};
/* Pcap Data */
struct pcap_file_data {
        struct pcap_global_head p_glob_head;      /* заголовок pcap файла */
        int number_packet_data;                /* количество пакетов */
        struct pcap_packet_data *p_packets;    /* массив пакетов */
};
static void help(void)
{
        fprintf(stderr, "Usage: " PROGNAME " [options] file...\n"
                        "\n"
                        "Options:\n"
                        "  -i [INTERF]    writen on interface\n"
                        "  -s [SEC]       job time in seconds\n"
                        "  -c [COUNT]     cycles to send the file\n"
                        "  -h             view this help\n");
}
static void usage(void)
{
        fprintf(stderr, "Usage: " PROGNAME " [options] -i [eth] file\n");
}
/*
 * Возвращает количество пакетов находящихся
 * в pcap файле.
 */
static int get_number_pcap_packet(FILE *fp)
{
        int number;
        fseek(fp, sizeof(struct pcap_global_head), SEEK_SET);
        for (number = 0;;) {
                struct pcap_packet_head p_packet;
                size_t n;
                n = fread(&p_packet, sizeof(p_packet), 1, fp);
                if (n != 1) {
                        if (!feof(fp)) {
                                err_msg("Failed counting packets of pcap file.");
                                return 0;
                        } else
                                break;
                }
                number++;
                fseek(fp, p_packet.caplen, SEEK_CUR);
        }
        return number;
}
/*
 * Загружает pcap файл в память и возвращает указатель на
 * структуру pcap_file_data содержащую данные из файла.
 */
static struct pcap_file_data *load_pcap_file(const char *pcap_name)
{
        struct pcap_file_data *p_file = NULL;
        struct pcap_global_head p_glob_head;
        int number_packet_data, i;
        FILE *fp;
        if ((fp = fopen(pcap_name, "rb")) == NULL)
                return NULL;
        if (fread(&p_glob_head, sizeof(p_glob_head), 1, fp) != 1)
                goto out;
#define PCAP_MAGIC                0xa1b2c3d4
#define PCAP_VERSION_MAJOR                 2
#define PCAP_VERSION_MINOR                 4
        if (p_glob_head.magic != PCAP_MAGIC ||
                        p_glob_head.version_major != PCAP_VERSION_MAJOR ||
                        p_glob_head.version_minor != PCAP_VERSION_MINOR) {
                err_msg("The '%s' no pcap format file.", pcap_name);
                goto out;
        }
        number_packet_data = get_number_pcap_packet(fp);
        if (!number_packet_data) {
                err_msg("It '%s' not contain pcap data.", pcap_name);
                goto out;
        }
        p_file = xmalloc(sizeof(*p_file));
        p_file->p_glob_head = p_glob_head;
        p_file->p_packets =
                xmalloc(sizeof(*p_file->p_packets) * number_packet_data);
        fseek(fp, sizeof(struct pcap_global_head), SEEK_SET);
        for (i = 0; i < number_packet_data; i++) {
                struct pcap_packet_data *p;
                size_t n;
                p = &p_file->p_packets[i];
                n = fread(&p->p_head, sizeof(p->p_head), 1, fp);
                if (n != 1) {
                        err_msg("Failed load packet head is '%s' pcap file.\n"
                                        "Loading only %d packets one of a %d.",
                                        pcap_name, i, number_packet_data);
                        break;
                }
                p->packet_data = xmalloc(p->p_head.caplen);
                n = fread(p->packet_data, p->p_head.caplen, 1, fp);
                if (n != 1) {
                        err_msg("Failed load packet data is '%s' pcap file.\n"
                                        "Loading only %d packets one of a %d.",
                                        pcap_name, i, number_packet_data);
                        break;
                }
        }
        p_file->number_packet_data = i;
out:
        fclose(fp);
        return p_file;
}
/*
 * Освобождает память выделенную под загруженный pcap файл.
 */
static void free_pcap_file(struct pcap_file_data *p_file)
{
        int i;
        for (i = 0; i < p_file->number_packet_data; i++)
                xfree(p_file->p_packets[i].packet_data);
        xfree(p_file->p_packets);
        xfree(p_file);
}
/*
 * Открывает eth интерфейс для записи в него пакетов.
 */
static int open_eth_dev(const char *eth_name)
{
        int sock;
        struct ifreq ifr;
        struct sockaddr_ll sll;
        sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
        if (sock == -1) {
                err_msg("Failed open RAW socket: %s", strerror(errno));
                return -1;
        }
        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, eth_name, sizeof(ifr.ifr_name) - 1);
        if (ioctl(sock, SIOCGIFINDEX, &ifr) == -1) {
                err_msg("ioctl SIOCGIFINDEX error: %s", strerror(errno));
                goto errout;
        }
        memset(&sll, 0, sizeof(sll));
        sll.sll_family = AF_PACKET;
        sll.sll_ifindex = ifr.ifr_ifindex;
        sll.sll_protocol = htons(ETH_P_ALL);
        if (bind(sock, (struct sockaddr *)&sll, sizeof(sll)) == -1) {
                err_msg("Failed binding socket: %s", strerror(errno));
                goto errout;
        }
        return sock;
errout:
        close(sock);
        return -1;
}
/*
 * Закрывает eth интерфей.
 */
static void close_eth_dev(int sock)
{
        close(sock);
}
/* флаг указывающий о прекращении работы */
static volatile int flags_exit;
static void sig_func(int signo)
{
        if (signo == SIGINT)
                printf("signal SIGINT\n");
        flags_exit = 1;
}
int main(int argc, char **argv)
{
        const char *fpcap = NULL, *dev = NULL;
        struct pcap_file_data *p_file;
        int oc, sock_dev;
        int count_send = 0, timeout_job = 0;
        prog_name = argv[0];
        while ((oc = getopt(argc, argv, ":i:s:c:h")) != -1) {
                switch (oc) {
                        case 'i':
                                dev = optarg;
                                break;
                        case 's':
                                timeout_job = atoi(optarg);
                                break;
                        case 'c':
                                count_send = atoi(optarg);
                                break;
                        case 'h':
                                help();
                                exit(1);
                                break;
                        case ':':
                                err_quit("option '-%c' requires an argument.", optopt);
                                break;
                        case '?':
                        default:
                                err_quit("option '-%c' is invalid.", optopt);
                                break;
                }
        }
        fpcap = argv[optind];
        if (!dev || !fpcap) {
                usage();
                exit(1);
        }
        if ((p_file = load_pcap_file(fpcap)) == NULL)
                err_quit("Failed load '%s' pcap file.", fpcap);
        if ((sock_dev = open_eth_dev(dev)) == -1)
                err_quit("Failed open '%s' device.", dev);
        if (signal(SIGALRM, sig_func) == SIG_ERR)
                err_quit("Failed setting signal 'SIGALRM': %s", strerror(errno));
        if (signal(SIGINT, sig_func) == SIG_ERR)
                err_quit("Failed setting signal 'SIGINT': %s", strerror(errno));
        if (timeout_job)
                alarm(timeout_job);
        while (!flags_exit) {
                int i;
                for (i = 0; !flags_exit && (i < p_file->number_packet_data); i++) {
                        struct pcap_packet_data *p = &p_file->p_packets[i];
                        size_t n;
                        n = write(sock_dev, p->packet_data, p->p_head.caplen);
                        if (n == -1) {
                                err_quit("Error writing device '%s': %s",
                                                dev, strerror(errno));
                        } else if (n != p->p_head.caplen) {
                                err_msg("WARNING: writing %u of %u in the '%s': %s",
                                                (unsigned)n, p->p_head.caplen, dev, strerror(errno));
                        }
                }
                if (count_send) {
                        if (!--count_send)
                                flags_exit = 1;
                }
        }
        if (timeout_job)
                alarm(0);
        close_eth_dev(sock_dev);
        free_pcap_file(p_file);
        return 0;
}