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

Generated by: LCOV version 2.0-1