ipv6 6rd前缀计算

来源:互联网 发布:网龙java笔试题 编辑:程序博客网 时间:2024/06/07 22:26

通过获取到6rd配置信息计算组合后的前缀

/* * 计算6rd前缀 */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>typedef struct{    struct in6_addr addr;    int prefix_len;}ipv6_addr_struct;typedef unsigned char uchar;/* 数组向右移位 */void shift_right(uchar *ar, int size, int shift){    uchar carry = 0;                        uchar next = 0;    int i = 0;    while (shift--)     {                                  carry = 0;        for (i = 0; i < size; i++)         {               next = (ar[i] & 1) ? 0x80 : 0;             ar[i] = carry | (ar[i] >> 1);                  carry = next;                           }       }}   /* dst和src进行或运算,结果保存在dst */void binary_or_op(uchar *dst, uchar *src, int size){    int i = 0;    for(i = 0; i < size; i++)    {        dst[i] |= src[i];    }}/* 打印字符串的二进制 */void print_binary(uchar *s, int size){    int i = 0;    int j = 0;    for(i = 0; i < size; i++)    {        for(j = 0; j < 8; j++)        {            if((s[i] << j) & 0x80)                printf("1");            else                printf("0");        }        printf(" ");    }    printf("\n");}/*  * 计算6rd的前缀,得到IPV4的尾部地址后移位Prefix len长度再与prefix进行或运算  * prefix: 上级下发的前缀 * prefix_len: 下发的前缀长度 * wan_ip: wan口IP * mask_len: 边界路由器ipv4地址的掩码长度 * ipv6_addr: 保存计算结果,其中含计算出的LAN前缀和前缀长度 */int calc_6rd_prefix(char *prefix, int prefix_len, char *wan_ip, int mask_len,     ipv6_addr_struct *ipv6_addr){    unsigned long wan_ip_tail = (inet_addr(wan_ip) >> mask_len); //网络字节序,大端,右移    uchar addr_pad[16] = {0};    struct in6_addr prefix_addr;     inet_pton(AF_INET6, prefix, &prefix_addr);    memcpy(addr_pad, &wan_ip_tail, sizeof(wan_ip_tail));    shift_right(addr_pad, sizeof(addr_pad), prefix_len);    binary_or_op((uchar*)addr_pad, (uchar*)&prefix_addr, sizeof(addr_pad));    memcpy(ipv6_addr, addr_pad, sizeof(*ipv6_addr));    ipv6_addr->prefix_len = prefix_len + (32 - mask_len);    return 0;}int main(int argc, char *argv[]){    if(argc < 5)        return 0;    ipv6_addr_struct ipv6_addr;    char ip[128] = {0};    calc_6rd_prefix(argv[1], atoi(argv[2]), argv[3], atoi(argv[4]), &ipv6_addr);    inet_ntop(AF_INET6, &ipv6_addr.addr, ip, sizeof(ip));    printf("%s/%d\n", ip, ipv6_addr.prefix_len);    return 0;}/* 测试root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 32 192.168.3.4 162001:db8:304::/48root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 32 192.168.3.4 242001:db8:400::/40root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 32 192.168.3.4 82001:db8:a803:400::/56root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 32 192.168.3.4 02001:db8:c0a8:304::/64root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 48 192.168.3.4 02001:db8:0:c0a8:304::/80root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 48 192.168.3.4 162001:db8:0:304::/64root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 33 192.168.3.4 162001:db8:182::/49root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 33 192.168.3.4 242001:db8:200::/41root@leon-virtual-machine:6rd_prefix_calc# ./a.out 2001:db8:: 33 192.168.3.4 152001:db8:384::/50*/
原创粉丝点击