1 /* $NetBSD: pf_print_state.c,v 1.1 2010/12/05 05:11:30 christos Exp $ */
2 /* $OpenBSD: pf_print_state.c,v 1.45 2007/05/31 04:13:37 mcbride Exp $ */
5 * Copyright (c) 2001 Daniel Hartmeier
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
36 __RCSID("$NetBSD: pf_print_state.c,v 1.1 2010/12/05 05:11:30 christos Exp $");
43 #include <sys/types.h>
44 #include <sys/socket.h>
47 #include <netinet/tcp_fsm.h>
48 #include <net/pfvar.h>
49 #include <arpa/inet.h>
55 #include "pfctl_parser.h"
58 void print_name(struct pf_addr
*, sa_family_t
);
61 print_addr(struct pf_addr_wrap
*addr
, sa_family_t af
, int verbose
)
65 printf("(%s", addr
->v
.ifname
);
66 if (addr
->iflags
& PFI_AFLAG_NETWORK
)
68 if (addr
->iflags
& PFI_AFLAG_BROADCAST
)
70 if (addr
->iflags
& PFI_AFLAG_PEER
)
72 if (addr
->iflags
& PFI_AFLAG_NOALIAS
)
75 if (addr
->p
.dyncnt
<= 0)
78 printf(":%d", addr
->p
.dyncnt
);
84 if (addr
->p
.tblcnt
== -1)
85 printf("<%s:*>", addr
->v
.tblname
);
87 printf("<%s:%d>", addr
->v
.tblname
,
90 printf("<%s>", addr
->v
.tblname
);
92 case PF_ADDR_ADDRMASK
:
93 if (PF_AZERO(&addr
->v
.a
.addr
, AF_INET6
) &&
94 PF_AZERO(&addr
->v
.a
.mask
, AF_INET6
))
99 if (inet_ntop(af
, &addr
->v
.a
.addr
, buf
,
100 sizeof(buf
)) == NULL
)
106 case PF_ADDR_NOROUTE
:
109 case PF_ADDR_URPFFAILED
:
110 printf("urpf-failed");
112 case PF_ADDR_RTLABEL
:
113 printf("route \"%s\"", addr
->v
.rtlabelname
);
120 /* mask if not _both_ address and mask are zero */
121 if (!(PF_AZERO(&addr
->v
.a
.addr
, AF_INET6
) &&
122 PF_AZERO(&addr
->v
.a
.mask
, AF_INET6
))) {
123 int bits
= unmask(&addr
->v
.a
.mask
, af
);
125 if (bits
!= (af
== AF_INET
? 32 : 128))
131 print_name(struct pf_addr
*addr
, sa_family_t af
)
133 char host
[NI_MAXHOST
];
135 strlcpy(host
, "?", sizeof(host
));
138 struct sockaddr_in sin
;
140 memset(&sin
, 0, sizeof(sin
));
141 sin
.sin_len
= sizeof(sin
);
142 sin
.sin_family
= AF_INET
;
143 sin
.sin_addr
= addr
->v4
;
144 getnameinfo((struct sockaddr
*)&sin
, sin
.sin_len
,
145 host
, sizeof(host
), NULL
, 0, NI_NOFQDN
);
149 struct sockaddr_in6 sin6
;
151 memset(&sin6
, 0, sizeof(sin6
));
152 sin6
.sin6_len
= sizeof(sin6
);
153 sin6
.sin6_family
= AF_INET6
;
154 sin6
.sin6_addr
= addr
->v6
;
155 getnameinfo((struct sockaddr
*)&sin6
, sin6
.sin6_len
,
156 host
, sizeof(host
), NULL
, 0, NI_NOFQDN
);
164 print_host(struct pfsync_state_host
*h
, sa_family_t af
, int opts
)
166 u_int16_t p
= ntohs(h
->port
);
168 if (opts
& PF_OPT_USEDNS
)
169 print_name(&h
->addr
, af
);
171 struct pf_addr_wrap aw
;
173 memset(&aw
, 0, sizeof(aw
));
174 aw
.v
.a
.addr
= h
->addr
;
176 aw
.v
.a
.mask
.addr32
[0] = 0xffffffff;
178 memset(&aw
.v
.a
.mask
, 0xff, sizeof(aw
.v
.a
.mask
));
181 print_addr(&aw
, af
, opts
& PF_OPT_VERBOSE2
);
193 print_seq(struct pfsync_state_peer
*p
)
196 printf("[%u + %u](+%u)", p
->seqlo
, p
->seqhi
- p
->seqlo
,
199 printf("[%u + %u]", p
->seqlo
, p
->seqhi
- p
->seqlo
);
203 print_state(struct pfsync_state
*s
, int opts
)
205 struct pfsync_state_peer
*src
, *dst
;
209 if (s
->direction
== PF_OUT
) {
216 printf("%s ", s
->ifname
);
217 if ((p
= getprotobynumber(s
->proto
)) != NULL
)
218 printf("%s ", p
->p_name
);
220 printf("%u ", s
->proto
);
221 if (PF_ANEQ(&s
->lan
.addr
, &s
->gwy
.addr
, s
->af
) ||
222 (s
->lan
.port
!= s
->gwy
.port
)) {
223 print_host(&s
->lan
, s
->af
, opts
);
224 if (s
->direction
== PF_OUT
)
229 print_host(&s
->gwy
, s
->af
, opts
);
230 if (s
->direction
== PF_OUT
)
234 print_host(&s
->ext
, s
->af
, opts
);
237 if (s
->proto
== IPPROTO_TCP
) {
238 if (src
->state
<= TCPS_TIME_WAIT
&&
239 dst
->state
<= TCPS_TIME_WAIT
)
240 printf(" %s:%s\n", tcpstates
[src
->state
],
241 tcpstates
[dst
->state
]);
242 else if (src
->state
== PF_TCPS_PROXY_SRC
||
243 dst
->state
== PF_TCPS_PROXY_SRC
)
244 printf(" PROXY:SRC\n");
245 else if (src
->state
== PF_TCPS_PROXY_DST
||
246 dst
->state
== PF_TCPS_PROXY_DST
)
247 printf(" PROXY:DST\n");
249 printf(" <BAD STATE LEVELS %u:%u>\n",
250 src
->state
, dst
->state
);
251 if (opts
& PF_OPT_VERBOSE
) {
254 if (src
->wscale
&& dst
->wscale
)
256 src
->wscale
& PF_WSCALE_MASK
);
259 if (src
->wscale
&& dst
->wscale
)
261 dst
->wscale
& PF_WSCALE_MASK
);
264 } else if (s
->proto
== IPPROTO_UDP
&& src
->state
< PFUDPS_NSTATES
&&
265 dst
->state
< PFUDPS_NSTATES
) {
266 const char *states
[] = PFUDPS_NAMES
;
268 printf(" %s:%s\n", states
[src
->state
], states
[dst
->state
]);
269 } else if (s
->proto
!= IPPROTO_ICMP
&& src
->state
< PFOTHERS_NSTATES
&&
270 dst
->state
< PFOTHERS_NSTATES
) {
271 /* XXX ICMP doesn't really have state levels */
272 const char *states
[] = PFOTHERS_NAMES
;
274 printf(" %s:%s\n", states
[src
->state
], states
[dst
->state
]);
276 printf(" %u:%u\n", src
->state
, dst
->state
);
279 if (opts
& PF_OPT_VERBOSE
) {
280 sec
= s
->creation
% 60;
282 min
= s
->creation
% 60;
284 printf(" age %.2u:%.2u:%.2u", s
->creation
, min
, sec
);
285 sec
= s
->expire
% 60;
287 min
= s
->expire
% 60;
289 printf(", expires in %.2u:%.2u:%.2u", s
->expire
, min
, sec
);
290 printf(", %llu:%llu pkts, %llu:%llu bytes",
291 (unsigned long long)pf_state_counter_from_pfsync(s
->packets
[0]),
292 (unsigned long long)pf_state_counter_from_pfsync(s
->packets
[1]),
293 (unsigned long long)pf_state_counter_from_pfsync(s
->bytes
[0]),
294 (unsigned long long)pf_state_counter_from_pfsync(s
->bytes
[1]));
296 printf(", anchor %u", s
->anchor
);
298 printf(", rule %u", s
->rule
);
299 if (s
->sync_flags
& PFSYNC_FLAG_SRCNODE
)
300 printf(", source-track");
301 if (s
->sync_flags
& PFSYNC_FLAG_NATSRCNODE
)
302 printf(", sticky-address");
305 if (opts
& PF_OPT_VERBOSE2
) {
306 printf(" id: %016llx creatorid: %08x%s\n",
307 (unsigned long long int)pf_state_counter_from_pfsync(s
->id
),
309 ((s
->sync_flags
& PFSTATE_NOSYNC
) ? " (no-sync)" : ""));
314 unmask(struct pf_addr
*m
, sa_family_t af
)
316 int i
= 31, j
= 0, b
= 0;
319 while (j
< 4 && m
->addr32
[j
] == 0xffffffff) {
324 tmp
= ntohl(m
->addr32
[j
]);
325 for (i
= 31; tmp
& (1 << i
); --i
)