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_basic.h> 73 #include <net/ipfw3_basic/ip_fw3_table.h> 74 #include <net/ipfw3_basic/ip_fw3_state.h> 75 #include <net/ipfw3_basic/ip_fw3_sync.h> 76 #include <net/ipfw3_nat/ip_fw3_nat.h> 77 #include <net/dummynet3/ip_dummynet3.h> 78 79 #include "ipfw3.h" 80 #include "ipfw3basic.h" 81 82 extern int verbose; 83 extern int do_time; 84 extern int do_quiet; 85 extern int do_force; 86 extern int do_acct; 87 extern int do_compact; 88 89 90 void 91 state_add(int ac, char *av[]) 92 { 93 /* TODO */ 94 } 95 96 void 97 state_delete(int ac, char *av[]) 98 { 99 int rulenum; 100 NEXT_ARG; 101 if (ac == 1 && isdigit(**av)) 102 rulenum = atoi(*av); 103 if (do_set_x(IP_FW_STATE_DEL, &rulenum, sizeof(int)) < 0 ) 104 err(EX_UNAVAILABLE, "do_set_x(IP_FW_STATE_DEL)"); 105 } 106 107 void 108 state_flush(int ac, char *av[]) 109 { 110 if (!do_force) { 111 int c; 112 113 printf("Are you sure? [yn] "); 114 fflush(stdout); 115 do { 116 c = toupper(getc(stdin)); 117 while (c != '\n' && getc(stdin) != '\n') 118 if (feof(stdin)) 119 return; /* and do not flush */ 120 } while (c != 'Y' && c != 'N'); 121 if (c == 'N') /* user said no */ 122 return; 123 } 124 if (do_set_x(IP_FW_STATE_FLUSH, NULL, 0) < 0 ) 125 err(EX_UNAVAILABLE, "do_set_x(IP_FW_STATE_FLUSH)"); 126 if (!do_quiet) 127 printf("Flushed all states.\n"); 128 } 129 130 void 131 state_list(int ac, char *av[]) 132 { 133 int nbytes, nalloc; 134 int rule_id; 135 uint8_t *data; 136 137 nalloc = 1024; 138 data = NULL; 139 140 NEXT_ARG; 141 if (ac == 0) 142 rule_id = 0; 143 else 144 rule_id = strtoul(*av, NULL, 10); 145 146 nbytes = nalloc; 147 while (nbytes >= nalloc) { 148 nalloc = nalloc * 2; 149 nbytes = nalloc; 150 if ((data = realloc(data, nbytes)) == NULL) { 151 err(EX_OSERR, "realloc"); 152 } 153 memcpy(data, &rule_id, sizeof(int)); 154 if (do_get_x(IP_FW_STATE_GET, data, &nbytes) < 0) { 155 err(EX_OSERR, "do_get_x(IP_FW_NAT_GET_RECORD)"); 156 } 157 } 158 159 if (nbytes == 0) 160 exit(EX_OK); 161 162 struct ipfw3_ioc_state *ioc; 163 ioc =(struct ipfw3_ioc_state *)data; 164 int count = nbytes / LEN_IOC_FW3_STATE; 165 int i; 166 for (i = 0; i < count; i ++) { 167 printf("%05u %d", ioc->rule_id, ioc->cpu_id); 168 if (ioc->proto == IPPROTO_ICMP) { 169 printf(" icmp"); 170 } else if (ioc->proto == IPPROTO_TCP) { 171 printf(" tcp"); 172 } else if (ioc->proto == IPPROTO_UDP) { 173 printf(" udp"); 174 } 175 printf(" %s:%hu",inet_ntoa(ioc->src_addr), 176 htons(ioc->src_port)); 177 printf(" %s:%hu",inet_ntoa(ioc->dst_addr), 178 htons(ioc->dst_port)); 179 printf(" %c", ioc->direction? 'o' : 'i'); 180 printf(" %lld", (long long)ioc->life); 181 printf("\n"); 182 ioc++; 183 } 184 } 185 186 void 187 state_main(int ac, char **av) 188 { 189 if (!strncmp(*av, "add", strlen(*av))) { 190 state_add(ac, av); 191 } else if (!strncmp(*av, "delete", strlen(*av))) { 192 state_delete(ac, av); 193 } else if (!strncmp(*av, "flush", strlen(*av))) { 194 state_flush(ac, av); 195 } else if (!strncmp(*av, "list", strlen(*av))) { 196 state_list(ac, av); 197 } else if (!strncmp(*av, "show", strlen(*av))) { 198 do_acct = 1; 199 state_list(ac, av); 200 } else { 201 errx(EX_USAGE, "bad ipfw3 state command `%s'", *av); 202 } 203 } 204 205 206