1 /* 2 * Copyright (c) 2014 - 2018 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Bill Yuan <bycn82@dragonflybsd.org> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/mbuf.h> 37 #include <sys/socket.h> 38 #include <sys/sockio.h> 39 #include <sys/sysctl.h> 40 #include <sys/time.h> 41 #include <sys/wait.h> 42 43 #include <arpa/inet.h> 44 #include <ctype.h> 45 #include <dlfcn.h> 46 #include <err.h> 47 #include <errno.h> 48 #include <grp.h> 49 #include <limits.h> 50 #include <netdb.h> 51 #include <pwd.h> 52 #include <sysexits.h> 53 #include <signal.h> 54 #include <stdio.h> 55 #include <stdlib.h> 56 #include <stdarg.h> 57 #include <string.h> 58 #include <timeconv.h> 59 #include <unistd.h> 60 61 #include <netinet/in.h> 62 #include <netinet/in_systm.h> 63 #include <netinet/ip.h> 64 #include <netinet/ip_icmp.h> 65 #include <netinet/tcp.h> 66 #include <net/if.h> 67 #include <net/if_dl.h> 68 #include <net/route.h> 69 #include <net/ethernet.h> 70 71 #include <net/ipfw3/ip_fw3.h> 72 #include <net/ipfw3_basic/ip_fw3_table.h> 73 #include <net/ipfw3_basic/ip_fw3_sync.h> 74 #include <net/ipfw3_basic/ip_fw3_basic.h> 75 #include <net/ipfw3_nat/ip_fw3_nat.h> 76 #include <net/dummynet3/ip_dummynet3.h> 77 78 #include "ipfw3.h" 79 #include "ipfw3set.h" 80 81 void 82 set_toggle(int ac, char **av) 83 { 84 int error, num; 85 86 NEXT_ARG; 87 88 num = atoi(av[0]); 89 if (num > 0 && num < 32) { 90 error = do_set_x(IP_FW_SET_TOGGLE, &num, sizeof num); 91 if (error) { 92 err(EX_OSERR, "getsockopt(IP_FW_SET_TOGGLE)"); 93 } 94 } else { 95 errx(EX_USAGE, "invalid set %s", *av); 96 } 97 } 98 99 void 100 set_show(int ac, char **av) 101 { 102 int i, sets = 0, len; 103 104 len = sizeof(int); 105 if (do_get_x(IP_FW_SET_GET, &sets, &len) < 0) { 106 err(EX_OSERR, "getsockopt(IP_FW_SET_GET)"); 107 } 108 109 printf("disable:"); 110 for (i = 0; i < 32; i++) { 111 if (sets & (1<<i)) { 112 printf(" %d", i); 113 } 114 } 115 printf("\n"); 116 printf("enable:"); 117 for (i = 0; i < 32; i++) { 118 if (!(sets & (1<<i))) { 119 printf(" %d", i); 120 } 121 } 122 printf("\n"); 123 } 124 125 void 126 set_swap(int ac, char **av) 127 { 128 int num[2], error; 129 130 NEXT_ARG; 131 132 if (ac != 2) 133 errx(EX_USAGE, "set swap needs 2 set numbers"); 134 135 num[0] = atoi(av[0]); 136 num[1] = atoi(av[1]); 137 if (num[0] < 1 || num[0] > 31) { 138 errx(EX_DATAERR, "invalid set number %s", av[0]); 139 } 140 if (num[1] < 1 || num[1] > 31) { 141 errx(EX_DATAERR, "invalid set number %s", av[1]); 142 } 143 if (num[0] == num[1]) { 144 errx(EX_DATAERR, "same set numbers %s", av[0]); 145 } 146 147 error = do_set_x(IP_FW_SET_SWAP, num, sizeof(num)); 148 if (error) { 149 err(EX_OSERR, "getsockopt(IP_FW_SET_SWAP)"); 150 } 151 } 152 153 void 154 set_move_rule(int ac, char **av) 155 { 156 int num[2], error; 157 158 NEXT_ARG; 159 160 if (ac != 2) 161 errx(EX_USAGE, "move rule needs 2 numbers"); 162 163 num[0] = atoi(av[0]); 164 num[1] = atoi(av[1]); 165 if (num[0] < 1 || num[0] > 65534) { 166 errx(EX_DATAERR, "invalid rule number %s", av[0]); 167 } 168 if (num[1] < 1 || num[1] > 31) { 169 errx(EX_DATAERR, "invalid set number %s", av[1]); 170 } 171 if (num[0] == num[1]) { 172 errx(EX_DATAERR, "same set numbers %s", av[0]); 173 } 174 175 error = do_set_x(IP_FW_SET_MOVE_RULE, num, sizeof(num)); 176 if (error) { 177 err(EX_OSERR, "getsockopt(IP_FW_SET_MOVE_RULE)"); 178 } 179 } 180 181 void 182 set_move_set(int ac, char **av) 183 { 184 int num[2], error; 185 186 NEXT_ARG; 187 188 if (ac != 2) 189 errx(EX_USAGE, "move set needs 2 set numbers"); 190 191 num[0] = atoi(av[0]); 192 num[1] = atoi(av[1]); 193 if (num[0] < 1 || num[0] > 31) { 194 errx(EX_DATAERR, "invalid set number %s", av[0]); 195 } 196 if (num[1] < 1 || num[1] > 31) { 197 errx(EX_DATAERR, "invalid set number %s", av[1]); 198 } 199 if (num[0] == num[1]) { 200 errx(EX_DATAERR, "same set numbers %s", av[0]); 201 } 202 203 error = do_set_x(IP_FW_SET_MOVE_SET, num, sizeof(num)); 204 if (error) { 205 err(EX_OSERR, "getsockopt(IP_FW_SET_MOVE_SET)"); 206 } 207 } 208 209 void 210 set_flush(int ac, char **av) 211 { 212 int error, num; 213 214 NEXT_ARG; 215 216 num = atoi(av[0]); 217 if (num > 0 && num < 32) { 218 error = do_set_x(IP_FW_SET_FLUSH, &num, sizeof num); 219 if (error) { 220 err(EX_OSERR, "getsockopt(IP_FW_SET_FLUSH)"); 221 } 222 } else { 223 errx(EX_USAGE, "invalid set %s", *av); 224 } 225 } 226 /* 227 * ipfw3 set show 228 * ipfw3 set <set num> toggle 229 * ipfw3 set swap <old set num> <new set num> 230 * ipfw3 set move set <old set num> to <new set num> 231 * ipfw3 set move rule <rule num> to <set num> 232 * ipfw3 set <set num> flush 233 */ 234 void 235 set_main(int ac, char **av) 236 { 237 SWAP_ARG; 238 NEXT_ARG; 239 240 if (!ac) 241 errx(EX_USAGE, "set needs command"); 242 if (!strncmp(*av, "show", strlen(*av)) ) { 243 set_show(ac, av); 244 } else if (!strncmp(*av, "swap", strlen(*av))) { 245 set_swap(ac, av); 246 } else if (!strncmp(*av, "move", strlen(*av))) { 247 NEXT_ARG; 248 if (!strncmp(*av, "set", strlen(*av)) ) { 249 set_move_set(ac, av); 250 } else if (!strncmp(*av, "rule", strlen(*av)) ) { 251 set_move_rule(ac, av); 252 } else { 253 errx(EX_USAGE, "invalid move command %s", *av); 254 } 255 256 } else if (!strncmp(*av, "toggle", strlen(*av))) { 257 set_toggle(ac, av); 258 } else if (!strncmp(*av, "flush", strlen(*av))) { 259 set_flush(ac, av); 260 } else { 261 errx(EX_USAGE, "invalid set command %s", *av); 262 } 263 } 264 265