* fill the addr and mask fields in the instruction as appropriate from av. * Update length as appropriate. * The following formats are allowed: * any matches any IP6. Actually returns an empty instruction. * me returns O_IP6_*_ME * * 03f1::234:123:0342 single IP6 address * 03f1::234:123:0342/24 address/masklen * 03f1::234:123:0342/ffff::ffff:ffff address/ma
| 338 | * Return 1 on success, 0 on failure. |
| 339 | */ |
| 340 | static int |
| 341 | fill_ip6(ipfw_insn_ip6 *cmd, char *av, int cblen, struct tidx *tstate) |
| 342 | { |
| 343 | int len = 0; |
| 344 | struct in6_addr *d = &(cmd->addr6); |
| 345 | char *oav; |
| 346 | /* |
| 347 | * Needed for multiple address. |
| 348 | * Note d[1] points to struct in6_add r mask6 of cmd |
| 349 | */ |
| 350 | |
| 351 | cmd->o.len &= ~F_LEN_MASK; /* zero len */ |
| 352 | |
| 353 | if (strcmp(av, "any") == 0) |
| 354 | return (1); |
| 355 | |
| 356 | /* Set the data for "me" opt */ |
| 357 | if (strcmp(av, "me") == 0 || strcmp(av, "me6") == 0) { |
| 358 | cmd->o.len |= F_INSN_SIZE(ipfw_insn); |
| 359 | return (1); |
| 360 | } |
| 361 | |
| 362 | if (strncmp(av, "table(", 6) == 0) { |
| 363 | fill_table(&cmd->o, av, O_IP_DST_LOOKUP, tstate); |
| 364 | return (1); |
| 365 | } |
| 366 | |
| 367 | oav = av = strdup(av); |
| 368 | while (av) { |
| 369 | /* |
| 370 | * After the address we can have '/' indicating a mask, |
| 371 | * or ',' indicating another address follows. |
| 372 | */ |
| 373 | |
| 374 | char *p, *q; |
| 375 | int masklen; |
| 376 | char md = '\0'; |
| 377 | |
| 378 | CHECK_LENGTH(cblen, |
| 379 | 1 + len + 2 * (int)F_INSN_SIZE(struct in6_addr)); |
| 380 | |
| 381 | if ((q = strchr(av, ',')) ) { |
| 382 | *q = '\0'; |
| 383 | q++; |
| 384 | } |
| 385 | |
| 386 | if ((p = strchr(av, '/')) ) { |
| 387 | md = *p; /* save the separator */ |
| 388 | *p = '\0'; /* terminate address string */ |
| 389 | p++; /* and skip past it */ |
| 390 | } |
| 391 | /* now p points to NULL, mask or next entry */ |
| 392 | |
| 393 | /* lookup stores address in *d as a side effect */ |
| 394 | if (lookup_host6(av, d) != 0) { |
| 395 | /* XXX: failed. Free memory and go */ |
| 396 | errx(EX_DATAERR, "bad address \"%s\"", av); |
| 397 | } |
no test coverage detected