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

Generated by: LCOV version 2.0-1