|
Lines 382-388
iface_match(struct ifnet *ifp, ipfw_insn_if *cmd,
Link Here
|
| 382 |
/* Check by name or by IP address */ |
382 |
/* Check by name or by IP address */ |
| 383 |
if (cmd->name[0] != '\0') { /* match by name */ |
383 |
if (cmd->name[0] != '\0') { /* match by name */ |
| 384 |
if (cmd->name[0] == '\1') /* use tablearg to match */ |
384 |
if (cmd->name[0] == '\1') /* use tablearg to match */ |
| 385 |
return ipfw_lookup_table_extended(chain, cmd->p.kidx, 0, |
385 |
return ipfw_lookup_table(chain, cmd->p.kidx, 0, |
| 386 |
&ifp->if_index, tablearg); |
386 |
&ifp->if_index, tablearg); |
| 387 |
/* Check name */ |
387 |
/* Check name */ |
| 388 |
if (cmd->p.glob) { |
388 |
if (cmd->p.glob) { |
|
Lines 1454-1541
do { \
Link Here
|
| 1454 |
src_ip.s_addr); |
1454 |
src_ip.s_addr); |
| 1455 |
break; |
1455 |
break; |
| 1456 |
|
1456 |
|
| 1457 |
case O_IP_SRC_LOOKUP: |
|
|
| 1458 |
case O_IP_DST_LOOKUP: |
1457 |
case O_IP_DST_LOOKUP: |
| 1459 |
if (is_ipv4) { |
1458 |
{ |
| 1460 |
uint32_t key = |
1459 |
void *pkey; |
| 1461 |
(cmd->opcode == O_IP_DST_LOOKUP) ? |
1460 |
uint32_t vidx, key; |
| 1462 |
dst_ip.s_addr : src_ip.s_addr; |
1461 |
uint16_t keylen; |
| 1463 |
uint32_t v = 0; |
|
|
| 1464 |
|
1462 |
|
| 1465 |
if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { |
1463 |
if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { |
| 1466 |
/* generic lookup. The key must be |
1464 |
/* Determine lookup key type */ |
| 1467 |
* in 32bit big-endian format. |
1465 |
vidx = ((ipfw_insn_u32 *)cmd)->d[1]; |
| 1468 |
*/ |
1466 |
if (vidx != 4 /* uid */ && |
| 1469 |
v = ((ipfw_insn_u32 *)cmd)->d[1]; |
1467 |
vidx != 5 /* jail */ && |
| 1470 |
if (v == 0) |
1468 |
is_ipv6 == 0 && is_ipv4 == 0) |
| 1471 |
key = dst_ip.s_addr; |
1469 |
break; |
| 1472 |
else if (v == 1) |
1470 |
/* Determine key length */ |
| 1473 |
key = src_ip.s_addr; |
1471 |
if (vidx == 0 /* dst-ip */ || |
| 1474 |
else if (v == 6) /* dscp */ |
1472 |
vidx == 1 /* src-ip */) |
| 1475 |
key = (ip->ip_tos >> 2) & 0x3f; |
1473 |
keylen = is_ipv6 ? |
| 1476 |
else if (offset != 0) |
1474 |
sizeof(struct in6_addr): |
| 1477 |
break; |
1475 |
sizeof(in_addr_t); |
| 1478 |
else if (proto != IPPROTO_TCP && |
1476 |
else { |
| 1479 |
proto != IPPROTO_UDP) |
1477 |
keylen = sizeof(key); |
| 1480 |
break; |
1478 |
pkey = &key; |
| 1481 |
else if (v == 2) |
1479 |
} |
| 1482 |
key = dst_port; |
1480 |
if (vidx == 0 /* dst-ip */) |
| 1483 |
else if (v == 3) |
1481 |
pkey = is_ipv4 ? (void *)&dst_ip: |
| 1484 |
key = src_port; |
1482 |
(void *)&args->f_id.dst_ip6; |
|
|
1483 |
else if (vidx == 1 /* src-ip */) |
| 1484 |
pkey = is_ipv4 ? (void *)&src_ip: |
| 1485 |
(void *)&args->f_id.src_ip6; |
| 1486 |
else if (vidx == 6 /* dscp */) { |
| 1487 |
if (is_ipv4) |
| 1488 |
key = ip->ip_tos >> 2; |
| 1489 |
else { |
| 1490 |
key = args->f_id.flow_id6; |
| 1491 |
key = (key & 0x0f) << 2 | |
| 1492 |
(key & 0xf000) >> 14; |
| 1493 |
} |
| 1494 |
key &= 0x3f; |
| 1495 |
} else if (vidx == 2 /* dst-port */ || |
| 1496 |
vidx == 3 /* src-port */) { |
| 1497 |
/* Skip fragments */ |
| 1498 |
if (offset != 0) |
| 1499 |
break; |
| 1500 |
/* Skip proto without ports */ |
| 1501 |
if (proto != IPPROTO_TCP && |
| 1502 |
proto != IPPROTO_UDP && |
| 1503 |
proto != IPPROTO_SCTP) |
| 1504 |
break; |
| 1505 |
if (vidx == 2 /* dst-port */) |
| 1506 |
key = dst_port; |
| 1507 |
else |
| 1508 |
key = src_port; |
| 1509 |
} |
| 1485 |
#ifndef USERSPACE |
1510 |
#ifndef USERSPACE |
| 1486 |
else if (v == 4 || v == 5) { |
1511 |
else if (vidx == 4 /* uid */ || |
| 1487 |
check_uidgid( |
1512 |
vidx == 5 /* jail */) { |
| 1488 |
(ipfw_insn_u32 *)cmd, |
1513 |
check_uidgid( |
| 1489 |
args, &ucred_lookup, |
1514 |
(ipfw_insn_u32 *)cmd, |
|
|
1515 |
args, &ucred_lookup, |
| 1490 |
#ifdef __FreeBSD__ |
1516 |
#ifdef __FreeBSD__ |
| 1491 |
&ucred_cache); |
1517 |
&ucred_cache); |
| 1492 |
if (v == 4 /* O_UID */) |
1518 |
if (vidx == 4 /* uid */) |
| 1493 |
key = ucred_cache->cr_uid; |
1519 |
key = ucred_cache->cr_uid; |
| 1494 |
else if (v == 5 /* O_JAIL */) |
1520 |
else if (vidx == 5 /* jail */) |
| 1495 |
key = ucred_cache->cr_prison->pr_id; |
1521 |
key = ucred_cache->cr_prison->pr_id; |
| 1496 |
#else /* !__FreeBSD__ */ |
1522 |
#else /* !__FreeBSD__ */ |
| 1497 |
(void *)&ucred_cache); |
1523 |
(void *)&ucred_cache); |
| 1498 |
if (v ==4 /* O_UID */) |
1524 |
if (vidx == 4 /* uid */) |
| 1499 |
key = ucred_cache.uid; |
1525 |
key = ucred_cache.uid; |
| 1500 |
else if (v == 5 /* O_JAIL */) |
1526 |
else if (vidx == 5 /* jail */) |
| 1501 |
key = ucred_cache.xid; |
1527 |
key = ucred_cache.xid; |
| 1502 |
#endif /* !__FreeBSD__ */ |
1528 |
#endif /* !__FreeBSD__ */ |
| 1503 |
} |
1529 |
} |
| 1504 |
#endif /* !USERSPACE */ |
1530 |
#endif /* !USERSPACE */ |
| 1505 |
else |
1531 |
else |
| 1506 |
break; |
1532 |
break; |
| 1507 |
} |
1533 |
match = ipfw_lookup_table(chain, |
| 1508 |
match = ipfw_lookup_table(chain, |
1534 |
cmd->arg1, keylen, pkey, &vidx); |
| 1509 |
cmd->arg1, key, &v); |
1535 |
if (!match) |
| 1510 |
if (!match) |
1536 |
break; |
|
|
1537 |
tablearg = vidx; |
| 1511 |
break; |
1538 |
break; |
| 1512 |
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) |
1539 |
} |
| 1513 |
match = |
1540 |
/* cmdlen =< F_INSN_SIZE(ipfw_insn_u32) */ |
| 1514 |
((ipfw_insn_u32 *)cmd)->d[0] == v; |
1541 |
/* FALLTHROUGH */ |
| 1515 |
else |
1542 |
} |
| 1516 |
tablearg = v; |
1543 |
case O_IP_SRC_LOOKUP: |
|
|
1544 |
{ |
| 1545 |
void *pkey; |
| 1546 |
uint32_t vidx; |
| 1547 |
uint16_t keylen; |
| 1548 |
|
| 1549 |
if (is_ipv4) { |
| 1550 |
keylen = sizeof(in_addr_t); |
| 1551 |
if (cmd->opcode == O_IP_DST_LOOKUP) |
| 1552 |
pkey = &dst_ip; |
| 1553 |
else |
| 1554 |
pkey = &src_ip; |
| 1517 |
} else if (is_ipv6) { |
1555 |
} else if (is_ipv6) { |
| 1518 |
uint32_t v = 0; |
1556 |
keylen = sizeof(struct in6_addr); |
| 1519 |
void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ? |
1557 |
if (cmd->opcode == O_IP_DST_LOOKUP) |
| 1520 |
&args->f_id.dst_ip6: &args->f_id.src_ip6; |
1558 |
pkey = &args->f_id.dst_ip6; |
| 1521 |
match = ipfw_lookup_table_extended(chain, |
1559 |
else |
| 1522 |
cmd->arg1, |
1560 |
pkey = &args->f_id.src_ip6; |
| 1523 |
sizeof(struct in6_addr), |
1561 |
} else |
| 1524 |
pkey, &v); |
1562 |
break; |
| 1525 |
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) |
1563 |
match = ipfw_lookup_table(chain, cmd->arg1, |
| 1526 |
match = ((ipfw_insn_u32 *)cmd)->d[0] == v; |
1564 |
keylen, pkey, &vidx); |
| 1527 |
if (match) |
1565 |
if (!match) |
| 1528 |
tablearg = v; |
1566 |
break; |
|
|
1567 |
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) { |
| 1568 |
match = ((ipfw_insn_u32 *)cmd)->d[0] == |
| 1569 |
TARG_VAL(chain, vidx, tag); |
| 1570 |
if (!match) |
| 1571 |
break; |
| 1529 |
} |
1572 |
} |
|
|
1573 |
tablearg = vidx; |
| 1530 |
break; |
1574 |
break; |
|
|
1575 |
} |
| 1531 |
|
1576 |
|
| 1532 |
case O_IP_FLOW_LOOKUP: |
1577 |
case O_IP_FLOW_LOOKUP: |
| 1533 |
{ |
1578 |
{ |
| 1534 |
uint32_t v = 0; |
1579 |
uint32_t v = 0; |
| 1535 |
match = ipfw_lookup_table_extended(chain, |
1580 |
match = ipfw_lookup_table(chain, |
| 1536 |
cmd->arg1, 0, &args->f_id, &v); |
1581 |
cmd->arg1, 0, &args->f_id, &v); |
| 1537 |
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) |
1582 |
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) |
| 1538 |
match = ((ipfw_insn_u32 *)cmd)->d[0] == v; |
1583 |
match = ((ipfw_insn_u32 *)cmd)->d[0] == |
|
|
1584 |
TARG_VAL(chain, v, tag); |
| 1539 |
if (match) |
1585 |
if (match) |
| 1540 |
tablearg = v; |
1586 |
tablearg = v; |
| 1541 |
} |
1587 |
} |