Я хочу внедрить дейтаграммы IPv6, доступные в пользовательском пространстве (и полученные по схеме, которая сначала требует некоторой распаковки, которая выполняется в пользовательском пространстве) в подходящий необработанный сокет для дальнейшей обработки ядром Linux. Это довольно просто сделать с IPv4, используя следующий код:
int fd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
struct sockaddr_ll sa;
memset(sa, 0, sizeof(sa));
// ip4h is the IPv4 datagram unwrapped in the user space and ready to be
// sent to the kernel
if (sendto(fd, iph, iplen, 0, (struct sockaddr *)&sa, sizeof(sa)) != iplen) {
// Error processing.
}
Вышеуказанное вводит полные пакеты IPv4 (включая заголовки IPv4), а полезная нагрузка IPv4 обрабатывается соответствующим образом стеком Linux. Как следует изменить приведенное выше для использования с пакетами IPv6? Следующие настройки, которые я пробовал, не помогли:
int fd=socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
sa.sll_family=AF_PACKET;
sa.sll_protocol=htons(ETH_P_IPV6);
sa.sll_halen=ETH_ALEN;
sa.sll_ifindex=2; // <index of eth0>
if (sendto(fd, iph, iplen, 0, (struct sockaddr *)&sa, sizeof(sa)) != iplen) {
// Error processing.
}
Есть мысли о том, почему вышеперечисленное не работает с необработанными дейтаграммами IPv6? 'tcpdump ip6' показывает пакеты IPv6, которые я вставляю, что говорит о том, что ядро их видит! Просто так получилось, что я их игнорирую.
@stark: Да, AF_INET6 / SOCK_DGRAM вместе с sockaddr_in6 пробовали, но это не помогло. Пример, безусловно, поможет, если вам это удастся.
Зачем менять протоколы? Вам просто нужны AF_INET6 и sockaddr_in6