1*c74ad251Schristos /* $NetBSD: print-pfsync.c,v 1.5 2023/08/17 20:19:40 christos Exp $ */
211b3aaa1Schristos /* $OpenBSD: print-pfsync.c,v 1.30 2007/05/31 04:16:26 mcbride Exp $ */
311b3aaa1Schristos
411b3aaa1Schristos /*
511b3aaa1Schristos * Copyright (c) 2002 Michael Shalayeff
611b3aaa1Schristos * All rights reserved.
711b3aaa1Schristos *
811b3aaa1Schristos * Redistribution and use in source and binary forms, with or without
911b3aaa1Schristos * modification, are permitted provided that the following conditions
1011b3aaa1Schristos * are met:
1111b3aaa1Schristos * 1. Redistributions of source code must retain the above copyright
1211b3aaa1Schristos * notice, this list of conditions and the following disclaimer.
1311b3aaa1Schristos * 2. Redistributions in binary form must reproduce the above copyright
1411b3aaa1Schristos * notice, this list of conditions and the following disclaimer in the
1511b3aaa1Schristos * documentation and/or other materials provided with the distribution.
1611b3aaa1Schristos *
1711b3aaa1Schristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1811b3aaa1Schristos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1911b3aaa1Schristos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2011b3aaa1Schristos * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
2111b3aaa1Schristos * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2211b3aaa1Schristos * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2311b3aaa1Schristos * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2411b3aaa1Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2511b3aaa1Schristos * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2611b3aaa1Schristos * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2711b3aaa1Schristos * THE POSSIBILITY OF SUCH DAMAGE.
2811b3aaa1Schristos */
2911b3aaa1Schristos
3011b3aaa1Schristos #include <sys/cdefs.h>
3111b3aaa1Schristos #ifndef lint
3211b3aaa1Schristos #if 0
3311b3aaa1Schristos static const char rcsid[] =
34*c74ad251Schristos "@(#) $Header: /cvsroot/src/external/bsd/tcpdump/dist/print-pfsync.c,v 1.5 2023/08/17 20:19:40 christos Exp $";
3511b3aaa1Schristos #else
36*c74ad251Schristos __RCSID("$NetBSD: print-pfsync.c,v 1.5 2023/08/17 20:19:40 christos Exp $");
3711b3aaa1Schristos #endif
3811b3aaa1Schristos #endif
3911b3aaa1Schristos
4011b3aaa1Schristos #ifdef HAVE_CONFIG_H
4111b3aaa1Schristos #include "config.h"
4211b3aaa1Schristos #endif
4311b3aaa1Schristos
44fdccd7e4Schristos #include <sys/types.h>
45fdccd7e4Schristos #include <sys/socket.h>
46fdccd7e4Schristos #include <net/if.h>
47fdccd7e4Schristos #include <net/pfvar.h>
48fdccd7e4Schristos #include <net/if_pflog.h>
49fdccd7e4Schristos
50fdccd7e4Schristos #include <netdissect-stdinc.h>
51b3a00663Schristos
5211b3aaa1Schristos #include <sys/param.h>
5311b3aaa1Schristos #include <sys/time.h>
5411b3aaa1Schristos #include <sys/socket.h>
5511b3aaa1Schristos #include <sys/file.h>
5611b3aaa1Schristos #include <sys/ioctl.h>
5711b3aaa1Schristos
5811b3aaa1Schristos #ifdef __STDC__
5911b3aaa1Schristos struct rtentry;
6011b3aaa1Schristos #endif
6111b3aaa1Schristos #include <net/if.h>
6211b3aaa1Schristos
63b3a00663Schristos #if 0
6411b3aaa1Schristos #include <netinet/in.h>
6511b3aaa1Schristos #include <netinet/in_systm.h>
6611b3aaa1Schristos #include <netinet/ip.h>
67b3a00663Schristos #endif
6811b3aaa1Schristos
6911b3aaa1Schristos #include <net/pfvar.h>
7011b3aaa1Schristos #include <net/if_pfsync.h>
7111b3aaa1Schristos
7211b3aaa1Schristos #include <ctype.h>
7311b3aaa1Schristos #include <netdb.h>
7411b3aaa1Schristos #include <pcap.h>
7511b3aaa1Schristos #include <signal.h>
7611b3aaa1Schristos #include <stdio.h>
7711b3aaa1Schristos #include <string.h>
7811b3aaa1Schristos
7911b3aaa1Schristos #include "interface.h"
80fdccd7e4Schristos #include "netdissect.h"
8111b3aaa1Schristos #include "pfctl_parser.h"
8211b3aaa1Schristos #include "pfctl.h"
8311b3aaa1Schristos
8411b3aaa1Schristos const char *pfsync_acts[] = { PFSYNC_ACTIONS };
8511b3aaa1Schristos
86fdccd7e4Schristos static void pfsync_print(netdissect_options *, struct pfsync_header *, int);
8711b3aaa1Schristos
88*c74ad251Schristos void
pfsync_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)89b3a00663Schristos pfsync_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
9011b3aaa1Schristos {
9111b3aaa1Schristos u_int caplen = h->caplen;
9211b3aaa1Schristos
93b3a00663Schristos ts_print(ndo, &h->ts);
9411b3aaa1Schristos
9511b3aaa1Schristos if (caplen < PFSYNC_HDRLEN) {
96*c74ad251Schristos ND_PRINT("[|pfsync]");
9711b3aaa1Schristos goto out;
9811b3aaa1Schristos }
9911b3aaa1Schristos
100fdccd7e4Schristos pfsync_print(ndo, (struct pfsync_header *)p,
10111b3aaa1Schristos caplen - sizeof(struct pfsync_header));
10211b3aaa1Schristos out:
103fdccd7e4Schristos if (ndo->ndo_suppress_default_print)
104fdccd7e4Schristos ND_DEFAULTPRINT((const u_char *)h, caplen);
10511b3aaa1Schristos //putchar('\n');
10611b3aaa1Schristos }
10711b3aaa1Schristos
10811b3aaa1Schristos void
pfsync_ip_print(netdissect_options * ndo,const u_char * bp,u_int len,const u_char * bp2 __unused)109fdccd7e4Schristos pfsync_ip_print(netdissect_options *ndo, const u_char *bp, u_int len, const u_char *bp2 __unused)
11011b3aaa1Schristos {
11111b3aaa1Schristos struct pfsync_header *hdr = (struct pfsync_header *)bp;
11211b3aaa1Schristos
11311b3aaa1Schristos if (len < PFSYNC_HDRLEN)
11411b3aaa1Schristos printf("[|pfsync]");
11511b3aaa1Schristos else
116fdccd7e4Schristos pfsync_print(ndo, hdr, (len - sizeof(struct pfsync_header)));
11711b3aaa1Schristos //putchar('\n');
11811b3aaa1Schristos }
11911b3aaa1Schristos
12011b3aaa1Schristos static void
pfsync_print(netdissect_options * ndo,struct pfsync_header * hdr,int len)121fdccd7e4Schristos pfsync_print(netdissect_options *ndo, struct pfsync_header *hdr, int len)
12211b3aaa1Schristos {
12311b3aaa1Schristos struct pfsync_state *s;
12411b3aaa1Schristos struct pfsync_state_upd *u;
12511b3aaa1Schristos struct pfsync_state_del *d;
12611b3aaa1Schristos struct pfsync_state_clr *c;
12711b3aaa1Schristos struct pfsync_state_upd_req *r;
12811b3aaa1Schristos struct pfsync_state_bus *b;
12911b3aaa1Schristos struct pfsync_tdb *t;
13011b3aaa1Schristos int i, flags = 0, min, sec;
13111b3aaa1Schristos u_int64_t id;
13211b3aaa1Schristos
133fdccd7e4Schristos if (ndo->ndo_eflag)
13411b3aaa1Schristos printf("PFSYNCv%d count %d: ",
13511b3aaa1Schristos hdr->version, hdr->count);
13611b3aaa1Schristos
13711b3aaa1Schristos if (hdr->action < PFSYNC_ACT_MAX)
138fdccd7e4Schristos printf("%s %s:", (ndo->ndo_vflag == 0) ? "PFSYNC" : "",
13911b3aaa1Schristos pfsync_acts[hdr->action]);
14011b3aaa1Schristos else
141fdccd7e4Schristos printf("%s %d?:", (ndo->ndo_vflag == 0) ? "PFSYNC" : "",
14211b3aaa1Schristos hdr->action);
14311b3aaa1Schristos
144fdccd7e4Schristos if (!ndo->ndo_vflag)
14511b3aaa1Schristos return;
146fdccd7e4Schristos if (ndo->ndo_vflag)
14711b3aaa1Schristos flags |= PF_OPT_VERBOSE;
148fdccd7e4Schristos if (ndo->ndo_vflag > 1)
14911b3aaa1Schristos flags |= PF_OPT_VERBOSE2;
150fdccd7e4Schristos if (!ndo->ndo_nflag)
15111b3aaa1Schristos flags |= PF_OPT_USEDNS;
15211b3aaa1Schristos
15311b3aaa1Schristos switch (hdr->action) {
15411b3aaa1Schristos case PFSYNC_ACT_CLR:
15511b3aaa1Schristos if (sizeof(*c) <= len) {
15611b3aaa1Schristos c = (void *)((char *)hdr + PFSYNC_HDRLEN);
15711b3aaa1Schristos printf("\n\tcreatorid: %08x", htonl(c->creatorid));
15811b3aaa1Schristos if (c->ifname[0] != '\0')
15911b3aaa1Schristos printf(" interface: %s", c->ifname);
16011b3aaa1Schristos }
16111b3aaa1Schristos case PFSYNC_ACT_INS:
16211b3aaa1Schristos case PFSYNC_ACT_UPD:
16311b3aaa1Schristos case PFSYNC_ACT_DEL:
16411b3aaa1Schristos for (i = 1, s = (void *)((char *)hdr + PFSYNC_HDRLEN);
16511b3aaa1Schristos i <= hdr->count && i * sizeof(*s) <= len; i++, s++) {
16611b3aaa1Schristos
16711b3aaa1Schristos putchar('\n');
16811b3aaa1Schristos print_state(s, flags);
169fdccd7e4Schristos if (ndo->ndo_vflag > 1 && hdr->action == PFSYNC_ACT_UPD)
17011b3aaa1Schristos printf(" updates: %d", s->updates);
17111b3aaa1Schristos }
17211b3aaa1Schristos break;
17311b3aaa1Schristos case PFSYNC_ACT_UPD_C:
17411b3aaa1Schristos for (i = 1, u = (void *)((char *)hdr + PFSYNC_HDRLEN);
17511b3aaa1Schristos i <= hdr->count && i * sizeof(*u) <= len; i++, u++) {
17611b3aaa1Schristos memcpy(&id, &u->id, sizeof(id));
17711b3aaa1Schristos printf("\n\tid: %" PRIu64 " creatorid: %08x",
17811b3aaa1Schristos be64toh(id), ntohl(u->creatorid));
179fdccd7e4Schristos if (ndo->ndo_vflag > 1)
18011b3aaa1Schristos printf(" updates: %d", u->updates);
18111b3aaa1Schristos }
18211b3aaa1Schristos break;
18311b3aaa1Schristos case PFSYNC_ACT_DEL_C:
18411b3aaa1Schristos for (i = 1, d = (void *)((char *)hdr + PFSYNC_HDRLEN);
18511b3aaa1Schristos i <= hdr->count && i * sizeof(*d) <= len; i++, d++) {
18611b3aaa1Schristos memcpy(&id, &d->id, sizeof(id));
18711b3aaa1Schristos printf("\n\tid: %" PRIu64 " creatorid: %08x",
18811b3aaa1Schristos be64toh(id), ntohl(d->creatorid));
18911b3aaa1Schristos }
19011b3aaa1Schristos break;
19111b3aaa1Schristos case PFSYNC_ACT_UREQ:
19211b3aaa1Schristos for (i = 1, r = (void *)((char *)hdr + PFSYNC_HDRLEN);
19311b3aaa1Schristos i <= hdr->count && i * sizeof(*r) <= len; i++, r++) {
19411b3aaa1Schristos memcpy(&id, &r->id, sizeof(id));
19511b3aaa1Schristos printf("\n\tid: %" PRIu64 " creatorid: %08x",
19611b3aaa1Schristos be64toh(id), ntohl(r->creatorid));
19711b3aaa1Schristos }
19811b3aaa1Schristos break;
19911b3aaa1Schristos case PFSYNC_ACT_BUS:
20011b3aaa1Schristos if (sizeof(*b) <= len) {
20111b3aaa1Schristos b = (void *)((char *)hdr + PFSYNC_HDRLEN);
20211b3aaa1Schristos printf("\n\tcreatorid: %08x", htonl(b->creatorid));
20311b3aaa1Schristos sec = b->endtime % 60;
20411b3aaa1Schristos b->endtime /= 60;
20511b3aaa1Schristos min = b->endtime % 60;
20611b3aaa1Schristos b->endtime /= 60;
20711b3aaa1Schristos printf(" age %.2u:%.2u:%.2u", b->endtime, min, sec);
20811b3aaa1Schristos switch (b->status) {
20911b3aaa1Schristos case PFSYNC_BUS_START:
21011b3aaa1Schristos printf(" status: start");
21111b3aaa1Schristos break;
21211b3aaa1Schristos case PFSYNC_BUS_END:
21311b3aaa1Schristos printf(" status: end");
21411b3aaa1Schristos break;
21511b3aaa1Schristos default:
21611b3aaa1Schristos printf(" status: ?");
21711b3aaa1Schristos break;
21811b3aaa1Schristos }
21911b3aaa1Schristos }
22011b3aaa1Schristos break;
22111b3aaa1Schristos case PFSYNC_ACT_TDB_UPD:
22211b3aaa1Schristos for (i = 1, t = (void *)((char *)hdr + PFSYNC_HDRLEN);
22311b3aaa1Schristos i <= hdr->count && i * sizeof(*t) <= len; i++, t++)
22411b3aaa1Schristos printf("\n\tspi: %08x rpl: %u cur_bytes: %" PRIu64,
22511b3aaa1Schristos htonl(t->spi), htonl(t->rpl),
22611b3aaa1Schristos be64toh(t->cur_bytes));
22711b3aaa1Schristos /* XXX add dst and sproto? */
22811b3aaa1Schristos break;
22911b3aaa1Schristos default:
23011b3aaa1Schristos break;
23111b3aaa1Schristos }
23211b3aaa1Schristos }
233