【Linux】Linux C判断两个IPv6地址是否有包含关系

功能说明

要判断两个 IPv6 地址是否具有包含关系,包括前缀的比较,可以通过以下步骤实现:

  1. 解析 IPv6 地址和前缀:将两个 IPv6 地址和它们的前缀长度解析为二进制形式。
  2. 生成掩码:根据前缀长度生成掩码。
  3. 按位比较:使用掩码对两个 IPv6 地址进行按位与操作,判断它们是否匹配。

代码实现

复制代码
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>

// 判断两个 IPv6 地址是否具有包含关系(包括前缀)
int is_ipv6_prefix_contained(const char *ip1_str, int prefix1_len, const char *ip2_str, int prefix2_len) 
{
    struct in6_addr ip1, ip2;
    unsigned char mask[16] = {0};
    int common_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;

    // 将字符串形式的 IPv6 地址转换为 in6_addr 结构
    if (inet_pton(AF_INET6, ip1_str, &ip1) != 1) 
    {
        fprintf(stderr, "Invalid IPv6 address: %s\n", ip1_str);
        return -1;
    }

    if (inet_pton(AF_INET6, ip2_str, &ip2) != 1)
    {
        fprintf(stderr, "Invalid IPv6 address: %s\n", ip2_str);
        return -1;
    }

    // 生成掩码,使用较短的公共前缀长度
    for (int i = 0; i < common_prefix_len / 8; i++) 
    {
        mask[i] = 0xFF; // 每个完整字节设置为 0xFF
    }
    if (common_prefix_len % 8 != 0) 
    {
        mask[common_prefix_len / 8] = (0xFF << (8 - (common_prefix_len % 8))) & 0xFF; // 部分字节掩码
    }

    // 比较地址和前缀
    for (int i = 0; i < 16; i++) 
    {
        if ((ip1.s6_addr[i] & mask[i]) != (ip2.s6_addr[i] & mask[i])) 
        {
            return 0; // 不包含
        }
    }

    return 1; // 包含
}

int main() 
{
    const char *ip1 = "2001:db8::1";
    int prefix1_len = 32;
    const char *ip2 = "2001:db8::";
    int prefix2_len = 48;

    int result = is_ipv6_prefix_contained(ip1, prefix1_len, ip2, prefix2_len);
    if (result == 1) 
    {
        printf("IPv6 address %s/%d is contained within %s/%d\n", ip1, prefix1_len, ip2, prefix2_len);
    }
    else if (result == 0)
    {
        printf("IPv6 address %s/%d is NOT contained within %s/%d\n", ip1, prefix1_len, ip2, prefix2_len);
    } 
    else
    {
        printf("An error occurred.\n");
    }

    return 0;
}

代码说明

inet_pton 函数

  • 将字符串形式的 IPv6 地址转换为 struct in6_addr 结构。
  • 如果转换失败,返回值为 0-1

掩码生成

  • 根据两个前缀长度的较小值生成掩码。
  • 每个完整字节设置为 0xFF,部分字节根据前缀长度生成部分掩码。

按位比较

  • 使用掩码对两个 IPv6 地址进行按位与操作。
  • 如果结果相同,则说明一个地址的前缀包含另一个地址。

返回值

  • 返回 1 表示 IPv6 地址 ip1/prefix1_len 包含或被包含于 ip2/prefix2_len
  • 返回 0 表示两者没有包含关系。
  • 返回 -1 表示输入无效。

测试用例

测试 1:IPv6 地址包含关系

输入:

  • IPv6 地址 1:2001:db8::1/32
  • IPv6 地址 2:2001:db8::/48

输出:

复制代码
IPv6 address 2001:db8::1/32 is contained within 2001:db8::/48
测试 2:IPv6 地址不包含关系

输入:

  • IPv6 地址 1:2001:db9::1/32
  • IPv6 地址 2:2001:db8::/48

输出:

复制代码
IPv6 address 2001:db9::1/32 is NOT contained within 2001:db8::/48
测试 3:无效输入

输入:

  • IPv6 地址 1:invalid_ip/32
  • IPv6 地址 2:2001:db8::/48

输出:

复制代码
Invalid IPv6 address: invalid_ip
An error occurred.
相关推荐
jz_ddk几秒前
[LVGL] 从0开始,学LVGL:进阶应用与项目实战(上)
linux·信息可视化·嵌入式·gui·lvgl·界面设计
Bruce_Liuxiaowei9 分钟前
Windows系统错误6118全面解决方案:修复此工作组的服务器列表当前无法使用
运维·服务器·windows·网络安全
望获linux25 分钟前
【实时Linux实战系列】Linux 内核的实时组调度(Real-Time Group Scheduling)
java·linux·服务器·前端·数据库·人工智能·深度学习
云宏信息26 分钟前
【深度解析】VMware替代的关键一环:云宏ROW快照如何实现高频业务下的“无感”数据保护?
服务器·网络·数据库·架构·云计算·快照
程序员大雄学编程29 分钟前
「深度学习笔记4」深度学习优化算法完全指南:从梯度下降到Adam的实战详解
笔记·深度学习·算法·机器学习
MC丶科35 分钟前
【SpringBoot常见报错与解决方案】端口被占用?Spring Boot 修改端口号的 3 种方法,第 3 种 90% 的人不知道!
java·linux·spring boot
江公望1 小时前
ubuntu kylin(优麒麟)和标准ubuntu的区别浅谈
linux·服务器·ubuntu·kylin
Lynnxiaowen1 小时前
今天我们开始学习python语句和模块
linux·运维·开发语言·python·学习
小O的算法实验室1 小时前
2022年ASOC SCI2区TOP,基于竞争与合作策略的金字塔粒子群算法PPSO,深度解析+性能实测,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
南莺莺1 小时前
邻接矩阵的基本操作
数据结构·算法··邻接矩阵