C中实现判断ipv4或ipv6地址是单播、组播、广播地址
    
  
      
      
     
    
      
        在 C 中我们需要实现输入一个字符集(单播、组播、广播地址类型),来判断某 ipv4 或 ipv6 地址的类型是否在指定的类型集内。
为方便用户输入,类型的字符集我们定义为:
1:单播地址
2:组播地址
3:广播地址
可以输入多个类型,以英文逗号分隔,如:1,2,3
首先定义处理字符串类型匹配的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | 
 
 
 
 
 
 
  bool pp_in_string(int target, char *data) {   bool found = false;   if (data == NULL) goto end;
    char str[128];      strncpy(str, data, sizeof(data) - 1);   str[sizeof(str) - 1] = '\0';
    char *token = strtok(str, ",");   while (token != NULL) {     if (atoi(token) == target) {       found = true;       break;     }     token = strtok(NULL, ",");   }
  end:   return found; }
 
  | 
 
定义地址类型判断方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   | 
 
 
 
 
 
 
 
  bool address_check_range_type(int family, unsigned int *ip, char *range_type) {   if (range_type[0] == '\0') {     return true;   }
       int result = 1;
    if (family == AF_INET) {     if (ntohl(ip[0]) == 0xFFFFFFFF) {       result = 3;     } else if ((ntohl(ip[0]) & 0xF0000000) == ((uint32_t)(0xE0 << 24))) {       result = 2;     }   } else if (family == AF_INET6) {               struct in6_addr  *addr_v6 = (struct in6_addr *)ip;     if (addr_v6->s6_addr[0] == 0xFF) {       result = 2;              if (pp_in_string(3, range_type)) {         result = 3;       }     }   }
    return pp_in_string(result, range_type); }
 
  | 
 
上面的在 ipv6 格式下比较,需要转换一下再去判断。
ipv6 的地址结构体为:
1 2 3 4 5 6 7
   | struct in6_addr {     union {         uint8_t   s6_addr[16];            uint16_t  s6_addr16[8];           uint32_t  s6_addr32[4];       } __u6_addr; }
  | 
 
所以我们需要使用 in6_addr 结构体中的 s6_addr 去判断,正好是 128 位的 ipv6 地址表示值,而且分了 16 个数组,所以每组即 8 位,正使满足我们比较前 8 位需要全是 1 的条件。而如果我们使用的 s6_addr32,那么每组是 32 位,共 4 组,不能满足判断前 8 位的条件。
ipv6 的地址数据格式为:AA22:BB11:1122:CDED:1234:AA99:7654:7410
      
     
    
      
  
  
    
      
      
        
        致力于网站建设与Web开发。喜欢新事物,关注前后端动态,对新的技术有追求, 做一个优秀的web全栈工程师。