static int get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, uint8_t term) { const char *end; int ret = in6_pton(src, min_t(size_t, dlen, 0xffff), (uint8_t *)dst, term, &end); if (ret > 0) return (int)(end - src); return 0; }
int cifs_inet_pton(const int address_family, const char *cp, void *dst) { int ret = 0; /* calculate length by finding first slash or NULL */ if (address_family == AF_INET) ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL); else if (address_family == AF_INET6) ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); cFYI(DBG2, ("address conversion returned %d for %s", ret, cp)); if (ret > 0) ret = 1; return ret; }
/* * Convert a string containing text IPv4 or IPv6 address to binary form. * * Returns 0 on failure. */ static int cifs_inet_pton(const int address_family, const char *cp, int len, void *dst) { int ret = 0; /* calculate length by finding first slash or NULL */ if (address_family == AF_INET) ret = in4_pton(cp, len, dst, '\\', NULL); else if (address_family == AF_INET6) ret = in6_pton(cp, len, dst , '\\', NULL); cifs_dbg(NOISY, "address conversion returned %d for %*.*s\n", ret, len, len, cp); if (ret > 0) ret = 1; return ret; }
static int dnsmq_ctrl_ipv6(struct file *file, const char *buffer, unsigned long length, void *data) { char s[64]; char *ptr; int i, j; // "[dnsmq ipv6] [dnsmq name] if ((length > 0) && (length < 64)) { memcpy(s, buffer, length); s[length] = 0; for(i=0;i<length;i++) { if (s[i] == ' ') break; } if (i<length) { s[i] = 0; ptr = s + i + 1; in6_pton(s, length, (void *)&dnsmq_ipv6, '\n', NULL); // convert to dnsname format j=0; for(;i<length;i++) { if (s[i] == '.') { s[i]=0; dnsmq_name_ipv6[j]=strlen(ptr); memcpy(dnsmq_name_ipv6+j+1, ptr, strlen(ptr)); j += strlen(ptr) + 1; ptr = s + i + 1; } } dnsmq_name_ipv6[j]=strlen(ptr); memcpy(dnsmq_name_ipv6+j+1, ptr, strlen(ptr)); dnsmq_name_ipv6[j+1+strlen(ptr)]=0; } } else memset(&dnsmq_ipv6, 0, sizeof(struct in6_addr)); printk(KERN_DEBUG "dnsmq ctrl ipv6: %pI6 %s\n", &dnsmq_ipv6, dnsmq_name_ipv6); if (ipv6_addr_equal(&dnsmq_ipv6, &in6addr_any)) dnsmq_hit_hook_func (NULL); else dnsmq_hit_hook_func(dnsmq_func); return length; }
int ofe_inet_pton(int af, const char* src, void* dst) { if( af == AF_INET ) { const char* end = NULL; if( in4_pton(src, -1, dst, -1, &end) == 1 && *end == '\0' ) return 1; else return 0; } else if( af == AF_INET6 ) { const char* end = NULL; if( in6_pton(src, -1, dst, -1, &end) == 1 && *end == '\0' ) return 1; else return 0; } else { return -1; } }
/** * Default configuration, until it be set up by the user space application. * * @return TRUE if all was fine, FALSE otherwise. */ bool nat64_config_init(void) { struct ipv6_prefixes ip6p; struct in_addr ipv4_pool_net; struct in_addr ipv4_pool_range_first; struct in_addr ipv4_pool_range_last; int ipv4_mask_bits; __be32 ipv4_netmask; // TODO change data type -> 'in_addr' type. Rob. // TODO: Define & Set values for operational parameters: cs.address_dependent_filtering = 0; //<<< TODO: Use a define for this value! cs.filter_informational_icmpv6 = 0; //<<< TODO: Use a define for this value! cs.hairpinning_mode = 0; /* IPv4 pool config */ // Validate IPv4 Pool Network if (! in4_pton(IPV4_DEF_POOL_NET, -1, (u8 *)&ipv4_pool_net.s_addr, '\x0', NULL)) { pr_warning("NAT64: IPv4 pool net in Headers is malformed [%s].", IPV4_DEF_POOL_NET); return false; } // Validate IPv4 Pool - Netmask ipv4_mask_bits = IPV4_DEF_POOL_NET_MASK_BITS; // Num. of bits 'on' in the net mask if (ipv4_mask_bits > 32 || ipv4_mask_bits < 1) { pr_warning("NAT64: IPv4 Pool netmask bits value is invalid [%d].", IPV4_DEF_POOL_NET_MASK_BITS); return false; } ipv4_netmask = inet_make_mask(ipv4_mask_bits); ipv4_pool_net.s_addr = ipv4_pool_net.s_addr & ipv4_netmask; // For the sake of correctness // Validate IPv4 Pool - First and Last addresses . if (! in4_pton(IPV4_DEF_POOL_FIRST, -1, (u8 *)&ipv4_pool_range_first.s_addr, '\x0', NULL)) { pr_warning("NAT64: IPv4 pool net in Headers is malformed [%s].", IPV4_DEF_POOL_FIRST); return false; } if (! in4_pton(IPV4_DEF_POOL_LAST, -1, (u8 *)&ipv4_pool_range_last.s_addr, '\x0', NULL)) { pr_warning("NAT64: IPv4 pool net in Headers is malformed [%s].", IPV4_DEF_POOL_LAST); return false; } // Assing IPv4 values to config struct. cs.ipv4_pool_net = ipv4_pool_net; cs.ipv4_pool_net_mask_bits = ipv4_mask_bits; cs.ipv4_pool_range_first = ipv4_pool_range_first; cs.ipv4_pool_range_last = ipv4_pool_range_last; /* IPv6 pool config */ // Validate IPv6 prefix if (! in6_pton(IPV6_DEF_PREFIX, -1, (u8 *)&(ip6p.addr), '\0', NULL)) { pr_warning("NAT64: IPv6 prefix in Headers is malformed [%s].", IPV6_DEF_PREFIX); return false; } if (IPV6_DEF_MASKBITS > IPV6_DEF_MASKBITS_MAX || IPV6_DEF_MASKBITS < IPV6_DEF_MASKBITS_MIN) { pr_warning("NAT64: Bad IPv6 network mask bits value in Headers: %d\n", IPV6_DEF_MASKBITS); return false; } ip6p.maskbits = IPV6_DEF_MASKBITS; // Allocate memory for IPv6 prefix cs.ipv6_net_prefixes = (struct ipv6_prefixes**) kmalloc(1*sizeof(struct ipv6_prefixes*), GFP_ATOMIC); cs.ipv6_net_prefixes[0] = (struct ipv6_prefixes*) kmalloc(sizeof(struct ipv6_prefixes), GFP_ATOMIC); // Store values in config struct (*cs.ipv6_net_prefixes[0]) = ip6p; cs.ipv6_net_prefixes_qty = 1; pr_debug("NAT64: Initial (default) configuration loaded:"); pr_debug("NAT64: using IPv4 pool subnet %pI4/%d (netmask %pI4),", &(cs.ipv4_pool_net), cs.ipv4_pool_net_mask_bits, &ipv4_netmask); pr_debug("NAT64: and IPv6 prefix %pI6c/%d.", &(cs.ipv6_net_prefixes[0]->addr), cs.ipv6_net_prefixes[0]->maskbits); /* Translate the packet config. */ config.packet_head_room = 0; config.packet_tail_room = 32; config.override_ipv6_traffic_class = false; config.override_ipv4_traffic_class = false; config.ipv4_traffic_class = 0; config.df_always_set = true; config.generate_ipv4_id = false; config.improve_mtu_failure_rate = true; config.ipv6_nexthop_mtu = 1280; config.ipv4_nexthop_mtu = 576; config.mtu_plateau_count = ARRAY_SIZE(DEFAULT_MTU_PLATEAUS); config.mtu_plateaus = kmalloc(sizeof(DEFAULT_MTU_PLATEAUS), GFP_ATOMIC); if (!config.mtu_plateaus) { pr_warning("Could not allocate memory to store the MTU plateaus.\n"); return false; } memcpy(config.mtu_plateaus, &DEFAULT_MTU_PLATEAUS, sizeof(DEFAULT_MTU_PLATEAUS)); /* Netlink sockets. */ // Create netlink socket, register 'my_nl_rcv_msg' as callback function. struct netlink_kernel_cfg cfg = { .input = &my_nl_rcv_msg, }; my_nl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, &cfg); if (!my_nl_sock) { pr_warning("NAT64: %s: Creation of netlink socket failed.\n", __func__); return false; } pr_debug("NAT64: Netlink socket created.\n"); return true; // Alles Klar! }