source: rtems-libbsd/freebsd/contrib/pf/pfctl/pf_print_state.c @ 084d4db

4.11
Last change on this file since 084d4db was 084d4db, checked in by Christian Mauderer <Christian.Mauderer@…>, on Jul 5, 2016 at 2:07:37 PM

pfctl: Import sources from FreeBSD.

  • Property mode set to 100644
File size: 9.7 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*      $OpenBSD: pf_print_state.c,v 1.52 2008/08/12 16:40:18 david Exp $       */
4
5/*
6 * Copyright (c) 2001 Daniel Hartmeier
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 *    - Redistributions of source code must retain the above copyright
14 *      notice, this list of conditions and the following disclaimer.
15 *    - Redistributions in binary form must reproduce the above
16 *      copyright notice, this list of conditions and the following
17 *      disclaimer in the documentation and/or other materials provided
18 *      with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD$");
37
38#include <rtems/bsd/sys/types.h>
39#include <sys/socket.h>
40#ifdef __FreeBSD__
41#include <sys/endian.h>
42#define betoh64 be64toh
43#endif
44#include <net/if.h>
45#define TCPSTATES
46#include <netinet/tcp_fsm.h>
47#include <net/pfvar.h>
48#include <arpa/inet.h>
49#include <netdb.h>
50
51#include <stdio.h>
52#include <string.h>
53
54#include "pfctl_parser.h"
55#include "pfctl.h"
56
57void    print_name(struct pf_addr *, sa_family_t);
58
59void
60print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
61{
62        switch (addr->type) {
63        case PF_ADDR_DYNIFTL:
64                printf("(%s", addr->v.ifname);
65                if (addr->iflags & PFI_AFLAG_NETWORK)
66                        printf(":network");
67                if (addr->iflags & PFI_AFLAG_BROADCAST)
68                        printf(":broadcast");
69                if (addr->iflags & PFI_AFLAG_PEER)
70                        printf(":peer");
71                if (addr->iflags & PFI_AFLAG_NOALIAS)
72                        printf(":0");
73                if (verbose) {
74                        if (addr->p.dyncnt <= 0)
75                                printf(":*");
76                        else
77                                printf(":%d", addr->p.dyncnt);
78                }
79                printf(")");
80                break;
81        case PF_ADDR_TABLE:
82                if (verbose)
83                        if (addr->p.tblcnt == -1)
84                                printf("<%s:*>", addr->v.tblname);
85                        else
86                                printf("<%s:%d>", addr->v.tblname,
87                                    addr->p.tblcnt);
88                else
89                        printf("<%s>", addr->v.tblname);
90                return;
91        case PF_ADDR_RANGE: {
92                char buf[48];
93
94                if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL)
95                        printf("?");
96                else
97                        printf("%s", buf);
98                if (inet_ntop(af, &addr->v.a.mask, buf, sizeof(buf)) == NULL)
99                        printf(" - ?");
100                else
101                        printf(" - %s", buf);
102                break;
103        }
104        case PF_ADDR_ADDRMASK:
105                if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
106                    PF_AZERO(&addr->v.a.mask, AF_INET6))
107                        printf("any");
108                else {
109                        char buf[48];
110
111                        if (inet_ntop(af, &addr->v.a.addr, buf,
112                            sizeof(buf)) == NULL)
113                                printf("?");
114                        else
115                                printf("%s", buf);
116                }
117                break;
118        case PF_ADDR_NOROUTE:
119                printf("no-route");
120                return;
121        case PF_ADDR_URPFFAILED:
122                printf("urpf-failed");
123                return;
124        case PF_ADDR_RTLABEL:
125                printf("route \"%s\"", addr->v.rtlabelname);
126                return;
127        default:
128                printf("?");
129                return;
130        }
131
132        /* mask if not _both_ address and mask are zero */
133        if (addr->type != PF_ADDR_RANGE &&
134            !(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
135            PF_AZERO(&addr->v.a.mask, AF_INET6))) {
136                int bits = unmask(&addr->v.a.mask, af);
137
138                if (bits != (af == AF_INET ? 32 : 128))
139                        printf("/%d", bits);
140        }
141}
142
143void
144print_name(struct pf_addr *addr, sa_family_t af)
145{
146        char host[NI_MAXHOST];
147
148        strlcpy(host, "?", sizeof(host));
149        switch (af) {
150        case AF_INET: {
151                struct sockaddr_in sin;
152
153                memset(&sin, 0, sizeof(sin));
154                sin.sin_len = sizeof(sin);
155                sin.sin_family = AF_INET;
156                sin.sin_addr = addr->v4;
157                getnameinfo((struct sockaddr *)&sin, sin.sin_len,
158                    host, sizeof(host), NULL, 0, NI_NOFQDN);
159                break;
160        }
161        case AF_INET6: {
162                struct sockaddr_in6 sin6;
163
164                memset(&sin6, 0, sizeof(sin6));
165                sin6.sin6_len = sizeof(sin6);
166                sin6.sin6_family = AF_INET6;
167                sin6.sin6_addr = addr->v6;
168                getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
169                    host, sizeof(host), NULL, 0, NI_NOFQDN);
170                break;
171        }
172        }
173        printf("%s", host);
174}
175
176void
177print_host(struct pf_addr *addr, u_int16_t port, sa_family_t af, int opts)
178{
179        if (opts & PF_OPT_USEDNS)
180                print_name(addr, af);
181        else {
182                struct pf_addr_wrap aw;
183
184                memset(&aw, 0, sizeof(aw));
185                aw.v.a.addr = *addr;
186                if (af == AF_INET)
187                        aw.v.a.mask.addr32[0] = 0xffffffff;
188                else {
189                        memset(&aw.v.a.mask, 0xff, sizeof(aw.v.a.mask));
190                        af = AF_INET6;
191                }
192                print_addr(&aw, af, opts & PF_OPT_VERBOSE2);
193        }
194
195        if (port) {
196                if (af == AF_INET)
197                        printf(":%u", ntohs(port));
198                else
199                        printf("[%u]", ntohs(port));
200        }
201}
202
203void
204print_seq(struct pfsync_state_peer *p)
205{
206        if (p->seqdiff)
207                printf("[%u + %u](+%u)", ntohl(p->seqlo),
208                    ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff));
209        else
210                printf("[%u + %u]", ntohl(p->seqlo),
211                    ntohl(p->seqhi) - ntohl(p->seqlo));
212}
213
214void
215print_state(struct pfsync_state *s, int opts)
216{
217        struct pfsync_state_peer *src, *dst;
218        struct pfsync_state_key *sk, *nk;
219        struct protoent *p;
220        int min, sec;
221
222        if (s->direction == PF_OUT) {
223                src = &s->src;
224                dst = &s->dst;
225                sk = &s->key[PF_SK_STACK];
226                nk = &s->key[PF_SK_WIRE];
227                if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6) 
228                        sk->port[0] = nk->port[0];
229        } else {
230                src = &s->dst;
231                dst = &s->src;
232                sk = &s->key[PF_SK_WIRE];
233                nk = &s->key[PF_SK_STACK];
234                if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6) 
235                        sk->port[1] = nk->port[1];
236        }
237        printf("%s ", s->ifname);
238        if ((p = getprotobynumber(s->proto)) != NULL)
239                printf("%s ", p->p_name);
240        else
241                printf("%u ", s->proto);
242
243        print_host(&nk->addr[1], nk->port[1], s->af, opts);
244        if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
245            nk->port[1] != sk->port[1]) {
246                printf(" (");
247                print_host(&sk->addr[1], sk->port[1], s->af, opts);
248                printf(")");
249        }
250        if (s->direction == PF_OUT)
251                printf(" -> ");
252        else
253                printf(" <- ");
254        print_host(&nk->addr[0], nk->port[0], s->af, opts);
255        if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
256            nk->port[0] != sk->port[0]) {
257                printf(" (");
258                print_host(&sk->addr[0], sk->port[0], s->af, opts);
259                printf(")");
260        }
261
262        printf("    ");
263        if (s->proto == IPPROTO_TCP) {
264                if (src->state <= TCPS_TIME_WAIT &&
265                    dst->state <= TCPS_TIME_WAIT)
266                        printf("   %s:%s\n", tcpstates[src->state],
267                            tcpstates[dst->state]);
268                else if (src->state == PF_TCPS_PROXY_SRC ||
269                    dst->state == PF_TCPS_PROXY_SRC)
270                        printf("   PROXY:SRC\n");
271                else if (src->state == PF_TCPS_PROXY_DST ||
272                    dst->state == PF_TCPS_PROXY_DST)
273                        printf("   PROXY:DST\n");
274                else
275                        printf("   <BAD STATE LEVELS %u:%u>\n",
276                            src->state, dst->state);
277                if (opts & PF_OPT_VERBOSE) {
278                        printf("   ");
279                        print_seq(src);
280                        if (src->wscale && dst->wscale)
281                                printf(" wscale %u",
282                                    src->wscale & PF_WSCALE_MASK);
283                        printf("  ");
284                        print_seq(dst);
285                        if (src->wscale && dst->wscale)
286                                printf(" wscale %u",
287                                    dst->wscale & PF_WSCALE_MASK);
288                        printf("\n");
289                }
290        } else if (s->proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
291            dst->state < PFUDPS_NSTATES) {
292                const char *states[] = PFUDPS_NAMES;
293
294                printf("   %s:%s\n", states[src->state], states[dst->state]);
295        } else if (s->proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
296            dst->state < PFOTHERS_NSTATES) {
297                /* XXX ICMP doesn't really have state levels */
298                const char *states[] = PFOTHERS_NAMES;
299
300                printf("   %s:%s\n", states[src->state], states[dst->state]);
301        } else {
302                printf("   %u:%u\n", src->state, dst->state);
303        }
304
305        if (opts & PF_OPT_VERBOSE) {
306                u_int64_t packets[2];
307                u_int64_t bytes[2];
308                u_int32_t creation = ntohl(s->creation);
309                u_int32_t expire = ntohl(s->expire);
310
311                sec = creation % 60;
312                creation /= 60;
313                min = creation % 60;
314                creation /= 60;
315                printf("   age %.2u:%.2u:%.2u", creation, min, sec);
316                sec = expire % 60;
317                expire /= 60;
318                min = expire % 60;
319                expire /= 60;
320                printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
321
322                bcopy(s->packets[0], &packets[0], sizeof(u_int64_t));
323                bcopy(s->packets[1], &packets[1], sizeof(u_int64_t));
324                bcopy(s->bytes[0], &bytes[0], sizeof(u_int64_t));
325                bcopy(s->bytes[1], &bytes[1], sizeof(u_int64_t));
326                printf(", %llu:%llu pkts, %llu:%llu bytes",
327#ifdef __FreeBSD__
328                    (unsigned long long)betoh64(packets[0]),
329                    (unsigned long long)betoh64(packets[1]),
330                    (unsigned long long)betoh64(bytes[0]),
331                    (unsigned long long)betoh64(bytes[1]));
332#else
333                    betoh64(packets[0]),
334                    betoh64(packets[1]),
335                    betoh64(bytes[0]),
336                    betoh64(bytes[1]));
337#endif
338                if (ntohl(s->anchor) != -1)
339                        printf(", anchor %u", ntohl(s->anchor));
340                if (ntohl(s->rule) != -1)
341                        printf(", rule %u", ntohl(s->rule));
342                if (s->state_flags & PFSTATE_SLOPPY)
343                        printf(", sloppy");
344                if (s->state_flags & PFSTATE_PFLOW)
345                        printf(", pflow");
346                if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
347                        printf(", source-track");
348                if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)
349                        printf(", sticky-address");
350                printf("\n");
351        }
352        if (opts & PF_OPT_VERBOSE2) {
353                u_int64_t id;
354
355                bcopy(&s->id, &id, sizeof(u_int64_t));
356                printf("   id: %016llx creatorid: %08x",
357#ifdef __FreeBSD__
358                    (unsigned long long)betoh64(id), ntohl(s->creatorid));
359#else
360                    betoh64(id), ntohl(s->creatorid));
361#endif
362                printf("\n");
363        }
364}
365
366int
367unmask(struct pf_addr *m, sa_family_t af)
368{
369        int i = 31, j = 0, b = 0;
370        u_int32_t tmp;
371
372        while (j < 4 && m->addr32[j] == 0xffffffff) {
373                b += 32;
374                j++;
375        }
376        if (j < 4) {
377                tmp = ntohl(m->addr32[j]);
378                for (i = 31; tmp & (1 << i); --i)
379                        b++;
380        }
381        return (b);
382}
Note: See TracBrowser for help on using the repository browser.