LCOV - code coverage report
Current view: top level - bpfilter/xlate/ipt - dump.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 98 0
Test Date: 2025-09-16 14:46:44 Functions: 0.0 % 5 0

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-2.0-only */
       2              : /*
       3              :  * Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
       4              :  */
       5              : 
       6              : #include "dump.h"
       7              : 
       8              : #include <linux/netfilter.h>
       9              : #include <linux/netfilter/x_tables.h>
      10              : #include <linux/netfilter_ipv4/ip_tables.h>
      11              : 
      12              : #include <stdbool.h>
      13              : #include <stdint.h>
      14              : #include <stdio.h>
      15              : 
      16              : #include <bpfilter/dump.h>
      17              : #include <bpfilter/helper.h>
      18              : 
      19              : #include "xlate/ipt/helpers.h"
      20              : 
      21              : /**
      22              :  * Map each hook to its name as a string.
      23              :  */
      24              : static const char *hook_name[] = {
      25              :     [NF_INET_PRE_ROUTING] = "PRE_ROUTING",   [NF_INET_LOCAL_IN] = "LOCAL_IN",
      26              :     [NF_INET_FORWARD] = "FORWARD",           [NF_INET_LOCAL_OUT] = "LOCAL_OUT",
      27              :     [NF_INET_POST_ROUTING] = "POST_ROUTING",
      28              : };
      29              : 
      30              : /**
      31              :  * Map each target to its name as a string.
      32              :  */
      33              : static const char *target_name[] = {
      34              :     [NF_DROP] = "DROP",   [NF_ACCEPT] = "ACCEPT", [NF_STOLEN] = "STOLEN",
      35              :     [NF_QUEUE] = "QUEUE", [NF_REPEAT] = "REPEAT", [NF_STOP] = "STOP",
      36              : };
      37              : 
      38              : /**
      39              :  * Dump content of @p ipt_counters structure.
      40              :  *
      41              :  * @param counters @p ipt_counters structure. Must be non-NULL.
      42              :  * @param prefix @p log_prefix structure.
      43              :  */
      44            0 : static inline void ipt_dump_counters(const struct ipt_counters *counters,
      45              :                                      prefix_t *prefix)
      46              : {
      47            0 :     bf_assert(counters && prefix);
      48              : 
      49            0 :     DUMP(prefix, "struct ipt_counters at %p", counters);
      50            0 : }
      51              : 
      52              : /**
      53              :  * Dump content of @p ipt_ip structure.
      54              :  *
      55              :  * @param ip @p ipt_ip structure. Must be non-NULL.
      56              :  * @param prefix @p log_prefix structure.
      57              :  */
      58            0 : static void ipt_dump_ip(const struct ipt_ip *ip, prefix_t *prefix)
      59              : {
      60            0 :     bf_assert(ip && prefix);
      61              : 
      62            0 :     DUMP(prefix, "struct ipt_ip at %p", ip);
      63              : 
      64            0 :     bf_dump_prefix_push(prefix);
      65            0 :     DUMP(prefix, "src: " IP4_FMT, IP4_SPLIT(ip->src));
      66            0 :     DUMP(prefix, "dst: " IP4_FMT, IP4_SPLIT(ip->dst));
      67            0 :     DUMP(prefix, "src_mask: " IP4_FMT, IP4_SPLIT(ip->smsk));
      68            0 :     DUMP(prefix, "dst_mask: " IP4_FMT, IP4_SPLIT(ip->dmsk));
      69            0 :     DUMP(prefix, "in_iface: %s", ip->iniface);
      70            0 :     DUMP(prefix, "out_iface: %s", ip->outiface);
      71            0 :     DUMP(prefix, "in_iface_mask: %s", ip->iniface_mask);
      72            0 :     DUMP(prefix, "out_iface_mask: %s", ip->outiface_mask);
      73            0 :     DUMP(prefix, "protocol: %d", ip->proto);
      74            0 :     DUMP(prefix, "flags: %d", ip->flags);
      75            0 :     DUMP(bf_dump_prefix_last(prefix), "invflags: %d", ip->invflags);
      76            0 :     bf_dump_prefix_pop(prefix);
      77            0 : }
      78              : 
      79              : /**
      80              :  * Dump content of @p ipt_entry_match structure.
      81              :  *
      82              :  * @param match @p ipt_entry_match structure. Must be non-NULL.
      83              :  * @param prefix @p log_prefix structure.
      84              :  */
      85            0 : static void ipt_dump_match(const struct ipt_entry_match *match,
      86              :                            prefix_t *prefix)
      87              : {
      88            0 :     bf_assert(match && prefix);
      89              : 
      90            0 :     DUMP(prefix, "struct ipt_entry_match at %p", match);
      91              : 
      92            0 :     bf_dump_prefix_push(prefix);
      93            0 :     DUMP(prefix, "user:");
      94            0 :     DUMP(prefix, "match_size: %d", match->u.user.match_size);
      95            0 :     DUMP(prefix, "name: %s", match->u.user.name);
      96            0 :     DUMP(prefix, "revision: %d", match->u.user.revision);
      97            0 :     DUMP(prefix, "kernel:");
      98            0 :     DUMP(prefix, "match_size: %d", match->u.kernel.match_size);
      99            0 :     DUMP(prefix, "match at %p", match->u.kernel.match);
     100            0 :     DUMP(bf_dump_prefix_last(prefix), "match_size: %d", match->u.match_size);
     101            0 :     bf_dump_prefix_pop(prefix);
     102            0 : }
     103              : 
     104              : static inline int _bf_ipt_convert_verdict(int verdict)
     105              : {
     106            0 :     return -verdict - 1;
     107              : }
     108              : 
     109              : /**
     110              :  * Dump content of @p ipt_entry_target structure.
     111              :  *
     112              :  * @param target @p ipt_entry_target structure. Must be non-NULL.
     113              :  * @param prefix @p log_prefix structure.
     114              :  */
     115            0 : static void ipt_dump_target(const struct ipt_entry_target *target,
     116              :                             prefix_t *prefix)
     117              : {
     118              :     bool is_standard;
     119              :     struct ipt_standard_target *std_target = (void *)target;
     120              : 
     121            0 :     bf_assert(target && prefix);
     122              : 
     123            0 :     is_standard = bf_streq(target->u.user.name, "");
     124              : 
     125            0 :     DUMP(prefix, "struct ipt_entry_target at %p", target);
     126              : 
     127            0 :     bf_dump_prefix_push(prefix);
     128            0 :     DUMP(prefix, "user:");
     129              : 
     130            0 :     bf_dump_prefix_push(prefix);
     131            0 :     DUMP(prefix, "target_size: %d", target->u.user.target_size);
     132            0 :     DUMP(prefix, "name: '%s'", target->u.user.name);
     133            0 :     DUMP(bf_dump_prefix_last(prefix), "revision: %d", target->u.user.revision);
     134            0 :     bf_dump_prefix_pop(prefix);
     135              : 
     136            0 :     DUMP(prefix, "kernel:");
     137              : 
     138            0 :     bf_dump_prefix_push(prefix);
     139            0 :     DUMP(prefix, "target_size: %d", target->u.kernel.target_size);
     140            0 :     DUMP(bf_dump_prefix_last(prefix), "target: %p", target->u.kernel.target);
     141            0 :     bf_dump_prefix_pop(prefix);
     142              : 
     143            0 :     DUMP((is_standard ? prefix : bf_dump_prefix_last(prefix)),
     144              :          "target_size: %d", target->u.target_size);
     145            0 :     if (is_standard) {
     146            0 :         DUMP(bf_dump_prefix_last(prefix), "verdict: %s",
     147              :              target_name[_bf_ipt_convert_verdict(std_target->verdict)]);
     148              :     }
     149              : 
     150            0 :     bf_dump_prefix_pop(prefix);
     151            0 : }
     152              : 
     153            0 : void bf_ipt_dump_replace(const struct ipt_replace *ipt, prefix_t *prefix)
     154              : {
     155              :     int i;
     156              :     uint32_t offset;
     157              :     struct ipt_entry *first_rule;
     158              :     struct ipt_entry *last_rule;
     159              : 
     160            0 :     bf_assert(ipt && prefix);
     161              : 
     162            0 :     DUMP(prefix, "struct ipt_replace at %p", ipt);
     163              : 
     164            0 :     bf_dump_prefix_push(prefix);
     165              : 
     166            0 :     DUMP(prefix, "name: '%s'", ipt->name);
     167            0 :     DUMP(prefix, "valid_hooks: " BIN_FMT "", BIN_SPLIT(ipt->valid_hooks));
     168            0 :     DUMP(prefix, "num_entries: %d", ipt->num_entries);
     169            0 :     DUMP(prefix, "size: %d", ipt->size);
     170            0 :     DUMP(bf_dump_prefix_last(prefix), "struct ipt_entry at %p", ipt->entries);
     171              : 
     172            0 :     bf_dump_prefix_push(prefix);
     173              : 
     174              :     // Loop over each hook to print its rules (if defined).
     175            0 :     for (i = 0; i < NF_INET_NUMHOOKS; ++i) {
     176            0 :         if (i == NF_INET_POST_ROUTING)
     177            0 :             bf_dump_prefix_last(prefix);
     178              : 
     179            0 :         if (!ipt_is_hook_enabled(ipt, i)) {
     180            0 :             DUMP(prefix, "%s: no rule defined", hook_name[i]);
     181            0 :             continue;
     182              :         }
     183              : 
     184            0 :         DUMP(prefix, "%s (from %x to %x):", hook_name[i], ipt->hook_entry[i],
     185              :              ipt->underflow[i]);
     186              : 
     187            0 :         bf_dump_prefix_push(prefix);
     188              : 
     189            0 :         first_rule = ipt_get_first_rule(ipt, i);
     190            0 :         last_rule = ipt_get_last_rule(ipt, i);
     191              :         offset = sizeof(*first_rule);
     192              : 
     193              :         // Loop over the rules for the current hook.
     194            0 :         while (first_rule <= last_rule) {
     195            0 :             if (first_rule == last_rule)
     196            0 :                 bf_dump_prefix_last(prefix);
     197              : 
     198            0 :             DUMP(prefix, "struct ipt_entry at %p", first_rule);
     199              : 
     200            0 :             bf_dump_prefix_push(prefix);
     201              : 
     202            0 :             ipt_dump_ip(&first_rule->ip, prefix);
     203              : 
     204            0 :             DUMP(prefix, "target_offset: %d", first_rule->target_offset);
     205            0 :             DUMP(prefix, "next_offset: %d", first_rule->next_offset);
     206            0 :             DUMP(prefix, "comefrom: %d", first_rule->comefrom);
     207              : 
     208            0 :             ipt_dump_counters(&first_rule->counters, prefix);
     209              : 
     210              :             // Loop over the matches for the current rule.
     211            0 :             while (offset < first_rule->target_offset) {
     212            0 :                 ipt_dump_match(ipt_get_match(first_rule, offset), prefix);
     213            0 :                 offset += ipt_get_match(first_rule, offset)->u.match_size;
     214              :             }
     215              : 
     216            0 :             ipt_dump_target(ipt_get_target(first_rule),
     217              :                             bf_dump_prefix_last(prefix));
     218              : 
     219            0 :             bf_dump_prefix_pop(prefix);
     220              : 
     221            0 :             if (!first_rule->next_offset)
     222              :                 break;
     223              : 
     224            0 :             first_rule = ipt_get_next_rule(first_rule);
     225              :         }
     226            0 :         bf_dump_prefix_pop(prefix);
     227              :     }
     228              : 
     229            0 :     bf_dump_prefix_pop(prefix);
     230              : 
     231              :     // Force flush, otherwise output on stderr might appear.
     232            0 :     (void)fflush(stdout);
     233            0 : }
        

Generated by: LCOV version 2.0-1