13b3a8eb9SGleb Smirnoff /*- 23b3a8eb9SGleb Smirnoff * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 33b3a8eb9SGleb Smirnoff * 43b3a8eb9SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 53b3a8eb9SGleb Smirnoff * modification, are permitted provided that the following conditions 63b3a8eb9SGleb Smirnoff * are met: 73b3a8eb9SGleb Smirnoff * 1. Redistributions of source code must retain the above copyright 83b3a8eb9SGleb Smirnoff * notice, this list of conditions and the following disclaimer. 93b3a8eb9SGleb Smirnoff * 2. Redistributions in binary form must reproduce the above copyright 103b3a8eb9SGleb Smirnoff * notice, this list of conditions and the following disclaimer in the 113b3a8eb9SGleb Smirnoff * documentation and/or other materials provided with the distribution. 123b3a8eb9SGleb Smirnoff * 133b3a8eb9SGleb Smirnoff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 143b3a8eb9SGleb Smirnoff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 153b3a8eb9SGleb Smirnoff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 163b3a8eb9SGleb Smirnoff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 173b3a8eb9SGleb Smirnoff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 183b3a8eb9SGleb Smirnoff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 193b3a8eb9SGleb Smirnoff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 203b3a8eb9SGleb Smirnoff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 213b3a8eb9SGleb Smirnoff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 223b3a8eb9SGleb Smirnoff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 233b3a8eb9SGleb Smirnoff * SUCH DAMAGE. 243b3a8eb9SGleb Smirnoff */ 253b3a8eb9SGleb Smirnoff 263b3a8eb9SGleb Smirnoff #include <sys/cdefs.h> 273b3a8eb9SGleb Smirnoff __FBSDID("$FreeBSD$"); 283b3a8eb9SGleb Smirnoff 293b3a8eb9SGleb Smirnoff /* 303b3a8eb9SGleb Smirnoff * Logging support for ipfw 313b3a8eb9SGleb Smirnoff */ 323b3a8eb9SGleb Smirnoff 333b3a8eb9SGleb Smirnoff #include "opt_ipfw.h" 343b3a8eb9SGleb Smirnoff #include "opt_inet.h" 353b3a8eb9SGleb Smirnoff #ifndef INET 363b3a8eb9SGleb Smirnoff #error IPFIREWALL requires INET. 373b3a8eb9SGleb Smirnoff #endif /* INET */ 383b3a8eb9SGleb Smirnoff #include "opt_inet6.h" 393b3a8eb9SGleb Smirnoff 403b3a8eb9SGleb Smirnoff #include <sys/param.h> 413b3a8eb9SGleb Smirnoff #include <sys/systm.h> 423b3a8eb9SGleb Smirnoff #include <sys/kernel.h> 438ec07310SGleb Smirnoff #include <sys/mbuf.h> 443b3a8eb9SGleb Smirnoff #include <sys/socket.h> 453b3a8eb9SGleb Smirnoff #include <sys/sysctl.h> 463b3a8eb9SGleb Smirnoff #include <sys/syslog.h> 473b3a8eb9SGleb Smirnoff #include <net/ethernet.h> /* for ETHERTYPE_IP */ 483b3a8eb9SGleb Smirnoff #include <net/if.h> 4976039bc8SGleb Smirnoff #include <net/if_var.h> 503b3a8eb9SGleb Smirnoff #include <net/vnet.h> 513b3a8eb9SGleb Smirnoff 523b3a8eb9SGleb Smirnoff #include <netinet/in.h> 533b3a8eb9SGleb Smirnoff #include <netinet/ip.h> 543b3a8eb9SGleb Smirnoff #include <netinet/ip_icmp.h> 553b3a8eb9SGleb Smirnoff #include <netinet/ip_var.h> 563b3a8eb9SGleb Smirnoff #include <netinet/ip_fw.h> 573b3a8eb9SGleb Smirnoff #include <netinet/tcp_var.h> 583b3a8eb9SGleb Smirnoff #include <netinet/udp.h> 593b3a8eb9SGleb Smirnoff 603b3a8eb9SGleb Smirnoff #include <netinet/ip6.h> 613b3a8eb9SGleb Smirnoff #include <netinet/icmp6.h> 623b3a8eb9SGleb Smirnoff #ifdef INET6 633b3a8eb9SGleb Smirnoff #include <netinet6/in6_var.h> /* ip6_sprintf() */ 643b3a8eb9SGleb Smirnoff #endif 653b3a8eb9SGleb Smirnoff 663b3a8eb9SGleb Smirnoff #include <netpfil/ipfw/ip_fw_private.h> 673b3a8eb9SGleb Smirnoff 683b3a8eb9SGleb Smirnoff #ifdef MAC 693b3a8eb9SGleb Smirnoff #include <security/mac/mac_framework.h> 703b3a8eb9SGleb Smirnoff #endif 713b3a8eb9SGleb Smirnoff 723b3a8eb9SGleb Smirnoff /* 733b3a8eb9SGleb Smirnoff * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T 743b3a8eb9SGleb Smirnoff * Other macros just cast void * into the appropriate type 753b3a8eb9SGleb Smirnoff */ 763b3a8eb9SGleb Smirnoff #define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl)) 773b3a8eb9SGleb Smirnoff #define TCP(p) ((struct tcphdr *)(p)) 783b3a8eb9SGleb Smirnoff #define SCTP(p) ((struct sctphdr *)(p)) 793b3a8eb9SGleb Smirnoff #define UDP(p) ((struct udphdr *)(p)) 803b3a8eb9SGleb Smirnoff #define ICMP(p) ((struct icmphdr *)(p)) 813b3a8eb9SGleb Smirnoff #define ICMP6(p) ((struct icmp6_hdr *)(p)) 823b3a8eb9SGleb Smirnoff 83d0f65d47SLuigi Rizzo #ifdef __APPLE__ 84d0f65d47SLuigi Rizzo #undef snprintf 85d0f65d47SLuigi Rizzo #define snprintf sprintf 86d0f65d47SLuigi Rizzo #define SNPARGS(buf, len) buf + len 87d0f65d47SLuigi Rizzo #define SNP(buf) buf 88d0f65d47SLuigi Rizzo #else /* !__APPLE__ */ 893b3a8eb9SGleb Smirnoff #define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0 903b3a8eb9SGleb Smirnoff #define SNP(buf) buf, sizeof(buf) 91d0f65d47SLuigi Rizzo #endif /* !__APPLE__ */ 923b3a8eb9SGleb Smirnoff 930cba2b28SAlexander V. Chernikov #define TARG(k, f) IP_FW_ARG_TABLEARG(chain, k, f) 943b3a8eb9SGleb Smirnoff /* 953b3a8eb9SGleb Smirnoff * We enter here when we have a rule with O_LOG. 963b3a8eb9SGleb Smirnoff * XXX this function alone takes about 2Kbytes of code! 973b3a8eb9SGleb Smirnoff */ 983b3a8eb9SGleb Smirnoff void 990cba2b28SAlexander V. Chernikov ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, 1000cba2b28SAlexander V. Chernikov struct ip_fw_args *args, struct mbuf *m, struct ifnet *oif, 1010cba2b28SAlexander V. Chernikov u_short offset, uint32_t tablearg, struct ip *ip) 1023b3a8eb9SGleb Smirnoff { 1033b3a8eb9SGleb Smirnoff char *action; 1043b3a8eb9SGleb Smirnoff int limit_reached = 0; 1053b3a8eb9SGleb Smirnoff char action2[92], proto[128], fragment[32]; 1063b3a8eb9SGleb Smirnoff 1073b3a8eb9SGleb Smirnoff if (V_fw_verbose == 0) { 1083b3a8eb9SGleb Smirnoff if (args->eh) /* layer2, use orig hdr */ 10956132dccSAndrey V. Elsukov ipfw_bpf_mtap2(args->eh, ETHER_HDR_LEN, m); 110b49bf73fSPhilip Paeps else { 1113b3a8eb9SGleb Smirnoff /* Add fake header. Later we will store 1123b3a8eb9SGleb Smirnoff * more info in the header. 1133b3a8eb9SGleb Smirnoff */ 114b49bf73fSPhilip Paeps if (ip->ip_v == 4) 11556132dccSAndrey V. Elsukov ipfw_bpf_mtap2("DDDDDDSSSSSS\x08\x00", 11656132dccSAndrey V. Elsukov ETHER_HDR_LEN, m); 117b49bf73fSPhilip Paeps else if (ip->ip_v == 6) 11856132dccSAndrey V. Elsukov ipfw_bpf_mtap2("DDDDDDSSSSSS\x86\xdd", 11956132dccSAndrey V. Elsukov ETHER_HDR_LEN, m); 120b49bf73fSPhilip Paeps else 121b49bf73fSPhilip Paeps /* Obviously bogus EtherType. */ 12256132dccSAndrey V. Elsukov ipfw_bpf_mtap2("DDDDDDSSSSSS\xff\xff", 12356132dccSAndrey V. Elsukov ETHER_HDR_LEN, m); 124b49bf73fSPhilip Paeps } 1253b3a8eb9SGleb Smirnoff return; 1263b3a8eb9SGleb Smirnoff } 1273b3a8eb9SGleb Smirnoff /* the old 'log' function */ 1283b3a8eb9SGleb Smirnoff fragment[0] = '\0'; 1293b3a8eb9SGleb Smirnoff proto[0] = '\0'; 1303b3a8eb9SGleb Smirnoff 1313b3a8eb9SGleb Smirnoff if (f == NULL) { /* bogus pkt */ 1323b3a8eb9SGleb Smirnoff if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit) 1333b3a8eb9SGleb Smirnoff return; 1343b3a8eb9SGleb Smirnoff V_norule_counter++; 1353b3a8eb9SGleb Smirnoff if (V_norule_counter == V_verbose_limit) 1363b3a8eb9SGleb Smirnoff limit_reached = V_verbose_limit; 1373b3a8eb9SGleb Smirnoff action = "Refuse"; 1383b3a8eb9SGleb Smirnoff } else { /* O_LOG is the first action, find the real one */ 1393b3a8eb9SGleb Smirnoff ipfw_insn *cmd = ACTION_PTR(f); 1403b3a8eb9SGleb Smirnoff ipfw_insn_log *l = (ipfw_insn_log *)cmd; 1413b3a8eb9SGleb Smirnoff 1423b3a8eb9SGleb Smirnoff if (l->max_log != 0 && l->log_left == 0) 1433b3a8eb9SGleb Smirnoff return; 1443b3a8eb9SGleb Smirnoff l->log_left--; 1453b3a8eb9SGleb Smirnoff if (l->log_left == 0) 1463b3a8eb9SGleb Smirnoff limit_reached = l->max_log; 1473b3a8eb9SGleb Smirnoff cmd += F_LEN(cmd); /* point to first action */ 1483b3a8eb9SGleb Smirnoff if (cmd->opcode == O_ALTQ) { 1493b3a8eb9SGleb Smirnoff ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd; 1503b3a8eb9SGleb Smirnoff 1513b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Altq %d", 1523b3a8eb9SGleb Smirnoff altq->qid); 1533b3a8eb9SGleb Smirnoff cmd += F_LEN(cmd); 1543b3a8eb9SGleb Smirnoff } 155ae01d73cSAlexander V. Chernikov if (cmd->opcode == O_PROB || cmd->opcode == O_TAG || 156ae01d73cSAlexander V. Chernikov cmd->opcode == O_SETDSCP) 1573b3a8eb9SGleb Smirnoff cmd += F_LEN(cmd); 1583b3a8eb9SGleb Smirnoff 1593b3a8eb9SGleb Smirnoff action = action2; 1603b3a8eb9SGleb Smirnoff switch (cmd->opcode) { 1613b3a8eb9SGleb Smirnoff case O_DENY: 1623b3a8eb9SGleb Smirnoff action = "Deny"; 1633b3a8eb9SGleb Smirnoff break; 1643b3a8eb9SGleb Smirnoff 1653b3a8eb9SGleb Smirnoff case O_REJECT: 1663b3a8eb9SGleb Smirnoff if (cmd->arg1==ICMP_REJECT_RST) 1673b3a8eb9SGleb Smirnoff action = "Reset"; 1683b3a8eb9SGleb Smirnoff else if (cmd->arg1==ICMP_UNREACH_HOST) 1693b3a8eb9SGleb Smirnoff action = "Reject"; 1703b3a8eb9SGleb Smirnoff else 1713b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Unreach %d", 1723b3a8eb9SGleb Smirnoff cmd->arg1); 1733b3a8eb9SGleb Smirnoff break; 1743b3a8eb9SGleb Smirnoff 1753b3a8eb9SGleb Smirnoff case O_UNREACH6: 1763b3a8eb9SGleb Smirnoff if (cmd->arg1==ICMP6_UNREACH_RST) 1773b3a8eb9SGleb Smirnoff action = "Reset"; 1783b3a8eb9SGleb Smirnoff else 1793b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Unreach %d", 1803b3a8eb9SGleb Smirnoff cmd->arg1); 1813b3a8eb9SGleb Smirnoff break; 1823b3a8eb9SGleb Smirnoff 1833b3a8eb9SGleb Smirnoff case O_ACCEPT: 1843b3a8eb9SGleb Smirnoff action = "Accept"; 1853b3a8eb9SGleb Smirnoff break; 1863b3a8eb9SGleb Smirnoff case O_COUNT: 1873b3a8eb9SGleb Smirnoff action = "Count"; 1883b3a8eb9SGleb Smirnoff break; 1893b3a8eb9SGleb Smirnoff case O_DIVERT: 1903b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Divert %d", 1910cba2b28SAlexander V. Chernikov TARG(cmd->arg1, divert)); 1923b3a8eb9SGleb Smirnoff break; 1933b3a8eb9SGleb Smirnoff case O_TEE: 1943b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Tee %d", 1950cba2b28SAlexander V. Chernikov TARG(cmd->arg1, divert)); 1963b3a8eb9SGleb Smirnoff break; 1973b3a8eb9SGleb Smirnoff case O_SETFIB: 1983b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "SetFib %d", 19991e93dafSAlexander V. Chernikov TARG(cmd->arg1, fib) & 0x7FFF); 2003b3a8eb9SGleb Smirnoff break; 2013b3a8eb9SGleb Smirnoff case O_SKIPTO: 2023b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "SkipTo %d", 2030cba2b28SAlexander V. Chernikov TARG(cmd->arg1, skipto)); 2043b3a8eb9SGleb Smirnoff break; 2053b3a8eb9SGleb Smirnoff case O_PIPE: 2063b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Pipe %d", 2070cba2b28SAlexander V. Chernikov TARG(cmd->arg1, pipe)); 2083b3a8eb9SGleb Smirnoff break; 2093b3a8eb9SGleb Smirnoff case O_QUEUE: 2103b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Queue %d", 2110cba2b28SAlexander V. Chernikov TARG(cmd->arg1, pipe)); 2123b3a8eb9SGleb Smirnoff break; 2133b3a8eb9SGleb Smirnoff case O_FORWARD_IP: { 2148144690aSEric van Gyzen char buf[INET_ADDRSTRLEN]; 2153b3a8eb9SGleb Smirnoff ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd; 2163b3a8eb9SGleb Smirnoff int len; 2173b3a8eb9SGleb Smirnoff struct in_addr dummyaddr; 2183b3a8eb9SGleb Smirnoff if (sa->sa.sin_addr.s_addr == INADDR_ANY) 2193b3a8eb9SGleb Smirnoff dummyaddr.s_addr = htonl(tablearg); 2203b3a8eb9SGleb Smirnoff else 2213b3a8eb9SGleb Smirnoff dummyaddr.s_addr = sa->sa.sin_addr.s_addr; 2223b3a8eb9SGleb Smirnoff 2233b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(action2, 0), "Forward to %s", 2248144690aSEric van Gyzen inet_ntoa_r(dummyaddr, buf)); 2253b3a8eb9SGleb Smirnoff 2263b3a8eb9SGleb Smirnoff if (sa->sa.sin_port) 2273b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, len), ":%d", 2283b3a8eb9SGleb Smirnoff sa->sa.sin_port); 2293b3a8eb9SGleb Smirnoff } 2303b3a8eb9SGleb Smirnoff break; 2313b3a8eb9SGleb Smirnoff #ifdef INET6 2323b3a8eb9SGleb Smirnoff case O_FORWARD_IP6: { 2333b3a8eb9SGleb Smirnoff char buf[INET6_ADDRSTRLEN]; 2343b3a8eb9SGleb Smirnoff ipfw_insn_sa6 *sa = (ipfw_insn_sa6 *)cmd; 2353b3a8eb9SGleb Smirnoff int len; 2363b3a8eb9SGleb Smirnoff 2373b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(action2, 0), "Forward to [%s]", 2383b3a8eb9SGleb Smirnoff ip6_sprintf(buf, &sa->sa.sin6_addr)); 2393b3a8eb9SGleb Smirnoff 2403b3a8eb9SGleb Smirnoff if (sa->sa.sin6_port) 2413b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, len), ":%u", 2423b3a8eb9SGleb Smirnoff sa->sa.sin6_port); 2433b3a8eb9SGleb Smirnoff } 2443b3a8eb9SGleb Smirnoff break; 2453b3a8eb9SGleb Smirnoff #endif 2463b3a8eb9SGleb Smirnoff case O_NETGRAPH: 2473b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Netgraph %d", 2483b3a8eb9SGleb Smirnoff cmd->arg1); 2493b3a8eb9SGleb Smirnoff break; 2503b3a8eb9SGleb Smirnoff case O_NGTEE: 2513b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Ngtee %d", 2523b3a8eb9SGleb Smirnoff cmd->arg1); 2533b3a8eb9SGleb Smirnoff break; 2543b3a8eb9SGleb Smirnoff case O_NAT: 2553b3a8eb9SGleb Smirnoff action = "Nat"; 2563b3a8eb9SGleb Smirnoff break; 2573b3a8eb9SGleb Smirnoff case O_REASS: 2583b3a8eb9SGleb Smirnoff action = "Reass"; 2593b3a8eb9SGleb Smirnoff break; 2603b3a8eb9SGleb Smirnoff case O_CALLRETURN: 2613b3a8eb9SGleb Smirnoff if (cmd->len & F_NOT) 2623b3a8eb9SGleb Smirnoff action = "Return"; 2633b3a8eb9SGleb Smirnoff else 2643b3a8eb9SGleb Smirnoff snprintf(SNPARGS(action2, 0), "Call %d", 2653b3a8eb9SGleb Smirnoff cmd->arg1); 2663b3a8eb9SGleb Smirnoff break; 267*399ad578SAndrey V. Elsukov case O_EXTERNAL_ACTION: 268*399ad578SAndrey V. Elsukov snprintf(SNPARGS(action2, 0), "Eaction %s", 269*399ad578SAndrey V. Elsukov ((struct named_object *)SRV_OBJECT(chain, 270*399ad578SAndrey V. Elsukov cmd->arg1))->name); 271*399ad578SAndrey V. Elsukov break; 2723b3a8eb9SGleb Smirnoff default: 2733b3a8eb9SGleb Smirnoff action = "UNKNOWN"; 2743b3a8eb9SGleb Smirnoff break; 2753b3a8eb9SGleb Smirnoff } 2763b3a8eb9SGleb Smirnoff } 2773b3a8eb9SGleb Smirnoff 2783b3a8eb9SGleb Smirnoff if (hlen == 0) { /* non-ip */ 2793b3a8eb9SGleb Smirnoff snprintf(SNPARGS(proto, 0), "MAC"); 2803b3a8eb9SGleb Smirnoff 2813b3a8eb9SGleb Smirnoff } else { 2823b3a8eb9SGleb Smirnoff int len; 2833b3a8eb9SGleb Smirnoff #ifdef INET6 2843b3a8eb9SGleb Smirnoff char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2]; 2853b3a8eb9SGleb Smirnoff #else 2863b3a8eb9SGleb Smirnoff char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN]; 2873b3a8eb9SGleb Smirnoff #endif 2883b3a8eb9SGleb Smirnoff struct icmphdr *icmp; 2893b3a8eb9SGleb Smirnoff struct tcphdr *tcp; 2903b3a8eb9SGleb Smirnoff struct udphdr *udp; 2913b3a8eb9SGleb Smirnoff #ifdef INET6 2923b3a8eb9SGleb Smirnoff struct ip6_hdr *ip6 = NULL; 2933b3a8eb9SGleb Smirnoff struct icmp6_hdr *icmp6; 2943b3a8eb9SGleb Smirnoff u_short ip6f_mf; 2953b3a8eb9SGleb Smirnoff #endif 2963b3a8eb9SGleb Smirnoff src[0] = '\0'; 2973b3a8eb9SGleb Smirnoff dst[0] = '\0'; 2983b3a8eb9SGleb Smirnoff #ifdef INET6 2993b3a8eb9SGleb Smirnoff ip6f_mf = offset & IP6F_MORE_FRAG; 3003b3a8eb9SGleb Smirnoff offset &= IP6F_OFF_MASK; 3013b3a8eb9SGleb Smirnoff 3023b3a8eb9SGleb Smirnoff if (IS_IP6_FLOW_ID(&(args->f_id))) { 3033b3a8eb9SGleb Smirnoff char ip6buf[INET6_ADDRSTRLEN]; 3043b3a8eb9SGleb Smirnoff snprintf(src, sizeof(src), "[%s]", 3053b3a8eb9SGleb Smirnoff ip6_sprintf(ip6buf, &args->f_id.src_ip6)); 3063b3a8eb9SGleb Smirnoff snprintf(dst, sizeof(dst), "[%s]", 3073b3a8eb9SGleb Smirnoff ip6_sprintf(ip6buf, &args->f_id.dst_ip6)); 3083b3a8eb9SGleb Smirnoff 3093b3a8eb9SGleb Smirnoff ip6 = (struct ip6_hdr *)ip; 3103b3a8eb9SGleb Smirnoff tcp = (struct tcphdr *)(((char *)ip) + hlen); 3113b3a8eb9SGleb Smirnoff udp = (struct udphdr *)(((char *)ip) + hlen); 3123b3a8eb9SGleb Smirnoff } else 3133b3a8eb9SGleb Smirnoff #endif 3143b3a8eb9SGleb Smirnoff { 3153b3a8eb9SGleb Smirnoff tcp = L3HDR(struct tcphdr, ip); 3163b3a8eb9SGleb Smirnoff udp = L3HDR(struct udphdr, ip); 3173b3a8eb9SGleb Smirnoff 3183b3a8eb9SGleb Smirnoff inet_ntop(AF_INET, &ip->ip_src, src, sizeof(src)); 3193b3a8eb9SGleb Smirnoff inet_ntop(AF_INET, &ip->ip_dst, dst, sizeof(dst)); 3203b3a8eb9SGleb Smirnoff } 3213b3a8eb9SGleb Smirnoff 3223b3a8eb9SGleb Smirnoff switch (args->f_id.proto) { 3233b3a8eb9SGleb Smirnoff case IPPROTO_TCP: 3243b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(proto, 0), "TCP %s", src); 3253b3a8eb9SGleb Smirnoff if (offset == 0) 3263b3a8eb9SGleb Smirnoff snprintf(SNPARGS(proto, len), ":%d %s:%d", 3273b3a8eb9SGleb Smirnoff ntohs(tcp->th_sport), 3283b3a8eb9SGleb Smirnoff dst, 3293b3a8eb9SGleb Smirnoff ntohs(tcp->th_dport)); 3303b3a8eb9SGleb Smirnoff else 3313b3a8eb9SGleb Smirnoff snprintf(SNPARGS(proto, len), " %s", dst); 3323b3a8eb9SGleb Smirnoff break; 3333b3a8eb9SGleb Smirnoff 3343b3a8eb9SGleb Smirnoff case IPPROTO_UDP: 3353b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(proto, 0), "UDP %s", src); 3363b3a8eb9SGleb Smirnoff if (offset == 0) 3373b3a8eb9SGleb Smirnoff snprintf(SNPARGS(proto, len), ":%d %s:%d", 3383b3a8eb9SGleb Smirnoff ntohs(udp->uh_sport), 3393b3a8eb9SGleb Smirnoff dst, 3403b3a8eb9SGleb Smirnoff ntohs(udp->uh_dport)); 3413b3a8eb9SGleb Smirnoff else 3423b3a8eb9SGleb Smirnoff snprintf(SNPARGS(proto, len), " %s", dst); 3433b3a8eb9SGleb Smirnoff break; 3443b3a8eb9SGleb Smirnoff 3453b3a8eb9SGleb Smirnoff case IPPROTO_ICMP: 3463b3a8eb9SGleb Smirnoff icmp = L3HDR(struct icmphdr, ip); 3473b3a8eb9SGleb Smirnoff if (offset == 0) 3483b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(proto, 0), 3493b3a8eb9SGleb Smirnoff "ICMP:%u.%u ", 3503b3a8eb9SGleb Smirnoff icmp->icmp_type, icmp->icmp_code); 3513b3a8eb9SGleb Smirnoff else 3523b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(proto, 0), "ICMP "); 3533b3a8eb9SGleb Smirnoff len += snprintf(SNPARGS(proto, len), "%s", src); 3543b3a8eb9SGleb Smirnoff snprintf(SNPARGS(proto, len), " %s", dst); 3553b3a8eb9SGleb Smirnoff break; 3563b3a8eb9SGleb Smirnoff #ifdef INET6 3573b3a8eb9SGleb Smirnoff case IPPROTO_ICMPV6: 3583b3a8eb9SGleb Smirnoff icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen); 3593b3a8eb9SGleb Smirnoff if (offset == 0) 3603b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(proto, 0), 3613b3a8eb9SGleb Smirnoff "ICMPv6:%u.%u ", 3623b3a8eb9SGleb Smirnoff icmp6->icmp6_type, icmp6->icmp6_code); 3633b3a8eb9SGleb Smirnoff else 3643b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(proto, 0), "ICMPv6 "); 3653b3a8eb9SGleb Smirnoff len += snprintf(SNPARGS(proto, len), "%s", src); 3663b3a8eb9SGleb Smirnoff snprintf(SNPARGS(proto, len), " %s", dst); 3673b3a8eb9SGleb Smirnoff break; 3683b3a8eb9SGleb Smirnoff #endif 3693b3a8eb9SGleb Smirnoff default: 3703b3a8eb9SGleb Smirnoff len = snprintf(SNPARGS(proto, 0), "P:%d %s", 3713b3a8eb9SGleb Smirnoff args->f_id.proto, src); 3723b3a8eb9SGleb Smirnoff snprintf(SNPARGS(proto, len), " %s", dst); 3733b3a8eb9SGleb Smirnoff break; 3743b3a8eb9SGleb Smirnoff } 3753b3a8eb9SGleb Smirnoff 3763b3a8eb9SGleb Smirnoff #ifdef INET6 3773b3a8eb9SGleb Smirnoff if (IS_IP6_FLOW_ID(&(args->f_id))) { 378bf55a003SAndrey V. Elsukov if (offset || ip6f_mf) 3793b3a8eb9SGleb Smirnoff snprintf(SNPARGS(fragment, 0), 3803b3a8eb9SGleb Smirnoff " (frag %08x:%d@%d%s)", 3813b3a8eb9SGleb Smirnoff args->f_id.extra, 3823b3a8eb9SGleb Smirnoff ntohs(ip6->ip6_plen) - hlen, 3833b3a8eb9SGleb Smirnoff ntohs(offset) << 3, ip6f_mf ? "+" : ""); 3843b3a8eb9SGleb Smirnoff } else 3853b3a8eb9SGleb Smirnoff #endif 3863b3a8eb9SGleb Smirnoff { 3873b3a8eb9SGleb Smirnoff int ipoff, iplen; 3883b3a8eb9SGleb Smirnoff ipoff = ntohs(ip->ip_off); 3893b3a8eb9SGleb Smirnoff iplen = ntohs(ip->ip_len); 3903b3a8eb9SGleb Smirnoff if (ipoff & (IP_MF | IP_OFFMASK)) 3913b3a8eb9SGleb Smirnoff snprintf(SNPARGS(fragment, 0), 3923b3a8eb9SGleb Smirnoff " (frag %d:%d@%d%s)", 3933b3a8eb9SGleb Smirnoff ntohs(ip->ip_id), iplen - (ip->ip_hl << 2), 3943b3a8eb9SGleb Smirnoff offset << 3, 3953b3a8eb9SGleb Smirnoff (ipoff & IP_MF) ? "+" : ""); 3963b3a8eb9SGleb Smirnoff } 3973b3a8eb9SGleb Smirnoff } 3983b3a8eb9SGleb Smirnoff #ifdef __FreeBSD__ 3993b3a8eb9SGleb Smirnoff if (oif || m->m_pkthdr.rcvif) 4003b3a8eb9SGleb Smirnoff log(LOG_SECURITY | LOG_INFO, 4013b3a8eb9SGleb Smirnoff "ipfw: %d %s %s %s via %s%s\n", 4023b3a8eb9SGleb Smirnoff f ? f->rulenum : -1, 4033b3a8eb9SGleb Smirnoff action, proto, oif ? "out" : "in", 4043b3a8eb9SGleb Smirnoff oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname, 4053b3a8eb9SGleb Smirnoff fragment); 4063b3a8eb9SGleb Smirnoff else 4073b3a8eb9SGleb Smirnoff #endif 4083b3a8eb9SGleb Smirnoff log(LOG_SECURITY | LOG_INFO, 4093b3a8eb9SGleb Smirnoff "ipfw: %d %s %s [no if info]%s\n", 4103b3a8eb9SGleb Smirnoff f ? f->rulenum : -1, 4113b3a8eb9SGleb Smirnoff action, proto, fragment); 4123b3a8eb9SGleb Smirnoff if (limit_reached) 4133b3a8eb9SGleb Smirnoff log(LOG_SECURITY | LOG_NOTICE, 4143b3a8eb9SGleb Smirnoff "ipfw: limit %d reached on entry %d\n", 4153b3a8eb9SGleb Smirnoff limit_reached, f ? f->rulenum : -1); 4163b3a8eb9SGleb Smirnoff } 4173b3a8eb9SGleb Smirnoff /* end of file */ 418