buildTCPIPFilterCheckFromLocalVars creates a filter using local vars $s0-$s3 and $d0-$d3. This is required because the BPF verifier doesn't allow reading from different offsets of args after a probe_read. We read bytes into local vars first, then filter. SECURITY: IPs are converted to integer byte v
()
| 513 | // offsets of args after a probe_read. We read bytes into local vars first, then filter. |
| 514 | // SECURITY: IPs are converted to integer byte values - no string interpolation. |
| 515 | func (g *ScriptGenerator) buildTCPIPFilterCheckFromLocalVars() string { |
| 516 | if len(g.config.FilterIPs) == 0 && len(g.config.FilterCIDRs) == 0 { |
| 517 | return "" // No filter |
| 518 | } |
| 519 | |
| 520 | var conditions []string |
| 521 | |
| 522 | // Add IP filters - compare using local vars |
| 523 | for _, ip := range g.config.FilterIPs { |
| 524 | ipv4 := ip.To4() |
| 525 | if ipv4 == nil { |
| 526 | continue |
| 527 | } |
| 528 | // Match either source or destination using local vars |
| 529 | conditions = append(conditions, fmt.Sprintf( |
| 530 | "(($s0 == %d && $s1 == %d && $s2 == %d && $s3 == %d) || ($d0 == %d && $d1 == %d && $d2 == %d && $d3 == %d))", |
| 531 | ipv4[0], ipv4[1], ipv4[2], ipv4[3], |
| 532 | ipv4[0], ipv4[1], ipv4[2], ipv4[3])) |
| 533 | } |
| 534 | |
| 535 | // Add CIDR filters - mask and compare using local vars |
| 536 | for _, cidr := range g.config.FilterCIDRs { |
| 537 | if cidr == nil { |
| 538 | continue |
| 539 | } |
| 540 | ipv4 := cidr.IP.To4() |
| 541 | mask := cidr.Mask |
| 542 | if ipv4 == nil || len(mask) != 4 { |
| 543 | continue |
| 544 | } |
| 545 | // (byte & mask) == network_byte for each byte |
| 546 | conditions = append(conditions, fmt.Sprintf( |
| 547 | "((($s0 & %d) == %d && ($s1 & %d) == %d && ($s2 & %d) == %d && ($s3 & %d) == %d) || (($d0 & %d) == %d && ($d1 & %d) == %d && ($d2 & %d) == %d && ($d3 & %d) == %d))", |
| 548 | mask[0], ipv4[0], mask[1], ipv4[1], mask[2], ipv4[2], mask[3], ipv4[3], |
| 549 | mask[0], ipv4[0], mask[1], ipv4[1], mask[2], ipv4[2], mask[3], ipv4[3])) |
| 550 | } |
| 551 | |
| 552 | if len(conditions) == 0 { |
| 553 | return "" |
| 554 | } |
| 555 | |
| 556 | // Generate an if-statement that returns early if no condition matches |
| 557 | combined := strings.Join(conditions, " || ") |
| 558 | return fmt.Sprintf(" // IP/CIDR filter: skip if not matching\n if (!(%s)) { return; }\n\n", combined) |
| 559 | } |
| 560 | |
| 561 | // generateTableOutput generates printf for table format. |
| 562 | func (g *ScriptGenerator) generateTableOutput() string { |
no outgoing calls
no test coverage detected