xref: /dflybsd-src/lib/libipfw3/layer4/ipfw3_layer4.c (revision 10cf3bfcde2ee9c50d77a153397b93d8026b03e1)
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 <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <sysexits.h>
43 
44 #include <net/if.h>
45 #include <net/route.h>
46 #include <net/pfil.h>
47 #include <netinet/in.h>
48 
49 #include "../../../sys/net/ipfw3/ip_fw3.h"
50 #include "../../../sbin/ipfw3/ipfw.h"
51 #include "ipfw3_layer4.h"
52 
53 
54 void
55 parse_tcpflag(ipfw_insn **cmd, int *ac, char **av[])
56 {
57 	(*cmd)->opcode = O_LAYER4_TCPFLAG;
58 	(*cmd)->module = MODULE_LAYER4_ID;
59 	(*cmd)->len =  ((*cmd)->len&(F_NOT|F_OR))|LEN_OF_IPFWINSN;
60 	/* XXX TODO parse the tcpflag value and store in arg1 or arg3 */
61 	NEXT_ARG1;
62 }
63 
64 void
65 parse_uid(ipfw_insn **cmd, int *ac, char **av[])
66 {
67 	char *end;
68 	uid_t uid;
69 	struct passwd *pwd;
70 
71 	NEXT_ARG1;
72 	ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)(*cmd);
73 	uid = strtoul(**av, &end, 0);
74 	pwd = (*end == '\0') ? getpwuid(uid) : getpwnam(**av);
75 	if (pwd == NULL)
76 		errx(EX_DATAERR, "uid \"%s\" not exists", **av);
77 
78 	cmd32->d[0] = pwd->pw_uid;
79 
80 	(*cmd)->opcode = O_LAYER4_UID;
81 	(*cmd)->module = MODULE_LAYER4_ID;
82 	(*cmd)->len = F_INSN_SIZE(ipfw_insn_u32);
83 	NEXT_ARG1;
84 }
85 
86 void
87 parse_gid(ipfw_insn **cmd, int *ac, char **av[])
88 {
89 	char *end;
90 	gid_t gid;
91 	struct group *grp;
92 
93 	NEXT_ARG1;
94 	ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)(*cmd);
95 	gid = strtoul(**av, &end, 0);
96 	grp = (*end == '\0') ? getgrgid(gid) : getgrnam(**av);
97 	if (grp == NULL)
98 		errx(EX_DATAERR, "gid \"%s\" not exists", **av);
99 
100 	cmd32->d[0] = grp->gr_gid;
101 
102 	(*cmd)->opcode = O_LAYER4_GID;
103 	(*cmd)->module = MODULE_LAYER4_ID;
104 	(*cmd)->len = F_INSN_SIZE(ipfw_insn_u32);
105 	NEXT_ARG1;
106 }
107 
108 void
109 show_tcpflag(ipfw_insn *cmd)
110 {
111 	printf(" tcpflag %d", cmd->arg1);
112 }
113 
114 void
115 show_uid(ipfw_insn *cmd)
116 {
117 	ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd;
118 	struct passwd *pwd = getpwuid(cmd32->d[0]);
119 	if (pwd){
120 		printf(" uid %s", pwd->pw_name);
121 	}else{
122 		printf(" uid %u", cmd32->d[0]);
123 	}
124 }
125 
126 void
127 show_gid(ipfw_insn *cmd)
128 {
129 	ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd;
130 	struct group *grp = getgrgid(cmd32->d[0]);
131 	if (grp){
132 		printf(" gid %s", grp->gr_name);
133 	}else{
134 		printf(" gid %u", cmd32->d[0]);
135 	}
136 }
137 
138 
139 void
140 load_module(register_func function, register_keyword keyword)
141 {
142 	keyword(MODULE_LAYER4_ID, O_LAYER4_TCPFLAG, "tcpflag", IPFW_KEYWORD_TYPE_FILTER);
143 	function(MODULE_LAYER4_ID, O_LAYER4_TCPFLAG,
144 			(parser_func)parse_tcpflag, (shower_func)show_tcpflag);
145 	keyword(MODULE_LAYER4_ID, O_LAYER4_UID, "uid", IPFW_KEYWORD_TYPE_FILTER);
146 	function(MODULE_LAYER4_ID, O_LAYER4_UID,
147 			(parser_func)parse_uid, (shower_func)show_uid);
148 	keyword(MODULE_LAYER4_ID, O_LAYER4_GID, "gid", IPFW_KEYWORD_TYPE_FILTER);
149 	function(MODULE_LAYER4_ID, O_LAYER4_GID,
150 			(parser_func)parse_gid, (shower_func)show_gid);
151 }
152