1 /* 2 * Copyright (c) 2014 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Bill Yuan <bycn82@gmail.com> 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 <err.h> 36 #include <errno.h> 37 #include <grp.h> 38 #include <pwd.h> 39 #include <pcap.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <sysexits.h> 44 45 #include <net/if.h> 46 #include <net/route.h> 47 #include <net/pfil.h> 48 #include <netinet/in.h> 49 50 #include "../../../sys/net/ipfw3/ip_fw3.h" 51 #include "../../../sbin/ipfw3/ipfw.h" 52 #include "ipfw3_layer4.h" 53 54 int 55 char_at(char *str, char c) 56 { 57 int pos; 58 for (pos = 0; str[pos] != '\0'; pos++) { 59 if (str[pos] == c) 60 return pos; 61 } 62 return -1; 63 } 64 65 void 66 parse_tcpflag(ipfw_insn **cmd, int *ac, char **av[]) 67 { 68 (*cmd)->opcode = O_LAYER4_TCPFLAG; 69 (*cmd)->module = MODULE_LAYER4_ID; 70 (*cmd)->len = ((*cmd)->len&(F_NOT|F_OR))|LEN_OF_IPFWINSN; 71 /* XXX TODO parse the tcpflag value and store in arg1 or arg3 */ 72 NEXT_ARG1; 73 } 74 75 void 76 parse_uid(ipfw_insn **cmd, int *ac, char **av[]) 77 { 78 char *end; 79 uid_t uid; 80 struct passwd *pwd; 81 82 NEXT_ARG1; 83 ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)(*cmd); 84 uid = strtoul(**av, &end, 0); 85 pwd = (*end == '\0') ? getpwuid(uid) : getpwnam(**av); 86 if (pwd == NULL) 87 errx(EX_DATAERR, "uid \"%s\" not exists", **av); 88 89 cmd32->d[0] = pwd->pw_uid; 90 91 (*cmd)->opcode = O_LAYER4_UID; 92 (*cmd)->module = MODULE_LAYER4_ID; 93 (*cmd)->len = F_INSN_SIZE(ipfw_insn_u32); 94 NEXT_ARG1; 95 } 96 97 void 98 parse_gid(ipfw_insn **cmd, int *ac, char **av[]) 99 { 100 char *end; 101 gid_t gid; 102 struct group *grp; 103 104 NEXT_ARG1; 105 ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)(*cmd); 106 gid = strtoul(**av, &end, 0); 107 grp = (*end == '\0') ? getgrgid(gid) : getgrnam(**av); 108 if (grp == NULL) 109 errx(EX_DATAERR, "gid \"%s\" not exists", **av); 110 111 cmd32->d[0] = grp->gr_gid; 112 113 (*cmd)->opcode = O_LAYER4_GID; 114 (*cmd)->module = MODULE_LAYER4_ID; 115 (*cmd)->len = F_INSN_SIZE(ipfw_insn_u32); 116 NEXT_ARG1; 117 } 118 119 void 120 parse_established(ipfw_insn **cmd, int *ac, char **av[]) 121 { 122 NEXT_ARG1; 123 (*cmd)->opcode = O_LAYER4_ESTABLISHED; 124 (*cmd)->module = MODULE_LAYER4_ID; 125 (*cmd)->len |= LEN_OF_IPFWINSN; 126 } 127 128 void 129 parse_bpf(ipfw_insn **cmd, int *ac, char **av[]) 130 { 131 struct bpf_program program; 132 ipfw_insn_bpf *bpf; 133 int avlen; 134 135 NEXT_ARG1; 136 (*cmd)->opcode = O_LAYER4_BPF; 137 (*cmd)->module = MODULE_LAYER4_ID; 138 139 avlen = strlen(**av); 140 if (avlen > 256) 141 errx(EX_DATAERR, "bpf \"%s\" too long (max 256)", **av); 142 bpf = (ipfw_insn_bpf *)(*cmd); 143 strcpy(bpf->bf_str, **av); 144 if (pcap_compile_nopcap(65535, DLT_RAW, &program, **av, 1, 145 PCAP_NETMASK_UNKNOWN)) 146 errx(EX_DATAERR, "bpf \"%s\" compilation error", **av); 147 bpf->bf_len = program.bf_len; 148 149 memcpy(&bpf->bf_insn, program.bf_insns, 150 sizeof(struct bpf_insn) * program.bf_len); 151 (*cmd)->len |= (sizeof(ipfw_insn_bpf) + 152 sizeof(struct bpf_insn) * (bpf->bf_len - 1)) / 153 sizeof(uint32_t); 154 155 pcap_freecode(&program); 156 NEXT_ARG1; 157 } 158 159 void 160 show_tcpflag(ipfw_insn *cmd, int show_or) 161 { 162 printf(" tcpflag %d", cmd->arg1); 163 } 164 165 void 166 show_uid(ipfw_insn *cmd, int show_or) 167 { 168 ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd; 169 struct passwd *pwd = getpwuid(cmd32->d[0]); 170 if (pwd){ 171 printf(" uid %s", pwd->pw_name); 172 }else{ 173 printf(" uid %u", cmd32->d[0]); 174 } 175 } 176 177 void 178 show_gid(ipfw_insn *cmd, int show_or) 179 { 180 ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd; 181 struct group *grp = getgrgid(cmd32->d[0]); 182 if (grp){ 183 printf(" gid %s", grp->gr_name); 184 }else{ 185 printf(" gid %u", cmd32->d[0]); 186 } 187 } 188 189 void 190 show_established(ipfw_insn *cmd, int show_or) 191 { 192 printf(" established"); 193 } 194 195 void 196 show_bpf(ipfw_insn *cmd, int show_or) 197 { 198 ipfw_insn_bpf *bpf; 199 char *word = "bpf"; 200 if (show_or) 201 word = "or"; 202 bpf = (ipfw_insn_bpf *)cmd; 203 printf(" %s \"%s\"", word, bpf->bf_str); 204 } 205 206 void 207 load_module(register_func function, register_keyword keyword) 208 { 209 keyword(MODULE_LAYER4_ID, O_LAYER4_TCPFLAG, "tcpflag", FILTER); 210 function(MODULE_LAYER4_ID, O_LAYER4_TCPFLAG, 211 (parser_func)parse_tcpflag, (shower_func)show_tcpflag); 212 keyword(MODULE_LAYER4_ID, O_LAYER4_UID, "uid", FILTER); 213 function(MODULE_LAYER4_ID, O_LAYER4_UID, 214 (parser_func)parse_uid, (shower_func)show_uid); 215 keyword(MODULE_LAYER4_ID, O_LAYER4_GID, "gid", FILTER); 216 function(MODULE_LAYER4_ID, O_LAYER4_GID, 217 (parser_func)parse_gid, (shower_func)show_gid); 218 keyword(MODULE_LAYER4_ID, O_LAYER4_ESTABLISHED, "established", FILTER); 219 function(MODULE_LAYER4_ID, O_LAYER4_ESTABLISHED, 220 (parser_func)parse_established, (shower_func)show_established); 221 keyword(MODULE_LAYER4_ID, O_LAYER4_BPF, "bpf", FILTER); 222 function(MODULE_LAYER4_ID, O_LAYER4_BPF, 223 (parser_func)parse_bpf, (shower_func)show_bpf); 224 } 225