1 /* $OpenBSD: pf_print_state.c,v 1.51 2008/06/29 08:42:15 mcbride Exp $ */
4 * Copyright (c) 2001 Daniel Hartmeier
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <sys/endian.h>
38 #include <netinet/tcp_fsm.h>
39 #include <net/pf/pfvar.h>
40 #include <arpa/inet.h>
47 #include "pfctl_parser.h"
50 void print_name(struct pf_addr
*, sa_family_t
);
53 print_addr(struct pf_addr_wrap
*addr
, sa_family_t af
, int verbose
)
57 printf("(%s", addr
->v
.ifname
);
58 if (addr
->iflags
& PFI_AFLAG_NETWORK
)
60 if (addr
->iflags
& PFI_AFLAG_BROADCAST
)
62 if (addr
->iflags
& PFI_AFLAG_PEER
)
64 if (addr
->iflags
& PFI_AFLAG_NOALIAS
)
67 if (addr
->p
.dyncnt
<= 0)
70 printf(":%d", addr
->p
.dyncnt
);
76 if (addr
->p
.tblcnt
== -1)
77 printf("<%s:*>", addr
->v
.tblname
);
79 printf("<%s:%d>", addr
->v
.tblname
,
82 printf("<%s>", addr
->v
.tblname
);
87 if (inet_ntop(af
, &addr
->v
.a
.addr
, buf
, sizeof(buf
)) == NULL
)
91 if (inet_ntop(af
, &addr
->v
.a
.mask
, buf
, sizeof(buf
)) == NULL
)
97 case PF_ADDR_ADDRMASK
:
98 if (PF_AZERO(&addr
->v
.a
.addr
, AF_INET6
) &&
99 PF_AZERO(&addr
->v
.a
.mask
, AF_INET6
))
104 if (inet_ntop(af
, &addr
->v
.a
.addr
, buf
,
105 sizeof(buf
)) == NULL
)
111 case PF_ADDR_NOROUTE
:
114 case PF_ADDR_URPFFAILED
:
115 printf("urpf-failed");
117 case PF_ADDR_RTLABEL
:
118 printf("route \"%s\"", addr
->v
.rtlabelname
);
125 /* mask if not _both_ address and mask are zero */
126 if (addr
->type
!= PF_ADDR_RANGE
&&
127 !(PF_AZERO(&addr
->v
.a
.addr
, AF_INET6
) &&
128 PF_AZERO(&addr
->v
.a
.mask
, AF_INET6
))) {
129 int bits
= unmask(&addr
->v
.a
.mask
, af
);
131 if (bits
!= (af
== AF_INET
? 32 : 128))
137 print_name(struct pf_addr
*addr
, sa_family_t af
)
139 char his_host
[NI_MAXHOST
];
141 strlcpy(his_host
, "?", sizeof(his_host
));
144 struct sockaddr_in sin
;
146 memset(&sin
, 0, sizeof(sin
));
147 sin
.sin_len
= sizeof(sin
);
148 sin
.sin_family
= AF_INET
;
149 sin
.sin_addr
= addr
->v4
;
150 getnameinfo((struct sockaddr
*)&sin
, sin
.sin_len
,
151 his_host
, sizeof(his_host
), NULL
, 0, NI_NOFQDN
);
155 struct sockaddr_in6 sin6
;
157 memset(&sin6
, 0, sizeof(sin6
));
158 sin6
.sin6_len
= sizeof(sin6
);
159 sin6
.sin6_family
= AF_INET6
;
160 sin6
.sin6_addr
= addr
->v6
;
161 getnameinfo((struct sockaddr
*)&sin6
, sin6
.sin6_len
,
162 his_host
, sizeof(his_host
), NULL
, 0, NI_NOFQDN
);
166 printf("%s", his_host
);
170 print_host(struct pf_addr
*addr
, u_int16_t port
, sa_family_t af
, int opts
)
172 if (opts
& PF_OPT_USEDNS
)
173 print_name(addr
, af
);
175 struct pf_addr_wrap aw
;
177 memset(&aw
, 0, sizeof(aw
));
180 aw
.v
.a
.mask
.addr32
[0] = 0xffffffff;
182 memset(&aw
.v
.a
.mask
, 0xff, sizeof(aw
.v
.a
.mask
));
185 print_addr(&aw
, af
, opts
& PF_OPT_VERBOSE2
);
190 printf(":%u", ntohs(port
));
192 printf("[%u]", ntohs(port
));
197 print_seq(struct pfsync_state_peer
*p
)
200 printf("[%u + %u](+%u)", ntohl(p
->seqlo
),
201 ntohl(p
->seqhi
) - ntohl(p
->seqlo
), ntohl(p
->seqdiff
));
203 printf("[%u + %u]", ntohl(p
->seqlo
),
204 ntohl(p
->seqhi
) - ntohl(p
->seqlo
));
208 print_state(struct pfsync_state
*s
, int opts
)
210 struct pfsync_state_peer
*src
, *dst
;
211 struct pfsync_state_key
*sk
, *nk
;
215 if (s
->direction
== PF_OUT
) {
218 sk
= &s
->key
[PF_SK_STACK
];
219 nk
= &s
->key
[PF_SK_WIRE
];
220 if (s
->proto
== IPPROTO_ICMP
|| s
->proto
== IPPROTO_ICMPV6
)
221 sk
->port
[0] = nk
->port
[0];
225 sk
= &s
->key
[PF_SK_WIRE
];
226 nk
= &s
->key
[PF_SK_STACK
];
227 if (s
->proto
== IPPROTO_ICMP
|| s
->proto
== IPPROTO_ICMPV6
)
228 sk
->port
[1] = nk
->port
[1];
230 printf("%s ", s
->ifname
);
231 if ((p
= getprotobynumber(s
->proto
)) != NULL
)
232 printf("%s ", p
->p_name
);
234 printf("%u ", s
->proto
);
236 print_host(&nk
->addr
[1], nk
->port
[1], s
->af
, opts
);
237 if (PF_ANEQ(&nk
->addr
[1], &sk
->addr
[1], s
->af
) ||
238 nk
->port
[1] != sk
->port
[1]) {
240 print_host(&sk
->addr
[1], sk
->port
[1], s
->af
, opts
);
243 if (s
->direction
== PF_OUT
)
247 print_host(&nk
->addr
[0], nk
->port
[0], s
->af
, opts
);
248 if (PF_ANEQ(&nk
->addr
[0], &sk
->addr
[0], s
->af
) ||
249 nk
->port
[0] != sk
->port
[0]) {
251 print_host(&sk
->addr
[0], sk
->port
[0], s
->af
, opts
);
256 if (s
->proto
== IPPROTO_TCP
) {
257 if (src
->state
<= TCPS_TIME_WAIT
&&
258 dst
->state
<= TCPS_TIME_WAIT
)
259 printf(" %s:%s\n", tcpstates
[src
->state
],
260 tcpstates
[dst
->state
]);
261 else if (src
->state
== PF_TCPS_PROXY_SRC
||
262 dst
->state
== PF_TCPS_PROXY_SRC
)
263 printf(" PROXY:SRC\n");
264 else if (src
->state
== PF_TCPS_PROXY_DST
||
265 dst
->state
== PF_TCPS_PROXY_DST
)
266 printf(" PROXY:DST\n");
268 printf(" <BAD STATE LEVELS %u:%u>\n",
269 src
->state
, dst
->state
);
270 if (opts
& PF_OPT_VERBOSE
) {
273 if (src
->wscale
&& dst
->wscale
)
275 src
->wscale
& PF_WSCALE_MASK
);
278 if (src
->wscale
&& dst
->wscale
)
280 dst
->wscale
& PF_WSCALE_MASK
);
283 } else if (s
->proto
== IPPROTO_UDP
&& src
->state
< PFUDPS_NSTATES
&&
284 dst
->state
< PFUDPS_NSTATES
) {
285 const char *states
[] = PFUDPS_NAMES
;
287 printf(" %s:%s\n", states
[src
->state
], states
[dst
->state
]);
288 } else if (s
->proto
!= IPPROTO_ICMP
&& src
->state
< PFOTHERS_NSTATES
&&
289 dst
->state
< PFOTHERS_NSTATES
) {
290 /* XXX ICMP doesn't really have state levels */
291 const char *states
[] = PFOTHERS_NAMES
;
293 printf(" %s:%s\n", states
[src
->state
], states
[dst
->state
]);
295 printf(" %u:%u\n", src
->state
, dst
->state
);
298 if (opts
& PF_OPT_VERBOSE
) {
299 u_int64_t packets
[2];
301 u_int32_t creation
= ntohl(s
->creation
);
302 u_int32_t expire
= ntohl(s
->expire
);
308 printf(" age %.2u:%.2u:%.2u", creation
, min
, sec
);
311 min
= s
->expire
% 60;
313 printf(", expires in %.2u:%.2u:%.2u", expire
, min
, sec
);
315 bcopy(s
->packets
[0], &packets
[0], sizeof(u_int64_t
));
316 bcopy(s
->packets
[1], &packets
[1], sizeof(u_int64_t
));
317 bcopy(s
->bytes
[0], &bytes
[0], sizeof(u_int64_t
));
318 bcopy(s
->bytes
[1], &bytes
[1], sizeof(u_int64_t
));
319 printf(", %" PRIu64
":%" PRIu64
" pkts, %" PRIu64
":%" PRIu64
" bytes",
324 if (ntohl(s
->anchor
) != -1)
325 printf(", anchor %u", ntohl(s
->anchor
));
326 if (ntohl(s
->rule
) != -1)
327 printf(", rule %u", ntohl(s
->rule
));
328 if (s
->state_flags
& PFSTATE_SLOPPY
)
330 if (s
->sync_flags
& PFSYNC_FLAG_SRCNODE
)
331 printf(", source-track");
332 if (s
->sync_flags
& PFSYNC_FLAG_NATSRCNODE
)
333 printf(", sticky-address");
336 if (opts
& PF_OPT_VERBOSE2
) {
339 bcopy(&s
->id
, &id
, sizeof(u_int64_t
));
340 printf(" id: %016jx creatorid: %08x",
341 be64toh(id
), ntohl(s
->creatorid
));
347 unmask(struct pf_addr
*m
, sa_family_t af __unused
)
349 int i
= 31, j
= 0, b
= 0;
352 while (j
< 4 && m
->addr32
[j
] == 0xffffffff) {
357 tmp
= ntohl(m
->addr32
[j
]);
358 for (i
= 31; tmp
& (1 << i
); --i
)