一个ipv4到ipv6的移植问题

之前在使用ipv4的时候,有一个模块是使用raw socket来发包,它使用的一个option是:IP_HDRINCL。

如果设置了IP_HDRINCL选项,则raw会绕过source validate逻辑,即构造的IP源地址可以是非本机地址,比如我们在流媒体中发送udp包,替换码流源就可以用到这种。

或者通过劫持DNS请求,用别人ip给请求方发包,也可以利用这个特性,诸如此类。

如果没有设置IP_HDRINCL选项忽略构造的IP源地址,以路由查找逻辑动态确定IP源地址。

很显然,我们的应用场景需要利用这个特性。

v4迁移到v6的时候,我们很自信地写上了 IPV6_HDRINCL ,结果发现没有用。我的内核版本是3.10,然后git一份高版本内核,发现这个是有的:

static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
                char __user *optval, unsigned int optlen)
{
    struct raw6_sock *rp = raw6_sk(sk);
    int val;

    if (get_user(val, (int __user *)optval))
        return -EFAULT;

    switch (optname) {
    case IPV6_HDRINCL:
        if (sk->sk_type != SOCK_RAW)
            return -EINVAL;
        inet_sk(sk)->hdrincl = !!val;
        return 0;

反向移植到我们的版本就可以搞定。

猜你喜欢

转载自www.cnblogs.com/10087622blog/p/10133599.html