source: rtems-libbsd/freebsd/sys/netinet/ipfw/ip_fw_log.c @ f244de9

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since f244de9 was f244de9, checked in by Sebastian Huber <sebastian.huber@…>, on 11/06/13 at 07:56:38

Rename rtems-bsd-config.h

Rename rtems-bsd-config.h in rtems-bsd-kernel-space.h.

  • Property mode set to 100644
File size: 11.3 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
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 <rtems/bsd/local/opt_ipfw.h>
36#include <rtems/bsd/local/opt_inet.h>
37#ifndef INET
38#error IPFIREWALL requires INET.
39#endif /* INET */
40#include <rtems/bsd/local/opt_inet6.h>
41
42#include <rtems/bsd/sys/param.h>
43#include <sys/systm.h>
44#include <sys/mbuf.h>
45#include <sys/kernel.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/vnet.h>
52#include <net/if_types.h>       /* for IFT_ETHER */
53#include <net/bpf.h>            /* for BPF */
54
55#include <netinet/in.h>
56#include <netinet/ip.h>
57#include <netinet/ip_icmp.h>
58#include <netinet/ip_var.h>
59#include <netinet/ip_fw.h>
60#include <netinet/ipfw/ip_fw_private.h>
61#include <netinet/tcp_var.h>
62#include <netinet/udp.h>
63
64#include <netinet/ip6.h>
65#include <netinet/icmp6.h>
66#ifdef INET6
67#include <netinet6/in6_var.h>   /* ip6_sprintf() */
68#endif
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#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
86#define SNP(buf) buf, sizeof(buf)
87
88#ifdef WITHOUT_BPF
89void
90ipfw_log_bpf(int onoff)
91{
92}
93#else /* !WITHOUT_BPF */
94static struct ifnet *log_if;    /* hook to attach to bpf */
95
96/* we use this dummy function for all ifnet callbacks */
97static int
98log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr)
99{
100        return EINVAL;
101}
102
103static int
104ipfw_log_output(struct ifnet *ifp, struct mbuf *m,
105        struct sockaddr *dst, struct route *ro)
106{
107        if (m != NULL)
108                m_freem(m);
109        return EINVAL;
110}
111
112static void
113ipfw_log_start(struct ifnet* ifp)
114{
115        panic("ipfw_log_start() must not be called");
116}
117
118static const u_char ipfwbroadcastaddr[6] =
119        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
120
121void
122ipfw_log_bpf(int onoff)
123{
124        struct ifnet *ifp;
125
126        if (onoff) {
127                if (log_if)
128                        return;
129                ifp = if_alloc(IFT_ETHER);
130                if (ifp == NULL)
131                        return;
132                if_initname(ifp, "ipfw", 0);
133                ifp->if_mtu = 65536;
134                ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
135                ifp->if_init = (void *)log_dummy;
136                ifp->if_ioctl = log_dummy;
137                ifp->if_start = ipfw_log_start;
138                ifp->if_output = ipfw_log_output;
139                ifp->if_addrlen = 6;
140                ifp->if_hdrlen = 14;
141                if_attach(ifp);
142                ifp->if_broadcastaddr = ipfwbroadcastaddr;
143                ifp->if_baudrate = IF_Mbps(10);
144                bpfattach(ifp, DLT_EN10MB, 14);
145                log_if = ifp;
146        } else {
147                if (log_if) {
148                        ether_ifdetach(log_if);
149                        if_free(log_if);
150                }
151                log_if = NULL;
152        }
153}
154#endif /* !WITHOUT_BPF */
155
156/*
157 * We enter here when we have a rule with O_LOG.
158 * XXX this function alone takes about 2Kbytes of code!
159 */
160void
161ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
162    struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
163    struct ip *ip)
164{
165        char *action;
166        int limit_reached = 0;
167        char action2[40], proto[128], fragment[32];
168
169        if (V_fw_verbose == 0) {
170#ifndef WITHOUT_BPF
171
172                if (log_if == NULL || log_if->if_bpf == NULL)
173                        return;
174
175                if (args->eh) /* layer2, use orig hdr */
176                        BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m);
177                else
178                        /* Add fake header. Later we will store
179                         * more info in the header.
180                         */
181                        BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m);
182#endif /* !WITHOUT_BPF */
183                return;
184        }
185        /* the old 'log' function */
186        fragment[0] = '\0';
187        proto[0] = '\0';
188
189        if (f == NULL) {        /* bogus pkt */
190                if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit)
191                        return;
192                V_norule_counter++;
193                if (V_norule_counter == V_verbose_limit)
194                        limit_reached = V_verbose_limit;
195                action = "Refuse";
196        } else {        /* O_LOG is the first action, find the real one */
197                ipfw_insn *cmd = ACTION_PTR(f);
198                ipfw_insn_log *l = (ipfw_insn_log *)cmd;
199
200                if (l->max_log != 0 && l->log_left == 0)
201                        return;
202                l->log_left--;
203                if (l->log_left == 0)
204                        limit_reached = l->max_log;
205                cmd += F_LEN(cmd);      /* point to first action */
206                if (cmd->opcode == O_ALTQ) {
207                        ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
208
209                        snprintf(SNPARGS(action2, 0), "Altq %d",
210                                altq->qid);
211                        cmd += F_LEN(cmd);
212                }
213                if (cmd->opcode == O_PROB)
214                        cmd += F_LEN(cmd);
215
216                if (cmd->opcode == O_TAG)
217                        cmd += F_LEN(cmd);
218
219                action = action2;
220                switch (cmd->opcode) {
221                case O_DENY:
222                        action = "Deny";
223                        break;
224
225                case O_REJECT:
226                        if (cmd->arg1==ICMP_REJECT_RST)
227                                action = "Reset";
228                        else if (cmd->arg1==ICMP_UNREACH_HOST)
229                                action = "Reject";
230                        else
231                                snprintf(SNPARGS(action2, 0), "Unreach %d",
232                                        cmd->arg1);
233                        break;
234
235                case O_UNREACH6:
236                        if (cmd->arg1==ICMP6_UNREACH_RST)
237                                action = "Reset";
238                        else
239                                snprintf(SNPARGS(action2, 0), "Unreach %d",
240                                        cmd->arg1);
241                        break;
242
243                case O_ACCEPT:
244                        action = "Accept";
245                        break;
246                case O_COUNT:
247                        action = "Count";
248                        break;
249                case O_DIVERT:
250                        snprintf(SNPARGS(action2, 0), "Divert %d",
251                                cmd->arg1);
252                        break;
253                case O_TEE:
254                        snprintf(SNPARGS(action2, 0), "Tee %d",
255                                cmd->arg1);
256                        break;
257                case O_SETFIB:
258                        snprintf(SNPARGS(action2, 0), "SetFib %d",
259                                cmd->arg1);
260                        break;
261                case O_SKIPTO:
262                        snprintf(SNPARGS(action2, 0), "SkipTo %d",
263                                cmd->arg1);
264                        break;
265                case O_PIPE:
266                        snprintf(SNPARGS(action2, 0), "Pipe %d",
267                                cmd->arg1);
268                        break;
269                case O_QUEUE:
270                        snprintf(SNPARGS(action2, 0), "Queue %d",
271                                cmd->arg1);
272                        break;
273                case O_FORWARD_IP: {
274                        ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
275                        int len;
276                        struct in_addr dummyaddr;
277                        if (sa->sa.sin_addr.s_addr == INADDR_ANY)
278                                dummyaddr.s_addr = htonl(tablearg);
279                        else
280                                dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
281
282                        len = snprintf(SNPARGS(action2, 0), "Forward to %s",
283                                inet_ntoa(dummyaddr));
284
285                        if (sa->sa.sin_port)
286                                snprintf(SNPARGS(action2, len), ":%d",
287                                    sa->sa.sin_port);
288                        }
289                        break;
290                case O_NETGRAPH:
291                        snprintf(SNPARGS(action2, 0), "Netgraph %d",
292                                cmd->arg1);
293                        break;
294                case O_NGTEE:
295                        snprintf(SNPARGS(action2, 0), "Ngtee %d",
296                                cmd->arg1);
297                        break;
298                case O_NAT:
299                        action = "Nat";
300                        break;
301                case O_REASS:
302                        action = "Reass";
303                        break;
304                case O_CALLRETURN:
305                        if (cmd->len & F_NOT)
306                                action = "Return";
307                        else
308                                snprintf(SNPARGS(action2, 0), "Call %d",
309                                    cmd->arg1);
310                        break;
311                default:
312                        action = "UNKNOWN";
313                        break;
314                }
315        }
316
317        if (hlen == 0) {        /* non-ip */
318                snprintf(SNPARGS(proto, 0), "MAC");
319
320        } else {
321                int len;
322#ifdef INET6
323                char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
324#else
325                char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
326#endif
327                struct icmphdr *icmp;
328                struct tcphdr *tcp;
329                struct udphdr *udp;
330#ifdef INET6
331                struct ip6_hdr *ip6 = NULL;
332                struct icmp6_hdr *icmp6;
333                u_short ip6f_mf;
334#endif
335                src[0] = '\0';
336                dst[0] = '\0';
337#ifdef INET6
338                ip6f_mf = offset & IP6F_MORE_FRAG;
339                offset &= IP6F_OFF_MASK;
340
341                if (IS_IP6_FLOW_ID(&(args->f_id))) {
342                        char ip6buf[INET6_ADDRSTRLEN];
343                        snprintf(src, sizeof(src), "[%s]",
344                            ip6_sprintf(ip6buf, &args->f_id.src_ip6));
345                        snprintf(dst, sizeof(dst), "[%s]",
346                            ip6_sprintf(ip6buf, &args->f_id.dst_ip6));
347
348                        ip6 = (struct ip6_hdr *)ip;
349                        tcp = (struct tcphdr *)(((char *)ip) + hlen);
350                        udp = (struct udphdr *)(((char *)ip) + hlen);
351                } else
352#endif
353                {
354                        tcp = L3HDR(struct tcphdr, ip);
355                        udp = L3HDR(struct udphdr, ip);
356
357                        inet_ntoa_r(ip->ip_src, src);
358                        inet_ntoa_r(ip->ip_dst, dst);
359                }
360
361                switch (args->f_id.proto) {
362                case IPPROTO_TCP:
363                        len = snprintf(SNPARGS(proto, 0), "TCP %s", src);
364                        if (offset == 0)
365                                snprintf(SNPARGS(proto, len), ":%d %s:%d",
366                                    ntohs(tcp->th_sport),
367                                    dst,
368                                    ntohs(tcp->th_dport));
369                        else
370                                snprintf(SNPARGS(proto, len), " %s", dst);
371                        break;
372
373                case IPPROTO_UDP:
374                        len = snprintf(SNPARGS(proto, 0), "UDP %s", src);
375                        if (offset == 0)
376                                snprintf(SNPARGS(proto, len), ":%d %s:%d",
377                                    ntohs(udp->uh_sport),
378                                    dst,
379                                    ntohs(udp->uh_dport));
380                        else
381                                snprintf(SNPARGS(proto, len), " %s", dst);
382                        break;
383
384                case IPPROTO_ICMP:
385                        icmp = L3HDR(struct icmphdr, ip);
386                        if (offset == 0)
387                                len = snprintf(SNPARGS(proto, 0),
388                                    "ICMP:%u.%u ",
389                                    icmp->icmp_type, icmp->icmp_code);
390                        else
391                                len = snprintf(SNPARGS(proto, 0), "ICMP ");
392                        len += snprintf(SNPARGS(proto, len), "%s", src);
393                        snprintf(SNPARGS(proto, len), " %s", dst);
394                        break;
395#ifdef INET6
396                case IPPROTO_ICMPV6:
397                        icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen);
398                        if (offset == 0)
399                                len = snprintf(SNPARGS(proto, 0),
400                                    "ICMPv6:%u.%u ",
401                                    icmp6->icmp6_type, icmp6->icmp6_code);
402                        else
403                                len = snprintf(SNPARGS(proto, 0), "ICMPv6 ");
404                        len += snprintf(SNPARGS(proto, len), "%s", src);
405                        snprintf(SNPARGS(proto, len), " %s", dst);
406                        break;
407#endif
408                default:
409                        len = snprintf(SNPARGS(proto, 0), "P:%d %s",
410                            args->f_id.proto, src);
411                        snprintf(SNPARGS(proto, len), " %s", dst);
412                        break;
413                }
414
415#ifdef INET6
416                if (IS_IP6_FLOW_ID(&(args->f_id))) {
417                        if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG))
418                                snprintf(SNPARGS(fragment, 0),
419                                    " (frag %08x:%d@%d%s)",
420                                    args->f_id.extra,
421                                    ntohs(ip6->ip6_plen) - hlen,
422                                    ntohs(offset) << 3, ip6f_mf ? "+" : "");
423                } else
424#endif
425                {
426                        int ipoff, iplen;
427                        ipoff = ntohs(ip->ip_off);
428                        iplen = ntohs(ip->ip_len);
429                        if (ipoff & (IP_MF | IP_OFFMASK))
430                                snprintf(SNPARGS(fragment, 0),
431                                    " (frag %d:%d@%d%s)",
432                                    ntohs(ip->ip_id), iplen - (ip->ip_hl << 2),
433                                    offset << 3,
434                                    (ipoff & IP_MF) ? "+" : "");
435                }
436        }
437#ifdef __FreeBSD__
438        if (oif || m->m_pkthdr.rcvif)
439                log(LOG_SECURITY | LOG_INFO,
440                    "ipfw: %d %s %s %s via %s%s\n",
441                    f ? f->rulenum : -1,
442                    action, proto, oif ? "out" : "in",
443                    oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname,
444                    fragment);
445        else
446#endif
447                log(LOG_SECURITY | LOG_INFO,
448                    "ipfw: %d %s %s [no if info]%s\n",
449                    f ? f->rulenum : -1,
450                    action, proto, fragment);
451        if (limit_reached)
452                log(LOG_SECURITY | LOG_NOTICE,
453                    "ipfw: limit %d reached on entry %d\n",
454                    limit_reached, f ? f->rulenum : -1);
455}
456/* end of file */
Note: See TracBrowser for help on using the repository browser.