1 /* $NetBSD: pfsync.c Exp $ */
3 * Copyright (c) 2009 The NetBSD Foundation, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: pfsync.c Exp $");
33 #include <sys/param.h>
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <sys/sockio.h>
39 #include <net/route.h>
40 #include <net/pfvar.h>
41 #include <net/if_pfsync.h>
43 #include <arpa/inet.h>
57 static status_func_t status
;
58 static usage_func_t usage
;
59 static cmdloop_branch_t branch
;
61 static void pfsync_constructor(void) __attribute__((constructor
));
62 static void pfsync_status(prop_dictionary_t
, prop_dictionary_t
);
63 static int setpfsync_maxupd(prop_dictionary_t
, prop_dictionary_t
);
64 static int setpfsync_peer(prop_dictionary_t
, prop_dictionary_t
);
65 static int setpfsyncdev(prop_dictionary_t
, prop_dictionary_t
);
67 struct pinteger parse_maxupd
= PINTEGER_INITIALIZER1(&parse_maxupd
, "maxupd",
68 0, 255, 10, setpfsync_maxupd
, "maxupd", &command_root
.pb_parser
);
70 struct piface pfsyncdev
= PIFACE_INITIALIZER(&pfsyncdev
, "syncdev", setpfsyncdev
,
71 "syncdev", &command_root
.pb_parser
);
73 struct paddr parse_sync_peer
= PADDR_INITIALIZER(&parse_sync_peer
, "syncpeer",
74 setpfsync_peer
, "syncpeer", NULL
, NULL
, NULL
, &command_root
.pb_parser
);
76 static const struct kwinst pfsynckw
[] = {
77 {.k_word
= "maxupd", .k_nextparser
= &parse_maxupd
.pi_parser
},
78 {.k_word
= "syncdev", .k_nextparser
= &pfsyncdev
.pif_parser
},
79 {.k_word
= "-syncdev", .k_key
= "syncdev", .k_type
= KW_T_STR
,
80 .k_str
= "", .k_exec
= setpfsyncdev
,
81 .k_nextparser
= &command_root
.pb_parser
},
82 {.k_word
= "syncpeer", .k_nextparser
= &parse_sync_peer
.pa_parser
},
83 {.k_word
= "-syncpeer", .k_key
= "syncpeer", .k_type
= KW_T_STR
,
84 .k_str
= "", .k_exec
= setpfsync_peer
,
85 .k_nextparser
= &command_root
.pb_parser
}
88 struct pkw pfsync
= PKW_INITIALIZER(&pfsync
, "pfsync", NULL
, NULL
,
89 pfsynckw
, __arraycount(pfsynckw
), NULL
);
92 pfsync_set(prop_dictionary_t env
, struct pfsyncreq
*pfsyncr
)
94 if (indirect_ioctl(env
, SIOCSETPFSYNC
, pfsyncr
) == -1)
95 err(EXIT_FAILURE
, "SIOCSETPFSYNC");
99 pfsync_get1(prop_dictionary_t env
, struct pfsyncreq
*pfsyncr
)
101 memset(pfsyncr
, 0, sizeof(*pfsyncr
));
103 return indirect_ioctl(env
, SIOCGETPFSYNC
, pfsyncr
);
107 pfsync_get(prop_dictionary_t env
, struct pfsyncreq
*pfsyncr
)
109 if (pfsync_get1(env
, pfsyncr
) == -1)
110 err(EXIT_FAILURE
, "SIOCGETPFSYNC");
114 pfsync_status(prop_dictionary_t env
, prop_dictionary_t oenv
)
116 struct pfsyncreq pfsyncr
;
118 if (pfsync_get1(env
, &pfsyncr
) == -1)
121 if (pfsyncr
.pfsyncr_syncdev
[0] != '\0') {
122 printf("\tpfsync: syncdev: %s ", pfsyncr
.pfsyncr_syncdev
);
123 if (pfsyncr
.pfsyncr_syncpeer
.s_addr
!= INADDR_PFSYNC_GROUP
)
124 printf("syncpeer: %s ",
125 inet_ntoa(pfsyncr
.pfsyncr_syncpeer
));
126 printf("maxupd: %d\n", pfsyncr
.pfsyncr_maxupdates
);
132 setpfsync_maxupd(prop_dictionary_t env
, prop_dictionary_t oenv
)
134 struct pfsyncreq pfsyncr
;
137 if (!prop_dictionary_get_uint8(env
, "maxupd", &maxupd
)) {
142 pfsync_get(env
, &pfsyncr
);
144 pfsyncr
.pfsyncr_maxupdates
= maxupd
;
146 pfsync_set(env
, &pfsyncr
);
153 setpfsyncdev(prop_dictionary_t env
, prop_dictionary_t oenv
)
155 struct pfsyncreq pfsyncr
;
158 if (!prop_dictionary_get_cstring_nocopy(env
, "syncdev", &dev
)) {
163 pfsync_get(env
, &pfsyncr
);
165 strlcpy(pfsyncr
.pfsyncr_syncdev
, dev
, sizeof(pfsyncr
.pfsyncr_syncdev
));
167 pfsync_set(env
, &pfsyncr
);
173 setpfsync_peer(prop_dictionary_t env
, prop_dictionary_t oenv
)
175 struct pfsyncreq pfsyncr
;
177 const struct paddr_prefix
*peerpfx
;
178 const struct sockaddr_in
*s
;
180 data
= (prop_data_t
)prop_dictionary_get(env
, "syncpeer");
186 pfsync_get(env
, &pfsyncr
);
188 peerpfx
= prop_data_data_nocopy(data
);
190 if (peerpfx
!= NULL
) {
191 // Only AF_INET is supported for now
192 if (peerpfx
->pfx_addr
.sa_family
!= AF_INET
) {
198 s
= (const struct sockaddr_in
*)&peerpfx
->pfx_addr
;
200 memcpy(&pfsyncr
.pfsyncr_syncpeer
.s_addr
, &s
->sin_addr
,
201 MIN(sizeof(pfsyncr
.pfsyncr_syncpeer
.s_addr
),
202 peerpfx
->pfx_addr
.sa_len
));
204 memset(&pfsyncr
.pfsyncr_syncpeer
.s_addr
, 0,
205 sizeof(pfsyncr
.pfsyncr_syncpeer
.s_addr
));
208 pfsync_set(env
, &pfsyncr
);
214 pfsync_usage(prop_dictionary_t env
)
217 "\t[ maxupd n ] [ syncdev iface ] [syncpeer peer_addr]\n");
221 pfsync_constructor(void)
223 cmdloop_branch_init(&branch
, &pfsync
.pk_parser
);
224 register_cmdloop_branch(&branch
);
225 status_func_init(&status
, pfsync_status
);
226 usage_func_init(&usage
, pfsync_usage
);
227 register_status(&status
);
228 register_usage(&usage
);