The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netpfil/ipfw/ip_fw_log.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 
   31 /*
   32  * Logging support for ipfw
   33  */
   34 
   35 #include "opt_ipfw.h"
   36 #include "opt_inet.h"
   37 #ifndef INET
   38 #error IPFIREWALL requires INET.
   39 #endif /* INET */
   40 #include "opt_inet6.h"
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/kernel.h>
   45 #include <sys/mbuf.h>
   46 #include <sys/socket.h>
   47 #include <sys/sysctl.h>
   48 #include <sys/syslog.h>
   49 #include <net/ethernet.h> /* for ETHERTYPE_IP */
   50 #include <net/if.h>
   51 #include <net/if_var.h>
   52 #include <net/vnet.h>
   53 
   54 #include <netinet/in.h>
   55 #include <netinet/ip.h>
   56 #include <netinet/ip_icmp.h>
   57 #include <netinet/ip_var.h>
   58 #include <netinet/ip_fw.h>
   59 #include <netinet/udp.h>
   60 #include <netinet/tcp.h>
   61 
   62 #include <netinet/ip6.h>
   63 #include <netinet/icmp6.h>
   64 #ifdef INET6
   65 #include <netinet6/in6_var.h>   /* ip6_sprintf() */
   66 #endif
   67 
   68 #include <netpfil/ipfw/ip_fw_private.h>
   69 
   70 #ifdef MAC
   71 #include <security/mac/mac_framework.h>
   72 #endif
   73 
   74 /*
   75  * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
   76  * Other macros just cast void * into the appropriate type
   77  */
   78 #define L3HDR(T, ip)    ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
   79 #define TCP(p)          ((struct tcphdr *)(p))
   80 #define SCTP(p)         ((struct sctphdr *)(p))
   81 #define UDP(p)          ((struct udphdr *)(p))
   82 #define ICMP(p)         ((struct icmphdr *)(p))
   83 #define ICMP6(p)        ((struct icmp6_hdr *)(p))
   84 
   85 #ifdef __APPLE__
   86 #undef snprintf
   87 #define snprintf        sprintf
   88 #define SNPARGS(buf, len) buf + len
   89 #define SNP(buf) buf
   90 #else   /* !__APPLE__ */
   91 #define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
   92 #define SNP(buf) buf, sizeof(buf)
   93 #endif /* !__APPLE__ */
   94 
   95 #define TARG(k, f)      IP_FW_ARG_TABLEARG(chain, k, f)
   96 /*
   97  * We enter here when we have a rule with O_LOG.
   98  * XXX this function alone takes about 2Kbytes of code!
   99  */
  100 void
  101 ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen,
  102     struct ip_fw_args *args, u_short offset, uint32_t tablearg, struct ip *ip)
  103 {
  104         char *action;
  105         int limit_reached = 0;
  106         char action2[92], proto[128], fragment[32];
  107 
  108         if (V_fw_verbose == 0) {
  109                 if (args->flags & IPFW_ARGS_LENMASK)
  110                         ipfw_bpf_tap(args->mem, IPFW_ARGS_LENGTH(args->flags));
  111                 else if (args->flags & IPFW_ARGS_ETHER)
  112                         /* layer2, use orig hdr */
  113                         ipfw_bpf_mtap(args->m);
  114                 else {
  115                         /* Add fake header. Later we will store
  116                          * more info in the header.
  117                          */
  118                         if (ip->ip_v == 4)
  119                                 ipfw_bpf_mtap2("DDDDDDSSSSSS\x08\x00",
  120                                     ETHER_HDR_LEN, args->m);
  121                         else if (ip->ip_v == 6)
  122                                 ipfw_bpf_mtap2("DDDDDDSSSSSS\x86\xdd",
  123                                     ETHER_HDR_LEN, args->m);
  124                         else
  125                                 /* Obviously bogus EtherType. */
  126                                 ipfw_bpf_mtap2("DDDDDDSSSSSS\xff\xff",
  127                                     ETHER_HDR_LEN, args->m);
  128                 }
  129                 return;
  130         }
  131         /* the old 'log' function */
  132         fragment[0] = '\0';
  133         proto[0] = '\0';
  134 
  135         if (f == NULL) {        /* bogus pkt */
  136                 if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit)
  137                         return;
  138                 V_norule_counter++;
  139                 if (V_norule_counter == V_verbose_limit)
  140                         limit_reached = V_verbose_limit;
  141                 action = "Refuse";
  142         } else {        /* O_LOG is the first action, find the real one */
  143                 ipfw_insn *cmd = ACTION_PTR(f);
  144                 ipfw_insn_log *l = (ipfw_insn_log *)cmd;
  145 
  146                 if (l->max_log != 0 && l->log_left == 0)
  147                         return;
  148                 l->log_left--;
  149                 if (l->log_left == 0)
  150                         limit_reached = l->max_log;
  151                 cmd += F_LEN(cmd);      /* point to first action */
  152                 if (cmd->opcode == O_ALTQ) {
  153                         ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
  154 
  155                         snprintf(SNPARGS(action2, 0), "Altq %d",
  156                                 altq->qid);
  157                         cmd += F_LEN(cmd);
  158                 }
  159                 if (cmd->opcode == O_PROB || cmd->opcode == O_TAG)
  160                         cmd += F_LEN(cmd);
  161 
  162                 action = action2;
  163                 switch (cmd->opcode) {
  164                 case O_DENY:
  165                         action = "Deny";
  166                         break;
  167 
  168                 case O_REJECT:
  169                         if (cmd->arg1==ICMP_REJECT_RST)
  170                                 action = "Reset";
  171                         else if (cmd->arg1==ICMP_REJECT_ABORT)
  172                                 action = "Abort";
  173                         else if (cmd->arg1==ICMP_UNREACH_HOST)
  174                                 action = "Reject";
  175                         else
  176                                 snprintf(SNPARGS(action2, 0), "Unreach %d",
  177                                         cmd->arg1);
  178                         break;
  179 
  180                 case O_UNREACH6:
  181                         if (cmd->arg1==ICMP6_UNREACH_RST)
  182                                 action = "Reset";
  183                         else if (cmd->arg1==ICMP6_UNREACH_ABORT)
  184                                 action = "Abort";
  185                         else
  186                                 snprintf(SNPARGS(action2, 0), "Unreach %d",
  187                                         cmd->arg1);
  188                         break;
  189 
  190                 case O_ACCEPT:
  191                         action = "Accept";
  192                         break;
  193                 case O_COUNT:
  194                         action = "Count";
  195                         break;
  196                 case O_DIVERT:
  197                         snprintf(SNPARGS(action2, 0), "Divert %d",
  198                                 TARG(cmd->arg1, divert));
  199                         break;
  200                 case O_TEE:
  201                         snprintf(SNPARGS(action2, 0), "Tee %d",
  202                                 TARG(cmd->arg1, divert));
  203                         break;
  204                 case O_SETDSCP:
  205                         snprintf(SNPARGS(action2, 0), "SetDscp %d",
  206                                 TARG(cmd->arg1, dscp) & 0x3F);
  207                         break;
  208                 case O_SETFIB:
  209                         snprintf(SNPARGS(action2, 0), "SetFib %d",
  210                                 TARG(cmd->arg1, fib) & 0x7FFF);
  211                         break;
  212                 case O_SKIPTO:
  213                         snprintf(SNPARGS(action2, 0), "SkipTo %d",
  214                                 TARG(cmd->arg1, skipto));
  215                         break;
  216                 case O_PIPE:
  217                         snprintf(SNPARGS(action2, 0), "Pipe %d",
  218                                 TARG(cmd->arg1, pipe));
  219                         break;
  220                 case O_QUEUE:
  221                         snprintf(SNPARGS(action2, 0), "Queue %d",
  222                                 TARG(cmd->arg1, pipe));
  223                         break;
  224                 case O_FORWARD_IP: {
  225                         char buf[INET_ADDRSTRLEN];
  226                         ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
  227                         int len;
  228                         struct in_addr dummyaddr;
  229                         if (sa->sa.sin_addr.s_addr == INADDR_ANY)
  230                                 dummyaddr.s_addr = htonl(tablearg);
  231                         else
  232                                 dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
  233 
  234                         len = snprintf(SNPARGS(action2, 0), "Forward to %s",
  235                                 inet_ntoa_r(dummyaddr, buf));
  236 
  237                         if (sa->sa.sin_port)
  238                                 snprintf(SNPARGS(action2, len), ":%d",
  239                                     sa->sa.sin_port);
  240                         }
  241                         break;
  242 #ifdef INET6
  243                 case O_FORWARD_IP6: {
  244                         char buf[INET6_ADDRSTRLEN];
  245                         ipfw_insn_sa6 *sa = (ipfw_insn_sa6 *)cmd;
  246                         int len;
  247 
  248                         len = snprintf(SNPARGS(action2, 0), "Forward to [%s]",
  249                             ip6_sprintf(buf, &sa->sa.sin6_addr));
  250 
  251                         if (sa->sa.sin6_port)
  252                                 snprintf(SNPARGS(action2, len), ":%u",
  253                                     sa->sa.sin6_port);
  254                         }
  255                         break;
  256 #endif
  257                 case O_NETGRAPH:
  258                         snprintf(SNPARGS(action2, 0), "Netgraph %d",
  259                                 cmd->arg1);
  260                         break;
  261                 case O_NGTEE:
  262                         snprintf(SNPARGS(action2, 0), "Ngtee %d",
  263                                 cmd->arg1);
  264                         break;
  265                 case O_NAT:
  266                         action = "Nat";
  267                         break;
  268                 case O_REASS:
  269                         action = "Reass";
  270                         break;
  271                 case O_CALLRETURN:
  272                         if (cmd->len & F_NOT)
  273                                 action = "Return";
  274                         else
  275                                 snprintf(SNPARGS(action2, 0), "Call %d",
  276                                     cmd->arg1);
  277                         break;
  278                 case O_EXTERNAL_ACTION:
  279                         snprintf(SNPARGS(action2, 0), "Eaction %s",
  280                             ((struct named_object *)SRV_OBJECT(chain,
  281                             cmd->arg1))->name);
  282                         break;
  283                 default:
  284                         action = "UNKNOWN";
  285                         break;
  286                 }
  287         }
  288 
  289         if (hlen == 0) {        /* non-ip */
  290                 snprintf(SNPARGS(proto, 0), "MAC");
  291 
  292         } else {
  293                 int len;
  294 #ifdef INET6
  295                 char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
  296 #else
  297                 char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
  298 #endif
  299                 struct icmphdr *icmp;
  300                 struct tcphdr *tcp;
  301                 struct udphdr *udp;
  302 #ifdef INET6
  303                 struct ip6_hdr *ip6 = NULL;
  304                 struct icmp6_hdr *icmp6;
  305                 u_short ip6f_mf;
  306 #endif
  307                 src[0] = '\0';
  308                 dst[0] = '\0';
  309 #ifdef INET6
  310                 ip6f_mf = offset & IP6F_MORE_FRAG;
  311                 offset &= IP6F_OFF_MASK;
  312 
  313                 if (IS_IP6_FLOW_ID(&(args->f_id))) {
  314                         char ip6buf[INET6_ADDRSTRLEN];
  315                         snprintf(src, sizeof(src), "[%s]",
  316                             ip6_sprintf(ip6buf, &args->f_id.src_ip6));
  317                         snprintf(dst, sizeof(dst), "[%s]",
  318                             ip6_sprintf(ip6buf, &args->f_id.dst_ip6));
  319 
  320                         ip6 = (struct ip6_hdr *)ip;
  321                         tcp = (struct tcphdr *)(((char *)ip) + hlen);
  322                         udp = (struct udphdr *)(((char *)ip) + hlen);
  323                 } else
  324 #endif
  325                 {
  326                         tcp = L3HDR(struct tcphdr, ip);
  327                         udp = L3HDR(struct udphdr, ip);
  328 
  329                         inet_ntop(AF_INET, &ip->ip_src, src, sizeof(src));
  330                         inet_ntop(AF_INET, &ip->ip_dst, dst, sizeof(dst));
  331                 }
  332 
  333                 switch (args->f_id.proto) {
  334                 case IPPROTO_TCP:
  335                         len = snprintf(SNPARGS(proto, 0), "TCP %s", src);
  336                         if (offset == 0)
  337                                 snprintf(SNPARGS(proto, len), ":%d %s:%d",
  338                                     ntohs(tcp->th_sport),
  339                                     dst,
  340                                     ntohs(tcp->th_dport));
  341                         else
  342                                 snprintf(SNPARGS(proto, len), " %s", dst);
  343                         break;
  344 
  345                 case IPPROTO_UDP:
  346                 case IPPROTO_UDPLITE:
  347                         len = snprintf(SNPARGS(proto, 0), "UDP%s%s",
  348                             args->f_id.proto == IPPROTO_UDP ? " ": "Lite ",
  349                             src);
  350                         if (offset == 0)
  351                                 snprintf(SNPARGS(proto, len), ":%d %s:%d",
  352                                     ntohs(udp->uh_sport),
  353                                     dst,
  354                                     ntohs(udp->uh_dport));
  355                         else
  356                                 snprintf(SNPARGS(proto, len), " %s", dst);
  357                         break;
  358 
  359                 case IPPROTO_ICMP:
  360                         icmp = L3HDR(struct icmphdr, ip);
  361                         if (offset == 0)
  362                                 len = snprintf(SNPARGS(proto, 0),
  363                                     "ICMP:%u.%u ",
  364                                     icmp->icmp_type, icmp->icmp_code);
  365                         else
  366                                 len = snprintf(SNPARGS(proto, 0), "ICMP ");
  367                         len += snprintf(SNPARGS(proto, len), "%s", src);
  368                         snprintf(SNPARGS(proto, len), " %s", dst);
  369                         break;
  370 #ifdef INET6
  371                 case IPPROTO_ICMPV6:
  372                         icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen);
  373                         if (offset == 0)
  374                                 len = snprintf(SNPARGS(proto, 0),
  375                                     "ICMPv6:%u.%u ",
  376                                     icmp6->icmp6_type, icmp6->icmp6_code);
  377                         else
  378                                 len = snprintf(SNPARGS(proto, 0), "ICMPv6 ");
  379                         len += snprintf(SNPARGS(proto, len), "%s", src);
  380                         snprintf(SNPARGS(proto, len), " %s", dst);
  381                         break;
  382 #endif
  383                 default:
  384                         len = snprintf(SNPARGS(proto, 0), "P:%d %s",
  385                             args->f_id.proto, src);
  386                         snprintf(SNPARGS(proto, len), " %s", dst);
  387                         break;
  388                 }
  389 
  390 #ifdef INET6
  391                 if (IS_IP6_FLOW_ID(&(args->f_id))) {
  392                         if (offset || ip6f_mf)
  393                                 snprintf(SNPARGS(fragment, 0),
  394                                     " (frag %08x:%d@%d%s)",
  395                                     args->f_id.extra,
  396                                     ntohs(ip6->ip6_plen) - hlen,
  397                                     ntohs(offset) << 3, ip6f_mf ? "+" : "");
  398                 } else
  399 #endif
  400                 {
  401                         int ipoff, iplen;
  402                         ipoff = ntohs(ip->ip_off);
  403                         iplen = ntohs(ip->ip_len);
  404                         if (ipoff & (IP_MF | IP_OFFMASK))
  405                                 snprintf(SNPARGS(fragment, 0),
  406                                     " (frag %d:%d@%d%s)",
  407                                     ntohs(ip->ip_id), iplen - (ip->ip_hl << 2),
  408                                     offset << 3,
  409                                     (ipoff & IP_MF) ? "+" : "");
  410                 }
  411         }
  412 #ifdef __FreeBSD__
  413         log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s %s via %s%s\n",
  414             f ? f->rulenum : -1, action, proto,
  415             args->flags & IPFW_ARGS_OUT ? "out" : "in", args->ifp->if_xname,
  416             fragment);
  417 #else
  418         log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s [no if info]%s\n",
  419             f ? f->rulenum : -1, action, proto, fragment);
  420 #endif
  421         if (limit_reached)
  422                 log(LOG_SECURITY | LOG_NOTICE,
  423                     "ipfw: limit %d reached on entry %d\n",
  424                     limit_reached, f ? f->rulenum : -1);
  425 }
  426 /* end of file */

Cache object: e3f9578020b00a4b8932f48415341673


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.