Support all the tcpflag options in firewall.

Add reading options from file, now ipfw <filename> will
read commands string after string from file , form of strings
same as command line interface.
This commit is contained in:
Ugen J.S. Antsilevich 1995-10-23 03:58:06 +00:00
parent e17bed1226
commit 7934237885
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=11706
2 changed files with 258 additions and 47 deletions

View File

@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
@ -61,12 +62,19 @@ u_short flags=0; /* New entry flags */
#define IS_TOKEN(x) (IS_TO(x) || IS_FROM(x) || IS_VIA(x) ||\
IS_IPOPT(x) || IS_TCPFLG(x))
#define IPO_LSRR "ls"
#define IPO_SSRR "ss"
#define IPO_RR "rr"
#define IPO_TS "ts"
#define TCPF_FIN "fin"
#define TCPF_SYN "syn"
#define TCPF_RST "rst"
#define TCPF_PUSH "pus"
#define TCPF_ACK "ack"
#define TCPF_URG "urg"
#define P_AC "a" /* of "accept" for policy action */
#define P_DE "d" /* of "deny" for policy action */
@ -285,19 +293,25 @@ else
he=gethostbyaddr((char *)&adrt,sizeof(u_long),AF_INET);
if (he==NULL) {
printf(inet_ntoa(chain->fw_src));
printf(":");
printf(inet_ntoa(chain->fw_smsk));
} else
printf("%s",he->h_name);
} else {
printf(inet_ntoa(chain->fw_src));
if (adrt!=ULONG_MAX)
if ((mb=mask_bits(chain->fw_smsk))>=0)
printf("/%d",mb);
else {
printf(":");
printf(inet_ntoa(chain->fw_smsk));
if (adrt!=ULONG_MAX) {
mb=mask_bits(chain->fw_smsk);
if (mb == 0) {
printf("any");
} else {
if (mb > 0) {
printf(inet_ntoa(chain->fw_src));
printf("/%d",mb);
} else {
printf(inet_ntoa(chain->fw_src));
printf(":");
printf(inet_ntoa(chain->fw_smsk));
}
}
} else
printf(inet_ntoa(chain->fw_src));
}
comma = " ";
@ -320,19 +334,25 @@ else
he=gethostbyaddr((char *)&adrt,sizeof(u_long),AF_INET);
if (he==NULL) {
printf(inet_ntoa(chain->fw_dst));
printf(":");
printf(inet_ntoa(chain->fw_dmsk));
} else
printf("%s",he->h_name);
} else {
printf(inet_ntoa(chain->fw_dst));
if (adrt!=ULONG_MAX)
if ((mb=mask_bits(chain->fw_dmsk))>=0)
printf("/%d",mb);
else {
printf(":");
printf(inet_ntoa(chain->fw_dmsk));
if (adrt!=ULONG_MAX) {
mb=mask_bits(chain->fw_dmsk);
if (mb == 0) {
printf("any");
} else {
if (mb > 0) {
printf(inet_ntoa(chain->fw_dst));
printf("/%d",mb);
} else {
printf(inet_ntoa(chain->fw_dst));
printf(":");
printf(inet_ntoa(chain->fw_dmsk));
}
}
} else
printf(inet_ntoa(chain->fw_dst));
}
comma = " ";
@ -364,7 +384,7 @@ if (chain->fw_via_ip.s_addr) {
if (do_short)
printf("]");
if (chain->fw_ipopt && chain->fw_ipnopt) {
if (chain->fw_ipopt || chain->fw_ipnopt) {
if (do_short) {
printf("[");
if (chain->fw_ipopt & IP_FW_IPOPT_SSRR)
@ -389,7 +409,7 @@ if (do_short)
#define PRINTOPT(x) {if (_opt_printed) printf(",");\
printf(x); _opt_printed = 1;}
printf("ipopt ");
printf(" ipopt ");
if (chain->fw_ipopt & IP_FW_IPOPT_SSRR)
PRINTOPT("ssrr");
if (chain->fw_ipnopt & IP_FW_IPOPT_SSRR)
@ -408,6 +428,67 @@ if (do_short)
PRINTOPT("!ts");
}
}
if (chain->fw_tcpf || chain->fw_tcpnf) {
if (do_short) {
printf("[*");
if (chain->fw_tcpf & IP_FW_TCPF_FIN)
printf("F");
if (chain->fw_tcpnf & IP_FW_TCPF_FIN)
printf("f");
if (chain->fw_tcpf & IP_FW_TCPF_SYN)
printf("S");
if (chain->fw_tcpnf & IP_FW_TCPF_SYN)
printf("s");
if (chain->fw_tcpf & IP_FW_TCPF_RST)
printf("R");
if (chain->fw_tcpnf & IP_FW_TCPF_RST)
printf("r");
if (chain->fw_tcpf & IP_FW_TCPF_PUSH)
printf("P");
if (chain->fw_tcpnf & IP_FW_TCPF_PUSH)
printf("p");
if (chain->fw_tcpf & IP_FW_TCPF_ACK)
printf("A");
if (chain->fw_tcpnf & IP_FW_TCPF_ACK)
printf("a");
if (chain->fw_tcpf & IP_FW_TCPF_URG)
printf("U");
if (chain->fw_tcpnf & IP_FW_TCPF_URG)
printf("u");
printf("]");
} else {
int _flg_printed = 0;
#define PRINTFLG(x) {if (_flg_printed) printf(",");\
printf(x); _flg_printed = 1;}
printf(" tcpflg ");
if (chain->fw_tcpf & IP_FW_TCPF_FIN)
PRINTFLG("fin");
if (chain->fw_tcpnf & IP_FW_TCPF_FIN)
PRINTFLG("!fin");
if (chain->fw_tcpf & IP_FW_TCPF_SYN)
PRINTFLG("syn");
if (chain->fw_tcpnf & IP_FW_TCPF_SYN)
PRINTFLG("!syn");
if (chain->fw_tcpf & IP_FW_TCPF_RST)
PRINTFLG("rst");
if (chain->fw_tcpnf & IP_FW_TCPF_RST)
PRINTFLG("!rst");
if (chain->fw_tcpf & IP_FW_TCPF_PUSH)
PRINTFLG("push");
if (chain->fw_tcpnf & IP_FW_TCPF_PUSH)
PRINTFLG("!push");
if (chain->fw_tcpf & IP_FW_TCPF_ACK)
PRINTFLG("ack");
if (chain->fw_tcpnf & IP_FW_TCPF_ACK)
PRINTFLG("!ack");
if (chain->fw_tcpf & IP_FW_TCPF_URG)
PRINTFLG("urg");
if (chain->fw_tcpnf & IP_FW_TCPF_URG)
PRINTFLG("!urg");
}
}
printf("\n");
}
@ -711,7 +792,7 @@ u_char *optr;
p_str = str;
while ((t_str = strtok(p_str,",")) != NULL) {
p_str = NULL;
printf("tstr = %s\n", t_str);
if (t_str[0] == '!') {
optr = &(frwl->fw_ipnopt);
t_str ++;
@ -730,7 +811,49 @@ printf("tstr = %s\n", t_str);
if (!strncmp(t_str, IPO_TS, strlen(IPO_TS)))
*(optr) |= IP_FW_IPOPT_TS;
else {
fprintf(stderr,"%s: bad ipoption.\n", progname);
fprintf(stderr,"%s: bad ip option.\n", progname);
exit(1);
}
}
}
void set_entry_tcpflgs(str, frwl)
char *str;
struct ip_fw *frwl;
{
char *t_str,*p_str;
u_char *fptr;
p_str = str;
while ((t_str = strtok(p_str,",")) != NULL) {
p_str = NULL;
if (t_str[0] == '!') {
fptr = &(frwl->fw_tcpnf);
t_str ++;
} else
fptr = &(frwl->fw_tcpf);
if (!strncmp(t_str, TCPF_FIN, strlen(TCPF_FIN)))
*(fptr) |= IP_FW_TCPF_FIN;
else
if (!strncmp(t_str, TCPF_SYN, strlen(TCPF_SYN)))
*(fptr) |= IP_FW_TCPF_SYN;
else
if (!strncmp(t_str, TCPF_RST, strlen(TCPF_RST)))
*(fptr) |= IP_FW_TCPF_RST;
else
if (!strncmp(t_str, TCPF_PUSH, strlen(TCPF_PUSH)))
*(fptr) |= IP_FW_TCPF_PUSH;
else
if (!strncmp(t_str, TCPF_ACK, strlen(TCPF_ACK)))
*(fptr) |= IP_FW_TCPF_ACK;
else
if (!strncmp(t_str, TCPF_URG, strlen(TCPF_URG)))
*(fptr) |= IP_FW_TCPF_URG;
else {
fprintf(stderr,"%s: bad tcp flag.\n", progname);
exit(1);
}
}
@ -760,6 +883,8 @@ int token;
frwl->fw_ndp=0;
frwl->fw_ipopt = 0;
frwl->fw_ipnopt = 0;
frwl->fw_tcpf = 0;
frwl->fw_tcpnf = 0;
frwl->fw_via_ip.s_addr=0L;
frwl->fw_src.s_addr=0L;
frwl->fw_dst.s_addr=0L;
@ -845,6 +970,23 @@ int token;
got_ipopt = 1;
}
if (IS_TCPFLG(*av)) {
token = T_TCPFLG;
if (got_tcpflg) {
show_usage("Redefined 'tcpflags'.");
exit(1);
}
if (*(++av)==NULL) {
show_usage("Missing 'tcpflags' specification.");
exit(1);
}
set_entry_tcpflgs(*av, frwl);
got_tcpflg = 1;
}
if (*(++av)==NULL) {
return;
@ -904,7 +1046,7 @@ char **av;
} else {
printf("All accounting entries flushed.\n");
}
exit(0);
return;
}
if (!strncmp(*av,CH_FW,strlen(CH_FW))) {
if (setsockopt(s,IPPROTO_IP,IP_FW_FLUSH,NULL,0)<0) {
@ -912,7 +1054,7 @@ char **av;
exit(1);
} else {
printf("All firewall entries flushed.\n");
exit(0);
return;
}
}
if (!strncmp(*av,CH_AC,strlen(CH_AC))) {
@ -921,7 +1063,7 @@ char **av;
exit(1);
} else {
printf("All accounting entries flushed.\n");
exit(0);
return;
}
}
@ -974,7 +1116,7 @@ if (setsockopt(s,IPPROTO_IP,IP_FW_POLICY,&p,sizeof(p))<0) {
printf("Policy set to DENY.\n");
else
printf("Policy set to ACCEPT.\n");
exit(0);
return;
}
}
@ -987,11 +1129,11 @@ zero()
exit(1);
} else {
printf("Accounting cleared.\n");
exit(0);
return;
}
}
main(ac,av)
ipfw_main(ac,av)
int ac;
char **av;
{
@ -1062,16 +1204,16 @@ struct ip_fw frwl;
break;
case A_FLUSH:
flush(++av);
exit(0); /* successful exit */
return;
case A_LIST:
list(++av);
exit(0); /* successful exit */
return;
case A_ZERO:
zero();
exit(0); /* successful exit */
return;
case A_POLICY:
policy(++av);
exit(0); /* we never get here */
return;
default:
int_t=(AC|FW);
int_notdef=1;
@ -1243,4 +1385,44 @@ struct ip_fw frwl;
close(s);
}
void main(ac, av)
int ac;
char **av;
{
#define MAX_ARGS 32
char buf[_POSIX_ARG_MAX];
char *args[MAX_ARGS];
char linename[10];
int lineno = 0, i, j;
FILE *f;
if (av[1] && !access(av[1], R_OK)) {
f = fopen(av[1], "r");
while (fgets(buf, _POSIX_ARG_MAX, f)) {
if (buf[strlen(buf)-1]=='\n')
buf[strlen(buf)-1] = 0;
lineno++;
sprintf(linename, "Line %d", lineno);
args[0] = linename;
args[1] = buf;
while(*args[1] == ' ')
args[1]++;
i = 2;
while(args[i] = findchar(args[i-1],' ')) {
*(args[i]++) = 0;
while(*args[i] == ' ')
args[i]++;
i++;
}
if (*args[i-1] == 0)
i--;
args[i] = NULL;
ipfw_main(i, args);
}
fclose(f);
} else
ipfw_main(ac,av);
}

View File

@ -99,6 +99,24 @@ port_match(portptr, nports, port, range_flag)
return FALSE;
}
int
tcpflg_match(tcp, f)
struct tcphdr *tcp;
struct ip_fw *f;
{
u_char flg_set, flg_clr;
flg_set = tcp->th_flags & f->fw_tcpf;
flg_clr = tcp->th_flags & f->fw_tcpnf;
if (flg_set != f->fw_tcpf)
return 0;
if (flg_clr != f->fw_tcpnf)
return 0;
return 1;
}
int
ipopts_match(ip, f)
@ -109,14 +127,11 @@ ipopts_match(ip, f)
int opt, optlen, cnt;
u_char opts, nopts, nopts_sve;
printf("Here\n");
cp = (u_char *)(ip + 1);
cnt = (ip->ip_hl << 2) - sizeof (struct ip);
opts = f->fw_ipopt;
nopts = nopts_sve = f->fw_ipnopt;
printf("opts = %x, nopts = %x\n", opts, nopts);
printf("Cnt = %d\n", cnt);
for (; cnt > 0; cnt -= optlen, cp += optlen) {
opt = cp[IPOPT_OPTVAL];
if (opt == IPOPT_EOL)
@ -135,7 +150,6 @@ printf("Cnt = %d\n", cnt);
break;
case IPOPT_LSRR:
printf("Has LSRR\n");
opts &= ~IP_FW_IPOPT_LSRR;
nopts &= ~IP_FW_IPOPT_LSRR;
break;
@ -157,7 +171,6 @@ printf("Has LSRR\n");
if (opts == nopts)
break;
}
printf("opts = %x, nopts = %x\n", opts, nopts);
if (opts == 0 && nopts == nopts_sve)
return 1;
else
@ -314,15 +327,21 @@ ip_fw_chk(m, ip, rif, chain)
* Specific firewall - packet's protocol must
* match firewall's
*/
if (prt == f_prt) {
if (prt == IP_FW_F_ICMP ||
(port_match(&f->fw_pts[0], f->fw_nsp, src_port,
f->fw_flg & IP_FW_F_SRNG) &&
port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port,
f->fw_flg & IP_FW_F_DRNG))) {
if (prt != f_prt)
continue;
if (prt == IP_FW_F_ICMP)
goto got_match;
if (prt == IP_FW_F_TCP)
if (f->fw_tcpf != f->fw_tcpnf)
if (!tcpflg_match(tcp, f))
continue;
if (port_match(&f->fw_pts[0], f->fw_nsp,
src_port, f->fw_flg & IP_FW_F_SRNG) &&
port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp,
dst_port, f->fw_flg & IP_FW_F_DRNG))
goto got_match;
} /* Ports match */
} /* Proto matches */
} /* ALL/Specific */
} /* IP addr/mask matches */
/*
@ -719,6 +738,16 @@ add_entry(chainptr, frwl)
if (n_dr > o_dr)
addb4--;
if (n_dr == o_dr && n_sr == o_sr &&
oldkind == IP_FW_F_TCP) {
if (ftmp->fw_tcpf != 0 &&
chtmp->fw_tcpf == 0)
addb4++;
if (ftmp->fw_tcpnf != 0 &&
chtmp->fw_tcpnf == 0)
addb4++;
}
skip_check:
}
if (ftmp->fw_ipopt != 0 && chtmp->fw_ipopt == 0)