5 typedef struct ipfopentry {
13 static ipfopentry_t opwords[17] = {
14 { IPF_EXP_IP_ADDR, 2, 0, 1, "ip.addr" },
15 { IPF_EXP_IP6_ADDR, 2, 0, 4, "ip6.addr" },
16 { IPF_EXP_IP_PR, 1, 0, 1, "ip.p" },
17 { IPF_EXP_IP_SRCADDR, 2, 0, 1, "ip.src" },
18 { IPF_EXP_IP_DSTADDR, 2, 0, 1, "ip.dst" },
19 { IPF_EXP_IP6_SRCADDR, 2, 0, 4, "ip6.src" },
20 { IPF_EXP_IP6_DSTADDR, 2, 0, 4, "ip6.dst" },
21 { IPF_EXP_TCP_PORT, 1, 0, 1, "tcp.port" },
22 { IPF_EXP_TCP_DPORT, 1, 0, 1, "tcp.dport" },
23 { IPF_EXP_TCP_SPORT, 1, 0, 1, "tcp.sport" },
24 { IPF_EXP_TCP_FLAGS, 2, 0, 1, "tcp.flags" },
25 { IPF_EXP_UDP_PORT, 1, 0, 1, "udp.port" },
26 { IPF_EXP_UDP_DPORT, 1, 0, 1, "udp.dport" },
27 { IPF_EXP_UDP_SPORT, 1, 0, 1, "udp.sport" },
28 { IPF_EXP_TCP_STATE, 1, 0, 1, "tcp.state" },
29 { IPF_EXP_IDLE_GT, 1, 1, 1, "idle-gt" },
35 parseipfexpr(line, errorptr)
39 int not, items, asize, *oplist, osize, i;
40 char *temp, *arg, *s, *t, *ops, *error;
50 error = "strdup failed";
55 * Eliminate any white spaces to make parsing easier.
57 for (s = temp; *s != '\0'; ) {
66 * It should be sets of "ip.dst=1.2.3.4/32;" things.
67 * There must be a "=" or "!=" and it must end in ";".
69 if (temp[strlen(temp) - 1] != ';') {
70 error = "last character not ';'";
75 * Work through the list of complete operands present.
77 for (ops = strtok(temp, ";"); ops != NULL; ops = strtok(NULL, ";")) {
78 arg = strchr(ops, '=');
79 if ((arg < ops + 2) || (arg == NULL)) {
80 error = "bad 'arg' vlaue";
84 if (*(arg - 1) == '!') {
93 for (e = opwords; e->ipoe_word; e++) {
94 if (strcmp(ops, e->ipoe_word) == 0)
97 if (e->ipoe_word == NULL) {
100 sprintf(error, "keyword (%.10s) not found",
107 * Count the number of commas so we know how big to
110 for (s = arg, items = 1; *s != '\0'; s++)
114 if ((e->ipoe_maxarg != 0) && (items > e->ipoe_maxarg)) {
115 error = "too many items";
120 * osize will mark the end of where we have filled up to
121 * and is thus where we start putting new data.
124 asize += 4 + (items * e->ipoe_nbasearg * e->ipoe_argsize);
126 oplist = calloc(1, sizeof(int) * (asize + 2));
128 oplist = realloc(oplist, sizeof(int) * (asize + 2));
129 if (oplist == NULL) {
130 error = "oplist alloc failed";
133 ipfe = (ipfexp_t *)(oplist + osize);
135 ipfe->ipfe_cmd = e->ipoe_cmd;
136 ipfe->ipfe_not = not;
137 ipfe->ipfe_narg = items * e->ipoe_nbasearg;
138 ipfe->ipfe_size = items * e->ipoe_nbasearg * e->ipoe_argsize;
139 ipfe->ipfe_size += 4;
141 for (s = arg; (*s != '\0') && (osize < asize); s = t) {
143 * Look for the end of this arg or the ',' to say
144 * there is another following.
146 for (t = s; (*t != '\0') && (*t != ','); t++)
151 if (!strcasecmp(ops, "ip.addr") ||
152 !strcasecmp(ops, "ip.src") ||
153 !strcasecmp(ops, "ip.dst")) {
157 delim = strchr(s, '/');
160 if (genmask(AF_INET, delim,
162 error = "genmask failed";
166 mask.in4.s_addr = 0xffffffff;
168 if (gethost(AF_INET, s, &addr) == -1) {
169 error = "gethost failed";
173 oplist[osize++] = addr.in4.s_addr;
174 oplist[osize++] = mask.in4.s_addr;
177 } else if (!strcasecmp(ops, "ip6.addr") ||
178 !strcasecmp(ops, "ip6.src") ||
179 !strcasecmp(ops, "ip6.dst")) {
183 delim = strchr(s, '/');
186 if (genmask(AF_INET6, delim,
188 error = "genmask failed";
192 mask.i6[0] = 0xffffffff;
193 mask.i6[1] = 0xffffffff;
194 mask.i6[2] = 0xffffffff;
195 mask.i6[3] = 0xffffffff;
197 if (gethost(AF_INET6, s, &addr) == -1) {
198 error = "gethost failed";
202 oplist[osize++] = addr.i6[0];
203 oplist[osize++] = addr.i6[1];
204 oplist[osize++] = addr.i6[2];
205 oplist[osize++] = addr.i6[3];
206 oplist[osize++] = mask.i6[0];
207 oplist[osize++] = mask.i6[1];
208 oplist[osize++] = mask.i6[2];
209 oplist[osize++] = mask.i6[3];
212 } else if (!strcasecmp(ops, "ip.p")) {
220 } else if (!strcasecmp(ops, "tcp.flags")) {
224 delim = strchr(s, '/');
227 mask = tcpflags(delim);
233 oplist[osize++] = flags;
234 oplist[osize++] = mask;
237 } else if (!strcasecmp(ops, "tcp.port") ||
238 !strcasecmp(ops, "tcp.sport") ||
239 !strcasecmp(ops, "tcp.dport") ||
240 !strcasecmp(ops, "udp.port") ||
241 !strcasecmp(ops, "udp.sport") ||
242 !strcasecmp(ops, "udp.dport")) {
246 strncpy(proto, ops, 3);
248 if (getport(NULL, s, &port, proto) == -1)
250 oplist[osize++] = port;
252 } else if (!strcasecmp(ops, "tcp.state")) {
253 oplist[osize++] = atoi(s);
256 error = "unknown word";
264 if (errorptr != NULL)
267 for (i = asize; i > 0; i--)
268 oplist[i] = oplist[i - 1];
270 oplist[0] = asize + 2;
271 oplist[asize + 1] = IPF_EXP_END;
276 if (errorptr != NULL)