| 183 | #define NAT64CLAT_HAS_CLAT_PREFIX 0x01 |
| 184 | #define NAT64CLAT_HAS_PLAT_PREFIX 0x02 |
| 185 | static void |
| 186 | nat64clat_create(const char *name, uint8_t set, int ac, char *av[]) |
| 187 | { |
| 188 | char buf[sizeof(ipfw_obj_lheader) + sizeof(ipfw_nat64clat_cfg)]; |
| 189 | ipfw_nat64clat_cfg *cfg; |
| 190 | ipfw_obj_lheader *olh; |
| 191 | int tcmd, flags; |
| 192 | char *p; |
| 193 | struct in6_addr prefix; |
| 194 | uint8_t plen; |
| 195 | |
| 196 | memset(buf, 0, sizeof(buf)); |
| 197 | olh = (ipfw_obj_lheader *)buf; |
| 198 | cfg = (ipfw_nat64clat_cfg *)(olh + 1); |
| 199 | |
| 200 | /* Some reasonable defaults */ |
| 201 | inet_pton(AF_INET6, "64:ff9b::", &cfg->plat_prefix); |
| 202 | cfg->plat_plen = 96; |
| 203 | cfg->set = set; |
| 204 | flags = NAT64CLAT_HAS_PLAT_PREFIX; |
| 205 | while (ac > 0) { |
| 206 | tcmd = get_token(nat64newcmds, *av, "option"); |
| 207 | ac--; av++; |
| 208 | |
| 209 | switch (tcmd) { |
| 210 | case TOK_PLAT_PREFIX: |
| 211 | case TOK_CLAT_PREFIX: |
| 212 | if (tcmd == TOK_PLAT_PREFIX) { |
| 213 | NEED1("IPv6 plat_prefix required"); |
| 214 | } else { |
| 215 | NEED1("IPv6 clat_prefix required"); |
| 216 | } |
| 217 | |
| 218 | if ((p = strchr(*av, '/')) != NULL) |
| 219 | *p++ = '\0'; |
| 220 | if (inet_pton(AF_INET6, *av, &prefix) != 1) |
| 221 | errx(EX_USAGE, |
| 222 | "Bad prefix: %s", *av); |
| 223 | plen = strtol(p, NULL, 10); |
| 224 | if (ipfw_check_nat64prefix(&prefix, plen) != 0) |
| 225 | errx(EX_USAGE, |
| 226 | "Bad prefix length: %s", p); |
| 227 | if (tcmd == TOK_PLAT_PREFIX) { |
| 228 | flags |= NAT64CLAT_HAS_PLAT_PREFIX; |
| 229 | cfg->plat_prefix = prefix; |
| 230 | cfg->plat_plen = plen; |
| 231 | } else { |
| 232 | flags |= NAT64CLAT_HAS_CLAT_PREFIX; |
| 233 | cfg->clat_prefix = prefix; |
| 234 | cfg->clat_plen = plen; |
| 235 | } |
| 236 | ac--; av++; |
| 237 | break; |
| 238 | case TOK_LOG: |
| 239 | cfg->flags |= NAT64_LOG; |
| 240 | break; |
| 241 | case TOK_LOGOFF: |
| 242 | cfg->flags &= ~NAT64_LOG; |
no test coverage detected