ILD

kernel api determine ipv6 address type
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2023-9-14 站点:Inside Linux Development

__ipv6_addr_type()可以返回地址的类型


net/ipv6/addrconf_core.c


int __ipv6_addr_type(const struct in6_addr *addr)

{

        __be32 st; 


        st = addr->s6_addr32[0];


        /* Consider all addresses with the first three bits different of

           000 and 111 as unicasts.

         */

        if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&

            (st & htonl(0xE0000000)) != htonl(0xE0000000))

                return (IPV6_ADDR_UNICAST |

                        IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));


        if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {

                /* multicast */

                /* addr-select 3.1 */

                return (IPV6_ADDR_MULTICAST |

                        ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));

        }


        if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))

                return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |

                        IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));               /* addr-select 3.1 */

        if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))

                return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |

                        IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL));               /* addr-select 3.1 */

        if ((st & htonl(0xFE000000)) == htonl(0xFC000000))

                return (IPV6_ADDR_UNICAST |

                        IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));                  /* RFC 4193 */


        if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {

                if (addr->s6_addr32[2] == 0) {

                        if (addr->s6_addr32[3] == 0)

                                return IPV6_ADDR_ANY;


                        if (addr->s6_addr32[3] == htonl(0x00000001))

                                return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |

                                        IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));       /* addr-select 3.4 */


                        return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |

                                IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.3 */

                }


                if (addr->s6_addr32[2] == htonl(0x0000ffff))

                        return (IPV6_ADDR_MAPPED |

                                IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.3 */

        }


        return (IPV6_ADDR_UNICAST |

                IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.4 */

}

EXPORT_SYMBOL(__ipv6_addr_type);


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.