1 /* $NetBSD: pf_print_state.c 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/types.h>
35 #include <sys/socket.h>
38 #include <netinet/tcp_fsm.h>
39 #include <net/pfvar.h>
40 #include <arpa/inet.h>
46 #include "pfctl_parser.h"
49 void print_name(struct pf_addr
*, sa_family_t
);
52 print_addr(struct pf_addr_wrap
*addr
, sa_family_t af
, int verbose
)
56 printf("(%s", addr
->v
.ifname
);
57 if (addr
->iflags
& PFI_AFLAG_NETWORK
)
59 if (addr
->iflags
& PFI_AFLAG_BROADCAST
)
61 if (addr
->iflags
& PFI_AFLAG_PEER
)
63 if (addr
->iflags
& PFI_AFLAG_NOALIAS
)
66 if (addr
->p
.dyncnt
<= 0)
69 printf(":%d", addr
->p
.dyncnt
);
75 if (addr
->p
.tblcnt
== -1)
76 printf("<%s:*>", addr
->v
.tblname
);
78 printf("<%s:%d>", addr
->v
.tblname
,
81 printf("<%s>", addr
->v
.tblname
);
83 case PF_ADDR_ADDRMASK
:
84 if (PF_AZERO(&addr
->v
.a
.addr
, AF_INET6
) &&
85 PF_AZERO(&addr
->v
.a
.mask
, AF_INET6
))
90 if (inet_ntop(af
, &addr
->v
.a
.addr
, buf
,
100 case PF_ADDR_URPFFAILED
:
101 printf("urpf-failed");
103 case PF_ADDR_RTLABEL
:
104 printf("route \"%s\"", addr
->v
.rtlabelname
);
111 /* mask if not _both_ address and mask are zero */
112 if (!(PF_AZERO(&addr
->v
.a
.addr
, AF_INET6
) &&
113 PF_AZERO(&addr
->v
.a
.mask
, AF_INET6
))) {
114 int bits
= unmask(&addr
->v
.a
.mask
, af
);
116 if (bits
!= (af
== AF_INET
? 32 : 128))
122 print_name(struct pf_addr
*addr
, sa_family_t af
)
124 char host
[NI_MAXHOST
];
126 strlcpy(host
, "?", sizeof(host
));
129 struct sockaddr_in sin
;
131 memset(&sin
, 0, sizeof(sin
));
132 sin
.sin_len
= sizeof(sin
);
133 sin
.sin_family
= AF_INET
;
134 sin
.sin_addr
= addr
->v4
;
135 getnameinfo((struct sockaddr
*)&sin
, sin
.sin_len
,
136 host
, sizeof(host
), NULL
, 0, NI_NOFQDN
);
140 struct sockaddr_in6 sin6
;
142 memset(&sin6
, 0, sizeof(sin6
));
143 sin6
.sin6_len
= sizeof(sin6
);
144 sin6
.sin6_family
= AF_INET6
;
145 sin6
.sin6_addr
= addr
->v6
;
146 getnameinfo((struct sockaddr
*)&sin6
, sin6
.sin6_len
,
147 host
, sizeof(host
), NULL
, 0, NI_NOFQDN
);
155 print_host(struct pfsync_state_host
*h
, sa_family_t af
, int opts
)
157 u_int16_t p
= ntohs(h
->port
);
159 if (opts
& PF_OPT_USEDNS
)
160 print_name(&h
->addr
, af
);
162 struct pf_addr_wrap aw
;
164 memset(&aw
, 0, sizeof(aw
));
165 aw
.v
.a
.addr
= h
->addr
;
167 aw
.v
.a
.mask
.addr32
[0] = 0xffffffff;
169 memset(&aw
.v
.a
.mask
, 0xff, sizeof(aw
.v
.a
.mask
));
172 print_addr(&aw
, af
, opts
& PF_OPT_VERBOSE2
);
184 print_seq(struct pfsync_state_peer
*p
)
187 printf("[%u + %u](+%u)", p
->seqlo
, p
->seqhi
- p
->seqlo
,
190 printf("[%u + %u]", p
->seqlo
, p
->seqhi
- p
->seqlo
);
194 print_state(struct pfsync_state
*s
, int opts
)
196 struct pfsync_state_peer
*src
, *dst
;
200 if (s
->direction
== PF_OUT
) {
207 printf("%s ", s
->ifname
);
208 if ((p
= getprotobynumber(s
->proto
)) != NULL
)
209 printf("%s ", p
->p_name
);
211 printf("%u ", s
->proto
);
212 if (PF_ANEQ(&s
->lan
.addr
, &s
->gwy
.addr
, s
->af
) ||
213 (s
->lan
.port
!= s
->gwy
.port
)) {
214 print_host(&s
->lan
, s
->af
, opts
);
215 if (s
->direction
== PF_OUT
)
220 print_host(&s
->gwy
, s
->af
, opts
);
221 if (s
->direction
== PF_OUT
)
225 print_host(&s
->ext
, s
->af
, opts
);
228 if (s
->proto
== IPPROTO_TCP
) {
229 if (src
->state
<= TCPS_TIME_WAIT
&&
230 dst
->state
<= TCPS_TIME_WAIT
)
231 printf(" %s:%s\n", tcpstates
[src
->state
],
232 tcpstates
[dst
->state
]);
233 else if (src
->state
== PF_TCPS_PROXY_SRC
||
234 dst
->state
== PF_TCPS_PROXY_SRC
)
235 printf(" PROXY:SRC\n");
236 else if (src
->state
== PF_TCPS_PROXY_DST
||
237 dst
->state
== PF_TCPS_PROXY_DST
)
238 printf(" PROXY:DST\n");
240 printf(" <BAD STATE LEVELS %u:%u>\n",
241 src
->state
, dst
->state
);
242 if (opts
& PF_OPT_VERBOSE
) {
245 if (src
->wscale
&& dst
->wscale
)
247 src
->wscale
& PF_WSCALE_MASK
);
250 if (src
->wscale
&& dst
->wscale
)
252 dst
->wscale
& PF_WSCALE_MASK
);
255 } else if (s
->proto
== IPPROTO_UDP
&& src
->state
< PFUDPS_NSTATES
&&
256 dst
->state
< PFUDPS_NSTATES
) {
257 const char *states
[] = PFUDPS_NAMES
;
259 printf(" %s:%s\n", states
[src
->state
], states
[dst
->state
]);
260 } else if (s
->proto
!= IPPROTO_ICMP
&& src
->state
< PFOTHERS_NSTATES
&&
261 dst
->state
< PFOTHERS_NSTATES
) {
262 /* XXX ICMP doesn't really have state levels */
263 const char *states
[] = PFOTHERS_NAMES
;
265 printf(" %s:%s\n", states
[src
->state
], states
[dst
->state
]);
267 printf(" %u:%u\n", src
->state
, dst
->state
);
270 if (opts
& PF_OPT_VERBOSE
) {
271 sec
= s
->creation
% 60;
273 min
= s
->creation
% 60;
275 printf(" age %.2u:%.2u:%.2u", s
->creation
, min
, sec
);
276 sec
= s
->expire
% 60;
278 min
= s
->expire
% 60;
280 printf(", expires in %.2u:%.2u:%.2u", s
->expire
, min
, sec
);
281 printf(", %llu:%llu pkts, %llu:%llu bytes",
282 (unsigned long long)pf_state_counter_from_pfsync(s
->packets
[0]),
283 (unsigned long long)pf_state_counter_from_pfsync(s
->packets
[1]),
284 (unsigned long long)pf_state_counter_from_pfsync(s
->bytes
[0]),
285 (unsigned long long)pf_state_counter_from_pfsync(s
->bytes
[1]));
287 printf(", anchor %u", s
->anchor
);
289 printf(", rule %u", s
->rule
);
290 if (s
->sync_flags
& PFSYNC_FLAG_SRCNODE
)
291 printf(", source-track");
292 if (s
->sync_flags
& PFSYNC_FLAG_NATSRCNODE
)
293 printf(", sticky-address");
296 if (opts
& PF_OPT_VERBOSE2
) {
297 printf(" id: %016llx creatorid: %08x%s\n",
298 (unsigned long long int)pf_state_counter_from_pfsync(s
->id
),
300 ((s
->sync_flags
& PFSTATE_NOSYNC
) ? " (no-sync)" : ""));
305 unmask(struct pf_addr
*m
, sa_family_t af
)
307 int i
= 31, j
= 0, b
= 0;
310 while (j
< 4 && m
->addr32
[j
] == 0xffffffff) {
315 tmp
= ntohl(m
->addr32
[j
]);
316 for (i
= 31; tmp
& (1 << i
); --i
)