| 1503 | } |
| 1504 | |
| 1505 | static void |
| 1506 | tentry_fill_value(ipfw_obj_header *oh __unused, ipfw_obj_tentry *tent, |
| 1507 | char *arg, uint8_t type __unused, uint32_t vmask) |
| 1508 | { |
| 1509 | struct addrinfo hints, *res; |
| 1510 | struct in_addr ipaddr; |
| 1511 | const char *etype; |
| 1512 | char *comma, *e, *n, *p; |
| 1513 | uint32_t a4, flag, val; |
| 1514 | ipfw_table_value *v; |
| 1515 | uint32_t i; |
| 1516 | int dval; |
| 1517 | |
| 1518 | v = &tent->v.value; |
| 1519 | |
| 1520 | /* Compat layer: keep old behavior for legacy value types */ |
| 1521 | if (vmask == IPFW_VTYPE_LEGACY) { |
| 1522 | /* Try to interpret as number first */ |
| 1523 | val = strtoul(arg, &p, 0); |
| 1524 | if (*p == '\0') { |
| 1525 | set_legacy_value(val, v); |
| 1526 | return; |
| 1527 | } |
| 1528 | if (inet_pton(AF_INET, arg, &val) == 1) { |
| 1529 | set_legacy_value(ntohl(val), v); |
| 1530 | return; |
| 1531 | } |
| 1532 | /* Try hostname */ |
| 1533 | if (lookup_host(arg, &ipaddr) == 0) { |
| 1534 | set_legacy_value(ntohl(ipaddr.s_addr), v); |
| 1535 | return; |
| 1536 | } |
| 1537 | errx(EX_OSERR, "Unable to parse value %s", arg); |
| 1538 | } |
| 1539 | |
| 1540 | /* |
| 1541 | * Shorthands: handle single value if vmask consists |
| 1542 | * of numbers only. e.g.: |
| 1543 | * vmask = "fib,skipto" -> treat input "1" as "1,1" |
| 1544 | */ |
| 1545 | |
| 1546 | n = arg; |
| 1547 | etype = NULL; |
| 1548 | for (i = 1; i < (1u << 31); i *= 2) { |
| 1549 | if ((flag = (vmask & i)) == 0) |
| 1550 | continue; |
| 1551 | vmask &= ~flag; |
| 1552 | |
| 1553 | if ((comma = strchr(n, ',')) != NULL) |
| 1554 | *comma = '\0'; |
| 1555 | |
| 1556 | switch (flag) { |
| 1557 | case IPFW_VTYPE_TAG: |
| 1558 | v->tag = strtol(n, &e, 10); |
| 1559 | if (*e != '\0') |
| 1560 | etype = "tag"; |
| 1561 | break; |
| 1562 | case IPFW_VTYPE_PIPE: |
no test coverage detected