Source code for include/validators/ipv6.h

#ifndef _IPV6_H_
#define _IPV6_H_
#define HEX_BASE 16
#define IP_CIDR_DELIMITER "/"
#define IPV4_DELIMITER "."
#define IPV6_DELIMITER ":"
#define IPV6_DELIMITER_CHAR ':'
#include "split.h" #include "utils.h" bool is_ipv6(char *ipv6_addr); bool is_ipv6_cidr(char *ipv6_addr_cidr);
[docs]/** * Returns ``true`` if given string is a IPv6 otherwise ``false``. * * Args: * ipv6_addr(char *): target string to be validated * * Returns: * ``true`` if given address is a IPv6 address */ bool is_ipv6(char *ipv6_addr) { struct split_t ipv6_groups; struct split_t ipv4_groups; char *ipv4_part; int blankctr, number; bool is_freed_ipv4; ipv6_groups = split(ipv6_addr, IPV6_DELIMITER); blankctr = blanks(ipv6_addr, IPV6_DELIMITER_CHAR); if (!ipv6_groups.length || ipv6_groups.length + blankctr <= 1) return free_split_r(&ipv6_groups, false); ipv4_part = ipv6_groups.tokens[ipv6_groups.length - 1]; ipv4_groups = split(ipv4_part, IPV4_DELIMITER); is_freed_ipv4 = false; if (ipv4_groups.length > 1) { if (!is_ipv4(ipv4_part)) return free_split_r(&ipv4_groups, free_split_r(&ipv6_groups, false)); free(ipv4_part); ipv4_part = NULL; ipv6_groups.length--; } else { free_split(&ipv4_groups); is_freed_ipv4 = true; } size_t max_groups = ipv4_groups.tokens ? 6 : 8; if (ipv6_groups.length + blankctr > max_groups) { if (!is_freed_ipv4) free_split(&ipv4_groups); return free_split_r(&ipv6_groups, false); } for (size_t i = 0; i < ipv6_groups.length; i++) { char *part = ipv6_groups.tokens[i]; if (!is_xdigit(part)) { if (!is_freed_ipv4) free_split(&ipv4_groups); return free_split_r(&ipv6_groups, false); } number = (int)strtol(part, NULL, HEX_BASE); if (!(0 <= number && number <= 65536)) { if (!is_freed_ipv4) free_split(&ipv4_groups); return free_split_r(&ipv6_groups, false); } } if (blankctr <= 2) { if (!is_freed_ipv4) free_split(&ipv4_groups); return free_split_r(&ipv6_groups, true); } if (!is_freed_ipv4) free_split(&ipv4_groups); return free_split_r(&ipv6_groups, false); }
[docs]/** * Returns ``true`` if given string is a IPv6CIDR otherwise ``false``. * * Args: * ipv6_addr_cidr(char *): target string to be validated * * Returns: * ``true`` if given address is a IPv6CIDR */ bool is_ipv6_cidr(char *ipv6_addr_cidr) { struct split_t splitted = split(ipv6_addr_cidr, IP_CIDR_DELIMITER); if (splitted.length != 2) return free_split_r(&splitted, false); char *prefix = splitted.tokens[0]; char *suffix = splitted.tokens[1]; if (!is_ipv6(prefix) || !is_digit(suffix)) return free_split_r(&splitted, false); if (!(0 <= atoi(suffix) && atoi(suffix) <= 128)) return free_split_r(&splitted, false); return free_split_r(&splitted, true); }
#endif