add3a7e137d8b35d8011e1829c979b992ec9ebfb
[dragonfly.git] / lib / libipfw3 / layer4 / ipfw3_layer4.c
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 parse_established(ipfw_insn **cmd, int *ac, char **av[])
110 {
111         NEXT_ARG1;
112         (*cmd)->opcode = O_LAYER4_ESTABLISHED;
113         (*cmd)->module = MODULE_LAYER4_ID;
114         (*cmd)->len |= LEN_OF_IPFWINSN;
115 }
116
117 void
118 show_tcpflag(ipfw_insn *cmd)
119 {
120         printf(" tcpflag %d", cmd->arg1);
121 }
122
123 void
124 show_uid(ipfw_insn *cmd)
125 {
126         ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd;
127         struct passwd *pwd = getpwuid(cmd32->d[0]);
128         if (pwd){
129                 printf(" uid %s", pwd->pw_name);
130         }else{
131                 printf(" uid %u", cmd32->d[0]);
132         }
133 }
134
135 void
136 show_gid(ipfw_insn *cmd)
137 {
138         ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd;
139         struct group *grp = getgrgid(cmd32->d[0]);
140         if (grp){
141                 printf(" gid %s", grp->gr_name);
142         }else{
143                 printf(" gid %u", cmd32->d[0]);
144         }
145 }
146
147 void
148 show_established(ipfw_insn *cmd)
149 {
150         printf(" established");
151 }
152
153 void
154 load_module(register_func function, register_keyword keyword)
155 {
156         keyword(MODULE_LAYER4_ID, O_LAYER4_TCPFLAG, "tcpflag", IPFW_KEYWORD_TYPE_FILTER);
157         function(MODULE_LAYER4_ID, O_LAYER4_TCPFLAG,
158                         (parser_func)parse_tcpflag, (shower_func)show_tcpflag);
159         keyword(MODULE_LAYER4_ID, O_LAYER4_UID, "uid", IPFW_KEYWORD_TYPE_FILTER);
160         function(MODULE_LAYER4_ID, O_LAYER4_UID,
161                         (parser_func)parse_uid, (shower_func)show_uid);
162         keyword(MODULE_LAYER4_ID, O_LAYER4_GID, "gid", IPFW_KEYWORD_TYPE_FILTER);
163         function(MODULE_LAYER4_ID, O_LAYER4_GID,
164                         (parser_func)parse_gid, (shower_func)show_gid);
165         keyword(MODULE_LAYER4_ID, O_LAYER4_ESTABLISHED, "established", IPFW_KEYWORD_TYPE_FILTER);
166         function(MODULE_LAYER4_ID, O_LAYER4_ESTABLISHED,
167                         (parser_func)parse_established, (shower_func)show_established);
168 }