diff options
Diffstat (limited to 'contrib/ipfilter/lib')
103 files changed, 8948 insertions, 0 deletions
diff --git a/contrib/ipfilter/lib/Makefile b/contrib/ipfilter/lib/Makefile new file mode 100644 index 0000000..d448ba0 --- /dev/null +++ b/contrib/ipfilter/lib/Makefile @@ -0,0 +1,309 @@ +INCDEP=$(TOP)/ip_compat.h $(TOP)/ip_fil.h $(TOP)/ipf.h + +LIBOBJS=$(DEST)/addicmp.o \ + $(DEST)/addipopt.o \ + $(DEST)/addkeep.o \ + $(DEST)/bcopywrap.o \ + $(DEST)/binprint.o \ + $(DEST)/buildopts.o \ + $(DEST)/checkrev.o \ + $(DEST)/count6bits.o \ + $(DEST)/count4bits.o \ + $(DEST)/debug.o \ + $(DEST)/extras.o \ + $(DEST)/facpri.o \ + $(DEST)/flags.o \ + $(DEST)/fill6bits.o \ + $(DEST)/genmask.o \ + $(DEST)/gethost.o \ + $(DEST)/getifname.o \ + $(DEST)/getline.o \ + $(DEST)/getnattype.o \ + $(DEST)/getport.o \ + $(DEST)/getportproto.o \ + $(DEST)/getproto.o \ + $(DEST)/getsumd.o \ + $(DEST)/hexdump.o \ + $(DEST)/hostmask.o \ + $(DEST)/hostname.o \ + $(DEST)/hostnum.o \ + $(DEST)/icmpcode.o \ + $(DEST)/inet_addr.o \ + $(DEST)/initparse.o \ + $(DEST)/ionames.o \ + $(DEST)/ipoptsec.o \ + $(DEST)/ipf_dotuning.o \ + $(DEST)/ipft_ef.o \ + $(DEST)/ipft_hx.o \ + $(DEST)/ipft_pc.o \ + $(DEST)/ipft_sn.o \ + $(DEST)/ipft_td.o \ + $(DEST)/ipft_tx.o \ + $(DEST)/kmem.o \ + $(DEST)/kmemcpywrap.o \ + $(DEST)/kvatoname.o \ + $(DEST)/load_hash.o \ + $(DEST)/load_hashnode.o \ + $(DEST)/load_pool.o \ + $(DEST)/load_poolnode.o \ + $(DEST)/loglevel.o \ + $(DEST)/make_range.o \ + $(DEST)/mutex_emul.o \ + $(DEST)/nametokva.o \ + $(DEST)/nat_setgroupmap.o \ + $(DEST)/ntomask.o \ + $(DEST)/optname.o \ + $(DEST)/optprint.o \ + $(DEST)/optprintv6.o \ + $(DEST)/optvalue.o \ + $(DEST)/portname.o \ + $(DEST)/portnum.o \ + $(DEST)/ports.o \ + $(DEST)/print_toif.o \ + $(DEST)/printactivenat.o \ + $(DEST)/printaps.o \ + $(DEST)/printbuf.o \ + $(DEST)/printhash.o \ + $(DEST)/printhashnode.o \ + $(DEST)/printip.o \ + $(DEST)/printpool.o \ + $(DEST)/printpoolnode.o \ + $(DEST)/printfr.o \ + $(DEST)/printfraginfo.o \ + $(DEST)/printhostmap.o \ + $(DEST)/printifname.o \ + $(DEST)/printhostmask.o \ + $(DEST)/printlog.o \ + $(DEST)/printmask.o \ + $(DEST)/printnat.o \ + $(DEST)/printportcmp.o \ + $(DEST)/printpacket.o \ + $(DEST)/printpacket6.o \ + $(DEST)/printsbuf.o \ + $(DEST)/printstate.o \ + $(DEST)/printtunable.o \ + $(DEST)/ratoi.o \ + $(DEST)/ratoui.o \ + $(DEST)/remove_hash.o \ + $(DEST)/remove_hashnode.o \ + $(DEST)/remove_pool.o \ + $(DEST)/remove_poolnode.o \ + $(DEST)/resetlexer.o \ + $(DEST)/rwlock_emul.o \ + $(DEST)/tcpflags.o \ + $(DEST)/tcp_flags.o \ + $(DEST)/to_interface.o \ + $(DEST)/var.o \ + $(DEST)/verbose.o \ + $(DEST)/v6ionames.o \ + $(DEST)/v6optvalue.o + +$(DEST)/libipf.a: $(LIBOBJS) + /bin/rm -f $@ + ar $(AROPTS) $@ $(LIBOBJS) + $(RANLIB) $@ + +$(DEST)/addicmp.o: $(LIBSRC)/addicmp.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/addicmp.c -o $@ +$(DEST)/addipopt.o: $(LIBSRC)/addipopt.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/addipopt.c -o $@ +$(DEST)/addkeep.o: $(LIBSRC)/addkeep.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/addkeep.c -o $@ +$(DEST)/bcopywrap.o: $(LIBSRC)/bcopywrap.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/bcopywrap.c -o $@ +$(DEST)/binprint.o: $(LIBSRC)/binprint.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/binprint.c -o $@ +$(DEST)/buildopts.o: $(LIBSRC)/buildopts.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/buildopts.c -o $@ +$(DEST)/count6bits.o: $(LIBSRC)/count6bits.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/count6bits.c -o $@ +$(DEST)/checkrev.o: $(LIBSRC)/checkrev.c $(INCDEP) $(TOP)/ipl.h + $(CC) $(CCARGS) -c $(LIBSRC)/checkrev.c -o $@ +$(DEST)/count4bits.o: $(LIBSRC)/count4bits.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/count4bits.c -o $@ +$(DEST)/debug.o: $(LIBSRC)/debug.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/debug.c -o $@ +$(DEST)/extras.o: $(LIBSRC)/extras.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/extras.c -o $@ +$(DEST)/facpri.o: $(LIBSRC)/facpri.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/facpri.c -o $@ +$(DEST)/fill6bits.o: $(LIBSRC)/fill6bits.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/fill6bits.c -o $@ +$(DEST)/flags.o: $(LIBSRC)/flags.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/flags.c -o $@ +$(DEST)/genmask.o: $(LIBSRC)/genmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/genmask.c -o $@ +$(DEST)/getline.o: $(LIBSRC)/getline.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getline.c -o $@ +$(DEST)/gethost.o: $(LIBSRC)/gethost.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/gethost.c -o $@ +$(DEST)/getifname.o: $(LIBSRC)/getifname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getifname.c -o $@ +$(DEST)/getnattype.o: $(LIBSRC)/getnattype.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getnattype.c -o $@ +$(DEST)/getport.o: $(LIBSRC)/getport.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getport.c -o $@ +$(DEST)/getportproto.o: $(LIBSRC)/getportproto.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getportproto.c -o $@ +$(DEST)/getproto.o: $(LIBSRC)/getproto.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getproto.c -o $@ +$(DEST)/getsumd.o: $(LIBSRC)/getsumd.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getsumd.c -o $@ +$(DEST)/hexdump.o: $(LIBSRC)/hexdump.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/hexdump.c -o $@ +$(DEST)/hostmask.o: $(LIBSRC)/hostmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/hostmask.c -o $@ +$(DEST)/hostname.o: $(LIBSRC)/hostname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/hostname.c -o $@ +$(DEST)/hostnum.o: $(LIBSRC)/hostnum.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/hostnum.c -o $@ +$(DEST)/icmpcode.o: $(LIBSRC)/icmpcode.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/icmpcode.c -o $@ +$(DEST)/ipoptsec.o: $(LIBSRC)/ipoptsec.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipoptsec.c -o $@ +$(DEST)/inet_addr.o: $(LIBSRC)/inet_addr.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/inet_addr.c -o $@ +$(DEST)/initparse.o: $(LIBSRC)/initparse.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/initparse.c -o $@ +$(DEST)/ionames.o: $(LIBSRC)/ionames.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ionames.c -o $@ +$(DEST)/ipf_dotuning.o: $(LIBSRC)/ipf_dotuning.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipf_dotuning.c -o $@ +$(DEST)/ipft_ef.o: $(LIBSRC)/ipft_ef.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_ef.c -o $@ +$(DEST)/ipft_hx.o: $(LIBSRC)/ipft_hx.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_hx.c -o $@ +$(DEST)/ipft_pc.o: $(LIBSRC)/ipft_pc.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_pc.c -o $@ +$(DEST)/ipft_sn.o: $(LIBSRC)/ipft_sn.c $(TOP)/snoop.h + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_sn.c -o $@ +$(DEST)/ipft_td.o: $(LIBSRC)/ipft_td.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_td.c -o $@ +$(DEST)/ipft_tx.o: $(LIBSRC)/ipft_tx.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_tx.c -o $@ +$(DEST)/kmem.o: $(LIBSRC)/kmem.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/kmem.c -o $@ +$(DEST)/kmemcpywrap.o: $(LIBSRC)/kmemcpywrap.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/kmemcpywrap.c -o $@ +$(DEST)/kvatoname.o: $(LIBSRC)/kvatoname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/kvatoname.c -o $@ +$(DEST)/load_hash.o: $(LIBSRC)/load_hash.c $(INCDEP) $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_hash.c -o $@ +$(DEST)/load_hashnode.o: $(LIBSRC)/load_hashnode.c $(INCDEP) $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_hashnode.c -o $@ +$(DEST)/load_pool.o: $(LIBSRC)/load_pool.c $(INCDEP) $(TOP)/ip_pool.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_pool.c -o $@ +$(DEST)/load_poolnode.o: $(LIBSRC)/load_poolnode.c $(INCDEP) $(TOP)/ip_pool.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_poolnode.c -o $@ +$(DEST)/make_range.o: $(LIBSRC)/make_range.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/make_range.c -o $@ +$(DEST)/mutex_emul.o: $(LIBSRC)/mutex_emul.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/mutex_emul.c -o $@ +$(DEST)/nametokva.o: $(LIBSRC)/nametokva.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/nametokva.c -o $@ +$(DEST)/nat_setgroupmap.o: $(LIBSRC)/nat_setgroupmap.c $(TOP)/ip_compat.h \ + $(TOP)/ipf.h $(TOP)/ip_nat.h + $(CC) $(CCARGS) -c $(LIBSRC)/nat_setgroupmap.c -o $@ +$(DEST)/ntomask.o: $(LIBSRC)/ntomask.c $(TOP)/ip_compat.h + $(CC) $(CCARGS) -c $(LIBSRC)/ntomask.c -o $@ +$(DEST)/loglevel.o: $(LIBSRC)/loglevel.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/loglevel.c -o $@ +$(DEST)/optname.o: $(LIBSRC)/optname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/optname.c -o $@ +$(DEST)/optprint.o: $(LIBSRC)/optprint.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/optprint.c -o $@ +$(DEST)/optprintv6.o: $(LIBSRC)/optprintv6.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/optprintv6.c -o $@ +$(DEST)/optvalue.o: $(LIBSRC)/optvalue.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/optvalue.c -o $@ +$(DEST)/portname.o: $(LIBSRC)/portname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/portname.c -o $@ +$(DEST)/portnum.o: $(LIBSRC)/portnum.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/portnum.c -o $@ +$(DEST)/ports.o: $(LIBSRC)/ports.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ports.c -o $@ +$(DEST)/print_toif.o: $(LIBSRC)/print_toif.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/print_toif.c -o $@ +$(DEST)/printactivenat.o: $(LIBSRC)/printactivenat.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printactivenat.c -o $@ +$(DEST)/printaps.o: $(LIBSRC)/printaps.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printaps.c -o $@ +$(DEST)/printbuf.o: $(LIBSRC)/printbuf.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printbuf.c -o $@ +$(DEST)/printfr.o: $(LIBSRC)/printfr.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printfr.c -o $@ +$(DEST)/printfraginfo.o: $(LIBSRC)/printfraginfo.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printfraginfo.c -o $@ +$(DEST)/printhash.o: $(LIBSRC)/printhash.c $(TOP)/ip_fil.h $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/printhash.c -o $@ +$(DEST)/printhashnode.o: $(LIBSRC)/printhashnode.c $(TOP)/ip_fil.h \ + $(TOP)/ip_htable.h $(TOP)/ip_lookup.h + $(CC) $(CCARGS) -c $(LIBSRC)/printhashnode.c -o $@ +$(DEST)/printip.o: $(LIBSRC)/printip.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printip.c -o $@ +$(DEST)/printpool.o: $(LIBSRC)/printpool.c $(TOP)/ip_fil.h $(TOP)/ip_pool.h + $(CC) $(CCARGS) -c $(LIBSRC)/printpool.c -o $@ +$(DEST)/printpoolnode.o: $(LIBSRC)/printpoolnode.c $(TOP)/ip_fil.h \ + $(TOP)/ip_pool.h $(TOP)/ip_lookup.h + $(CC) $(CCARGS) -c $(LIBSRC)/printpoolnode.c -o $@ +$(DEST)/printhostmap.o: $(LIBSRC)/printhostmap.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printhostmap.c -o $@ +$(DEST)/printifname.o: $(LIBSRC)/printifname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printifname.c -o $@ +$(DEST)/printmask.o: $(LIBSRC)/printmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printmask.c -o $@ +$(DEST)/printnat.o: $(LIBSRC)/printnat.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printnat.c -o $@ +$(DEST)/printhostmask.o: $(LIBSRC)/printhostmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printhostmask.c -o $@ +$(DEST)/printlog.o: $(LIBSRC)/printlog.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printlog.c -o $@ +$(DEST)/printpacket.o: $(LIBSRC)/printpacket.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printpacket.c -o $@ +$(DEST)/printpacket6.o: $(LIBSRC)/printpacket6.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printpacket6.c -o $@ +$(DEST)/printportcmp.o: $(LIBSRC)/printportcmp.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printportcmp.c -o $@ +$(DEST)/printsbuf.o: $(LIBSRC)/printsbuf.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printsbuf.c -o $@ +$(DEST)/printstate.o: $(LIBSRC)/printstate.c $(INCDEP) $(TOP)/ip_state.h + $(CC) $(CCARGS) -c $(LIBSRC)/printstate.c -o $@ +$(DEST)/printtunable.o: $(LIBSRC)/printtunable.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printtunable.c -o $@ +$(DEST)/ratoi.o: $(LIBSRC)/ratoi.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ratoi.c -o $@ +$(DEST)/ratoui.o: $(LIBSRC)/ratoui.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ratoui.c -o $@ +$(DEST)/remove_hash.o: $(LIBSRC)/remove_hash.c $(INCDEP) \ + $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/remove_hash.c -o $@ +$(DEST)/remove_hashnode.o: $(LIBSRC)/remove_hashnode.c $(INCDEP) \ + $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/remove_hashnode.c -o $@ +$(DEST)/remove_pool.o: $(LIBSRC)/remove_pool.c $(INCDEP) \ + $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/remove_pool.c -o $@ +$(DEST)/remove_poolnode.o: $(LIBSRC)/remove_poolnode.c $(INCDEP) \ + $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/remove_poolnode.c -o $@ +$(DEST)/resetlexer.o: $(LIBSRC)/resetlexer.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/resetlexer.c -o $@ +$(DEST)/rwlock_emul.o: $(LIBSRC)/rwlock_emul.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/rwlock_emul.c -o $@ +$(DEST)/to_interface.o: $(LIBSRC)/to_interface.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/to_interface.c -o $@ +$(DEST)/tcpflags.o: $(LIBSRC)/tcpflags.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/tcpflags.c -o $@ +$(DEST)/tcp_flags.o: $(LIBSRC)/tcp_flags.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/tcp_flags.c -o $@ +$(DEST)/var.o: $(LIBSRC)/var.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/var.c -o $@ +$(DEST)/verbose.o: $(LIBSRC)/verbose.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/verbose.c -o $@ +$(DEST)/v6ionames.o: $(LIBSRC)/v6ionames.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/v6ionames.c -o $@ +$(DEST)/v6optvalue.o: $(LIBSRC)/v6optvalue.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/v6optvalue.c -o $@ + +clean-lib: + /bin/rm -f ${LIBOBJS} ${LIB} diff --git a/contrib/ipfilter/lib/addicmp.c b/contrib/ipfilter/lib/addicmp.c new file mode 100644 index 0000000..a8c1722 --- /dev/null +++ b/contrib/ipfilter/lib/addicmp.c @@ -0,0 +1,94 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: addicmp.c,v 1.10.2.1 2004/12/09 19:41:16 darrenr Exp + */ + +#include <ctype.h> + +#include "ipf.h" + + +char *icmptypes[MAX_ICMPTYPE + 1] = { + "echorep", (char *)NULL, (char *)NULL, "unreach", "squench", + "redir", (char *)NULL, (char *)NULL, "echo", "routerad", + "routersol", "timex", "paramprob", "timest", "timestrep", + "inforeq", "inforep", "maskreq", "maskrep", "END" +}; + +/* + * set the icmp field to the correct type if "icmp" word is found + */ +int addicmp(cp, fp, linenum) +char ***cp; +struct frentry *fp; +int linenum; +{ + char **t; + int i; + + (*cp)++; + if (!**cp) + return -1; + if (!fp->fr_proto) /* to catch lusers */ + fp->fr_proto = IPPROTO_ICMP; + if (ISDIGIT(***cp)) { + if (!ratoi(**cp, &i, 0, 255)) { + fprintf(stderr, + "%d: Invalid icmp-type (%s) specified\n", + linenum, **cp); + return -1; + } + } else { + for (t = icmptypes, i = 0; ; t++, i++) { + if (!*t) + continue; + if (!strcasecmp("END", *t)) { + i = -1; + break; + } + if (!strcasecmp(*t, **cp)) + break; + } + if (i == -1) { + fprintf(stderr, + "%d: Unknown icmp-type (%s) specified\n", + linenum, **cp); + return -1; + } + } + fp->fr_icmp = (u_short)(i << 8); + fp->fr_icmpm = (u_short)0xff00; + (*cp)++; + if (!**cp) + return 0; + + if (**cp && strcasecmp("code", **cp)) + return 0; + (*cp)++; + if (ISDIGIT(***cp)) { + if (!ratoi(**cp, &i, 0, 255)) { + fprintf(stderr, + "%d: Invalid icmp code (%s) specified\n", + linenum, **cp); + return -1; + } + } else { + i = icmpcode(**cp); + if (i == -1) { + fprintf(stderr, + "%d: Unknown icmp code (%s) specified\n", + linenum, **cp); + return -1; + } + } + i &= 0xff; + fp->fr_icmp |= (u_short)i; + fp->fr_icmpm = (u_short)0xffff; + (*cp)++; + return 0; +} diff --git a/contrib/ipfilter/lib/addipopt.c b/contrib/ipfilter/lib/addipopt.c new file mode 100644 index 0000000..23f4427 --- /dev/null +++ b/contrib/ipfilter/lib/addipopt.c @@ -0,0 +1,67 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: addipopt.c,v 1.7 2002/01/28 06:50:45 darrenr Exp + */ + +#include "ipf.h" + + +int addipopt(op, io, len, class) +char *op; +struct ipopt_names *io; +int len; +char *class; +{ + int olen = len; + struct in_addr ipadr; + u_short val; + u_char lvl; + char *s; + + if ((len + io->on_siz) > 48) { + fprintf(stderr, "options too long\n"); + return 0; + } + len += io->on_siz; + *op++ = io->on_value; + if (io->on_siz > 1) { + s = op; + *op++ = io->on_siz; + *op++ = IPOPT_MINOFF; + + if (class) { + switch (io->on_value) + { + case IPOPT_SECURITY : + lvl = seclevel(class); + *(op - 1) = lvl; + break; + case IPOPT_LSRR : + case IPOPT_SSRR : + ipadr.s_addr = inet_addr(class); + s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4; + bcopy((char *)&ipadr, op, sizeof(ipadr)); + break; + case IPOPT_SATID : + val = atoi(class); + bcopy((char *)&val, op, 2); + break; + } + } + + op += io->on_siz - 3; + if (len & 3) { + *op++ = IPOPT_NOP; + len++; + } + } + if (opts & OPT_DEBUG) + fprintf(stderr, "bo: %s %d %#x: %d\n", + io->on_name, io->on_value, io->on_bit, len); + return len - olen; +} diff --git a/contrib/ipfilter/lib/addkeep.c b/contrib/ipfilter/lib/addkeep.c new file mode 100644 index 0000000..3f20fb4 --- /dev/null +++ b/contrib/ipfilter/lib/addkeep.c @@ -0,0 +1,86 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: addkeep.c,v 1.12 2003/12/01 01:59:42 darrenr Exp + */ + +#include "ipf.h" + + +/* + * Parses "keep state" and "keep frags" stuff on the end of a line. + */ +int addkeep(cp, fp, linenum) +char ***cp; +struct frentry *fp; +int linenum; +{ + char *s; + + (*cp)++; + if (!**cp) { + fprintf(stderr, "%d: Missing state/frag after keep\n", + linenum); + return -1; + } + + if (!strcasecmp(**cp, "state")) { + fp->fr_flags |= FR_KEEPSTATE; + (*cp)++; + if (**cp && !strcasecmp(**cp, "limit")) { + (*cp)++; + fp->fr_statemax = atoi(**cp); + (*cp)++; + } + if (**cp && !strcasecmp(**cp, "scan")) { + (*cp)++; + if (!strcmp(**cp, "*")) { + fp->fr_isc = NULL; + fp->fr_isctag[0] = '\0'; + } else { + strncpy(fp->fr_isctag, **cp, + sizeof(fp->fr_isctag)); + fp->fr_isctag[sizeof(fp->fr_isctag)-1] = '\0'; + fp->fr_isc = NULL; + } + (*cp)++; + } else + fp->fr_isc = (struct ipscan *)-1; + } else if (!strncasecmp(**cp, "frag", 4)) { + fp->fr_flags |= FR_KEEPFRAG; + (*cp)++; + } else if (!strcasecmp(**cp, "state-age")) { + if (fp->fr_ip.fi_p == IPPROTO_TCP) { + fprintf(stderr, "%d: cannot use state-age with tcp\n", + linenum); + return -1; + } + if ((fp->fr_flags & FR_KEEPSTATE) == 0) { + fprintf(stderr, "%d: state-age with no 'keep state'\n", + linenum); + return -1; + } + (*cp)++; + if (!**cp) { + fprintf(stderr, "%d: state-age with no arg\n", + linenum); + return -1; + } + fp->fr_age[0] = atoi(**cp); + s = strchr(**cp, '/'); + if (s != NULL) { + s++; + fp->fr_age[1] = atoi(s); + } else + fp->fr_age[1] = fp->fr_age[0]; + } else { + fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n", + linenum, **cp); + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/bcopywrap.c b/contrib/ipfilter/lib/bcopywrap.c new file mode 100644 index 0000000..939137b --- /dev/null +++ b/contrib/ipfilter/lib/bcopywrap.c @@ -0,0 +1,12 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int bcopywrap(from, to, size) +void *from, *to; +size_t size; +{ + bcopy((caddr_t)from, (caddr_t)to, size); + return 0; +} + diff --git a/contrib/ipfilter/lib/binprint.c b/contrib/ipfilter/lib/binprint.c new file mode 100644 index 0000000..afa4910 --- /dev/null +++ b/contrib/ipfilter/lib/binprint.c @@ -0,0 +1,31 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: binprint.c,v 1.8 2002/05/14 15:18:56 darrenr Exp + */ + +#include "ipf.h" + + +void binprint(ptr, size) +void *ptr; +size_t size; +{ + u_char *s; + int i, j; + + for (i = size, j = 0, s = (u_char *)ptr; i; i--, s++) { + j++; + printf("%02x ", *s); + if (j == 16) { + printf("\n"); + j = 0; + } + } + putchar('\n'); + (void)fflush(stdout); +} diff --git a/contrib/ipfilter/lib/buildopts.c b/contrib/ipfilter/lib/buildopts.c new file mode 100644 index 0000000..a35649b --- /dev/null +++ b/contrib/ipfilter/lib/buildopts.c @@ -0,0 +1,44 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: buildopts.c,v 1.6 2002/01/28 06:50:45 darrenr Exp + */ + +#include "ipf.h" + + +u_32_t buildopts(cp, op, len) +char *cp, *op; +int len; +{ + struct ipopt_names *io; + u_32_t msk = 0; + char *s, *t; + int inc; + + for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) { + if ((t = strchr(s, '='))) + *t++ = '\0'; + for (io = ionames; io->on_name; io++) { + if (strcasecmp(s, io->on_name) || (msk & io->on_bit)) + continue; + if ((inc = addipopt(op, io, len, t))) { + op += inc; + len += inc; + } + msk |= io->on_bit; + break; + } + if (!io->on_name) { + fprintf(stderr, "unknown IP option name %s\n", s); + return 0; + } + } + *op++ = IPOPT_EOL; + len++; + return len; +} diff --git a/contrib/ipfilter/lib/checkrev.c b/contrib/ipfilter/lib/checkrev.c new file mode 100644 index 0000000..28032ce --- /dev/null +++ b/contrib/ipfilter/lib/checkrev.c @@ -0,0 +1,46 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: checkrev.c,v 1.12.2.1 2004/03/09 14:44:39 darrenr Exp + */ + +#include <sys/ioctl.h> +#include <fcntl.h> + +#include "ipf.h" +#include "netinet/ipl.h" + +int checkrev(ipfname) +char *ipfname; +{ + static int vfd = -1; + struct friostat fio, *fiop = &fio; + ipfobj_t ipfo; + + bzero((caddr_t)&ipfo, sizeof(ipfo)); + ipfo.ipfo_rev = IPFILTER_VERSION; + ipfo.ipfo_size = sizeof(*fiop); + ipfo.ipfo_ptr = (void *)fiop; + ipfo.ipfo_type = IPFOBJ_IPFSTAT; + + if ((vfd == -1) && ((vfd = open(ipfname, O_RDONLY)) == -1)) { + perror("open device"); + return -1; + } + + if (ioctl(vfd, SIOCGETFS, &ipfo)) { + perror("ioctl(SIOCGETFS)"); + close(vfd); + vfd = -1; + return -1; + } + + if (strncmp(IPL_VERSION, fio.f_version, sizeof(fio.f_version))) { + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/count4bits.c b/contrib/ipfilter/lib/count4bits.c new file mode 100644 index 0000000..0f2187f --- /dev/null +++ b/contrib/ipfilter/lib/count4bits.c @@ -0,0 +1,40 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: count4bits.c,v 1.1 2002/06/15 04:46:39 darrenr Exp + */ + +#include "ipf.h" + + +/* + * count consecutive 1's in bit mask. If the mask generated by counting + * consecutive 1's is different to that passed, return -1, else return # + * of bits. + */ +int count4bits(ip) +u_int ip; +{ + int cnt = 0, i, j; + u_int ipn; + + ip = ipn = ntohl(ip); + for (i = 32; i; i--, ipn *= 2) + if (ipn & 0x80000000) + cnt++; + else + break; + ipn = 0; + for (i = 32, j = cnt; i; i--, j--) { + ipn *= 2; + if (j > 0) + ipn++; + } + if (ipn == ip) + return cnt; + return -1; +} diff --git a/contrib/ipfilter/lib/count6bits.c b/contrib/ipfilter/lib/count6bits.c new file mode 100644 index 0000000..bd4e9f8 --- /dev/null +++ b/contrib/ipfilter/lib/count6bits.c @@ -0,0 +1,29 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: count6bits.c,v 1.4 2001/06/09 17:09:23 darrenr Exp + */ + +#include "ipf.h" + + +int count6bits(msk) +u_32_t *msk; +{ + int i = 0, k; + u_32_t j; + + for (k = 3; k >= 0; k--) + if (msk[k] == 0xffffffff) + i += 32; + else { + for (j = msk[k]; j; j <<= 1) + if (j & 0x80000000) + i++; + } + return i; +} diff --git a/contrib/ipfilter/lib/debug.c b/contrib/ipfilter/lib/debug.c new file mode 100644 index 0000000..1510222 --- /dev/null +++ b/contrib/ipfilter/lib/debug.c @@ -0,0 +1,37 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: debug.c,v 1.6 2001/06/09 17:09:24 darrenr Exp + */ + +#if defined(__STDC__) +# include <stdarg.h> +#else +# include <varargs.h> +#endif +#include <stdio.h> + +#include "ipt.h" +#include "opts.h" + + +#ifdef __STDC__ +void debug(char *fmt, ...) +#else +void debug(fmt, va_alist) +char *fmt; +va_dcl +#endif +{ + va_list pvar; + + va_start(pvar, fmt); + + if (opts & OPT_DEBUG) + vprintf(fmt, pvar); + va_end(pvar); +} diff --git a/contrib/ipfilter/lib/extras.c b/contrib/ipfilter/lib/extras.c new file mode 100644 index 0000000..0f7f39f --- /dev/null +++ b/contrib/ipfilter/lib/extras.c @@ -0,0 +1,114 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: extras.c,v 1.12 2002/07/13 12:06:49 darrenr Exp + */ + +#include "ipf.h" + + +/* + * deal with extra bits on end of the line + */ +int extras(cp, fr, linenum) +char ***cp; +struct frentry *fr; +int linenum; +{ + u_short secmsk; + u_long opts; + int notopt; + + opts = 0; + secmsk = 0; + notopt = 0; + (*cp)++; + if (!**cp) + return -1; + + while (**cp) { + if (!strcasecmp(**cp, "not") || !strcasecmp(**cp, "no")) { + notopt = 1; + (*cp)++; + continue; + } else if (!strncasecmp(**cp, "ipopt", 5)) { + if (!notopt) + fr->fr_flx |= FI_OPTIONS; + fr->fr_mflx |= FI_OPTIONS; + goto nextopt; + } else if (!strcasecmp(**cp, "lowttl")) { + if (!notopt) + fr->fr_flx |= FI_LOWTTL; + fr->fr_mflx |= FI_LOWTTL; + goto nextopt; + } else if (!strcasecmp(**cp, "bad-src")) { + if (!notopt) + fr->fr_flx |= FI_BADSRC; + fr->fr_mflx |= FI_BADSRC; + goto nextopt; + } else if (!strncasecmp(**cp, "mbcast", 6)) { + if (!notopt) + fr->fr_flx |= FI_MBCAST; + fr->fr_mflx |= FI_MBCAST; + goto nextopt; + } else if (!strncasecmp(**cp, "nat", 3)) { + if (!notopt) + fr->fr_flx |= FI_NATED; + fr->fr_mflx |= FI_NATED; + goto nextopt; + } else if (!strncasecmp(**cp, "frag", 4)) { + if (!notopt) + fr->fr_flx |= FI_FRAG; + fr->fr_mflx |= FI_FRAG; + goto nextopt; + } else if (!strncasecmp(**cp, "opt", 3)) { + if (!*(*cp + 1)) { + fprintf(stderr, "%d: opt missing arguements\n", + linenum); + return -1; + } + (*cp)++; + if (!(opts = optname(cp, &secmsk, linenum))) + return -1; + + if (notopt) { + if (!secmsk) { + fr->fr_optmask |= opts; + } else { + fr->fr_optmask |= (opts & ~0x0100); + fr->fr_secmask |= secmsk; + } + fr->fr_secbits &= ~secmsk; + fr->fr_optbits &= ~opts; + } else { + fr->fr_optmask |= opts; + fr->fr_secmask |= secmsk; + fr->fr_optbits |= opts; + fr->fr_secbits |= secmsk; + } + } else if (!strncasecmp(**cp, "short", 5)) { + if (fr->fr_tcpf) { + fprintf(stderr, + "%d: short cannot be used with TCP flags\n", + linenum); + return -1; + } + + if (!notopt) + fr->fr_flx |= FI_SHORT; + fr->fr_mflx |= FI_SHORT; + goto nextopt; + } else + return -1; +nextopt: + notopt = 0; + opts = 0; + secmsk = 0; + (*cp)++; + } + return 0; +} diff --git a/contrib/ipfilter/lib/facpri.c b/contrib/ipfilter/lib/facpri.c new file mode 100644 index 0000000..1e35ea9 --- /dev/null +++ b/contrib/ipfilter/lib/facpri.c @@ -0,0 +1,153 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: facpri.c,v 1.6 2003/12/01 01:59:43 darrenr Exp + */ + +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <sys/types.h> +#if !defined(__SVR4) && !defined(__svr4__) +#include <strings.h> +#endif +#include <stdlib.h> +#include <unistd.h> +#include <stddef.h> +#include <syslog.h> +#include "facpri.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: facpri.c,v 1.6 2003/12/01 01:59:43 darrenr Exp"; +#endif + + +typedef struct table { + char *name; + int value; +} table_t; + +table_t facs[] = { + { "kern", LOG_KERN }, { "user", LOG_USER }, + { "mail", LOG_MAIL }, { "daemon", LOG_DAEMON }, + { "auth", LOG_AUTH }, { "syslog", LOG_SYSLOG }, + { "lpr", LOG_LPR }, { "news", LOG_NEWS }, + { "uucp", LOG_UUCP }, +#if LOG_CRON == LOG_CRON2 + { "cron2", LOG_CRON1 }, +#else + { "cron", LOG_CRON1 }, +#endif +#ifdef LOG_FTP + { "ftp", LOG_FTP }, +#endif +#ifdef LOG_AUTHPRIV + { "authpriv", LOG_AUTHPRIV }, +#endif +#ifdef LOG_AUDIT + { "audit", LOG_AUDIT }, +#endif +#ifdef LOG_LFMT + { "logalert", LOG_LFMT }, +#endif +#if LOG_CRON == LOG_CRON1 + { "cron", LOG_CRON2 }, +#else + { "cron2", LOG_CRON2 }, +#endif +#ifdef LOG_SECURITY + { "security", LOG_SECURITY }, +#endif + { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, + { NULL, 0 } +}; + + +/* + * map a facility number to its name + */ +char * +fac_toname(facpri) + int facpri; +{ + int i, j, fac; + + fac = facpri & LOG_FACMASK; + j = fac >> 3; + if (j < 24) { + if (facs[j].value == fac) + return facs[j].name; + for (i = 0; facs[i].name; i++) + if (fac == facs[i].value) + return facs[i].name; + } + + return NULL; +} + + +/* + * map a facility name to its number + */ +int +fac_findname(name) + char *name; +{ + int i; + + for (i = 0; facs[i].name; i++) + if (!strcmp(facs[i].name, name)) + return facs[i].value; + return -1; +} + + +table_t pris[] = { + { "emerg", LOG_EMERG }, { "alert", LOG_ALERT }, + { "crit", LOG_CRIT }, { "err", LOG_ERR }, + { "warn", LOG_WARNING }, { "notice", LOG_NOTICE }, + { "info", LOG_INFO }, { "debug", LOG_DEBUG }, + { NULL, 0 } +}; + + +/* + * map a priority name to its number + */ +int +pri_findname(name) + char *name; +{ + int i; + + for (i = 0; pris[i].name; i++) + if (!strcmp(pris[i].name, name)) + return pris[i].value; + return -1; +} + + +/* + * map a priority number to its name + */ +char * +pri_toname(facpri) + int facpri; +{ + int i, pri; + + pri = facpri & LOG_PRIMASK; + if (pris[pri].value == pri) + return pris[pri].name; + for (i = 0; pris[i].name; i++) + if (pri == pris[i].value) + return pris[i].name; + return NULL; +} diff --git a/contrib/ipfilter/lib/facpri.h b/contrib/ipfilter/lib/facpri.h new file mode 100644 index 0000000..e8eef2b --- /dev/null +++ b/contrib/ipfilter/lib/facpri.h @@ -0,0 +1,43 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1999-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: facpri.h,v 1.3 2001/06/09 17:19:50 darrenr Exp + */ + +#ifndef __FACPRI_H__ +#define __FACPRI_H__ + +#ifndef __P +# define P_DEF +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +extern char *fac_toname __P((int)); +extern int fac_findname __P((char *)); + +extern char *pri_toname __P((int)); +extern int pri_findname __P((char *)); + +#ifdef P_DEF +# undef __P +# undef P_DEF +#endif + +#if LOG_CRON == (9<<3) +# define LOG_CRON1 LOG_CRON +# define LOG_CRON2 (15<<3) +#endif +#if LOG_CRON == (15<<3) +# define LOG_CRON1 (9<<3) +# define LOG_CRON2 LOG_CRON +#endif + +#endif /* __FACPRI_H__ */ diff --git a/contrib/ipfilter/lib/fill6bits.c b/contrib/ipfilter/lib/fill6bits.c new file mode 100644 index 0000000..8f23a6f --- /dev/null +++ b/contrib/ipfilter/lib/fill6bits.c @@ -0,0 +1,48 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: fill6bits.c,v 1.5 2002/03/27 15:09:57 darrenr Exp + */ + +#include "ipf.h" + + +void fill6bits(bits, msk) +int bits; +u_int *msk; +{ + if (bits == 0) { + msk[0] = 0; + msk[1] = 0; + msk[2] = 0; + msk[3] = 0; + return; + } + + msk[0] = 0xffffffff; + msk[1] = 0xffffffff; + msk[2] = 0xffffffff; + msk[3] = 0xffffffff; + + if (bits == 128) + return; + if (bits > 96) { + msk[3] = htonl(msk[3] << (128 - bits)); + } else if (bits > 64) { + msk[3] = 0; + msk[2] = htonl(msk[2] << (96 - bits)); + } else if (bits > 32) { + msk[3] = 0; + msk[2] = 0; + msk[1] = htonl(msk[1] << (64 - bits)); + } else { + msk[3] = 0; + msk[2] = 0; + msk[1] = 0; + msk[0] = htonl(msk[0] << (32 - bits)); + } +} diff --git a/contrib/ipfilter/lib/flags.c b/contrib/ipfilter/lib/flags.c new file mode 100644 index 0000000..df6645d --- /dev/null +++ b/contrib/ipfilter/lib/flags.c @@ -0,0 +1,25 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: flags.c,v 1.4 2002/11/02 07:16:36 darrenr Exp + */ + +#include "ipf.h" + +/* + * ECN is a new addition to TCP - RFC 2481 + */ +#ifndef TH_ECN +# define TH_ECN 0x40 +#endif +#ifndef TH_CWR +# define TH_CWR 0x80 +#endif + +char flagset[] = "FSRPAUEC"; +u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG, + TH_ECN, TH_CWR }; diff --git a/contrib/ipfilter/lib/genmask.c b/contrib/ipfilter/lib/genmask.c new file mode 100644 index 0000000..06f6404 --- /dev/null +++ b/contrib/ipfilter/lib/genmask.c @@ -0,0 +1,56 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: genmask.c,v 1.7 2003/11/11 13:40:15 darrenr Exp + */ + +#include "ipf.h" + + +int genmask(msk, mskp) +char *msk; +u_32_t *mskp; +{ + char *endptr = 0L; + int bits; + + if (strchr(msk, '.') || strchr(msk, 'x') || strchr(msk, ':')) { + /* possibly of the form xxx.xxx.xxx.xxx + * or 0xYYYYYYYY */ +#ifdef USE_INET6 + if (use_inet6) { + if (inet_pton(AF_INET6, msk, mskp) != 1) + return -1; + } else +#endif + if (inet_aton(msk, (struct in_addr *)mskp) == 0) + return -1; + } else { + /* + * set x most significant bits + */ + bits = (int)strtol(msk, &endptr, 0); +#ifdef USE_INET6 + if ((*endptr != '\0') || + ((bits > 32) && !use_inet6) || (bits < 0) || + ((bits > 128) && use_inet6)) +#else + if (*endptr != '\0' || bits > 32 || bits < 0) +#endif + return -1; +#ifdef USE_INET6 + if (use_inet6) + fill6bits(bits, mskp); + else +#endif + if (bits == 0) + *mskp = 0; + else + *mskp = htonl(0xffffffff << (32 - bits)); + } + return 0; +} diff --git a/contrib/ipfilter/lib/gethost.c b/contrib/ipfilter/lib/gethost.c new file mode 100644 index 0000000..a03168a --- /dev/null +++ b/contrib/ipfilter/lib/gethost.c @@ -0,0 +1,36 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int gethost(name, hostp) +char *name; +u_32_t *hostp; +{ + struct hostent *h; + struct netent *n; + u_32_t addr; + + if (!strcmp(name, "test.host.dots")) { + *hostp = htonl(0xfedcba98); + return 0; + } + + if (!strcmp(name, "<thishost>")) + name = thishost; + + h = gethostbyname(name); + if (h != NULL) { + if ((h->h_addr != NULL) && (h->h_length == sizeof(addr))) { + bcopy(h->h_addr, (char *)&addr, sizeof(addr)); + *hostp = addr; + return 0; + } + } + + n = getnetbyname(name); + if (n != NULL) { + *hostp = (u_32_t)htonl(n->n_net & 0xffffffff); + return 0; + } + return -1; +} diff --git a/contrib/ipfilter/lib/getifname.c b/contrib/ipfilter/lib/getifname.c new file mode 100644 index 0000000..94c9c9c --- /dev/null +++ b/contrib/ipfilter/lib/getifname.c @@ -0,0 +1,76 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#include "kmem.h" + +/* + * Given a pointer to an interface in the kernel, return a pointer to a + * string which is the interface name. + */ +char *getifname(ptr) +struct ifnet *ptr; +{ +#if SOLARIS || defined(__hpux) +# if SOLARIS +# include <sys/mutex.h> +# include <sys/condvar.h> +# endif +# ifdef __hpux +# include "compat.h" +# endif +# include "../pfil/qif.h" + char *ifname; + qif_t qif; + + if ((void *)ptr == (void *)-1) + return "!"; + if (ptr == NULL) + return "-"; + + if (kmemcpy((char *)&qif, (u_long)ptr, sizeof(qif)) == -1) + return "X"; + ifname = strdup(qif.qf_name); + if ((ifname != NULL) && (*ifname == '\0')) { + free(ifname); + return "!"; + } + return ifname; +#else +# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ + defined(__OpenBSD__) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) +#else + char buf[32]; + int len; +# endif + struct ifnet netif; + + if ((void *)ptr == (void *)-1) + return "!"; + if (ptr == NULL) + return "-"; + + if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1) + return "X"; +# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ + defined(__OpenBSD__) || defined(linux) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) + return strdup(netif.if_xname); +# else + if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1) + return "X"; + if (netif.if_unit < 10) + len = 2; + else if (netif.if_unit < 1000) + len = 3; + else if (netif.if_unit < 10000) + len = 4; + else + len = 5; + buf[sizeof(buf) - len] = '\0'; + sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000); + return strdup(buf); +# endif +#endif +} diff --git a/contrib/ipfilter/lib/getline.c b/contrib/ipfilter/lib/getline.c new file mode 100644 index 0000000..61c00ba --- /dev/null +++ b/contrib/ipfilter/lib/getline.c @@ -0,0 +1,58 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: getline.c,v 1.3 2001/06/09 17:09:24 darrenr Exp + */ + +#include <stdio.h> +#if !defined(__SVR4) && !defined(__GNUC__) +#include <strings.h> +#endif +#include <string.h> +#include "ipf.h" + + +/* + * Similar to fgets(3) but can handle '\\' and NL is converted to NUL. + * Returns NULL if error occured, EOF encounterd or input line is too long. + */ +char *getline(str, size, file, linenum) +register char *str; +size_t size; +FILE *file; +int *linenum; +{ + char *p; + int s, len; + + do { + for (p = str, s = size;; p += (len - 1), s -= (len - 1)) { + /* + * if an error occured, EOF was encounterd, or there + * was no room to put NUL, return NULL. + */ + if (fgets(p, s, file) == NULL) + return (NULL); + len = strlen(p); + if (p[len - 1] != '\n') { + p[len] = '\0'; + break; + } + (*linenum)++; + p[len - 1] = '\0'; + if (len < 2 || p[len - 2] != '\\') + break; + else + /* + * Convert '\\' to a space so words don't + * run together + */ + p[len - 2] = ' '; + } + } while (*str == '\0'); + return (str); +} diff --git a/contrib/ipfilter/lib/getnattype.c b/contrib/ipfilter/lib/getnattype.c new file mode 100644 index 0000000..c783d6f --- /dev/null +++ b/contrib/ipfilter/lib/getnattype.c @@ -0,0 +1,54 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ +#include "ipf.h" +#include "kmem.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: getnattype.c,v 1.3 2004/01/17 17:26:07 darrenr Exp"; +#endif + + +/* + * Get a nat filter type given its kernel address. + */ +char *getnattype(ipnat) +ipnat_t *ipnat; +{ + static char unknownbuf[20]; + ipnat_t ipnatbuff; + char *which; + + if (!ipnat) + return "???"; + if (kmemcpy((char *)&ipnatbuff, (long)ipnat, sizeof(ipnatbuff))) + return "!!!"; + + switch (ipnatbuff.in_redir) + { + case NAT_MAP : + which = "MAP"; + break; + case NAT_MAPBLK : + which = "MAP-BLOCK"; + break; + case NAT_REDIRECT : + which = "RDR"; + break; + case NAT_BIMAP : + which = "BIMAP"; + break; + default : + sprintf(unknownbuf, "unknown(%04x)", + ipnatbuff.in_redir & 0xffffffff); + which = unknownbuf; + break; + } + return which; +} diff --git a/contrib/ipfilter/lib/getport.c b/contrib/ipfilter/lib/getport.c new file mode 100644 index 0000000..7cf903d --- /dev/null +++ b/contrib/ipfilter/lib/getport.c @@ -0,0 +1,46 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int getport(fr, name, port) +frentry_t *fr; +char *name; +u_short *port; +{ + struct protoent *p; + struct servent *s; + u_short p1; + + if (fr == NULL || fr->fr_type != FR_T_IPF) { + s = getservbyname(name, NULL); + if (s != NULL) { + *port = s->s_port; + return 0; + } + return -1; + } + + if ((fr->fr_flx & FI_TCPUDP) != 0) { + /* + * If a rule is "tcp/udp" then check that both TCP and UDP + * mappings for this protocol name match ports. + */ + s = getservbyname(name, "tcp"); + if (s == NULL) + return -1; + p1 = s->s_port; + s = getservbyname(name, "udp"); + if (s == NULL || s->s_port != p1) + return -1; + *port = p1; + return 0; + } + + p = getprotobynumber(fr->fr_proto); + s = getservbyname(name, p ? p->p_name : NULL); + if (s != NULL) { + *port = s->s_port; + return 0; + } + return -1; +} diff --git a/contrib/ipfilter/lib/getportproto.c b/contrib/ipfilter/lib/getportproto.c new file mode 100644 index 0000000..17efa43 --- /dev/null +++ b/contrib/ipfilter/lib/getportproto.c @@ -0,0 +1,32 @@ +/* $NetBSD$ */ + +#include <ctype.h> +#include "ipf.h" + +int getportproto(name, proto) +char *name; +int proto; +{ + struct servent *s; + struct protoent *p; + + if (ISDIGIT(*name)) { + int number; + char *s; + + for (s = name; *s != '\0'; s++) + if (!ISDIGIT(*s)) + return -1; + + number = atoi(name); + if (number < 0 || number > 65535) + return -1; + return htons(number); + } + + p = getprotobynumber(proto); + s = getservbyname(name, p ? p->p_name : NULL); + if (s != NULL) + return s->s_port; + return -1; +} diff --git a/contrib/ipfilter/lib/getproto.c b/contrib/ipfilter/lib/getproto.c new file mode 100644 index 0000000..c75f137 --- /dev/null +++ b/contrib/ipfilter/lib/getproto.c @@ -0,0 +1,21 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int getproto(name) +char *name; +{ + struct protoent *p; + char *s; + + for (s = name; *s != '\0'; s++) + if (!ISDIGIT(*s)) + break; + if (*s == '\0') + return atoi(name); + + p = getprotobyname(name); + if (p != NULL) + return p->p_proto; + return -1; +} diff --git a/contrib/ipfilter/lib/getsumd.c b/contrib/ipfilter/lib/getsumd.c new file mode 100644 index 0000000..11ecc57 --- /dev/null +++ b/contrib/ipfilter/lib/getsumd.c @@ -0,0 +1,15 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +char *getsumd(sum) +u_32_t sum; +{ + static char sumdbuf[17]; + + if (sum & NAT_HW_CKSUM) + sprintf(sumdbuf, "hw(%#0x)", sum & 0xffff); + else + sprintf(sumdbuf, "%#0x", sum); + return sumdbuf; +} diff --git a/contrib/ipfilter/lib/hexdump.c b/contrib/ipfilter/lib/hexdump.c new file mode 100644 index 0000000..4eb3b9ad --- /dev/null +++ b/contrib/ipfilter/lib/hexdump.c @@ -0,0 +1,30 @@ +/* $NetBSD$ */ + +#include <ctype.h> + +#include "ipf.h" + +void hexdump(out, addr, len, ascii) +FILE *out; +void *addr; +int len, ascii; +{ + FILE *fpout; + u_char *s, *t; + int i; + + fpout = out ? out : stdout; + for (i = 0, s = addr; i < len; i++, s++) { + fprintf(fpout, "%02x", *s); + if (i % 16 == 15) { + if (ascii != 0) { + fputc('\t', fpout); + for (t = s - 15; t<= s; t++) + fputc(ISPRINT(*t) ? *t : '.', fpout); + } + fputc('\n', fpout); + } else if (i % 4 == 3) { + fputc(' ', fpout); + } + } +} diff --git a/contrib/ipfilter/lib/hostmask.c b/contrib/ipfilter/lib/hostmask.c new file mode 100644 index 0000000..67755f8 --- /dev/null +++ b/contrib/ipfilter/lib/hostmask.c @@ -0,0 +1,95 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: hostmask.c,v 1.10 2002/01/28 06:50:46 darrenr Exp + */ + +#include "ipf.h" + + +/* + * returns -1 if neither "hostmask/num" or "hostmask mask addr" are + * found in the line segments, there is an error processing this information, + * or there is an error processing ports information. + */ +int hostmask(seg, proto, ifname, sa, msk, linenum) +char ***seg, *proto, *ifname; +u_32_t *sa, *msk; +int linenum; +{ + struct in_addr maskaddr; + char *s; + + if ((s = strchr(**seg, '='))) { + *s++ = '\0'; + if (!strcmp(**seg, "pool")) { + *sa = atoi(s); + return 1; + } + } + + /* + * is it possibly hostname/num ? + */ + if ((s = strchr(**seg, '/')) || + ((s = strchr(**seg, ':')) && !strchr(s + 1, ':'))) { + *s++ ='\0'; + if (genmask(s, msk) == -1) { + fprintf(stderr, "%d: bad mask (%s)\n", linenum, s); + return -1; + } + if (hostnum(sa, **seg, linenum, ifname) == -1) { + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); + return -1; + } + *sa &= *msk; + (*seg)++; + return 0; + } + + /* + * look for extra segments if "mask" found in right spot + */ + if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) { + if (hostnum(sa, **seg, linenum, ifname) == -1) { + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); + return -1; + } + (*seg)++; + (*seg)++; + if (inet_aton(**seg, &maskaddr) == 0) { + fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg); + return -1; + } + *msk = maskaddr.s_addr; + (*seg)++; + *sa &= *msk; + return 0; + } + + if (**seg) { + u_32_t k; + + if (hostnum(sa, **seg, linenum, ifname) == -1) { + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); + return -1; + } + (*seg)++; + k = *sa ? 0xffffffff : 0; +#ifdef USE_INET6 + if (use_inet6) { + msk[1] = k; + msk[2] = k; + msk[3] = k; + } +#endif + *msk = k; + return 0; + } + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); + return -1; +} diff --git a/contrib/ipfilter/lib/hostname.c b/contrib/ipfilter/lib/hostname.c new file mode 100644 index 0000000..a0109da --- /dev/null +++ b/contrib/ipfilter/lib/hostname.c @@ -0,0 +1,51 @@ +/* $NetBSD$ */ + + +#include "ipf.h" + +char *hostname(v, ip) +int v; +void *ip; +{ + static char hostbuf[MAXHOSTNAMELEN+1]; + struct hostent *hp; + struct in_addr ipa; + struct netent *np; + + if (v == 4) { + ipa.s_addr = *(u_32_t *)ip; + if (ipa.s_addr == htonl(0xfedcba98)) + return "test.host.dots"; + } + + if ((opts & OPT_NORESOLVE) == 0) { + if (v == 4) { + hp = gethostbyaddr(ip, 4, AF_INET); + if (hp != NULL && hp->h_name != NULL && + *hp->h_name != '\0') { + strncpy(hostbuf, hp->h_name, sizeof(hostbuf)); + hostbuf[sizeof(hostbuf) - 1] = '\0'; + return hostbuf; + } + + np = getnetbyaddr(ipa.s_addr, AF_INET); + if (np != NULL && np->n_name != NULL && + *np->n_name != '\0') { + strncpy(hostbuf, np->n_name, sizeof(hostbuf)); + hostbuf[sizeof(hostbuf) - 1] = '\0'; + return hostbuf; + } + } + } + + if (v == 4) { + return inet_ntoa(ipa); + } +#ifdef USE_INET6 + (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); + hostbuf[MAXHOSTNAMELEN] = '\0'; + return hostbuf; +#else + return "IPv6"; +#endif +} diff --git a/contrib/ipfilter/lib/hostnum.c b/contrib/ipfilter/lib/hostnum.c new file mode 100644 index 0000000..c62e4a1 --- /dev/null +++ b/contrib/ipfilter/lib/hostnum.c @@ -0,0 +1,49 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: hostnum.c,v 1.10.2.1 2004/12/09 19:41:20 darrenr Exp + */ + +#include <ctype.h> + +#include "ipf.h" + + +/* + * returns an ip address as a long var as a result of either a DNS lookup or + * straight inet_addr() call + */ +int hostnum(ipa, host, linenum, ifname) +u_32_t *ipa; +char *host; +int linenum; +char *ifname; +{ + struct in_addr ip; + + if (!strcasecmp("any", host) || + (ifname && *ifname && !strcasecmp(ifname, host))) + return 0; + +#ifdef USE_INET6 + if (use_inet6) { + if (inet_pton(AF_INET6, host, ipa) == 1) + return 0; + else + return -1; + } +#endif + if (ISDIGIT(*host) && inet_aton(host, &ip)) { + *ipa = ip.s_addr; + return 0; + } + + if (!strcasecmp("<thishost>", host)) + host = thishost; + + return gethost(host, ipa); +} diff --git a/contrib/ipfilter/lib/icmpcode.c b/contrib/ipfilter/lib/icmpcode.c new file mode 100644 index 0000000..17e1ba4 --- /dev/null +++ b/contrib/ipfilter/lib/icmpcode.c @@ -0,0 +1,49 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: icmpcode.c,v 1.7.2.1 2004/12/09 19:41:20 darrenr Exp + */ + +#include <ctype.h> + +#include "ipf.h" + +#ifndef MIN +# define MIN(a,b) ((a) > (b) ? (b) : (a)) +#endif + + +char *icmpcodes[MAX_ICMPCODE + 1] = { + "net-unr", "host-unr", "proto-unr", "port-unr", "needfrag", "srcfail", + "net-unk", "host-unk", "isolate", "net-prohib", "host-prohib", + "net-tos", "host-tos", "filter-prohib", "host-preced", "preced-cutoff", + NULL }; + +/* + * Return the number for the associated ICMP unreachable code. + */ +int icmpcode(str) +char *str; +{ + char *s; + int i, len; + + if ((s = strrchr(str, ')'))) + *s = '\0'; + if (ISDIGIT(*str)) { + if (!ratoi(str, &i, 0, 255)) + return -1; + else + return i; + } + len = strlen(str); + for (i = 0; icmpcodes[i]; i++) + if (!strncasecmp(str, icmpcodes[i], MIN(len, + strlen(icmpcodes[i])) )) + return i; + return -1; +} diff --git a/contrib/ipfilter/lib/inet_addr.c b/contrib/ipfilter/lib/inet_addr.c new file mode 100644 index 0000000..5ccf6a9 --- /dev/null +++ b/contrib/ipfilter/lib/inet_addr.c @@ -0,0 +1,210 @@ +/* $NetBSD$ */ + +/* + * ++Copyright++ 1983, 1990, 1993 + * - + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#if !defined(lint) +static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static const char rcsid[] = "@(#)Id: inet_addr.c,v 1.8.2.3 2004/12/09 19:41:20 darrenr Exp"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> + +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif +#ifndef linux +int inet_aton __P((const char *, struct in_addr *)); + +/* + * Because the ctype(3) posix definition, if used "safely" in code everywhere, + * would mean all normal code that walks through strings needed casts. Yuck. + */ +#define ISALNUM(x) isalnum((u_char)(x)) +#define ISALPHA(x) isalpha((u_char)(x)) +#define ISASCII(x) isascii((u_char)(x)) +#define ISDIGIT(x) isdigit((u_char)(x)) +#define ISPRINT(x) isprint((u_char)(x)) +#define ISSPACE(x) isspace((u_char)(x)) +#define ISUPPER(x) isupper((u_char)(x)) +#define ISXDIGIT(x) isxdigit((u_char)(x)) +#define ISLOWER(x) islower((u_char)(x)) + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(cp, addr) + register const char *cp; + struct in_addr *addr; +{ + register u_long val; + register int base, n; + register char c; + u_int parts[4]; + register u_int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!ISDIGIT(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (ISASCII(c) && ISDIGIT(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && ISASCII(c) && ISXDIGIT(c)) { + val = (val << 4) | + (c + 10 - (ISLOWER(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!ISASCII(c) || !ISSPACE(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} +#endif + +/* these are compatibility routines, not needed on recent BSD releases */ + +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +#if 0 +inet_addr(cp) + const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (0xffffffff); +} +#endif diff --git a/contrib/ipfilter/lib/initparse.c b/contrib/ipfilter/lib/initparse.c new file mode 100644 index 0000000..676774c --- /dev/null +++ b/contrib/ipfilter/lib/initparse.c @@ -0,0 +1,20 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: initparse.c,v 1.6 2002/01/28 06:50:46 darrenr Exp + */ +#include "ipf.h" + + +char thishost[MAXHOSTNAMELEN]; + + +void initparse __P((void)) +{ + gethostname(thishost, sizeof(thishost)); + thishost[sizeof(thishost) - 1] = '\0'; +} diff --git a/contrib/ipfilter/lib/ionames.c b/contrib/ipfilter/lib/ionames.c new file mode 100644 index 0000000..9e4602b --- /dev/null +++ b/contrib/ipfilter/lib/ionames.c @@ -0,0 +1,40 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ionames.c,v 1.7 2002/01/28 06:50:46 darrenr Exp + */ +#include "ipf.h" + + +struct ipopt_names ionames[] ={ + { IPOPT_NOP, 0x000001, 1, "nop" }, /* RFC791 */ + { IPOPT_RR, 0x000002, 7, "rr" }, /* 1 route */ + { IPOPT_ZSU, 0x000004, 3, "zsu" }, /* size ?? */ + { IPOPT_MTUP, 0x000008, 3, "mtup" }, /* RFC1191 */ + { IPOPT_MTUR, 0x000010, 3, "mtur" }, /* RFC1191 */ + { IPOPT_ENCODE, 0x000020, 3, "encode" }, /* size ?? */ + { IPOPT_TS, 0x000040, 8, "ts" }, /* 1 TS */ + { IPOPT_TR, 0x000080, 3, "tr" }, /* RFC1393 */ + { IPOPT_SECURITY,0x000100, 11, "sec" }, /* RFC1108 */ + { IPOPT_SECURITY,0x000100, 11, "sec-class" }, /* RFC1108 */ + { IPOPT_LSRR, 0x000200, 7, "lsrr" }, /* 1 route */ + { IPOPT_E_SEC, 0x000400, 3, "e-sec" }, /* RFC1108 */ + { IPOPT_CIPSO, 0x000800, 3, "cipso" }, /* size ?? */ + { IPOPT_SATID, 0x001000, 4, "satid" }, /* RFC791 */ + { IPOPT_SSRR, 0x002000, 7, "ssrr" }, /* 1 route */ + { IPOPT_ADDEXT, 0x004000, 3, "addext" }, /* IPv7 ?? */ + { IPOPT_VISA, 0x008000, 3, "visa" }, /* size ?? */ + { IPOPT_IMITD, 0x010000, 3, "imitd" }, /* size ?? */ + { IPOPT_EIP, 0x020000, 3, "eip" }, /* RFC1385 */ + { IPOPT_FINN, 0x040000, 3, "finn" }, /* size ?? */ + { IPOPT_DPS, 0x080000, 3, "dps" }, /* size ?? */ + { IPOPT_SDB, 0x100000, 3, "sdb" }, /* size ?? */ + { IPOPT_NSAPA, 0x200000, 3, "nsapa" }, /* size ?? */ + { IPOPT_RTRALRT,0x400000, 3, "rtralrt" }, /* RFC2113 */ + { IPOPT_UMP, 0x800000, 3, "ump" }, /* size ?? */ + { 0, 0, 0, (char *)NULL } /* must be last */ +}; diff --git a/contrib/ipfilter/lib/ipf_dotuning.c b/contrib/ipfilter/lib/ipf_dotuning.c new file mode 100644 index 0000000..c9416ff --- /dev/null +++ b/contrib/ipfilter/lib/ipf_dotuning.c @@ -0,0 +1,60 @@ +/* $NetBSD$ */ + +#include "ipf.h" +#include "ipl.h" +#include <sys/ioctl.h> + +void ipf_dotuning(fd, tuneargs, iocfn) +int fd; +char *tuneargs; +ioctlfunc_t iocfn; +{ + ipfobj_t obj; + ipftune_t tu; + char *s, *t; + + bzero((char *)&tu, sizeof(tu)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(tu);; + obj.ipfo_ptr = (void *)&tu; + obj.ipfo_type = IPFOBJ_TUNEABLE; + + for (s = strtok(tuneargs, ","); s != NULL; s = strtok(NULL, ",")) { + if (!strcmp(s, "list")) { + while (1) { + if ((*iocfn)(fd, SIOCIPFGETNEXT, &obj) == -1) { + perror("ioctl(SIOCIPFGETNEXT)"); + break; + } + if (tu.ipft_cookie == NULL) + break; + + tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0'; + printtunable(&tu); + } + } else if ((t = strchr(s, '=')) != NULL) { + *t++ = '\0'; + strncpy(tu.ipft_name, s, sizeof(tu.ipft_name)); + if (sscanf(t, "%lu", &tu.ipft_vlong) == 1) { + if ((*iocfn)(fd, SIOCIPFSET, &obj) == -1) { + perror("ioctl(SIOCIPFSET)"); + return; + } + } else { + fprintf(stderr, "invalid value '%s'\n", s); + return; + } + } else { + strncpy(tu.ipft_name, s, sizeof(tu.ipft_name)); + if ((*iocfn)(fd, SIOCIPFGET, &obj) == -1) { + perror("ioctl(SIOCIPFGET)"); + return; + } + if (tu.ipft_cookie == NULL) + return; + + tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0'; + printtunable(&tu); + } + } +} diff --git a/contrib/ipfilter/lib/ipft_ef.c b/contrib/ipfilter/lib/ipft_ef.c new file mode 100644 index 0000000..eebc417 --- /dev/null +++ b/contrib/ipfilter/lib/ipft_ef.c @@ -0,0 +1,130 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_ef.c,v 1.14 2004/01/08 13:34:31 darrenr Exp + */ + +/* + icmp type + lnth proto source destination src port dst port + +etherfind -n + + 60 tcp 128.250.20.20 128.250.133.13 2419 telnet + +etherfind -n -t + + 0.32 91 04 131.170.1.10 128.250.133.13 + 0.33 566 udp 128.250.37.155 128.250.133.3 901 901 +*/ + +#include "ipf.h" +#include "ipt.h" + +#ifndef linux +#include <netinet/ip_var.h> +#endif +#include <netinet/tcpip.h> + + +#if !defined(lint) +static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipft_ef.c,v 1.14 2004/01/08 13:34:31 darrenr Exp"; +#endif + +static int etherf_open __P((char *)); +static int etherf_close __P((void)); +static int etherf_readip __P((char *, int, char **, int *)); + +struct ipread etherf = { etherf_open, etherf_close, etherf_readip, 0 }; + +static FILE *efp = NULL; +static int efd = -1; + + +static int etherf_open(fname) +char *fname; +{ + if (efd != -1) + return efd; + + if (!strcmp(fname, "-")) { + efd = 0; + efp = stdin; + } else { + efd = open(fname, O_RDONLY); + efp = fdopen(efd, "r"); + } + return efd; +} + + +static int etherf_close() +{ + return close(efd); +} + + +static int etherf_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + struct tcpiphdr pkt; + ip_t *ip = (ip_t *)&pkt; + char src[16], dst[16], sprt[16], dprt[16]; + char lbuf[128], len[8], prot[8], time[8], *s; + int slen, extra = 0, i; + + if (!fgets(lbuf, sizeof(lbuf) - 1, efp)) + return 0; + + if ((s = strchr(lbuf, '\n'))) + *s = '\0'; + lbuf[sizeof(lbuf)-1] = '\0'; + + bzero(&pkt, sizeof(pkt)); + + if (sscanf(lbuf, "%7s %7s %15s %15s %15s %15s", len, prot, src, dst, + sprt, dprt) != 6) + if (sscanf(lbuf, "%7s %7s %7s %15s %15s %15s %15s", time, + len, prot, src, dst, sprt, dprt) != 7) + return -1; + + ip->ip_p = getproto(prot); + + switch (ip->ip_p) { + case IPPROTO_TCP : + case IPPROTO_UDP : + s = strtok(NULL, " :"); + ip->ip_len += atoi(s); + if (ip->ip_p == IPPROTO_TCP) + extra = sizeof(struct tcphdr); + else if (ip->ip_p == IPPROTO_UDP) + extra = sizeof(struct udphdr); + break; +#ifdef IGMP + case IPPROTO_IGMP : + extra = sizeof(struct igmp); + break; +#endif + case IPPROTO_ICMP : + extra = sizeof(struct icmp); + break; + default : + break; + } + + (void) inet_aton(src, &ip->ip_src); + (void) inet_aton(dst, &ip->ip_dst); + ip->ip_len = atoi(len); + IP_HL_A(ip, sizeof(ip_t)); + + slen = IP_HL(ip) + extra; + i = MIN(cnt, slen); + bcopy((char *)&pkt, buf, i); + return i; +} diff --git a/contrib/ipfilter/lib/ipft_hx.c b/contrib/ipfilter/lib/ipft_hx.c new file mode 100644 index 0000000..3cc8ec5 --- /dev/null +++ b/contrib/ipfilter/lib/ipft_hx.c @@ -0,0 +1,158 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1995-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipft_hx.c,v 1.11.4.1 2004/12/09 19:41:20 darrenr Exp"; +#endif + +#include <ctype.h> + +#include "ipf.h" +#include "ipt.h" + + +extern int opts; + +static int hex_open __P((char *)); +static int hex_close __P((void)); +static int hex_readip __P((char *, int, char **, int *)); +static char *readhex __P((char *, char *)); + +struct ipread iphex = { hex_open, hex_close, hex_readip, 0 }; +static FILE *tfp = NULL; +static int tfd = -1; + +static int hex_open(fname) +char *fname; +{ + if (tfp && tfd != -1) { + rewind(tfp); + return tfd; + } + + if (!strcmp(fname, "-")) { + tfd = 0; + tfp = stdin; + } else { + tfd = open(fname, O_RDONLY); + if (tfd != -1) + tfp = fdopen(tfd, "r"); + } + return tfd; +} + + +static int hex_close() +{ + int cfd = tfd; + + tfd = -1; + return close(cfd); +} + + +static int hex_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + register char *s, *t, *u; + char line[513]; + ip_t *ip; + + /* + * interpret start of line as possibly "[ifname]" or + * "[in/out,ifname]". + */ + if (ifn) + *ifn = NULL; + if (dir) + *dir = 0; + ip = (ip_t *)buf; + while (fgets(line, sizeof(line)-1, tfp)) { + if ((s = strchr(line, '\n'))) { + if (s == line) + return (char *)ip - buf; + *s = '\0'; + } + if ((s = strchr(line, '#'))) + *s = '\0'; + if (!*line) + continue; + if (!(opts & OPT_BRIEF)) { + printf("input: %s", line); + } + + if ((*line == '[') && (s = strchr(line, ']'))) { + t = line + 1; + if (s - t > 0) { + *s++ = '\0'; + if ((u = strchr(t, ',')) && (u < s)) { + u++; + if (ifn) + *ifn = strdup(u); + if (dir) { + if (*t == 'i') + *dir = 0; + else if (*t == 'o') + *dir = 1; + } + } else if (ifn) + *ifn = t; + } + } else + s = line; + t = (char *)ip; + ip = (ip_t *)readhex(s, (char *)ip); + if (!(opts & OPT_BRIEF)) { + if (opts & OPT_ASCII) { + if (t < (char *)ip) + putchar('\t'); + while (t < (char *)ip) { + if (ISPRINT(*t) && ISASCII(*t)) + putchar(*t); + else + putchar('.'); + t++; + } + } + putchar('\n'); + fflush(stdout); + } + } + return -1; +} + + +static char *readhex(src, dst) +register char *src, *dst; +{ + int state = 0; + char c; + + while ((c = *src++)) { + if (ISSPACE(c)) { + if (state) { + dst++; + state = 0; + } + continue; + } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F')) { + c = ISDIGIT(c) ? (c - '0') : (TOUPPER(c) - 55); + if (state == 0) { + *dst = (c << 4); + state++; + } else { + *dst++ |= c; + state = 0; + } + } else + break; + } + return dst; +} diff --git a/contrib/ipfilter/lib/ipft_pc.c b/contrib/ipfilter/lib/ipft_pc.c new file mode 100644 index 0000000..3678d78 --- /dev/null +++ b/contrib/ipfilter/lib/ipft_pc.c @@ -0,0 +1,252 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_pc.c,v 1.10 2004/02/07 18:17:40 darrenr Exp + */ +#include "ipf.h" +#include "pcap-ipf.h" +#include "bpf-ipf.h" +#include "ipt.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: ipft_pc.c,v 1.10 2004/02/07 18:17:40 darrenr Exp"; +#endif + +struct llc { + int lc_type; + int lc_sz; /* LLC header length */ + int lc_to; /* LLC Type offset */ + int lc_tl; /* LLC Type length */ +}; + +/* + * While many of these maybe the same, some do have different header formats + * which make this useful. + */ + +static struct llc llcs[] = { + { DLT_NULL, 0, 0, 0 }, + { DLT_EN10MB, 14, 12, 2 }, + { DLT_EN3MB, 0, 0, 0 }, + { DLT_AX25, 0, 0, 0 }, + { DLT_PRONET, 0, 0, 0 }, + { DLT_CHAOS, 0, 0, 0 }, + { DLT_IEEE802, 0, 0, 0 }, + { DLT_ARCNET, 0, 0, 0 }, + { DLT_SLIP, 0, 0, 0 }, + { DLT_PPP, 0, 0, 0 }, + { DLT_FDDI, 0, 0, 0 }, +#ifdef DLT_ATMRFC1483 + { DLT_ATMRFC1483, 0, 0, 0 }, +#endif + { DLT_RAW, 0, 0, 0 }, +#ifdef DLT_ENC + { DLT_ENC, 0, 0, 0 }, +#endif +#ifdef DLT_SLIP_BSDOS + { DLT_SLIP_BSDOS, 0, 0, 0 }, +#endif +#ifdef DLT_PPP_BSDOS + { DLT_PPP_BSDOS, 0, 0, 0 }, +#endif +#ifdef DLT_HIPPI + { DLT_HIPPI, 0, 0, 0 }, +#endif +#ifdef DLT_HDLC + { DLT_HDLC, 0, 0, 0 }, +#endif +#ifdef DLT_PPP_SERIAL + { DLT_PPP_SERIAL, 4, 4, 0 }, +#endif +#ifdef DLT_PPP_ETHER + { DLT_PPP_ETHER, 8, 8, 0 }, +#endif +#ifdef DLT_ECONET + { DLT_ECONET, 0, 0, 0 }, +#endif + { -1, -1, -1, -1 } +}; + +static int pcap_open __P((char *)); +static int pcap_close __P((void)); +static int pcap_readip __P((char *, int, char **, int *)); +static void swap_hdr __P((pcaphdr_t *)); +static int pcap_read_rec __P((struct pcap_pkthdr *)); + +static int pfd = -1, swapped = 0; +static struct llc *llcp = NULL; + +struct ipread pcap = { pcap_open, pcap_close, pcap_readip, 0 }; + +#define SWAPLONG(y) \ + ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) +#define SWAPSHORT(y) \ + ( (((y)&0xff)<<8) | (((y)&0xff00)>>8) ) + +static void swap_hdr(p) +pcaphdr_t *p; +{ + p->pc_v_maj = SWAPSHORT(p->pc_v_maj); + p->pc_v_min = SWAPSHORT(p->pc_v_min); + p->pc_zone = SWAPLONG(p->pc_zone); + p->pc_sigfigs = SWAPLONG(p->pc_sigfigs); + p->pc_slen = SWAPLONG(p->pc_slen); + p->pc_type = SWAPLONG(p->pc_type); +} + +static int pcap_open(fname) +char *fname; +{ + pcaphdr_t ph; + int fd, i; + + if (pfd != -1) + return pfd; + + if (!strcmp(fname, "-")) + fd = 0; + else if ((fd = open(fname, O_RDONLY)) == -1) + return -1; + + if (read(fd, (char *)&ph, sizeof(ph)) != sizeof(ph)) + return -2; + + if (ph.pc_id != TCPDUMP_MAGIC) { + if (SWAPLONG(ph.pc_id) != TCPDUMP_MAGIC) { + (void) close(fd); + return -2; + } + swapped = 1; + swap_hdr(&ph); + } + + if (ph.pc_v_maj != PCAP_VERSION_MAJ) { + (void) close(fd); + return -2; + } + + for (i = 0; llcs[i].lc_type != -1; i++) + if (llcs[i].lc_type == ph.pc_type) { + llcp = llcs + i; + break; + } + + if (llcp == NULL) { + (void) close(fd); + return -2; + } + + pfd = fd; + printf("opened pcap file %s:\n", fname); + printf("\tid: %08x version: %d.%d type: %d snap %d\n", + ph.pc_id, ph.pc_v_maj, ph.pc_v_min, ph.pc_type, ph.pc_slen); + + return fd; +} + + +static int pcap_close() +{ + return close(pfd); +} + + +/* + * read in the header (and validate) which should be the first record + * in a pcap file. + */ +static int pcap_read_rec(rec) +struct pcap_pkthdr *rec; +{ + int n, p; + + if (read(pfd, (char *)rec, sizeof(*rec)) != sizeof(*rec)) + return -2; + + if (swapped) { + rec->ph_clen = SWAPLONG(rec->ph_clen); + rec->ph_len = SWAPLONG(rec->ph_len); + rec->ph_ts.tv_sec = SWAPLONG(rec->ph_ts.tv_sec); + rec->ph_ts.tv_usec = SWAPLONG(rec->ph_ts.tv_usec); + } + p = rec->ph_clen; + n = MIN(p, rec->ph_len); + if (!n || n < 0) + return -3; + + return p; +} + + +#ifdef notyet +/* + * read an entire pcap packet record. only the data part is copied into + * the available buffer, with the number of bytes copied returned. + */ +static int pcap_read(buf, cnt) +char *buf; +int cnt; +{ + struct pcap_pkthdr rec; + static char *bufp = NULL; + int i, n; + + if ((i = pcap_read_rec(&rec)) <= 0) + return i; + + if (!bufp) + bufp = malloc(i); + else + bufp = realloc(bufp, i); + + if (read(pfd, bufp, i) != i) + return -2; + + n = MIN(i, cnt); + bcopy(bufp, buf, n); + return n; +} +#endif + + +/* + * return only an IP packet read into buf + */ +static int pcap_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + static char *bufp = NULL; + struct pcap_pkthdr rec; + struct llc *l; + char *s, ty[4]; + int i, n; + + l = llcp; + + /* do { */ + if ((i = pcap_read_rec(&rec)) <= 0) + return i; + + if (!bufp) + bufp = malloc(i); + else + bufp = realloc(bufp, i); + s = bufp; + + if (read(pfd, s, i) != i) + return -2; + + i -= l->lc_sz; + s += l->lc_to; + bcopy(s, ty, l->lc_tl); + s += l->lc_tl; + /* } while (ty[0] != 0x8 && ty[1] != 0); */ + n = MIN(i, cnt); + bcopy(s, buf, n); + return n; +} diff --git a/contrib/ipfilter/lib/ipft_sn.c b/contrib/ipfilter/lib/ipft_sn.c new file mode 100644 index 0000000..1458821 --- /dev/null +++ b/contrib/ipfilter/lib/ipft_sn.c @@ -0,0 +1,197 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_sn.c,v 1.7 2003/02/16 02:32:36 darrenr Exp + */ + +/* + * Written to comply with the recent RFC 1761 from Sun. + */ +#include "ipf.h" +#include "snoop.h" +#include "ipt.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: ipft_sn.c,v 1.7 2003/02/16 02:32:36 darrenr Exp"; +#endif + +struct llc { + int lc_sz; /* LLC header length */ + int lc_to; /* LLC Type offset */ + int lc_tl; /* LLC Type length */ +}; + +/* + * While many of these maybe the same, some do have different header formats + * which make this useful. + */ +static struct llc llcs[SDL_MAX+1] = { + { 0, 0, 0 }, /* SDL_8023 */ + { 0, 0, 0 }, /* SDL_8024 */ + { 0, 0, 0 }, /* SDL_8025 */ + { 0, 0, 0 }, /* SDL_8026 */ + { 14, 12, 2 }, /* SDL_ETHER */ + { 0, 0, 0 }, /* SDL_HDLC */ + { 0, 0, 0 }, /* SDL_CHSYNC */ + { 0, 0, 0 }, /* SDL_IBMCC */ + { 0, 0, 0 }, /* SDL_FDDI */ + { 0, 0, 0 }, /* SDL_OTHER */ +}; + +static int snoop_open __P((char *)); +static int snoop_close __P((void)); +static int snoop_readip __P((char *, int, char **, int *)); + +static int sfd = -1, s_type = -1; +static int snoop_read_rec __P((struct snooppkt *)); + +struct ipread snoop = { snoop_open, snoop_close, snoop_readip, 0 }; + + +static int snoop_open(fname) +char *fname; +{ + struct snoophdr sh; + int fd; + int s_v; + + if (sfd != -1) + return sfd; + + if (!strcmp(fname, "-")) + fd = 0; + else if ((fd = open(fname, O_RDONLY)) == -1) + return -1; + + if (read(fd, (char *)&sh, sizeof(sh)) != sizeof(sh)) + return -2; + + s_v = (int)ntohl(sh.s_v); + s_type = (int)ntohl(sh.s_type); + + if (s_v != SNOOP_VERSION || + s_type < 0 || s_type > SDL_MAX) { + (void) close(fd); + return -2; + } + + sfd = fd; + printf("opened snoop file %s:\n", fname); + printf("\tid: %8.8s version: %d type: %d\n", sh.s_id, s_v, s_type); + + return fd; +} + + +static int snoop_close() +{ + return close(sfd); +} + + +/* + * read in the header (and validate) which should be the first record + * in a snoop file. + */ +static int snoop_read_rec(rec) +struct snooppkt *rec; +{ + int n, plen, ilen; + + if (read(sfd, (char *)rec, sizeof(*rec)) != sizeof(*rec)) + return -2; + + ilen = (int)ntohl(rec->sp_ilen); + plen = (int)ntohl(rec->sp_plen); + if (ilen > plen || plen < sizeof(*rec)) + return -2; + + plen -= sizeof(*rec); + n = MIN(plen, ilen); + if (!n || n < 0) + return -3; + + return plen; +} + + +#ifdef notyet +/* + * read an entire snoop packet record. only the data part is copied into + * the available buffer, with the number of bytes copied returned. + */ +static int snoop_read(buf, cnt) +char *buf; +int cnt; +{ + struct snooppkt rec; + static char *bufp = NULL; + int i, n; + + if ((i = snoop_read_rec(&rec)) <= 0) + return i; + + if (!bufp) + bufp = malloc(i); + else + bufp = realloc(bufp, i); + + if (read(sfd, bufp, i) != i) + return -2; + + n = MIN(i, cnt); + bcopy(bufp, buf, n); + return n; +} +#endif + + +/* + * return only an IP packet read into buf + */ +static int snoop_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + static char *bufp = NULL; + struct snooppkt rec; + struct llc *l; + char ty[4], *s; + int i, n; + + do { + if ((i = snoop_read_rec(&rec)) <= 0) + return i; + + if (!bufp) + bufp = malloc(i); + else + bufp = realloc(bufp, i); + s = bufp; + + if (read(sfd, s, i) != i) + return -2; + + l = &llcs[s_type]; + i -= l->lc_to; + s += l->lc_to; + /* + * XXX - bogus assumption here on the part of the time field + * that it won't be greater than 4 bytes and the 1st two will + * have the values 8 and 0 for IP. Should be a table of + * these too somewhere. Really only works for SDL_ETHER. + */ + bcopy(s, ty, l->lc_tl); + } while (ty[0] != 0x8 && ty[1] != 0); + + i -= l->lc_tl; + s += l->lc_tl; + n = MIN(i, cnt); + bcopy(s, buf, n); + + return n; +} diff --git a/contrib/ipfilter/lib/ipft_td.c b/contrib/ipfilter/lib/ipft_td.c new file mode 100644 index 0000000..b278c72 --- /dev/null +++ b/contrib/ipfilter/lib/ipft_td.c @@ -0,0 +1,174 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_td.c,v 1.15 2004/01/08 13:34:31 darrenr Exp + */ + +/* +tcpdump -n + +00:05:47.816843 128.231.76.76.3291 > 224.2.252.231.36573: udp 36 (encap) + +tcpdump -nq + +00:33:48.410771 192.73.213.11.1463 > 224.2.248.153.59360: udp 31 (encap) + +tcpdump -nqt + +128.250.133.13.23 > 128.250.20.20.2419: tcp 27 + +tcpdump -nqtt + +123456789.1234567 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 + +tcpdump -nqte + +8:0:20:f:65:f7 0:0:c:1:8a:c5 81: 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 + +*/ + +#include "ipf.h" +#include "ipt.h" + +#ifndef linux +#include <netinet/ip_var.h> +#endif +#include <netinet/tcpip.h> + + +#if !defined(lint) +static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipft_td.c,v 1.15 2004/01/08 13:34:31 darrenr Exp"; +#endif + +static int tcpd_open __P((char *)); +static int tcpd_close __P((void)); +static int tcpd_readip __P((char *, int, char **, int *)); +static int count_dots __P((char *)); + +struct ipread tcpd = { tcpd_open, tcpd_close, tcpd_readip, 0 }; + +static FILE *tfp = NULL; +static int tfd = -1; + + +static int tcpd_open(fname) +char *fname; +{ + if (tfd != -1) + return tfd; + + if (!strcmp(fname, "-")) { + tfd = 0; + tfp = stdin; + } else { + tfd = open(fname, O_RDONLY); + tfp = fdopen(tfd, "r"); + } + return tfd; +} + + +static int tcpd_close() +{ + (void) fclose(tfp); + return close(tfd); +} + + +static int count_dots(str) +char *str; +{ + int i = 0; + + while (*str) + if (*str++ == '.') + i++; + return i; +} + + +static int tcpd_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + struct tcpiphdr pkt; + ip_t *ip = (ip_t *)&pkt; + char src[32], dst[32], misc[256], time[32], link1[32], link2[32]; + char lbuf[160], *s; + int n, slen, extra = 0; + + if (!fgets(lbuf, sizeof(lbuf) - 1, tfp)) + return 0; + + if ((s = strchr(lbuf, '\n'))) + *s = '\0'; + lbuf[sizeof(lbuf)-1] = '\0'; + + bzero(&pkt, sizeof(pkt)); + + if ((n = sscanf(lbuf, "%31s > %31s: %255s", src, dst, misc)) != 3) + if ((n = sscanf(lbuf, "%31s %31s > %31s: %255s", + time, src, dst, misc)) != 4) + if ((n = sscanf(lbuf, "%31s %31s: %31s > %31s: %255s", + link1, link2, src, dst, misc)) != 5) { + n = sscanf(lbuf, + "%31s %31s %31s: %31s > %31s: %255s", + time, link1, link2, src, dst, misc); + if (n != 6) + return -1; + } + + if (count_dots(dst) == 4) { + s = strrchr(src, '.'); + *s++ = '\0'; + (void) inet_aton(src, &ip->ip_src); + pkt.ti_sport = htons(atoi(s)); + *--s = '.'; + s = strrchr(dst, '.'); + + *s++ = '\0'; + (void) inet_aton(src, &ip->ip_dst); + pkt.ti_dport = htons(atoi(s)); + *--s = '.'; + + } else { + (void) inet_aton(src, &ip->ip_src); + (void) inet_aton(src, &ip->ip_dst); + } + ip->ip_len = sizeof(ip_t); + IP_HL_A(ip, sizeof(ip_t)); + + s = strtok(misc, " :"); + ip->ip_p = getproto(s); + + switch (ip->ip_p) + { + case IPPROTO_TCP : + case IPPROTO_UDP : + s = strtok(NULL, " :"); + ip->ip_len += atoi(s); + if (ip->ip_p == IPPROTO_TCP) + extra = sizeof(struct tcphdr); + else if (ip->ip_p == IPPROTO_UDP) + extra = sizeof(struct udphdr); + break; +#ifdef IGMP + case IPPROTO_IGMP : + extra = sizeof(struct igmp); + break; +#endif + case IPPROTO_ICMP : + extra = sizeof(struct icmp); + break; + default : + break; + } + + slen = IP_HL(ip) + extra + ip->ip_len; + return slen; +} diff --git a/contrib/ipfilter/lib/ipft_tx.c b/contrib/ipfilter/lib/ipft_tx.c new file mode 100644 index 0000000..c77fbc4 --- /dev/null +++ b/contrib/ipfilter/lib/ipft_tx.c @@ -0,0 +1,331 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1995-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_tx.c,v 1.15.2.2 2004/12/09 19:41:21 darrenr Exp + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipft_tx.c,v 1.15.2.2 2004/12/09 19:41:21 darrenr Exp"; +#endif + +#include <ctype.h> + +#include "ipf.h" +#include "ipt.h" + +#ifndef linux +#include <netinet/ip_var.h> +#endif +#include <netinet/tcpip.h> + + +extern int opts; + +static char *tx_proto = ""; + +static int text_open __P((char *)), text_close __P((void)); +static int text_readip __P((char *, int, char **, int *)); +static int parseline __P((char *, ip_t *, char **, int *)); + +static char _tcp_flagset[] = "FSRPAUEC"; +static u_char _tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, + TH_ACK, TH_URG, TH_ECN, TH_CWR }; + +struct ipread iptext = { text_open, text_close, text_readip, R_DO_CKSUM }; +static FILE *tfp = NULL; +static int tfd = -1; + +static u_32_t tx_hostnum __P((char *, int *)); +static u_short tx_portnum __P((char *)); + + +/* + * returns an ip address as a long var as a result of either a DNS lookup or + * straight inet_addr() call + */ +static u_32_t tx_hostnum(host, resolved) +char *host; +int *resolved; +{ + u_32_t ipa; + + *resolved = 0; + if (!strcasecmp("any", host)) + return 0L; + if (ISDIGIT(*host)) + return inet_addr(host); + + if (gethost(host, &ipa) == -1) { + *resolved = -1; + fprintf(stderr, "can't resolve hostname: %s\n", host); + return 0; + } + return ipa; +} + + +/* + * find the port number given by the name, either from getservbyname() or + * straight atoi() + */ +static u_short tx_portnum(name) +char *name; +{ + struct servent *sp, *sp2; + u_short p1 = 0; + + if (ISDIGIT(*name)) + return (u_short)atoi(name); + if (!tx_proto) + tx_proto = "tcp/udp"; + if (strcasecmp(tx_proto, "tcp/udp")) { + sp = getservbyname(name, tx_proto); + if (sp) + return ntohs(sp->s_port); + (void) fprintf(stderr, "unknown service \"%s\".\n", name); + return 0; + } + sp = getservbyname(name, "tcp"); + if (sp) + p1 = sp->s_port; + sp2 = getservbyname(name, "udp"); + if (!sp || !sp2) { + (void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n", + name); + return 0; + } + if (p1 != sp2->s_port) { + (void) fprintf(stderr, "%s %d/tcp is a different port to ", + name, p1); + (void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port); + return 0; + } + return ntohs(p1); +} + + +char *tx_icmptypes[] = { + "echorep", (char *)NULL, (char *)NULL, "unreach", "squench", + "redir", (char *)NULL, (char *)NULL, "echo", "routerad", + "routersol", "timex", "paramprob", "timest", "timestrep", + "inforeq", "inforep", "maskreq", "maskrep", "END" +}; + +static int text_open(fname) +char *fname; +{ + if (tfp && tfd != -1) { + rewind(tfp); + return tfd; + } + + if (!strcmp(fname, "-")) { + tfd = 0; + tfp = stdin; + } else { + tfd = open(fname, O_RDONLY); + if (tfd != -1) + tfp = fdopen(tfd, "r"); + } + return tfd; +} + + +static int text_close() +{ + int cfd = tfd; + + tfd = -1; + return close(cfd); +} + + +static int text_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + register char *s; + char line[513]; + + *ifn = NULL; + while (fgets(line, sizeof(line)-1, tfp)) { + if ((s = strchr(line, '\n'))) + *s = '\0'; + if ((s = strchr(line, '\r'))) + *s = '\0'; + if ((s = strchr(line, '#'))) + *s = '\0'; + if (!*line) + continue; + if (!(opts & OPT_BRIEF)) + printf("input: %s\n", line); + *ifn = NULL; + *dir = 0; + if (!parseline(line, (ip_t *)buf, ifn, dir)) +#if 0 + return sizeof(ip_t) + sizeof(tcphdr_t); +#else + return sizeof(ip_t); +#endif + } + return -1; +} + +static int parseline(line, ip, ifn, out) +char *line; +ip_t *ip; +char **ifn; +int *out; +{ + tcphdr_t th, *tcp = &th; + struct icmp icmp, *ic = &icmp; + char *cps[20], **cpp, c, ipopts[68]; + int i, r; + + if (*ifn) + free(*ifn); + bzero((char *)ip, MAX(sizeof(*tcp), sizeof(*ic)) + sizeof(*ip)); + bzero((char *)tcp, sizeof(*tcp)); + bzero((char *)ic, sizeof(*ic)); + bzero(ipopts, sizeof(ipopts)); + IP_HL_A(ip, sizeof(*ip) >> 2); + IP_V_A(ip, IPVERSION); + for (i = 0, cps[0] = strtok(line, " \b\t\r\n"); cps[i] && i < 19; ) + cps[++i] = strtok(NULL, " \b\t\r\n"); + + cpp = cps; + if (!*cpp) + return 1; + + c = **cpp; + if (!ISALPHA(c) || (TOLOWER(c) != 'o' && TOLOWER(c) != 'i')) { + fprintf(stderr, "bad direction \"%s\"\n", *cpp); + return 1; + } + *out = (TOLOWER(c) == 'o') ? 1 : 0; + cpp++; + if (!*cpp) + return 1; + + if (!strcasecmp(*cpp, "on")) { + cpp++; + if (!*cpp) + return 1; + *ifn = strdup(*cpp++); + if (!*cpp) + return 1; + } + + c = **cpp; + ip->ip_len = sizeof(ip_t); + if (!strcasecmp(*cpp, "tcp") || !strcasecmp(*cpp, "udp") || + !strcasecmp(*cpp, "icmp")) { + if (c == 't') { + ip->ip_p = IPPROTO_TCP; + ip->ip_len += sizeof(struct tcphdr); + tx_proto = "tcp"; + } else if (c == 'u') { + ip->ip_p = IPPROTO_UDP; + ip->ip_len += sizeof(struct udphdr); + tx_proto = "udp"; + } else { + ip->ip_p = IPPROTO_ICMP; + ip->ip_len += ICMPERR_IPICMPHLEN; + tx_proto = "icmp"; + } + cpp++; + } else if (ISDIGIT(**cpp) && !index(*cpp, '.')) { + ip->ip_p = atoi(*cpp); + cpp++; + } else + ip->ip_p = IPPROTO_IP; + + if (!*cpp) + return 1; + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) { + char *last; + + last = strchr(*cpp, ','); + if (!last) { + fprintf(stderr, "tcp/udp with no source port\n"); + return 1; + } + *last++ = '\0'; + tcp->th_sport = htons(tx_portnum(last)); + if (ip->ip_p == IPPROTO_TCP) { + tcp->th_win = htons(4096); + TCP_OFF_A(tcp, sizeof(*tcp) >> 2); + } + } + ip->ip_src.s_addr = tx_hostnum(*cpp, &r); + cpp++; + if (!*cpp) + return 1; + + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) { + char *last; + + last = strchr(*cpp, ','); + if (!last) { + fprintf(stderr, "tcp/udp with no destination port\n"); + return 1; + } + *last++ = '\0'; + tcp->th_dport = htons(tx_portnum(last)); + } + ip->ip_dst.s_addr = tx_hostnum(*cpp, &r); + cpp++; + if (*cpp && ip->ip_p == IPPROTO_TCP) { + extern char _tcp_flagset[]; + extern u_char _tcp_flags[]; + char *s, *t; + + tcp->th_flags = 0; + for (s = *cpp; *s; s++) + if ((t = strchr(_tcp_flagset, *s))) + tcp->th_flags |= _tcp_flags[t - _tcp_flagset]; + if (tcp->th_flags) + cpp++; + if (tcp->th_flags == 0) + abort(); + if (tcp->th_flags & TH_URG) + tcp->th_urp = htons(1); + } else if (*cpp && ip->ip_p == IPPROTO_ICMP) { + extern char *tx_icmptypes[]; + char **s, *t; + int i; + + for (s = tx_icmptypes, i = 0; !*s || strcmp(*s, "END"); + s++, i++) + if (*s && !strncasecmp(*cpp, *s, strlen(*s))) { + ic->icmp_type = i; + if ((t = strchr(*cpp, ','))) + ic->icmp_code = atoi(t+1); + cpp++; + break; + } + } + + if (*cpp && !strcasecmp(*cpp, "opt")) { + u_long olen; + + cpp++; + olen = buildopts(*cpp, ipopts, (IP_HL(ip) - 5) << 2); + if (olen) { + bcopy(ipopts, (char *)(ip + 1), olen); + IP_HL_A(ip, IP_HL(ip) + (olen >> 2)); + } + } + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) + bcopy((char *)tcp, ((char *)ip) + (IP_HL(ip) << 2), + sizeof(*tcp)); + else if (ip->ip_p == IPPROTO_ICMP) + bcopy((char *)ic, ((char *)ip) + (IP_HL(ip) << 2), + sizeof(*ic)); + ip->ip_len = htons(ip->ip_len); + return 0; +} diff --git a/contrib/ipfilter/lib/ipoptsec.c b/contrib/ipfilter/lib/ipoptsec.c new file mode 100644 index 0000000..95bde9c --- /dev/null +++ b/contrib/ipfilter/lib/ipoptsec.c @@ -0,0 +1,58 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipoptsec.c,v 1.2 2002/01/28 06:50:46 darrenr Exp + */ + +#include "ipf.h" + + +struct ipopt_names secclass[] = { + { IPSO_CLASS_RES4, 0x01, 0, "reserv-4" }, + { IPSO_CLASS_TOPS, 0x02, 0, "topsecret" }, + { IPSO_CLASS_SECR, 0x04, 0, "secret" }, + { IPSO_CLASS_RES3, 0x08, 0, "reserv-3" }, + { IPSO_CLASS_CONF, 0x10, 0, "confid" }, + { IPSO_CLASS_UNCL, 0x20, 0, "unclass" }, + { IPSO_CLASS_RES2, 0x40, 0, "reserv-2" }, + { IPSO_CLASS_RES1, 0x80, 0, "reserv-1" }, + { 0, 0, 0, NULL } /* must be last */ +}; + + +u_char seclevel(slevel) +char *slevel; +{ + struct ipopt_names *so; + + for (so = secclass; so->on_name; so++) + if (!strcasecmp(slevel, so->on_name)) + break; + + if (!so->on_name) { + fprintf(stderr, "no such security level: %s\n", slevel); + return 0; + } + return (u_char)so->on_value; +} + + +u_char secbit(class) +int class; +{ + struct ipopt_names *so; + + for (so = secclass; so->on_name; so++) + if (so->on_value == class) + break; + + if (!so->on_name) { + fprintf(stderr, "no such security class: %d\n", class); + return 0; + } + return (u_char)so->on_bit; +} diff --git a/contrib/ipfilter/lib/kmem.c b/contrib/ipfilter/lib/kmem.c new file mode 100644 index 0000000..3f044bb --- /dev/null +++ b/contrib/ipfilter/lib/kmem.c @@ -0,0 +1,203 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +/* + * kmemcpy() - copies n bytes from kernel memory into user buffer. + * returns 0 on success, -1 on error. + */ + +#include <stdio.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <sys/file.h> +#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) +#include <kvm.h> +#endif +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <net/if.h> +#if __FreeBSD_version >= 300000 +# include <net/if_var.h> +#endif +#if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux) +# include <stdlib.h> +#endif + +#include "kmem.h" + +#ifndef __STDC__ +# define const +#endif + +#if !defined(lint) +static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; +static const char rcsid[] = "@(#)Id: kmem.c,v 1.16.2.1 2004/06/20 10:25:58 darrenr Exp"; +#endif + + + +#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) +/* + * For all platforms where there is a libkvm and a kvm_t, we use that... + */ +static kvm_t *kvm_f = NULL; + +#else +/* + *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own. + */ + +typedef int * kvm_t; + +static kvm_t kvm_f = NULL; +static char *kvm_errstr = NULL; + +kvm_t kvm_open __P((char *, char *, char *, int, char *)); +int kvm_read __P((kvm_t, u_long, char *, size_t)); + +kvm_t kvm_open(kernel, core, swap, mode, errstr) +char *kernel, *core, *swap; +int mode; +char *errstr; +{ + kvm_t k; + int fd; + + kvm_errstr = errstr; + + if (core == NULL) + core = "/dev/kmem"; + + fd = open(core, mode); + if (fd == -1) + return NULL; + k = malloc(sizeof(*k)); + if (k == NULL) + return NULL; + *k = fd; + return k; +} + +int kvm_read(kvm, pos, buffer, size) +kvm_t kvm; +u_long pos; +char *buffer; +size_t size; +{ + int r = 0, left; + char *bufp; + + if (lseek(*kvm, pos, 0) == -1) { + if (kvm_errstr != NULL) { + fprintf(stderr, "%s", kvm_errstr); + perror("lseek"); + } + return -1; + } + + for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) { + r = read(*kvm, bufp, left); +#ifdef __osf__ + /* + * Tru64 returns "0" for successful operation, not the number + * of bytes read. + */ + if (r == 0) + r = left; +#endif + if (r <= 0) + return -1; + } + return r; +} +#endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */ + +int openkmem(kern, core) +char *kern, *core; +{ + kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); + if (kvm_f == NULL) + { + perror("openkmem:open"); + return -1; + } + return kvm_f != NULL; +} + +int kmemcpy(buf, pos, n) +register char *buf; +long pos; +register int n; +{ + register int r; + + if (!n) + return 0; + + if (kvm_f == NULL) + if (openkmem(NULL, NULL) == -1) + return -1; + + while ((r = kvm_read(kvm_f, pos, buf, n)) < n) + if (r <= 0) + { + fprintf(stderr, "pos=0x%lx ", (u_long)pos); + perror("kmemcpy:read"); + return -1; + } + else + { + buf += r; + pos += r; + n -= r; + } + return 0; +} + +int kstrncpy(buf, pos, n) +register char *buf; +long pos; +register int n; +{ + register int r; + + if (!n) + return 0; + + if (kvm_f == NULL) + if (openkmem(NULL, NULL) == -1) + return -1; + + while (n > 0) + { + r = kvm_read(kvm_f, pos, buf, 1); + if (r <= 0) + { + fprintf(stderr, "pos=0x%lx ", (u_long)pos); + perror("kmemcpy:read"); + return -1; + } + else + { + if (*buf == '\0') + break; + buf++; + pos++; + n--; + } + } + return 0; +} diff --git a/contrib/ipfilter/lib/kmem.h b/contrib/ipfilter/lib/kmem.h new file mode 100644 index 0000000..07a14f5 --- /dev/null +++ b/contrib/ipfilter/lib/kmem.h @@ -0,0 +1,34 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * Id: kmem.h,v 1.2 2002/08/21 22:57:36 darrenr Exp + */ + +#ifndef __KMEM_H__ +#define __KMEM_H__ + +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif +extern int openkmem __P((char *, char *)); +extern int kmemcpy __P((char *, long, int)); +extern int kstrncpy __P((char *, long, int)); + +#if defined(__NetBSD__) || defined(__OpenBSD) +# include <paths.h> +#endif + +#ifdef _PATH_KMEM +# define KMEM _PATH_KMEM +#else +# define KMEM "/dev/kmem" +#endif + +#endif /* __KMEM_H__ */ diff --git a/contrib/ipfilter/lib/kmemcpywrap.c b/contrib/ipfilter/lib/kmemcpywrap.c new file mode 100644 index 0000000..274bcb1 --- /dev/null +++ b/contrib/ipfilter/lib/kmemcpywrap.c @@ -0,0 +1,15 @@ +/* $NetBSD$ */ + +#include "ipf.h" +#include "kmem.h" + +int kmemcpywrap(from, to, size) +void *from, *to; +size_t size; +{ + int ret; + + ret = kmemcpy((caddr_t)to, (u_long)from, size); + return ret; +} + diff --git a/contrib/ipfilter/lib/kvatoname.c b/contrib/ipfilter/lib/kvatoname.c new file mode 100644 index 0000000..030c633 --- /dev/null +++ b/contrib/ipfilter/lib/kvatoname.c @@ -0,0 +1,31 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#include <fcntl.h> +#include <sys/ioctl.h> + +char *kvatoname(func, iocfunc) +ipfunc_t func; +ioctlfunc_t iocfunc; +{ + static char funcname[40]; + ipfunc_resolve_t res; + int fd; + + res.ipfu_addr = func; + res.ipfu_name[0] = '\0'; + fd = -1; + + if ((opts & OPT_DONOTHING) == 0) { + fd = open(IPL_NAME, O_RDONLY); + if (fd == -1) + return NULL; + } + (void) (*iocfunc)(fd, SIOCFUNCL, &res); + if (fd >= 0) + close(fd); + strncpy(funcname, res.ipfu_name, sizeof(funcname)); + funcname[sizeof(funcname) - 1] = '\0'; + return funcname; +} diff --git a/contrib/ipfilter/lib/load_hash.c b/contrib/ipfilter/lib/load_hash.c new file mode 100644 index 0000000..4fc042b --- /dev/null +++ b/contrib/ipfilter/lib/load_hash.c @@ -0,0 +1,112 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: load_hash.c,v 1.11.2.2 2005/02/01 02:44:05 darrenr Exp + */ + +#include <fcntl.h> +#include <sys/ioctl.h> +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int hashfd = -1; + + +int load_hash(iphp, list, iocfunc) +iphtable_t *iphp; +iphtent_t *list; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + iphtable_t iph; + iphtent_t *a; + size_t size; + int n; + + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + hashfd = open(IPLOOKUP_NAME, O_RDWR); + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + for (n = 0, a = list; a != NULL; a = a->ipe_next) + n++; + + op.iplo_arg = 0; + op.iplo_type = IPLT_HASH; + op.iplo_unit = iphp->iph_unit; + strncpy(op.iplo_name, iphp->iph_name, sizeof(op.iplo_name)); + if (*op.iplo_name == '\0') + op.iplo_arg = IPHASH_ANON; + op.iplo_size = sizeof(iph); + op.iplo_struct = &iph; + iph.iph_unit = iphp->iph_unit; + iph.iph_type = iphp->iph_type; + strncpy(iph.iph_name, iphp->iph_name, sizeof(iph.iph_name)); + iph.iph_flags = iphp->iph_flags; + if (n <= 0) + n = 1; + if (iphp->iph_size == 0) + size = n * 2 - 1; + else + size = iphp->iph_size; + if ((list == NULL) && (size == 1)) { + fprintf(stderr, + "WARNING: empty hash table %s, recommend setting %s\n", + iphp->iph_name, "size to match expected use"); + } + iph.iph_size = size; + iph.iph_seed = iphp->iph_seed; + iph.iph_table = NULL; + iph.iph_ref = 0; + + if ((opts & OPT_REMOVE) == 0) { + if ((*iocfunc)(hashfd, SIOCLOOKUPADDTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("load_hash:SIOCLOOKUPADDTABLE"); + return -1; + } + } + + strncpy(op.iplo_name, iph.iph_name, sizeof(op.iplo_name)); + strncpy(iphp->iph_name, iph.iph_name, sizeof(op.iplo_name)); + + if (opts & OPT_VERBOSE) { + for (a = list; a != NULL; a = a->ipe_next) { + a->ipe_addr.in4_addr = ntohl(a->ipe_addr.in4_addr); + a->ipe_mask.in4_addr = ntohl(a->ipe_mask.in4_addr); + } + iph.iph_table = calloc(size, sizeof(*iph.iph_table)); + if (iph.iph_table == NULL) { + perror("calloc(size, sizeof(*iph.iph_table))"); + return -1; + } + iph.iph_table[0] = list; + printhash(&iph, bcopywrap, iph.iph_name, opts); + free(iph.iph_table); + + for (a = list; a != NULL; a = a->ipe_next) { + a->ipe_addr.in4_addr = htonl(a->ipe_addr.in4_addr); + a->ipe_mask.in4_addr = htonl(a->ipe_mask.in4_addr); + } + } + + if (opts & OPT_DEBUG) + printf("Hash %s:\n", iph.iph_name); + + for (a = list; a != NULL; a = a->ipe_next) + load_hashnode(iphp->iph_unit, iph.iph_name, a, iocfunc); + + if ((opts & OPT_REMOVE) != 0) { + if ((*iocfunc)(hashfd, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("load_hash:SIOCLOOKUPDELTABLE"); + return -1; + } + } + return 0; +} diff --git a/contrib/ipfilter/lib/load_hashnode.c b/contrib/ipfilter/lib/load_hashnode.c new file mode 100644 index 0000000..186ba05 --- /dev/null +++ b/contrib/ipfilter/lib/load_hashnode.c @@ -0,0 +1,61 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: load_hashnode.c,v 1.2.4.1 2004/03/06 14:33:28 darrenr Exp + */ + +#include <fcntl.h> +#include <sys/ioctl.h> +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int hashfd = -1; + + +int load_hashnode(unit, name, node, iocfunc) +int unit; +char *name; +iphtent_t *node; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + iphtent_t ipe; + int err; + + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + hashfd = open(IPLOOKUP_NAME, O_RDWR); + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_type = IPLT_HASH; + op.iplo_unit = unit; + op.iplo_arg = 0; + op.iplo_size = sizeof(ipe); + op.iplo_struct = &ipe; + strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + + bzero((char *)&ipe, sizeof(ipe)); + bcopy((char *)&node->ipe_addr, (char *)&ipe.ipe_addr, + sizeof(ipe.ipe_addr)); + bcopy((char *)&node->ipe_mask, (char *)&ipe.ipe_mask, + sizeof(ipe.ipe_mask)); + bcopy((char *)&node->ipe_group, (char *)&ipe.ipe_group, + sizeof(ipe.ipe_group)); + + if ((opts & OPT_REMOVE) == 0) + err = (*iocfunc)(hashfd, SIOCLOOKUPADDNODE, &op); + else + err = (*iocfunc)(hashfd, SIOCLOOKUPDELNODE, &op); + + if (err != 0) + if (!(opts & OPT_DONOTHING)) { + perror("load_hash:SIOCLOOKUP*NODE"); + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/load_pool.c b/contrib/ipfilter/lib/load_pool.c new file mode 100644 index 0000000..5fab311 --- /dev/null +++ b/contrib/ipfilter/lib/load_pool.c @@ -0,0 +1,69 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: load_pool.c,v 1.14.2.2 2005/02/01 02:44:06 darrenr Exp + */ + +#include <fcntl.h> +#include <sys/ioctl.h> +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" + +static int poolfd = -1; + + +int load_pool(plp, iocfunc) +ip_pool_t *plp; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + ip_pool_node_t *a; + ip_pool_t pool; + + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_unit = plp->ipo_unit; + op.iplo_type = IPLT_POOL; + op.iplo_arg = 0; + strncpy(op.iplo_name, plp->ipo_name, sizeof(op.iplo_name)); + op.iplo_size = sizeof(pool); + op.iplo_struct = &pool; + bzero((char *)&pool, sizeof(pool)); + strncpy(pool.ipo_name, plp->ipo_name, sizeof(pool.ipo_name)); + if (*plp->ipo_name == '\0') + op.iplo_arg |= IPOOL_ANON; + + if ((opts & OPT_REMOVE) == 0) { + if ((*iocfunc)(poolfd, SIOCLOOKUPADDTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("load_pool:SIOCLOOKUPADDTABLE"); + return -1; + } + } + + if ((opts & OPT_VERBOSE) != 0) { + pool.ipo_list = plp->ipo_list; + printpool(&pool, bcopywrap, pool.ipo_name, opts); + pool.ipo_list = NULL; + } + + for (a = plp->ipo_list; a != NULL; a = a->ipn_next) + load_poolnode(plp->ipo_unit, plp->ipo_name, a, iocfunc); + + if ((opts & OPT_REMOVE) != 0) { + if ((*iocfunc)(poolfd, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("load_pool:SIOCLOOKUPDELTABLE"); + return -1; + } + } + return 0; +} diff --git a/contrib/ipfilter/lib/load_poolnode.c b/contrib/ipfilter/lib/load_poolnode.c new file mode 100644 index 0000000..e9d233f --- /dev/null +++ b/contrib/ipfilter/lib/load_poolnode.c @@ -0,0 +1,63 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: load_poolnode.c,v 1.3.2.1 2004/03/06 14:33:29 darrenr Exp + */ + +#include <fcntl.h> +#include <sys/ioctl.h> +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" + +static int poolfd = -1; + + +int load_poolnode(role, name, node, iocfunc) +int role; +char *name; +ip_pool_node_t *node; +ioctlfunc_t iocfunc; +{ + ip_pool_node_t pn; + iplookupop_t op; + int err; + + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_unit = role; + op.iplo_type = IPLT_POOL; + op.iplo_arg = 0; + op.iplo_struct = &pn; + op.iplo_size = sizeof(pn); + strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + + bzero((char *)&pn, sizeof(pn)); + bcopy((char *)&node->ipn_addr, (char *)&pn.ipn_addr, + sizeof(pn.ipn_addr)); + bcopy((char *)&node->ipn_mask, (char *)&pn.ipn_mask, + sizeof(pn.ipn_mask)); + pn.ipn_info = node->ipn_info; + strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name)); + + if ((opts & OPT_REMOVE) == 0) + err = (*iocfunc)(poolfd, SIOCLOOKUPADDNODE, &op); + else + err = (*iocfunc)(poolfd, SIOCLOOKUPDELNODE, &op); + + if (err != 0) { + if ((opts & OPT_DONOTHING) == 0) { + perror("load_pool:SIOCLOOKUP*NODE"); + return -1; + } + } + + return 0; +} diff --git a/contrib/ipfilter/lib/loglevel.c b/contrib/ipfilter/lib/loglevel.c new file mode 100644 index 0000000..31b4f17 --- /dev/null +++ b/contrib/ipfilter/lib/loglevel.c @@ -0,0 +1,55 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: loglevel.c,v 1.5 2001/06/09 17:09:24 darrenr Exp + */ + +#include "ipf.h" + + +int loglevel(cpp, facpri, linenum) +char **cpp; +u_int *facpri; +int linenum; +{ + int fac, pri; + char *s; + + fac = 0; + pri = 0; + if (!*++cpp) { + fprintf(stderr, "%d: %s\n", linenum, + "missing identifier after level"); + return -1; + } + + s = strchr(*cpp, '.'); + if (s) { + *s++ = '\0'; + fac = fac_findname(*cpp); + if (fac == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown facility", *cpp); + return -1; + } + pri = pri_findname(s); + if (pri == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown priority", s); + return -1; + } + } else { + pri = pri_findname(*cpp); + if (pri == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown priority", *cpp); + return -1; + } + } + *facpri = fac|pri; + return 0; +} diff --git a/contrib/ipfilter/lib/make_range.c b/contrib/ipfilter/lib/make_range.c new file mode 100644 index 0000000..9ec3ca3 --- /dev/null +++ b/contrib/ipfilter/lib/make_range.c @@ -0,0 +1,26 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: make_range.c,v 1.2 2002/05/18 07:27:52 darrenr Exp + */ +#include "ipf.h" + + +alist_t *make_range(not, a1, a2) +int not; +struct in_addr a1, a2; +{ + alist_t *a; + + a = (alist_t *)calloc(1, sizeof(*a)); + if (a != NULL) { + a->al_1 = a1.s_addr; + a->al_2 = a2.s_addr; + a->al_not = not; + } + return a; +} diff --git a/contrib/ipfilter/lib/mutex_emul.c b/contrib/ipfilter/lib/mutex_emul.c new file mode 100644 index 0000000..43b7f76 --- /dev/null +++ b/contrib/ipfilter/lib/mutex_emul.c @@ -0,0 +1,80 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#define EMM_MAGIC 0x9d7adba3 + +void eMmutex_enter(mtx, file, line) +eMmutex_t *mtx; +char *file; +int line; +{ + if (mtx->eMm_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMmutex_enter(%p): bad magic: %#x\n", + mtx->eMm_owner, mtx, mtx->eMm_magic); + abort(); + } + if (mtx->eMm_held != 0) { + fprintf(stderr, "%s:eMmutex_enter(%p): already locked: %d\n", + mtx->eMm_owner, mtx, mtx->eMm_held); + abort(); + } + mtx->eMm_held++; + mtx->eMm_heldin = file; + mtx->eMm_heldat = line; +} + + +void eMmutex_exit(mtx) +eMmutex_t *mtx; +{ + if (mtx->eMm_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMmutex_exit(%p): bad magic: %#x\n", + mtx->eMm_owner, mtx, mtx->eMm_magic); + abort(); + } + if (mtx->eMm_held != 1) { + fprintf(stderr, "%s:eMmutex_exit(%p): not locked: %d\n", + mtx->eMm_owner, mtx, mtx->eMm_held); + abort(); + } + mtx->eMm_held--; + mtx->eMm_heldin = NULL; + mtx->eMm_heldat = 0; +} + + +void eMmutex_init(mtx, who) +eMmutex_t *mtx; +char *who; +{ + if (mtx->eMm_magic == EMM_MAGIC) { /* safe bet ? */ + fprintf(stderr, + "%s:eMmutex_init(%p): already initialised?: %#x\n", + mtx->eMm_owner, mtx, mtx->eMm_magic); + abort(); + } + mtx->eMm_magic = EMM_MAGIC; + mtx->eMm_held = 0; + if (who != NULL) + mtx->eMm_owner = strdup(who); + else + mtx->eMm_owner = NULL; +} + + +void eMmutex_destroy(mtx) +eMmutex_t *mtx; +{ + if (mtx->eMm_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMmutex_destroy(%p): bad magic: %#x\n", + mtx->eMm_owner, mtx, mtx->eMm_magic); + abort(); + } + if (mtx->eMm_held != 0) { + fprintf(stderr, "%s:eMmutex_enter(%p): still locked: %d\n", + mtx->eMm_owner, mtx, mtx->eMm_held); + abort(); + } + memset(mtx, 0xa5, sizeof(*mtx)); +} diff --git a/contrib/ipfilter/lib/nametokva.c b/contrib/ipfilter/lib/nametokva.c new file mode 100644 index 0000000..50f3077 --- /dev/null +++ b/contrib/ipfilter/lib/nametokva.c @@ -0,0 +1,30 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#include <sys/ioctl.h> +#include <fcntl.h> + +ipfunc_t nametokva(name, iocfunc) +char *name; +ioctlfunc_t iocfunc; +{ + ipfunc_resolve_t res; + int fd; + + strncpy(res.ipfu_name, name, sizeof(res.ipfu_name)); + res.ipfu_addr = NULL; + fd = -1; + + if ((opts & OPT_DONOTHING) == 0) { + fd = open(IPL_NAME, O_RDONLY); + if (fd == -1) + return NULL; + } + (void) (*iocfunc)(fd, SIOCFUNCL, &res); + if (fd >= 0) + close(fd); + if (res.ipfu_addr == NULL) + res.ipfu_addr = (ipfunc_t)-1; + return res.ipfu_addr; +} diff --git a/contrib/ipfilter/lib/nat_setgroupmap.c b/contrib/ipfilter/lib/nat_setgroupmap.c new file mode 100644 index 0000000..ce64abb --- /dev/null +++ b/contrib/ipfilter/lib/nat_setgroupmap.c @@ -0,0 +1,34 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char rcsid[] = "@(#)Id: nat_setgroupmap.c,v 1.1 2003/04/13 06:40:14 darrenr Exp"; +#endif + +#include "ipf.h" + +void nat_setgroupmap(n) +ipnat_t *n; +{ + if (n->in_outmsk == n->in_inmsk) + n->in_ippip = 1; + else if (n->in_flags & IPN_AUTOPORTMAP) { + n->in_ippip = ~ntohl(n->in_inmsk); + if (n->in_outmsk != 0xffffffff) + n->in_ippip /= (~ntohl(n->in_outmsk) + 1); + n->in_ippip++; + if (n->in_ippip == 0) + n->in_ippip = 1; + n->in_ppip = USABLE_PORTS / n->in_ippip; + } else { + n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); + n->in_nip = 0; + if (!(n->in_ppip = n->in_pmin)) + n->in_ppip = 1; + n->in_ippip = USABLE_PORTS / n->in_ppip; + } +} diff --git a/contrib/ipfilter/lib/natparse.c b/contrib/ipfilter/lib/natparse.c new file mode 100644 index 0000000..adbbeb9 --- /dev/null +++ b/contrib/ipfilter/lib/natparse.c @@ -0,0 +1,730 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; +static const char rcsid[] = "@(#)Id: natparse.c,v 1.8.2.1 2004/12/09 19:41:21 darrenr Exp"; +#endif + +#include <sys/ioctl.h> +#include <errno.h> +#include <ctype.h> + +#include "ipf.h" +#include "opts.h" + + +void nat_setgroupmap(n) +ipnat_t *n; +{ + if (n->in_outmsk == n->in_inmsk) + n->in_ippip = 1; + else if (n->in_flags & IPN_AUTOPORTMAP) { + n->in_ippip = ~ntohl(n->in_inmsk); + if (n->in_outmsk != 0xffffffff) + n->in_ippip /= (~ntohl(n->in_outmsk) + 1); + n->in_ippip++; + if (n->in_ippip == 0) + n->in_ippip = 1; + n->in_ppip = USABLE_PORTS / n->in_ippip; + } else { + n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); + n->in_nip = 0; + if (!(n->in_ppip = n->in_pmin)) + n->in_ppip = 1; + n->in_ippip = USABLE_PORTS / n->in_ppip; + } +} + + + +ipnat_t *natparse(line, linenum) +char *line; +int linenum; +{ + static ipnat_t ipn; + struct protoent *pr; + char *dnetm = NULL, *dport = NULL, *proto = NULL; + char *s, *t, *cps[31], **cpp; + int i, cnt; + + + if ((s = strchr(line, '\n'))) + *s = '\0'; + if ((s = strchr(line, '#'))) + *s = '\0'; + while (*line && ISSPACE(*line)) + line++; + if (!*line) + return NULL; + + bzero((char *)&ipn, sizeof(ipn)); + cnt = 0; + + for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++) + cps[++i] = strtok(NULL, " \b\t\r\n"); + + cps[i] = NULL; + + if (cnt < 3) { + fprintf(stderr, "%d: not enough segments in line\n", linenum); + return NULL; + } + + cpp = cps; + + if (!strcasecmp(*cpp, "map")) + ipn.in_redir = NAT_MAP; + else if (!strcasecmp(*cpp, "map-block")) + ipn.in_redir = NAT_MAPBLK; + else if (!strcasecmp(*cpp, "rdr")) + ipn.in_redir = NAT_REDIRECT; + else if (!strcasecmp(*cpp, "bimap")) + ipn.in_redir = NAT_BIMAP; + else { + fprintf(stderr, "%d: unknown mapping: \"%s\"\n", + linenum, *cpp); + return NULL; + } + + cpp++; + + strncpy(ipn.in_ifnames[0], *cpp, sizeof(ipn.in_ifnames[0]) - 1); + ipn.in_ifnames[0][sizeof(ipn.in_ifnames[0]) - 1] = '\0'; + cpp++; + + if (!strcasecmp(*cpp, "from") || (**cpp == '!')) { + if (!strcmp(*cpp, "!")) { + cpp++; + if (strcasecmp(*cpp, "from")) { + fprintf(stderr, "Missing from after !\n"); + return NULL; + } + ipn.in_flags |= IPN_NOTSRC; + } else if (**cpp == '!') { + if (strcasecmp(*cpp + 1, "from")) { + fprintf(stderr, "Missing from after !\n"); + return NULL; + } + ipn.in_flags |= IPN_NOTSRC; + } + if ((ipn.in_flags & IPN_NOTSRC) && + (ipn.in_redir & (NAT_MAP|NAT_MAPBLK))) { + fprintf(stderr, "Cannot use '! from' with map\n"); + return NULL; + } + + ipn.in_flags |= IPN_FILTER; + cpp++; + if (ipn.in_redir == NAT_REDIRECT) { + if (hostmask(&cpp, proto, NULL, + (u_32_t *)&ipn.in_srcip, + (u_32_t *)&ipn.in_srcmsk, linenum) == -1) + return NULL; + + if (ports(&cpp, proto, &ipn.in_sport, + &ipn.in_scmp, &ipn.in_stop, linenum)) + return NULL; + } else { + if (hostmask(&cpp, proto, NULL, + (u_32_t *)&ipn.in_inip, + (u_32_t *)&ipn.in_inmsk, linenum) == -1) + return NULL; + + if (ports(&cpp, proto, &ipn.in_dport, + &ipn.in_dcmp, &ipn.in_dtop, linenum)) + return NULL; + } + + if (!strcmp(*cpp, "!")) { + cpp++; + ipn.in_flags |= IPN_NOTDST; + } else if (**cpp == '!') { + (*cpp)++; + ipn.in_flags |= IPN_NOTDST; + } + + if (strcasecmp(*cpp, "to")) { + fprintf(stderr, "%d: unexpected keyword (%s) - to\n", + linenum, *cpp); + return NULL; + } + if ((ipn.in_flags & IPN_NOTDST) && + (ipn.in_redir & (NAT_REDIRECT))) { + fprintf(stderr, "Cannot use '! to' with rdr\n"); + return NULL; + } + + if (!*++cpp) { + fprintf(stderr, "%d: missing host after to\n", linenum); + return NULL; + } + if (ipn.in_redir == NAT_REDIRECT) { + if (hostmask(&cpp, proto, NULL, + (u_32_t *)&ipn.in_outip, + (u_32_t *)&ipn.in_outmsk, linenum)) + return NULL; + + if (ports(&cpp, proto, &ipn.in_dport, + &ipn.in_dcmp, &ipn.in_dtop, linenum)) + return NULL; + ipn.in_pmin = htons(ipn.in_dport); + } else { + if (hostmask(&cpp, proto, NULL, + (u_32_t *)&ipn.in_srcip, + (u_32_t *)&ipn.in_srcmsk, linenum)) + return NULL; + + if (ports(&cpp, proto, &ipn.in_sport, + &ipn.in_scmp, &ipn.in_stop, linenum)) + return NULL; + } + } else { + s = *cpp; + if (!s) + return NULL; + t = strchr(s, '/'); + if (!t) + return NULL; + *t++ = '\0'; + if (ipn.in_redir == NAT_REDIRECT) { + if (hostnum((u_32_t *)&ipn.in_outip, s, linenum, NULL)) + return NULL; + if (genmask(t, (u_32_t *)&ipn.in_outmsk) == -1) { + return NULL; + } + } else { + if (hostnum((u_32_t *)&ipn.in_inip, s, linenum, NULL)) + return NULL; + if (genmask(t, (u_32_t *)&ipn.in_inmsk) == -1) { + return NULL; + } + } + cpp++; + if (!*cpp) + return NULL; + } + + if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) { + if (strcasecmp(*cpp, "port")) { + fprintf(stderr, "%d: missing fields - 1st port\n", + linenum); + return NULL; + } + + cpp++; + + if (!*cpp) { + fprintf(stderr, + "%d: missing fields (destination port)\n", + linenum); + return NULL; + } + + if (ISDIGIT(**cpp) && (s = strchr(*cpp, '-'))) + *s++ = '\0'; + else + s = NULL; + + if (!portnum(*cpp, proto, &ipn.in_pmin, linenum)) + return NULL; + ipn.in_pmin = htons(ipn.in_pmin); + cpp++; + + if (!strcmp(*cpp, "-")) { + cpp++; + s = *cpp++; + } + + if (s) { + if (!portnum(s, proto, &ipn.in_pmax, linenum)) + return NULL; + ipn.in_pmax = htons(ipn.in_pmax); + } else + ipn.in_pmax = ipn.in_pmin; + } + + if (!*cpp) { + fprintf(stderr, "%d: missing fields (->)\n", linenum); + return NULL; + } + if (strcmp(*cpp, "->")) { + fprintf(stderr, "%d: missing ->\n", linenum); + return NULL; + } + cpp++; + + if (!*cpp) { + fprintf(stderr, "%d: missing fields (%s)\n", + linenum, ipn.in_redir ? "destination" : "target"); + return NULL; + } + + if (ipn.in_redir == NAT_MAP) { + if (!strcasecmp(*cpp, "range")) { + cpp++; + ipn.in_flags |= IPN_IPRANGE; + if (!*cpp) { + fprintf(stderr, "%d: missing fields (%s)\n", + linenum, + ipn.in_redir ? "destination":"target"); + return NULL; + } + } + } + + if (ipn.in_flags & IPN_IPRANGE) { + dnetm = strrchr(*cpp, '-'); + if (dnetm == NULL) { + cpp++; + if (*cpp && !strcmp(*cpp, "-") && *(cpp + 1)) + dnetm = *(cpp + 1); + } else + *dnetm++ = '\0'; + if (dnetm == NULL || *dnetm == '\0') { + fprintf(stderr, + "%d: desination range not specified\n", + linenum); + return NULL; + } + } else if (ipn.in_redir != NAT_REDIRECT) { + dnetm = strrchr(*cpp, '/'); + if (dnetm == NULL) { + cpp++; + if (*cpp && !strcasecmp(*cpp, "netmask")) + dnetm = *++cpp; + } + if (dnetm == NULL) { + fprintf(stderr, + "%d: missing fields (dest netmask)\n", + linenum); + return NULL; + } + if (*dnetm == '/') + *dnetm++ = '\0'; + } + + if (ipn.in_redir == NAT_REDIRECT) { + dnetm = strchr(*cpp, ','); + if (dnetm != NULL) { + ipn.in_flags |= IPN_SPLIT; + *dnetm++ = '\0'; + } + if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum, NULL)) + return NULL; + } else { + if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum, NULL)) + return NULL; + } + cpp++; + + if (ipn.in_redir & NAT_MAPBLK) { + if (*cpp && strcasecmp(*cpp, "ports")) { + fprintf(stderr, + "%d: expected \"ports\" - got \"%s\"\n", + linenum, *cpp); + return NULL; + } + cpp++; + if (*cpp) { + ipn.in_pmin = atoi(*cpp); + cpp++; + } else + ipn.in_pmin = 0; + } else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) { + if (*cpp && strrchr(*cpp, '/') != NULL) { + fprintf(stderr, "%d: No netmask supported in %s\n", + linenum, "destination host for redirect"); + return NULL; + } + /* If it's a in_redir, expect target port */ + + if (!*cpp || strcasecmp(*cpp, "port")) { + fprintf(stderr, "%d: missing fields - 2nd port (%s)\n", + linenum, *cpp); + return NULL; + } + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: missing fields (destination port)\n", + linenum); + return NULL; + } + if (!portnum(*cpp, proto, &ipn.in_pnext, linenum)) + return NULL; + ipn.in_pnext = htons(ipn.in_pnext); + cpp++; + } + if (dnetm && *dnetm == '/') + *dnetm++ = '\0'; + + if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) { + if (ipn.in_flags & IPN_IPRANGE) { + if (hostnum((u_32_t *)&ipn.in_outmsk, dnetm, + linenum, NULL) == -1) + return NULL; + } else if (genmask(dnetm, (u_32_t *)&ipn.in_outmsk)) + return NULL; + } else { + if (ipn.in_flags & IPN_SPLIT) { + if (hostnum((u_32_t *)&ipn.in_inmsk, dnetm, + linenum, NULL) == -1) + return NULL; + } else if (genmask("255.255.255.255", (u_32_t *)&ipn.in_inmsk)) + return NULL; + if (!*cpp) { + ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */ + proto = "tcp"; + } else { + if (!strcasecmp(*cpp, "tcp")) + ipn.in_flags |= IPN_TCP; + else if (!strcasecmp(*cpp, "udp")) + ipn.in_flags |= IPN_UDP; + else if (!strcasecmp(*cpp, "tcp/udp")) + ipn.in_flags |= IPN_TCPUDP; + else if (!strcasecmp(*cpp, "tcpudp")) + ipn.in_flags |= IPN_TCPUDP; + else if (!strcasecmp(*cpp, "ip")) + ipn.in_flags |= IPN_ANY; + else { + ipn.in_flags |= IPN_ANY; + ipn.in_p = getproto(*cpp); + } + proto = *cpp; + cpp++; + + if (*cpp && !strcasecmp(*cpp, "round-robin")) { + cpp++; + ipn.in_flags |= IPN_ROUNDR; + } + + if (*cpp && !strcasecmp(*cpp, "frag")) { + cpp++; + ipn.in_flags |= IPN_FRAG; + } + + if (*cpp && !strcasecmp(*cpp, "age")) { + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: age with no parameters\n", + linenum); + return NULL; + } + + ipn.in_age[0] = atoi(*cpp); + s = strchr(*cpp, '/'); + if (s != NULL) + ipn.in_age[1] = atoi(s + 1); + else + ipn.in_age[1] = ipn.in_age[0]; + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "mssclamp")) { + cpp++; + if (*cpp) { + ipn.in_mssclamp = atoi(*cpp); + cpp++; + } else { + fprintf(stderr, + "%d: mssclamp with no parameters\n", + linenum); + return NULL; + } + } + + if (*cpp) { + fprintf(stderr, + "%d: extra junk at the end of rdr: %s\n", + linenum, *cpp); + return NULL; + } + } + } + + if (!(ipn.in_flags & IPN_SPLIT)) + ipn.in_inip &= ipn.in_inmsk; + if ((ipn.in_flags & IPN_IPRANGE) == 0) + ipn.in_outip &= ipn.in_outmsk; + ipn.in_srcip &= ipn.in_srcmsk; + + if ((ipn.in_redir & NAT_MAPBLK) != 0) + nat_setgroupmap(&ipn); + + if (*cpp && !strcasecmp(*cpp, "frag")) { + cpp++; + ipn.in_flags |= IPN_ROUNDR; + } + + if (!*cpp) + return &ipn; + + if (ipn.in_redir != NAT_BIMAP && !strcasecmp(*cpp, "proxy")) { + if (ipn.in_redir == NAT_BIMAP) { + fprintf(stderr, "%d: cannot use proxy with bimap\n", + linenum); + return NULL; + } + + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: missing parameter for \"proxy\"\n", + linenum); + return NULL; + } + dport = NULL; + + if (!strcasecmp(*cpp, "port")) { + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: missing parameter for \"port\"\n", + linenum); + return NULL; + } + + dport = *cpp; + cpp++; + + if (!*cpp) { + fprintf(stderr, + "%d: missing parameter for \"proxy\"\n", + linenum); + return NULL; + } + } else { + fprintf(stderr, + "%d: missing keyword \"port\"\n", linenum); + return NULL; + } + + if ((proto = strchr(*cpp, '/'))) { + *proto++ = '\0'; + ipn.in_p = getproto(proto); + } else + ipn.in_p = 0; + + if (dport && !portnum(dport, proto, &ipn.in_dport, linenum)) + return NULL; + ipn.in_dport = htons(ipn.in_dport); + + (void) strncpy(ipn.in_plabel, *cpp, sizeof(ipn.in_plabel)); + cpp++; + + if (*cpp) { + fprintf(stderr, + "%d: too many parameters for \"proxy\"\n", + linenum); + return NULL; + } + return &ipn; + } + + + if (!strcasecmp(*cpp, "icmpidmap")) { + + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: icmpidmap misses protocol and range\n", + linenum); + return NULL; + }; + + if (!strcasecmp(*cpp, "icmp")) + ipn.in_flags = IPN_ICMPQUERY; + else { + fprintf(stderr, "%d: icmpidmap only valid for icmp\n", + linenum); + return NULL; + } + cpp++; + + if (!*cpp) { + fprintf(stderr, "%d: no icmp id argument found\n", + linenum); + return NULL; + } + + if (!(t = strchr(*cpp, ':'))) { + fprintf(stderr, + "%d: no icmp id range detected in \"%s\"\n", + linenum, *cpp); + return NULL; + } + *t++ = '\0'; + + if (!icmpidnum(*cpp, &ipn.in_pmin, linenum) || + !icmpidnum(t, &ipn.in_pmax, linenum)) + return NULL; + } else if (!strcasecmp(*cpp, "portmap")) { + if (ipn.in_redir == NAT_BIMAP) { + fprintf(stderr, "%d: cannot use proxy with bimap\n", + linenum); + return NULL; + } + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: missing expression following portmap\n", + linenum); + return NULL; + } + + if (!strcasecmp(*cpp, "tcp")) + ipn.in_flags |= IPN_TCP; + else if (!strcasecmp(*cpp, "udp")) + ipn.in_flags |= IPN_UDP; + else if (!strcasecmp(*cpp, "tcpudp")) + ipn.in_flags |= IPN_TCPUDP; + else if (!strcasecmp(*cpp, "tcp/udp")) + ipn.in_flags |= IPN_TCPUDP; + else { + fprintf(stderr, + "%d: expected protocol name - got \"%s\"\n", + linenum, *cpp); + return NULL; + } + proto = *cpp; + cpp++; + + if (!*cpp) { + fprintf(stderr, "%d: no port range found\n", linenum); + return NULL; + } + + if (!strcasecmp(*cpp, "auto")) { + ipn.in_flags |= IPN_AUTOPORTMAP; + ipn.in_pmin = htons(1024); + ipn.in_pmax = htons(65535); + nat_setgroupmap(&ipn); + } else { + if (!(t = strchr(*cpp, ':'))) { + fprintf(stderr, + "%d: no port range in \"%s\"\n", + linenum, *cpp); + return NULL; + } + *t++ = '\0'; + if (!portnum(*cpp, proto, &ipn.in_pmin, linenum) || + !portnum(t, proto, &ipn.in_pmax, linenum)) + return NULL; + } + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "round-robin")) { + cpp++; + ipn.in_flags |= IPN_ROUNDR; + } + + if (*cpp && !strcasecmp(*cpp, "age")) { + cpp++; + if (!*cpp) { + fprintf(stderr, "%d: age with no parameters\n", + linenum); + return NULL; + } + s = strchr(*cpp, '/'); + if (s != NULL) + ipn.in_age[1] = atoi(s + 1); + else + ipn.in_age[1] = ipn.in_age[0]; + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "mssclamp")) { + cpp++; + if (*cpp) { + ipn.in_mssclamp = atoi(*cpp); + cpp++; + } else { + fprintf(stderr, "%d: mssclamp with no parameters\n", + linenum); + return NULL; + } + } + + if (*cpp) { + fprintf(stderr, "%d: extra junk at the end of the line: %s\n", + linenum, *cpp); + return NULL; + } + + ipn.in_pmin = htons(ipn.in_pmin); + ipn.in_pmax = htons(ipn.in_pmax); + return &ipn; +} + + +void natparsefile(fd, file, opts) +int fd; +char *file; +int opts; +{ + char line[512], *s; + ipnat_t *np; + FILE *fp; + int linenum = 0; + + if (strcmp(file, "-")) { + if (!(fp = fopen(file, "r"))) { + fprintf(stderr, "%s: open: %s\n", file, + STRERROR(errno)); + exit(1); + } + } else + fp = stdin; + + while (getline(line, sizeof(line) - 1, fp, &linenum)) { + line[sizeof(line) - 1] = '\0'; + if ((s = strchr(line, '\n'))) + *s = '\0'; + + if (!(np = natparse(line, linenum))) { + if (*line) + fprintf(stderr, "%d: syntax error in \"%s\"\n", + linenum, line); + } else { + if ((opts & OPT_VERBOSE) && np) + printnat(np, opts); + if (!(opts & OPT_DONOTHING)) { + if (!(opts & OPT_REMOVE)) { + if (ioctl(fd, SIOCADNAT, &np) == -1) + perror("ioctl(SIOCADNAT)"); + } else if (ioctl(fd, SIOCRMNAT, &np) == -1) + perror("ioctl(SIOCRMNAT)"); + } + } + } + if (fp != stdin) + fclose(fp); +} + + +int icmpidnum(str, id, linenum) +char *str; +u_short *id; +int linenum; +{ + int i; + + + i = atoi(str); + + if ((i<0) || (i>65535)) { + fprintf(stderr, "%d: invalid icmp id\"%s\".\n", linenum, str); + return 0; + } + + *id = (u_short)i; + + return 1; +} diff --git a/contrib/ipfilter/lib/ntomask.c b/contrib/ipfilter/lib/ntomask.c new file mode 100644 index 0000000..415a5e8 --- /dev/null +++ b/contrib/ipfilter/lib/ntomask.c @@ -0,0 +1,38 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int ntomask(v, nbits, ap) +int v, nbits; +u_32_t *ap; +{ + u_32_t mask; + + if (nbits < 0) + return -1; + + switch (v) + { + case 4 : + if (nbits > 32 || use_inet6 != 0) + return -1; + if (nbits == 0) { + mask = 0; + } else { + mask = 0xffffffff; + mask <<= (32 - nbits); + } + *ap = htonl(mask); + break; + + case 6 : + if ((nbits > 128) || (use_inet6 == 0)) + return -1; + fill6bits(nbits, ap); + break; + + default : + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/optname.c b/contrib/ipfilter/lib/optname.c new file mode 100644 index 0000000..7fdcc57 --- /dev/null +++ b/contrib/ipfilter/lib/optname.c @@ -0,0 +1,65 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: optname.c,v 1.3 2001/06/09 17:09:24 darrenr Exp + */ + +#include "ipf.h" + + +u_32_t optname(cp, sp, linenum) +char ***cp; +u_short *sp; +int linenum; +{ + struct ipopt_names *io, *so; + u_long msk = 0; + u_short smsk = 0; + char *s; + int sec = 0; + + for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) { + for (io = ionames; io->on_name; io++) + if (!strcasecmp(s, io->on_name)) { + msk |= io->on_bit; + break; + } + if (!io->on_name) { + fprintf(stderr, "%d: unknown IP option name %s\n", + linenum, s); + return 0; + } + if (!strcasecmp(s, "sec-class")) + sec = 1; + } + + if (sec && !*(*cp + 1)) { + fprintf(stderr, "%d: missing security level after sec-class\n", + linenum); + return 0; + } + + if (sec) { + (*cp)++; + for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) { + for (so = secclass; so->on_name; so++) + if (!strcasecmp(s, so->on_name)) { + smsk |= so->on_bit; + break; + } + if (!so->on_name) { + fprintf(stderr, + "%d: no such security level: %s\n", + linenum, s); + return 0; + } + } + if (smsk) + *sp = smsk; + } + return msk; +} diff --git a/contrib/ipfilter/lib/optprint.c b/contrib/ipfilter/lib/optprint.c new file mode 100644 index 0000000..261a75c --- /dev/null +++ b/contrib/ipfilter/lib/optprint.c @@ -0,0 +1,79 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: optprint.c,v 1.6 2002/07/13 15:59:49 darrenr Exp + */ +#include "ipf.h" + + +void optprint(sec, optmsk, optbits) +u_short *sec; +u_long optmsk, optbits; +{ + u_short secmsk = sec[0], secbits = sec[1]; + struct ipopt_names *io, *so; + char *s; + + s = " opt "; + for (io = ionames; io->on_name; io++) + if ((io->on_bit & optmsk) && + ((io->on_bit & optmsk) == (io->on_bit & optbits))) { + if ((io->on_value != IPOPT_SECURITY) || + (!secmsk && !secbits)) { + printf("%s%s", s, io->on_name); + if (io->on_value == IPOPT_SECURITY) + io++; + s = ","; + } + } + + + if (secmsk & secbits) { + printf("%ssec-class", s); + s = " "; + for (so = secclass; so->on_name; so++) + if ((secmsk & so->on_bit) && + ((so->on_bit & secmsk) == (so->on_bit & secbits))) { + printf("%s%s", s, so->on_name); + s = ","; + } + } + + if ((optmsk && (optmsk != optbits)) || + (secmsk && (secmsk != secbits))) { + s = " "; + printf(" not opt"); + if (optmsk != optbits) { + for (io = ionames; io->on_name; io++) + if ((io->on_bit & optmsk) && + ((io->on_bit & optmsk) != + (io->on_bit & optbits))) { + if ((io->on_value != IPOPT_SECURITY) || + (!secmsk && !secbits)) { + printf("%s%s", s, io->on_name); + s = ","; + if (io->on_value == + IPOPT_SECURITY) + io++; + } else + io++; + } + } + + if (secmsk != secbits) { + printf("%ssec-class", s); + s = " "; + for (so = secclass; so->on_name; so++) + if ((so->on_bit & secmsk) && + ((so->on_bit & secmsk) != + (so->on_bit & secbits))) { + printf("%s%s", s, so->on_name); + s = ","; + } + } + } +} diff --git a/contrib/ipfilter/lib/optprintv6.c b/contrib/ipfilter/lib/optprintv6.c new file mode 100644 index 0000000..75e0fd0 --- /dev/null +++ b/contrib/ipfilter/lib/optprintv6.c @@ -0,0 +1,47 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: optprintv6.c,v 1.2 2003/04/30 00:39:39 darrenr Exp + */ +#include "ipf.h" + + +#ifdef USE_INET6 + +void optprintv6(sec, optmsk, optbits) +u_short *sec; +u_long optmsk, optbits; +{ + u_short secmsk = sec[0], secbits = sec[1]; + struct ipopt_names *io; + char *s; + + s = " v6hdrs "; + for (io = v6ionames; io->on_name; io++) + if ((io->on_bit & optmsk) && + ((io->on_bit & optmsk) == (io->on_bit & optbits))) { + printf("%s%s", s, io->on_name); + s = ","; + } + + if ((optmsk && (optmsk != optbits)) || + (secmsk && (secmsk != secbits))) { + s = " "; + printf(" not v6hdrs"); + if (optmsk != optbits) { + for (io = v6ionames; io->on_name; io++) + if ((io->on_bit & optmsk) && + ((io->on_bit & optmsk) != + (io->on_bit & optbits))) { + printf("%s%s", s, io->on_name); + s = ","; + } + } + + } +} +#endif diff --git a/contrib/ipfilter/lib/optvalue.c b/contrib/ipfilter/lib/optvalue.c new file mode 100644 index 0000000..dc9448d --- /dev/null +++ b/contrib/ipfilter/lib/optvalue.c @@ -0,0 +1,34 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: optvalue.c,v 1.2 2002/01/28 06:50:47 darrenr Exp + */ +#include "ipf.h" + + +u_32_t getoptbyname(optname) +char *optname; +{ + struct ipopt_names *io; + + for (io = ionames; io->on_name; io++) + if (!strcasecmp(optname, io->on_name)) + return io->on_bit; + return -1; +} + + +u_32_t getoptbyvalue(optval) +int optval; +{ + struct ipopt_names *io; + + for (io = ionames; io->on_name; io++) + if (io->on_value == optval) + return io->on_bit; + return -1; +} diff --git a/contrib/ipfilter/lib/parse.c b/contrib/ipfilter/lib/parse.c new file mode 100644 index 0000000..4cf69ab --- /dev/null +++ b/contrib/ipfilter/lib/parse.c @@ -0,0 +1,754 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: parse.c,v 1.34.2.1 2004/12/09 19:41:21 darrenr Exp + */ +#include <ctype.h> +#include "ipf.h" +#include "opts.h" + +static frentry_t *fp = NULL; + +/* parse() + * + * parse a line read from the input filter rule file + */ +struct frentry *parse(line, linenum) +char *line; +int linenum; +{ + static fripf_t fip; + char *cps[31], **cpp, *endptr, *proto = NULL, *s; + struct protoent *p = NULL; + int i, cnt = 1, j; + u_int k; + + if (fp == NULL) { + fp = malloc(sizeof(*fp)); + if (fp == NULL) + return NULL; + } + + while (*line && ISSPACE(*line)) + line++; + if (!*line) + return NULL; + + bzero((char *)fp, sizeof(*fp)); + bzero((char *)&fip, sizeof(fip)); + fp->fr_v = use_inet6 ? 6 : 4; + fp->fr_ipf = &fip; + fp->fr_dsize = sizeof(fip); + fp->fr_ip.fi_v = fp->fr_v; + fp->fr_mip.fi_v = 0xf; + fp->fr_type = FR_T_NONE; + fp->fr_loglevel = 0xffff; + fp->fr_isc = (void *)-1; + fp->fr_tag = FR_NOTAG; + + /* + * break line up into max of 20 segments + */ + if (opts & OPT_DEBUG) + fprintf(stderr, "parse [%s]\n", line); + for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++) + cps[++i] = strtok(NULL, " \b\t\r\n"); + cps[i] = NULL; + + if (cnt < 3) { + fprintf(stderr, "%d: not enough segments in line\n", linenum); + return NULL; + } + + cpp = cps; + /* + * The presence of an '@' followed by a number gives the position in + * the current rule list to insert this one. + */ + if (**cpp == '@') + fp->fr_hits = (U_QUAD_T)atoi(*cpp++ + 1) + 1; + + /* + * Check the first keyword in the rule and any options that are + * expected to follow it. + */ + if (!strcasecmp("block", *cpp)) { + fp->fr_flags |= FR_BLOCK; + if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19) && + (i = 19)) + fp->fr_flags |= FR_FAKEICMP; + else if (!strncasecmp(*(cpp+1), "return-icmp", 11) && (i = 11)) + fp->fr_flags |= FR_RETICMP; + if (fp->fr_flags & FR_RETICMP) { + cpp++; + if (strlen(*cpp) == i) { + if (*(cpp + 1) && **(cpp +1) == '(') { + cpp++; + i = 0; + } else + i = -1; + } + + /* + * The ICMP code is not required to follow in ()'s + */ + if ((i >= 0) && (*(*cpp + i) == '(')) { + i++; + j = icmpcode(*cpp + i); + if (j == -1) { + fprintf(stderr, + "%d: unrecognised icmp code %s\n", + linenum, *cpp + 20); + return NULL; + } + fp->fr_icode = j; + } + } else if (!strncasecmp(*(cpp+1), "return-rst", 10)) { + fp->fr_flags |= FR_RETRST; + cpp++; + } + } else if (!strcasecmp("count", *cpp)) { + fp->fr_flags |= FR_ACCOUNT; + } else if (!strcasecmp("pass", *cpp)) { + fp->fr_flags |= FR_PASS; + } else if (!strcasecmp("auth", *cpp)) { + fp->fr_flags |= FR_AUTH; + } else if (fp->fr_arg != 0) { + printf("skip %u", fp->fr_arg); + } else if (!strcasecmp("preauth", *cpp)) { + fp->fr_flags |= FR_PREAUTH; + } else if (!strcasecmp("nomatch", *cpp)) { + fp->fr_flags |= FR_NOMATCH; + } else if (!strcasecmp("skip", *cpp)) { + cpp++; + if (ratoui(*cpp, &k, 0, UINT_MAX)) + fp->fr_arg = k; + else { + fprintf(stderr, "%d: integer must follow skip\n", + linenum); + return NULL; + } + } else if (!strcasecmp("log", *cpp)) { + fp->fr_flags |= FR_LOG; + if (!strcasecmp(*(cpp+1), "body")) { + fp->fr_flags |= FR_LOGBODY; + cpp++; + } + if (!strcasecmp(*(cpp+1), "first")) { + fp->fr_flags |= FR_LOGFIRST; + cpp++; + } + if (*cpp && !strcasecmp(*(cpp+1), "or-block")) { + fp->fr_flags |= FR_LOGORBLOCK; + cpp++; + } + if (!strcasecmp(*(cpp+1), "level")) { + cpp++; + if (loglevel(cpp, &fp->fr_loglevel, linenum) == -1) + return NULL; + cpp++; + } + } else { + /* + * Doesn't start with one of the action words + */ + fprintf(stderr, "%d: unknown keyword (%s)\n", linenum, *cpp); + return NULL; + } + if (!*++cpp) { + fprintf(stderr, "%d: missing 'in'/'out' keyword\n", linenum); + return NULL; + } + + /* + * Get the direction for filtering. Impose restrictions on direction + * if blocking with returning ICMP or an RST has been requested. + */ + if (!strcasecmp("in", *cpp)) + fp->fr_flags |= FR_INQUE; + else if (!strcasecmp("out", *cpp)) { + fp->fr_flags |= FR_OUTQUE; + if (fp->fr_flags & FR_RETICMP) { + fprintf(stderr, + "%d: Can only use return-icmp with 'in'\n", + linenum); + return NULL; + } else if (fp->fr_flags & FR_RETRST) { + fprintf(stderr, + "%d: Can only use return-rst with 'in'\n", + linenum); + return NULL; + } + } + if (!*++cpp) { + fprintf(stderr, "%d: missing source specification\n", linenum); + return NULL; + } + + if (!strcasecmp("log", *cpp)) { + if (!*++cpp) { + fprintf(stderr, "%d: missing source specification\n", + linenum); + return NULL; + } + if (FR_ISPASS(fp->fr_flags)) + fp->fr_flags |= FR_LOGP; + else if (FR_ISBLOCK(fp->fr_flags)) + fp->fr_flags |= FR_LOGB; + if (*cpp && !strcasecmp(*cpp, "body")) { + fp->fr_flags |= FR_LOGBODY; + cpp++; + } + if (*cpp && !strcasecmp(*cpp, "first")) { + fp->fr_flags |= FR_LOGFIRST; + cpp++; + } + if (*cpp && !strcasecmp(*cpp, "or-block")) { + if (!FR_ISPASS(fp->fr_flags)) { + fprintf(stderr, + "%d: or-block must be used with pass\n", + linenum); + return NULL; + } + fp->fr_flags |= FR_LOGORBLOCK; + cpp++; + } + if (*cpp && !strcasecmp(*cpp, "level")) { + if (loglevel(cpp, &fp->fr_loglevel, linenum) == -1) + return NULL; + cpp++; + cpp++; + } + } + + if (*cpp && !strcasecmp("quick", *cpp)) { + if (fp->fr_arg != 0) { + fprintf(stderr, "%d: cannot use skip with quick\n", + linenum); + return NULL; + } + cpp++; + fp->fr_flags |= FR_QUICK; + } + + /* + * Parse rule options that are available if a rule is tied to an + * interface. + */ + *fp->fr_ifname = '\0'; + *fp->fr_oifname = '\0'; + if (*cpp && !strcasecmp(*cpp, "on")) { + if (!*++cpp) { + fprintf(stderr, "%d: interface name missing\n", + linenum); + return NULL; + } + (void)strncpy(fp->fr_ifname, *cpp, IFNAMSIZ-1); + fp->fr_ifname[IFNAMSIZ-1] = '\0'; + cpp++; + if (!*cpp) { + if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) { + fprintf(stderr, + "%d: %s can only be used with TCP\n", + linenum, "return-rst"); + return NULL; + } + return fp; + } + + if (!strcasecmp(*cpp, "out-via")) { + if (fp->fr_flags & FR_OUTQUE) { + fprintf(stderr, + "out-via must be used with in\n"); + return NULL; + } + cpp++; + (void)strncpy(fp->fr_oifname, *cpp, IFNAMSIZ-1); + fp->fr_oifname[IFNAMSIZ-1] = '\0'; + cpp++; + } else if (!strcasecmp(*cpp, "in-via")) { + if (fp->fr_flags & FR_INQUE) { + fprintf(stderr, + "in-via must be used with out\n"); + return NULL; + } + cpp++; + (void)strncpy(fp->fr_oifname, *cpp, IFNAMSIZ-1); + fp->fr_oifname[IFNAMSIZ-1] = '\0'; + cpp++; + } + + if (!strcasecmp(*cpp, "dup-to") && *(cpp + 1)) { + cpp++; + if (to_interface(&fp->fr_dif, *cpp, linenum)) + return NULL; + cpp++; + } + if (*cpp && !strcasecmp(*cpp, "to") && *(cpp + 1)) { + cpp++; + if (to_interface(&fp->fr_tif, *cpp, linenum)) + return NULL; + cpp++; + } else if (*cpp && !strcasecmp(*cpp, "fastroute")) { + if (!(fp->fr_flags & FR_INQUE)) { + fprintf(stderr, + "can only use %s with 'in'\n", + "fastroute"); + return NULL; + } + fp->fr_flags |= FR_FASTROUTE; + cpp++; + } + + /* + * Set the "other" interface name. Lets you specify both + * inbound and outbound interfaces for state rules. Do not + * prevent both interfaces from being the same. + */ + strcpy(fp->fr_ifnames[3], "*"); + if ((*cpp != NULL) && (*(cpp + 1) != NULL) && + ((((fp->fr_flags & FR_INQUE) != 0) && + (strcasecmp(*cpp, "out-via") == 0)) || + (((fp->fr_flags & FR_OUTQUE) != 0) && + (strcasecmp(*cpp, "in-via") == 0)))) { + cpp++; + + s = strchr(*cpp, ','); + if (s != NULL) { + *s++ = '\0'; + (void)strncpy(fp->fr_ifnames[3], s, + IFNAMSIZ - 1); + fp->fr_ifnames[3][IFNAMSIZ - 1] = '\0'; + } + + (void)strncpy(fp->fr_ifnames[2], *cpp, IFNAMSIZ - 1); + fp->fr_ifnames[2][IFNAMSIZ - 1] = '\0'; + cpp++; + } else + strcpy(fp->fr_ifnames[2], "*"); + + } + + if (*cpp && !strcasecmp(*cpp, "tos")) { + if (!*++cpp) { + fprintf(stderr, "%d: tos missing value\n", linenum); + return NULL; + } + fp->fr_tos = strtol(*cpp, NULL, 0); + fp->fr_mip.fi_tos = 0xff; + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "ttl")) { + if (!*++cpp) { + fprintf(stderr, "%d: ttl missing hopcount value\n", + linenum); + return NULL; + } + if (ratoi(*cpp, &i, 0, 255)) + fp->fr_ttl = i; + else { + fprintf(stderr, "%d: invalid ttl (%s)\n", + linenum, *cpp); + return NULL; + } + fp->fr_mip.fi_ttl = 0xff; + cpp++; + } + + /* + * check for "proto <protoname>" only decode udp/tcp/icmp as protoname + */ + if (*cpp && !strcasecmp(*cpp, "proto")) { + if (!*++cpp) { + fprintf(stderr, "%d: protocol name missing\n", linenum); + return NULL; + } + fp->fr_type = FR_T_IPF; + proto = *cpp++; + if (!strcasecmp(proto, "tcp/udp")) { + fp->fr_flx |= FI_TCPUDP; + fp->fr_mflx |= FI_TCPUDP; + } else if (use_inet6 && !strcasecmp(proto, "icmp")) { + fprintf(stderr, +"%d: use proto ipv6-icmp with IPv6 (or use proto 1 if you really mean icmp)\n", + linenum); + return NULL; + } else { + fp->fr_proto = getproto(proto); + fp->fr_mip.fi_p = 0xff; + } + } + if ((fp->fr_proto != IPPROTO_TCP) && + ((fp->fr_flags & FR_RETMASK) == FR_RETRST)) { + fprintf(stderr, "%d: %s can only be used with TCP\n", + linenum, "return-rst"); + return NULL; + } + + /* + * get the from host and bit mask to use against packets + */ + + if (!*cpp) { + fprintf(stderr, "%d: missing source specification\n", linenum); + return NULL; + } + if (!strcasecmp(*cpp, "all")) { + cpp++; + if (!*cpp) { + if (fp->fr_type == FR_T_NONE) { + fp->fr_dsize = 0; + fp->fr_data = NULL; + } + return fp; + } + fp->fr_type = FR_T_IPF; +#ifdef IPFILTER_BPF + } else if (!strcmp(*cpp, "{")) { + struct bpf_program bpf; + struct pcap *p; + char **cp; + u_32_t l; + + if (fp->fr_type != FR_T_NONE) { + fprintf(stderr, + "%d: cannot mix BPF/ipf matching\n", linenum); + return NULL; + } + fp->fr_type = FR_T_BPFOPC; + cpp++; + if (!strncmp(*cpp, "0x", 2)) { + fp->fr_data = malloc(4); + for (cp = cpp, i = 0; *cp; cp++, i++) { + if (!strcmp(*cp, "}")) + break; + fp->fr_data = realloc(fp->fr_data, + (i + 1) * 4); + l = strtoul(*cp, NULL, 0); + ((u_32_t *)fp->fr_data)[i] = l; + } + if (!*cp) { + fprintf(stderr, "Missing closing '}'\n"); + return NULL; + } + fp->fr_dsize = i * sizeof(l); + bpf.bf_insns = fp->fr_data; + bpf.bf_len = fp->fr_dsize / sizeof(struct bpf_insn); + } else { + for (cp = cpp; *cp; cp++) { + if (!strcmp(*cp, "}")) + break; + (*cp)[-1] = ' '; + } + if (!*cp) { + fprintf(stderr, "Missing closing '}'\n"); + return NULL; + } + + bzero((char *)&bpf, sizeof(bpf)); + p = pcap_open_dead(DLT_RAW, 1); + if (!p) { + fprintf(stderr, "pcap_open_dead failed\n"); + return NULL; + } + + if (pcap_compile(p, &bpf, *cpp, 1, 0xffffffff)) { + pcap_perror(p, "ipf"); + pcap_close(p); + fprintf(stderr, "pcap parsing failed\n"); + return NULL; + } + pcap_close(p); + fp->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn); + fp->fr_data = bpf.bf_insns; + if (!bpf_validate(fp->fr_data, bpf.bf_len)) { + fprintf(stderr, "BPF validation failed\n"); + return NULL; + } + if (opts & OPT_DEBUG) + bpf_dump(&bpf, 0); + } + cpp = cp; + (*cpp)++; +#endif + } else { + fp->fr_type = FR_T_IPF; + + if (strcasecmp(*cpp, "from")) { + fprintf(stderr, "%d: unexpected keyword (%s) - from\n", + linenum, *cpp); + return NULL; + } + if (!*++cpp) { + fprintf(stderr, "%d: missing host after from\n", + linenum); + return NULL; + } + if (**cpp == '!') { + fp->fr_flags |= FR_NOTSRCIP; + (*cpp)++; + } else if (!strcmp(*cpp, "!")) { + fp->fr_flags |= FR_NOTSRCIP; + cpp++; + } + + s = *cpp; + i = hostmask(&cpp, proto, fp->fr_ifname, (u_32_t *)&fp->fr_src, + (u_32_t *)&fp->fr_smsk, linenum); + if (i == -1) + return NULL; + if (*fp->fr_ifname && !strcasecmp(s, fp->fr_ifname)) + fp->fr_satype = FRI_DYNAMIC; + if (i == 1) { + if (fp->fr_v == 6) { + fprintf(stderr, + "can only use pools with ipv4\n"); + return NULL; + } + fp->fr_satype = FRI_LOOKUP; + } + + if (ports(&cpp, proto, &fp->fr_sport, &fp->fr_scmp, + &fp->fr_stop, linenum)) + return NULL; + + if (!*cpp) { + fprintf(stderr, "%d: missing to fields\n", linenum); + return NULL; + } + + /* + * do the same for the to field (destination host) + */ + if (strcasecmp(*cpp, "to")) { + fprintf(stderr, "%d: unexpected keyword (%s) - to\n", + linenum, *cpp); + return NULL; + } + if (!*++cpp) { + fprintf(stderr, "%d: missing host after to\n", linenum); + return NULL; + } + + if (**cpp == '!') { + fp->fr_flags |= FR_NOTDSTIP; + (*cpp)++; + } else if (!strcmp(*cpp, "!")) { + fp->fr_flags |= FR_NOTDSTIP; + cpp++; + } + + s = *cpp; + i = hostmask(&cpp, proto, fp->fr_ifname, (u_32_t *)&fp->fr_dst, + (u_32_t *)&fp->fr_dmsk, linenum); + if (i == -1) + return NULL; + if (*fp->fr_ifname && !strcasecmp(s, fp->fr_ifname)) + fp->fr_datype = FRI_DYNAMIC; + if (i == 1) { + if (fp->fr_v == 6) { + fprintf(stderr, + "can only use pools with ipv4\n"); + return NULL; + } + fp->fr_datype = FRI_LOOKUP; + } + + if (ports(&cpp, proto, &fp->fr_dport, &fp->fr_dcmp, + &fp->fr_dtop, linenum)) + return NULL; + } + + if (fp->fr_type == FR_T_IPF) { + /* + * check some sanity, make sure we don't have icmp checks + * with tcp or udp or visa versa. + */ + if (fp->fr_proto && (fp->fr_dcmp || fp->fr_scmp) && + fp->fr_proto != IPPROTO_TCP && + fp->fr_proto != IPPROTO_UDP) { + fprintf(stderr, + "%d: port operation on non tcp/udp\n",linenum); + return NULL; + } + if (fp->fr_icmp && fp->fr_proto != IPPROTO_ICMP) { + fprintf(stderr, + "%d: icmp comparisons on wrong protocol\n", + linenum); + return NULL; + } + + if (!*cpp) + return fp; + + if (*cpp && (fp->fr_type == FR_T_IPF) && + !strcasecmp(*cpp, "flags")) { + if (!*++cpp) { + fprintf(stderr, "%d: no flags present\n", + linenum); + return NULL; + } + fp->fr_tcpf = tcp_flags(*cpp, &fp->fr_tcpfm, linenum); + cpp++; + } + + /* + * extras... + */ + if ((fp->fr_v == 4) && *cpp && (!strcasecmp(*cpp, "with") || + !strcasecmp(*cpp, "and"))) + if (extras(&cpp, fp, linenum)) + return NULL; + + /* + * icmp types for use with the icmp protocol + */ + if (*cpp && !strcasecmp(*cpp, "icmp-type")) { + if (fp->fr_proto != IPPROTO_ICMP && + fp->fr_proto != IPPROTO_ICMPV6) { + fprintf(stderr, + "%d: icmp with wrong protocol (%d)\n", + linenum, fp->fr_proto); + return NULL; + } + if (addicmp(&cpp, fp, linenum)) + return NULL; + fp->fr_icmp = htons(fp->fr_icmp); + fp->fr_icmpm = htons(fp->fr_icmpm); + } + } + + /* + * Keep something... + */ + while (*cpp && !strcasecmp(*cpp, "keep")) + if (addkeep(&cpp, fp, linenum)) + return NULL; + + /* + * This is here to enforce the old interface binding behaviour. + * That is, "on X" is equivalent to "<dir> on X <!dir>-via -,X" + */ + if (fp->fr_flags & FR_KEEPSTATE) { + if (*fp->fr_ifnames[0] && !*fp->fr_ifnames[3]) { + bcopy(fp->fr_ifnames[0], fp->fr_ifnames[3], + sizeof(fp->fr_ifnames[3])); + strncpy(fp->fr_ifnames[2], "*", + sizeof(fp->fr_ifnames[3])); + } + } + + /* + * head of a new group ? + */ + if (*cpp && !strcasecmp(*cpp, "head")) { + if (fp->fr_arg != 0) { + fprintf(stderr, "%d: cannot use skip with head\n", + linenum); + return NULL; + } + if (!*++cpp) { + fprintf(stderr, "%d: head without group #\n", linenum); + return NULL; + } + if (strlen(*cpp) > FR_GROUPLEN) { + fprintf(stderr, "%d: head name too long #\n", linenum); + return NULL; + } + strncpy(fp->fr_grhead, *cpp, FR_GROUPLEN); + cpp++; + } + + /* + * reference to an already existing group ? + */ + if (*cpp && !strcasecmp(*cpp, "group")) { + if (!*++cpp) { + fprintf(stderr, "%d: group without group #\n", + linenum); + return NULL; + } + if (strlen(*cpp) > FR_GROUPLEN) { + fprintf(stderr, "%d: group name too long #\n", linenum); + return NULL; + } + strncpy(fp->fr_group, *cpp, FR_GROUPLEN); + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "tag")) { + if (!*++cpp) { + fprintf(stderr, "%d: tag id missing value\n", linenum); + return NULL; + } + fp->fr_tag = strtol(*cpp, NULL, 0); + cpp++; + } + + /* + * pps counter + */ + if (*cpp && !strcasecmp(*cpp, "pps")) { + if (!*++cpp) { + fprintf(stderr, "%d: pps without rate\n", linenum); + return NULL; + } + if (ratoui(*cpp, &k, 0, INT_MAX)) + fp->fr_pps = k; + else { + fprintf(stderr, "%d: invalid pps rate (%s)\n", + linenum, *cpp); + return NULL; + } + cpp++; + } + + /* + * leftovers...yuck + */ + if (*cpp && **cpp) { + fprintf(stderr, "%d: unknown words at end: [", linenum); + for (; *cpp; cpp++) + fprintf(stderr, "%s ", *cpp); + fprintf(stderr, "]\n"); + return NULL; + } + + /* + * lazy users... + */ + if (fp->fr_type == FR_T_IPF) { + if ((fp->fr_tcpf || fp->fr_tcpfm) && + (fp->fr_proto != IPPROTO_TCP)) { + fprintf(stderr, + "%d: TCP protocol not specified\n", linenum); + return NULL; + } + if (!(fp->fr_flx & FI_TCPUDP) && + (fp->fr_proto != IPPROTO_TCP) && + (fp->fr_proto != IPPROTO_UDP) && + (fp->fr_dcmp || fp->fr_scmp)) { + if (!fp->fr_proto) { + fp->fr_flx |= FI_TCPUDP; + fp->fr_mflx |= FI_TCPUDP; + } else { + fprintf(stderr, + "%d: port check for non-TCP/UDP\n", + linenum); + return NULL; + } + } + } + if (*fp->fr_oifname && strcmp(fp->fr_oifname, "*") && + !(fp->fr_flags & FR_KEEPSTATE)) { + fprintf(stderr, "%d: *-via <if> must be used %s\n", + linenum, "with keep-state"); + return NULL; + } + return fp; +} diff --git a/contrib/ipfilter/lib/portname.c b/contrib/ipfilter/lib/portname.c new file mode 100644 index 0000000..7c0fc87 --- /dev/null +++ b/contrib/ipfilter/lib/portname.c @@ -0,0 +1,42 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: portname.c,v 1.7 2003/08/14 14:27:43 darrenr Exp + */ +#include "ipf.h" + + +char *portname(pr, port) +int pr, port; +{ + static char buf[32]; + struct protoent *p = NULL; + struct servent *sv = NULL, *sv1 = NULL; + + if ((opts & OPT_NORESOLVE) == 0) { + if (pr == -1) { + if ((sv = getservbyport(htons(port), "tcp"))) { + strncpy(buf, sv->s_name, sizeof(buf)-1); + buf[sizeof(buf)-1] = '\0'; + sv1 = getservbyport(htons(port), "udp"); + sv = strncasecmp(buf, sv->s_name, strlen(buf)) ? + NULL : sv1; + } + if (sv) + return buf; + } else if ((pr != -2) && (p = getprotobynumber(pr))) { + if ((sv = getservbyport(htons(port), p->p_name))) { + strncpy(buf, sv->s_name, sizeof(buf)-1); + buf[sizeof(buf)-1] = '\0'; + return buf; + } + } + } + + (void) sprintf(buf, "%d", port); + return buf; +} diff --git a/contrib/ipfilter/lib/portnum.c b/contrib/ipfilter/lib/portnum.c new file mode 100644 index 0000000..284bbc9 --- /dev/null +++ b/contrib/ipfilter/lib/portnum.c @@ -0,0 +1,64 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * + * Id: portnum.c,v 1.6.4.1 2004/12/09 19:41:22 darrenr Exp + */ + +#include <ctype.h> + +#include "ipf.h" + + +/* + * find the port number given by the name, either from getservbyname() or + * straight atoi(). Return 1 on success, 0 on failure + */ +int portnum(name, proto, port, linenum) +char *name, *proto; +u_short *port; +int linenum; +{ + struct servent *sp, *sp2; + u_short p1 = 0; + int i; + + if (ISDIGIT(*name)) { + if (ratoi(name, &i, 0, USHRT_MAX)) { + *port = (u_short)i; + return 1; + } + fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name); + return 0; + } + if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) { + sp = getservbyname(name, proto); + if (sp) { + *port = ntohs(sp->s_port); + return 1; + } + fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name); + return 0; + } + sp = getservbyname(name, "tcp"); + if (sp) + p1 = sp->s_port; + sp2 = getservbyname(name, "udp"); + if (!sp || !sp2) { + fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n", + linenum, name); + return 0; + } + if (p1 != sp2->s_port) { + fprintf(stderr, "%d: %s %d/tcp is a different port to ", + linenum, name, p1); + fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port); + return 0; + } + *port = ntohs(p1); + return 1; +} diff --git a/contrib/ipfilter/lib/ports.c b/contrib/ipfilter/lib/ports.c new file mode 100644 index 0000000..634dfeb --- /dev/null +++ b/contrib/ipfilter/lib/ports.c @@ -0,0 +1,81 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ports.c,v 1.9.4.1 2004/12/09 19:41:22 darrenr Exp + */ + +#include <ctype.h> + +#include "ipf.h" + + +/* + * check for possible presence of the port fields in the line + */ +int ports(seg, proto, pp, cp, tp, linenum) +char ***seg; +char *proto; +u_short *pp; +int *cp; +u_short *tp; +int linenum; +{ + int comp = -1; + + if (!*seg || !**seg || !***seg) + return 0; + if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) { + (*seg)++; + if (ISALNUM(***seg) && *(*seg + 2)) { + if (portnum(**seg, proto, pp, linenum) == 0) + return -1; + (*seg)++; + if (!strcmp(**seg, "<>")) + comp = FR_OUTRANGE; + else if (!strcmp(**seg, "><")) + comp = FR_INRANGE; + else { + fprintf(stderr, + "%d: unknown range operator (%s)\n", + linenum, **seg); + return -1; + } + (*seg)++; + if (**seg == NULL) { + fprintf(stderr, "%d: missing 2nd port value\n", + linenum); + return -1; + } + if (portnum(**seg, proto, tp, linenum) == 0) + return -1; + } else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq")) + comp = FR_EQUAL; + else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne")) + comp = FR_NEQUAL; + else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt")) + comp = FR_LESST; + else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt")) + comp = FR_GREATERT; + else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le")) + comp = FR_LESSTE; + else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge")) + comp = FR_GREATERTE; + else { + fprintf(stderr, "%d: unknown comparator (%s)\n", + linenum, **seg); + return -1; + } + if (comp != FR_OUTRANGE && comp != FR_INRANGE) { + (*seg)++; + if (portnum(**seg, proto, pp, linenum) == 0) + return -1; + } + *cp = comp; + (*seg)++; + } + return 0; +} diff --git a/contrib/ipfilter/lib/print_toif.c b/contrib/ipfilter/lib/print_toif.c new file mode 100644 index 0000000..0e230cd --- /dev/null +++ b/contrib/ipfilter/lib/print_toif.c @@ -0,0 +1,32 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: print_toif.c,v 1.8 2002/01/28 06:50:47 darrenr Exp + */ + +#include "ipf.h" + + +void print_toif(tag, fdp) +char *tag; +frdest_t *fdp; +{ + printf("%s %s%s", tag, fdp->fd_ifname, + (fdp->fd_ifp || (long)fdp->fd_ifp == -1) ? "" : "(!)"); +#ifdef USE_INET6 + if (use_inet6 && IP6_NOTZERO(&fdp->fd_ip6.in6)) { + char ipv6addr[80]; + + inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr, + sizeof(fdp->fd_ip6)); + printf(":%s", ipv6addr); + } else +#endif + if (fdp->fd_ip.s_addr) + printf(":%s", inet_ntoa(fdp->fd_ip)); + putchar(' '); +} diff --git a/contrib/ipfilter/lib/printactivenat.c b/contrib/ipfilter/lib/printactivenat.c new file mode 100644 index 0000000..3c56b14 --- /dev/null +++ b/contrib/ipfilter/lib/printactivenat.c @@ -0,0 +1,85 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" + + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: printactivenat.c,v 1.3.2.4 2004/05/11 16:07:32 darrenr Exp"; +#endif + + +void printactivenat(nat, opts) +nat_t *nat; +int opts; +{ + + printf("%s", getnattype(nat->nat_ptr)); + + if (nat->nat_flags & SI_CLONE) + printf(" CLONE"); + + printf(" %-15s", inet_ntoa(nat->nat_inip)); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + printf(" %-5hu", ntohs(nat->nat_inport)); + + printf(" <- -> %-15s",inet_ntoa(nat->nat_outip)); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + printf(" %-5hu", ntohs(nat->nat_outport)); + + printf(" [%s", inet_ntoa(nat->nat_oip)); + if ((nat->nat_flags & IPN_TCPUDP) != 0) + printf(" %hu", ntohs(nat->nat_oport)); + printf("]"); + + if (opts & OPT_VERBOSE) { + printf("\n\tage %lu use %hu sumd %s/", + nat->nat_age, nat->nat_use, getsumd(nat->nat_sumd[0])); + printf("%s pr %u bkt %d/%d flags %x\n", + getsumd(nat->nat_sumd[1]), nat->nat_p, + nat->nat_hv[0], nat->nat_hv[1], nat->nat_flags); + printf("\tifp %s", getifname(nat->nat_ifps[0])); + printf(",%s ", getifname(nat->nat_ifps[1])); +#ifdef USE_QUAD_T + printf("bytes %qu/%qu pkts %qu/%qu", + (unsigned long long)nat->nat_bytes[0], + (unsigned long long)nat->nat_bytes[1], + (unsigned long long)nat->nat_pkts[0], + (unsigned long long)nat->nat_pkts[1]); +#else + printf("bytes %lu/%lu pkts %lu/%lu", nat->nat_bytes[0], + nat->nat_bytes[1], nat->nat_pkts[0], nat->nat_pkts[1]); +#endif + printf(" ipsumd %x", nat->nat_ipsumd); + } + + if (opts & OPT_DEBUG) { + printf("\n\tnat_next %p _pnext %p _hm %p\n", + nat->nat_next, nat->nat_pnext, nat->nat_hm); + printf("\t_hnext %p/%p _phnext %p/%p\n", + nat->nat_hnext[0], nat->nat_hnext[1], + nat->nat_phnext[0], nat->nat_phnext[1]); + printf("\t_data %p _me %p _state %p _aps %p\n", + nat->nat_data, nat->nat_me, nat->nat_state, nat->nat_aps); + printf("\tfr %p ptr %p ifps %p/%p sync %p\n", + nat->nat_fr, nat->nat_ptr, nat->nat_ifps[0], + nat->nat_ifps[1], nat->nat_sync); + printf("\ttqe:pnext %p next %p ifq %p parent %p/%p\n", + nat->nat_tqe.tqe_pnext, nat->nat_tqe.tqe_next, + nat->nat_tqe.tqe_ifq, nat->nat_tqe.tqe_parent, nat); + printf("\ttqe:die %ld touched %ld flags %x state %d/%d\n", + nat->nat_tqe.tqe_die, nat->nat_tqe.tqe_touched, + nat->nat_tqe.tqe_flags, nat->nat_tqe.tqe_state[0], + nat->nat_tqe.tqe_state[1]); + } + putchar('\n'); +} diff --git a/contrib/ipfilter/lib/printaps.c b/contrib/ipfilter/lib/printaps.c new file mode 100644 index 0000000..5c5c3dd --- /dev/null +++ b/contrib/ipfilter/lib/printaps.c @@ -0,0 +1,112 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" +#include "kmem.h" + + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: printaps.c,v 1.4 2004/01/08 13:34:32 darrenr Exp"; +#endif + + +void printaps(aps, opts) +ap_session_t *aps; +int opts; +{ + ipsec_pxy_t ipsec; + ap_session_t ap; + ftpinfo_t ftp; + aproxy_t apr; + raudio_t ra; + + if (kmemcpy((char *)&ap, (long)aps, sizeof(ap))) + return; + if (kmemcpy((char *)&apr, (long)ap.aps_apr, sizeof(apr))) + return; + printf("\tproxy %s/%d use %d flags %x\n", apr.apr_label, + apr.apr_p, apr.apr_ref, apr.apr_flags); + printf("\t\tproto %d flags %#x bytes ", ap.aps_p, ap.aps_flags); +#ifdef USE_QUAD_T + printf("%qu pkts %qu", (unsigned long long)ap.aps_bytes, + (unsigned long long)ap.aps_pkts); +#else + printf("%lu pkts %lu", ap.aps_bytes, ap.aps_pkts); +#endif + printf(" data %s size %d\n", ap.aps_data ? "YES" : "NO", ap.aps_psiz); + if ((ap.aps_p == IPPROTO_TCP) && (opts & OPT_VERBOSE)) { + printf("\t\tstate[%u,%u], sel[%d,%d]\n", + ap.aps_state[0], ap.aps_state[1], + ap.aps_sel[0], ap.aps_sel[1]); +#if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \ + (__FreeBSD_version >= 300000) || defined(OpenBSD) + printf("\t\tseq: off %hd/%hd min %x/%x\n", + ap.aps_seqoff[0], ap.aps_seqoff[1], + ap.aps_seqmin[0], ap.aps_seqmin[1]); + printf("\t\tack: off %hd/%hd min %x/%x\n", + ap.aps_ackoff[0], ap.aps_ackoff[1], + ap.aps_ackmin[0], ap.aps_ackmin[1]); +#else + printf("\t\tseq: off %hd/%hd min %lx/%lx\n", + ap.aps_seqoff[0], ap.aps_seqoff[1], + ap.aps_seqmin[0], ap.aps_seqmin[1]); + printf("\t\tack: off %hd/%hd min %lx/%lx\n", + ap.aps_ackoff[0], ap.aps_ackoff[1], + ap.aps_ackmin[0], ap.aps_ackmin[1]); +#endif + } + + if (!strcmp(apr.apr_label, "raudio") && ap.aps_psiz == sizeof(ra)) { + if (kmemcpy((char *)&ra, (long)ap.aps_data, sizeof(ra))) + return; + printf("\tReal Audio Proxy:\n"); + printf("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n", + ra.rap_seenpna, ra.rap_version, ra.rap_eos); + printf("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf); + printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n", + ra.rap_plport, ra.rap_prport, ra.rap_srport); + } else if (!strcmp(apr.apr_label, "ftp") && + (ap.aps_psiz == sizeof(ftp))) { + if (kmemcpy((char *)&ftp, (long)ap.aps_data, sizeof(ftp))) + return; + printf("\tFTP Proxy:\n"); + printf("\t\tpassok: %d\n", ftp.ftp_passok); + ftp.ftp_side[0].ftps_buf[FTP_BUFSZ - 1] = '\0'; + ftp.ftp_side[1].ftps_buf[FTP_BUFSZ - 1] = '\0'; + printf("\tClient:\n"); + printf("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", + ftp.ftp_side[0].ftps_seq[0], + ftp.ftp_side[0].ftps_seq[1], + ftp.ftp_side[0].ftps_len, ftp.ftp_side[0].ftps_junk, + ftp.ftp_side[0].ftps_cmds); + printf("\t\tbuf ["); + printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1); + printf("]\n\tServer:\n"); + printf("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", + ftp.ftp_side[1].ftps_seq[0], + ftp.ftp_side[1].ftps_seq[1], + ftp.ftp_side[1].ftps_len, ftp.ftp_side[1].ftps_junk, + ftp.ftp_side[1].ftps_cmds); + printf("\t\tbuf ["); + printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1); + printf("]\n"); + } else if (!strcmp(apr.apr_label, "ipsec") && + (ap.aps_psiz == sizeof(ipsec))) { + if (kmemcpy((char *)&ipsec, (long)ap.aps_data, sizeof(ipsec))) + return; + printf("\tIPSec Proxy:\n"); + printf("\t\tICookie %08x%08x RCookie %08x%08x %s\n", + (u_int)ntohl(ipsec.ipsc_icookie[0]), + (u_int)ntohl(ipsec.ipsc_icookie[1]), + (u_int)ntohl(ipsec.ipsc_rcookie[0]), + (u_int)ntohl(ipsec.ipsc_rcookie[1]), + ipsec.ipsc_rckset ? "(Set)" : "(Not set)"); + } +} diff --git a/contrib/ipfilter/lib/printbuf.c b/contrib/ipfilter/lib/printbuf.c new file mode 100644 index 0000000..f2b7faa --- /dev/null +++ b/contrib/ipfilter/lib/printbuf.c @@ -0,0 +1,32 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printbuf.c,v 1.5.4.1 2004/12/09 19:41:22 darrenr Exp + */ + +#include <ctype.h> + +#include "ipf.h" + + +void printbuf(buf, len, zend) +char *buf; +int len, zend; +{ + char *s, c; + int i; + + for (s = buf, i = len; i; i--) { + c = *s++; + if (ISPRINT(c)) + putchar(c); + else + printf("\\%03o", c); + if ((c == '\0') && zend) + break; + } +} diff --git a/contrib/ipfilter/lib/printfr.c b/contrib/ipfilter/lib/printfr.c new file mode 100644 index 0000000..f0f5a0e --- /dev/null +++ b/contrib/ipfilter/lib/printfr.c @@ -0,0 +1,445 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printfr.c,v 1.43.2.10 2005/03/16 15:38:13 darrenr Exp + */ + +#include "ipf.h" + +static void printaddr(int, int, char *, u_32_t *, u_32_t *); + +static void printaddr(v, type, ifname, addr, mask) +int v, type; +char *ifname; +u_32_t *addr, *mask; +{ + char *suffix; + + switch (type) + { + case FRI_BROADCAST : + suffix = "/bcast"; + break; + + case FRI_DYNAMIC : + printf("%s", ifname); + printmask(mask); + suffix = NULL; + break; + + case FRI_NETWORK : + suffix = "/net"; + break; + + case FRI_NETMASKED : + suffix = "/netmasked"; + break; + + case FRI_PEERADDR : + suffix = "/peer"; + break; + + case FRI_LOOKUP : + suffix = NULL; + printlookup((i6addr_t *)addr, (i6addr_t *)mask); + break; + + case FRI_NORMAL : + printhostmask(v, addr, mask); + suffix = NULL; + break; + default : + printf("<%d>", type); + printmask(mask); + suffix = NULL; + break; + } + + if (suffix != NULL) { + printf("%s/%s", ifname, suffix); + } +} + + +void printlookup(addr, mask) +i6addr_t *addr, *mask; +{ + switch (addr->iplookuptype) + { + case IPLT_POOL : + printf("pool/"); + break; + case IPLT_HASH : + printf("hash/"); + break; + default : + printf("lookup(%x)=", addr->iplookuptype); + break; + } + + printf("%u", addr->iplookupnum); + if (mask->iplookupptr == NULL) + printf("(!)"); +} + + +/* + * print the filter structure in a useful way + */ +void printfr(fp, iocfunc) +struct frentry *fp; +ioctlfunc_t iocfunc; +{ + struct protoent *p; + u_short sec[2]; + u_32_t type; + u_char *t; + char *s; + int pr; + + pr = -2; + type = fp->fr_type & ~FR_T_BUILTIN; + + if ((fp->fr_type & FR_T_BUILTIN) != 0) + printf("# Builtin: "); + + if (fp->fr_type == FR_T_CALLFUNC) { + ; + } else if (fp->fr_func != NULL) { + printf("call"); + if ((fp->fr_flags & FR_CALLNOW) != 0) + printf(" now"); + s = kvatoname(fp->fr_func, iocfunc); + printf(" %s/%u", s ? s : "?", fp->fr_arg); + } else if (FR_ISPASS(fp->fr_flags)) + printf("pass"); + else if (FR_ISBLOCK(fp->fr_flags)) { + printf("block"); + if (fp->fr_flags & FR_RETICMP) { + if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP) + printf(" return-icmp-as-dest"); + else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP) + printf(" return-icmp"); + if (fp->fr_icode) { + if (fp->fr_icode <= MAX_ICMPCODE) + printf("(%s)", + icmpcodes[(int)fp->fr_icode]); + else + printf("(%d)", fp->fr_icode); + } + } else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) + printf(" return-rst"); + } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) { + printlog(fp); + } else if (FR_ISACCOUNT(fp->fr_flags)) + printf("count"); + else if (FR_ISAUTH(fp->fr_flags)) + printf("auth"); + else if (FR_ISPREAUTH(fp->fr_flags)) + printf("preauth"); + else if (FR_ISNOMATCH(fp->fr_flags)) + printf("nomatch"); + else if (FR_ISSKIP(fp->fr_flags)) + printf("skip %u", fp->fr_arg); + else { + printf("%x", fp->fr_flags); + } + + if (fp->fr_flags & FR_OUTQUE) + printf(" out "); + else + printf(" in "); + + if (((fp->fr_flags & FR_LOGB) == FR_LOGB) || + ((fp->fr_flags & FR_LOGP) == FR_LOGP)) { + printlog(fp); + putchar(' '); + } + + if (fp->fr_flags & FR_QUICK) + printf("quick "); + + if (*fp->fr_ifname) { + printifname("on ", fp->fr_ifname, fp->fr_ifa); + if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*")) + printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]); + putchar(' '); + } + + if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP)) + print_toif("dup-to", &fp->fr_dif); + if (*fp->fr_tif.fd_ifname) + print_toif("to", &fp->fr_tif); + if (*fp->fr_rif.fd_ifname) + print_toif("reply-to", &fp->fr_rif); + if (fp->fr_flags & FR_FASTROUTE) + printf("fastroute "); + + if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) || + (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) { + if (fp->fr_flags & FR_OUTQUE) + printf("in-via "); + else + printf("out-via "); + + if (*fp->fr_ifnames[2]) { + printifname("", fp->fr_ifnames[2], + fp->fr_ifas[2]); + putchar(' '); + + if (*fp->fr_ifnames[3]) { + printifname(",", fp->fr_ifnames[3], + fp->fr_ifas[3]); + } + } + } + + if (type == FR_T_IPF) { + if (fp->fr_mip.fi_tos) + printf("tos %#x ", fp->fr_tos); + if (fp->fr_mip.fi_ttl) + printf("ttl %d ", fp->fr_ttl); + if (fp->fr_flx & FI_TCPUDP) { + printf("proto tcp/udp "); + pr = -1; + } else if (fp->fr_mip.fi_p) { + pr = fp->fr_ip.fi_p; + if ((p = getprotobynumber(fp->fr_proto))) + printf("proto %s ", p->p_name); + else + printf("proto %d ", fp->fr_proto); + } + } + + if (type == FR_T_NONE) { + printf("all"); + } else if (type == FR_T_IPF) { + printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : ""); + printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname, + &fp->fr_src.s_addr, &fp->fr_smsk.s_addr); + if (fp->fr_scmp) + printportcmp(pr, &fp->fr_tuc.ftu_src); + + printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : ""); + printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname, + &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr); + if (fp->fr_dcmp) + printportcmp(pr, &fp->fr_tuc.ftu_dst); + + if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) { + int type = fp->fr_icmp, code; + + type = ntohs(fp->fr_icmp); + code = type & 0xff; + type /= 256; + if (type < (sizeof(icmptypes) / sizeof(char *) - 1) && + icmptypes[type]) + printf(" icmp-type %s", icmptypes[type]); + else + printf(" icmp-type %d", type); + if (ntohs(fp->fr_icmpm) & 0xff) + printf(" code %d", code); + } + if ((fp->fr_proto == IPPROTO_TCP) && + (fp->fr_tcpf || fp->fr_tcpfm)) { + printf(" flags "); + if (fp->fr_tcpf & ~TCPF_ALL) + printf("0x%x", fp->fr_tcpf); + else + for (s = flagset, t = flags; *s; s++, t++) + if (fp->fr_tcpf & *t) + (void)putchar(*s); + if (fp->fr_tcpfm) { + (void)putchar('/'); + if (fp->fr_tcpfm & ~TCPF_ALL) + printf("0x%x", fp->fr_tcpfm); + else + for (s = flagset, t = flags; *s; + s++, t++) + if (fp->fr_tcpfm & *t) + (void)putchar(*s); + } + } + } else if (type == FR_T_BPFOPC) { + fakebpf_t *fb; + int i; + + printf("bpf-v%d { \"", fp->fr_v); + i = fp->fr_dsize / sizeof(*fb); + + for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ") + printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t, + fb->fb_f, fb->fb_k); + + printf("\" }"); + } else if (type == FR_T_COMPIPF) { + ; + } else if (type == FR_T_CALLFUNC) { + printf("call function at %p", fp->fr_data); + } else { + printf("[unknown filter type %#x]", fp->fr_type); + } + + if ((type == FR_T_IPF) && + ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) || + fp->fr_optbits || fp->fr_optmask || + fp->fr_secbits || fp->fr_secmask)) { + char *comma = " "; + + printf(" with"); + if (fp->fr_optbits || fp->fr_optmask || + fp->fr_secbits || fp->fr_secmask) { + sec[0] = fp->fr_secmask; + sec[1] = fp->fr_secbits; + if (fp->fr_v == 4) + optprint(sec, fp->fr_optmask, fp->fr_optbits); +#ifdef USE_INET6 + else + optprintv6(sec, fp->fr_optmask, + fp->fr_optbits); +#endif + } else if (fp->fr_mflx & FI_OPTIONS) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_OPTIONS)) + printf("not "); + printf("ipopts"); + comma = ","; + } + if (fp->fr_mflx & FI_SHORT) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_SHORT)) + printf("not "); + printf("short"); + comma = ","; + } + if (fp->fr_mflx & FI_FRAG) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_FRAG)) + printf("not "); + printf("frag"); + comma = ","; + } + if (fp->fr_mflx & FI_FRAGBODY) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_FRAGBODY)) + printf("not "); + printf("frag-body"); + comma = ","; + } + if (fp->fr_mflx & FI_NATED) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_NATED)) + printf("not "); + printf("nat"); + comma = ","; + } + if (fp->fr_mflx & FI_LOWTTL) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_LOWTTL)) + printf("not "); + printf("lowttl"); + comma = ","; + } + if (fp->fr_mflx & FI_BAD) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_BAD)) + printf("not "); + printf("bad"); + comma = ","; + } + if (fp->fr_mflx & FI_BADSRC) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_BADSRC)) + printf("not "); + printf("bad-src"); + comma = ","; + } + if (fp->fr_mflx & FI_BADNAT) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_BADNAT)) + printf("not "); + printf("bad-nat"); + comma = ","; + } + if (fp->fr_mflx & FI_OOW) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_OOW)) + printf("not "); + printf("oow"); + } + } + + if (fp->fr_flags & FR_KEEPSTATE) { + printf(" keep state"); + if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|FR_NOICMPERR|FR_STATESYNC)) || + (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) { + char *comma = ""; + printf(" ("); + if (fp->fr_statemax != 0) { + printf("limit %u", fp->fr_statemax); + comma = ","; + } + if (fp->fr_flags & FR_STSTRICT) { + printf("%sstrict", comma); + comma = ","; + } + if (fp->fr_flags & FR_NEWISN) { + printf("%snewisn", comma); + comma = ","; + } + if (fp->fr_flags & FR_NOICMPERR) { + printf("%sno-icmp-err", comma); + comma = ","; + } + if (fp->fr_flags & FR_STATESYNC) { + printf("%ssync", comma); + comma = ","; + } + if (fp->fr_age[0] || fp->fr_age[1]) + printf("%sage %d/%d", comma, fp->fr_age[0], + fp->fr_age[1]); + printf(")"); + } + } + if (fp->fr_flags & FR_KEEPFRAG) { + printf(" keep frags"); + if (fp->fr_flags & (FR_FRSTRICT)) { + printf(" ("); + if (fp->fr_flags & FR_FRSTRICT) + printf(" strict"); + printf(" )"); + + } + } + if (fp->fr_isc != (struct ipscan *)-1) { + if (fp->fr_isctag[0]) + printf(" scan %s", fp->fr_isctag); + else + printf(" scan *"); + } + if (*fp->fr_grhead != '\0') + printf(" head %s", fp->fr_grhead); + if (*fp->fr_group != '\0') + printf(" group %s", fp->fr_group); + if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) { + char *s = ""; + + printf(" set-tag("); + if (fp->fr_logtag != FR_NOLOGTAG) { + printf("log=%u", fp->fr_logtag); + s = ", "; + } + if (*fp->fr_nattag.ipt_tag) { + printf("%snat=%-.*s", s, IPFTAG_LEN, + fp->fr_nattag.ipt_tag); + } + printf(")"); + } + if (fp->fr_pps) + printf(" pps %d", fp->fr_pps); + (void)putchar('\n'); +} diff --git a/contrib/ipfilter/lib/printfraginfo.c b/contrib/ipfilter/lib/printfraginfo.c new file mode 100644 index 0000000..b521c83 --- /dev/null +++ b/contrib/ipfilter/lib/printfraginfo.c @@ -0,0 +1,29 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2004 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printfraginfo.c,v 1.1.2.2 2004/03/23 15:15:45 darrenr Exp + */ +#include "ipf.h" +#include "kmem.h" + +void printfraginfo(prefix, ifr) +char *prefix; +struct ipfr *ifr; +{ + frentry_t fr; + + fr.fr_flags = 0xffffffff; + + printf("%s%s -> ", prefix, hostname(4, &ifr->ipfr_src)); + if (kmemcpy((char *)&fr, (u_long)ifr->ipfr_rule, + sizeof(fr)) == -1) + return; + printf("%s id %d ttl %d pr %d seen0 %d ifp %p tos %#02x = %#x\n", + hostname(4, &ifr->ipfr_dst), ifr->ipfr_id, ifr->ipfr_seen0, + ifr->ipfr_ttl, ifr->ipfr_p, ifr->ipfr_ifp, ifr->ipfr_tos, + fr.fr_flags); +} diff --git a/contrib/ipfilter/lib/printhash.c b/contrib/ipfilter/lib/printhash.c new file mode 100644 index 0000000..80157bb --- /dev/null +++ b/contrib/ipfilter/lib/printhash.c @@ -0,0 +1,144 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + + +iphtable_t *printhash(hp, copyfunc, name, opts) +iphtable_t *hp; +copyfunc_t copyfunc; +char *name; +int opts; +{ + iphtent_t *ipep, **table; + iphtable_t iph; + int i, printed; + size_t sz; + + if ((*copyfunc)((char *)hp, (char *)&iph, sizeof(iph))) + return NULL; + + if ((name != NULL) && strncmp(name, iph.iph_name, FR_GROUPLEN)) + return iph.iph_next; + + if ((opts & OPT_DEBUG) == 0) { + if ((iph.iph_type & IPHASH_ANON) == IPHASH_ANON) + PRINTF("# 'anonymous' table\n"); + switch (iph.iph_type & ~IPHASH_ANON) + { + case IPHASH_LOOKUP : + PRINTF("table"); + break; + case IPHASH_GROUPMAP : + PRINTF("group-map"); + if (iph.iph_flags & FR_INQUE) + PRINTF(" in"); + else if (iph.iph_flags & FR_OUTQUE) + PRINTF(" out"); + else + PRINTF(" ???"); + break; + default : + PRINTF("%#x", iph.iph_type); + break; + } + PRINTF(" role = "); + } else { + PRINTF("Hash Table Number: %s", iph.iph_name); + if ((iph.iph_type & IPHASH_ANON) == IPHASH_ANON) + PRINTF("(anon)"); + putchar(' '); + PRINTF("Role: "); + } + + switch (iph.iph_unit) + { + case IPL_LOGNAT : + PRINTF("nat"); + break; + case IPL_LOGIPF : + PRINTF("ipf"); + break; + case IPL_LOGAUTH : + PRINTF("auth"); + break; + case IPL_LOGCOUNT : + PRINTF("count"); + break; + default : + PRINTF("#%d", iph.iph_unit); + break; + } + + if ((opts & OPT_DEBUG) == 0) { + if ((iph.iph_type & ~IPHASH_ANON) == IPHASH_LOOKUP) + PRINTF(" type = hash"); + PRINTF(" number = %s size = %lu", + iph.iph_name, (u_long)iph.iph_size); + if (iph.iph_seed != 0) + PRINTF(" seed = %lu", iph.iph_seed); + putchar('\n'); + } else { + PRINTF(" Type: "); + switch (iph.iph_type & ~IPHASH_ANON) + { + case IPHASH_LOOKUP : + PRINTF("lookup"); + break; + case IPHASH_GROUPMAP : + PRINTF("groupmap Group. %s", iph.iph_name); + break; + default : + break; + } + + putchar('\n'); + PRINTF("\t\tSize: %lu\tSeed: %lu", + (u_long)iph.iph_size, iph.iph_seed); + PRINTF("\tRef. Count: %d\tMasks: %#x\n", iph.iph_ref, + iph.iph_masks); + } + + if ((opts & OPT_DEBUG) != 0) { + struct in_addr m; + + for (i = 0; i < 32; i++) { + if ((1 << i) & iph.iph_masks) { + ntomask(4, i, &m.s_addr); + PRINTF("\t\tMask: %s\n", inet_ntoa(m)); + } + } + } + + if ((opts & OPT_DEBUG) == 0) + PRINTF("\t{"); + + sz = iph.iph_size * sizeof(*table); + table = malloc(sz); + if ((*copyfunc)((char *)iph.iph_table, (char *)table, sz)) + return NULL; + + for (i = 0, printed = 0; i < iph.iph_size; i++) { + for (ipep = table[i]; ipep != NULL; ) { + ipep = printhashnode(&iph, ipep, copyfunc, opts); + printed++; + } + } + if (printed == 0) + putchar(';'); + + free(table); + + if ((opts & OPT_DEBUG) == 0) + PRINTF(" };\n"); + + return iph.iph_next; +} diff --git a/contrib/ipfilter/lib/printhashnode.c b/contrib/ipfilter/lib/printhashnode.c new file mode 100644 index 0000000..39255e7 --- /dev/null +++ b/contrib/ipfilter/lib/printhashnode.c @@ -0,0 +1,52 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + +iphtent_t *printhashnode(iph, ipep, copyfunc, opts) +iphtable_t *iph; +iphtent_t *ipep; +copyfunc_t copyfunc; +int opts; +{ + iphtent_t ipe; + + if ((*copyfunc)(ipep, &ipe, sizeof(ipe))) + return NULL; + + ipe.ipe_addr.in4_addr = htonl(ipe.ipe_addr.in4_addr); + ipe.ipe_mask.in4_addr = htonl(ipe.ipe_mask.in4_addr); + + if ((opts & OPT_DEBUG) != 0) { + PRINTF("\tAddress: %s", + inet_ntoa(ipe.ipe_addr.in4)); + printmask((u_32_t *)&ipe.ipe_mask.in4_addr); + PRINTF("\tRef. Count: %d\tGroup: %s\n", ipe.ipe_ref, + ipe.ipe_group); + } else { + putchar(' '); + printip((u_32_t *)&ipe.ipe_addr.in4_addr); + printmask((u_32_t *)&ipe.ipe_mask.in4_addr); + if (ipe.ipe_value != 0) { + switch (iph->iph_type & ~IPHASH_ANON) + { + case IPHASH_GROUPMAP : + if (strncmp(ipe.ipe_group, iph->iph_name, + FR_GROUPLEN)) + PRINTF(", group = %s", ipe.ipe_group); + break; + } + } + putchar(';'); + } + ipep = ipe.ipe_next; + return ipep; +} diff --git a/contrib/ipfilter/lib/printhostmap.c b/contrib/ipfilter/lib/printhostmap.c new file mode 100644 index 0000000..bdb6702 --- /dev/null +++ b/contrib/ipfilter/lib/printhostmap.c @@ -0,0 +1,13 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +void printhostmap(hmp, hv) +hostmap_t *hmp; +u_int hv; +{ + printf("%s,", inet_ntoa(hmp->hm_srcip)); + printf("%s -> ", inet_ntoa(hmp->hm_dstip)); + printf("%s ", inet_ntoa(hmp->hm_mapip)); + printf("(use = %d hv = %u)\n", hmp->hm_ref, hv); +} diff --git a/contrib/ipfilter/lib/printhostmask.c b/contrib/ipfilter/lib/printhostmask.c new file mode 100644 index 0000000..c34bc43 --- /dev/null +++ b/contrib/ipfilter/lib/printhostmask.c @@ -0,0 +1,46 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printhostmask.c,v 1.8 2002/04/11 15:01:19 darrenr Exp + */ + +#include "ipf.h" + + +void printhostmask(v, addr, mask) +int v; +u_32_t *addr, *mask; +{ +#ifdef USE_INET6 + char ipbuf[64]; +#else + struct in_addr ipa; +#endif + + if (!*addr && !*mask) + printf("any"); + else { +#ifdef USE_INET6 + void *ptr = addr; + int af; + + if (v == 4) { + ptr = addr; + af = AF_INET; + } else if (v == 6) { + ptr = addr; + af = AF_INET6; + } else + af = 0; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof(ipbuf))); +#else + ipa.s_addr = *addr; + printf("%s", inet_ntoa(ipa)); +#endif + printmask(mask); + } +} diff --git a/contrib/ipfilter/lib/printifname.c b/contrib/ipfilter/lib/printifname.c new file mode 100644 index 0000000..53a7fd7 --- /dev/null +++ b/contrib/ipfilter/lib/printifname.c @@ -0,0 +1,20 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printifname.c,v 1.2 2002/01/28 06:50:47 darrenr Exp + */ + +#include "ipf.h" + +void printifname(format, name, ifp) +char *format, *name; +void *ifp; +{ + printf("%s%s", format, name); + if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*")) + printf("(!)"); +} diff --git a/contrib/ipfilter/lib/printip.c b/contrib/ipfilter/lib/printip.c new file mode 100644 index 0000000..1a04f1d --- /dev/null +++ b/contrib/ipfilter/lib/printip.c @@ -0,0 +1,24 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printip.c,v 1.3 2002/07/13 12:10:27 darrenr Exp + */ + +#include "ipf.h" + + +void printip(addr) +u_32_t *addr; +{ + struct in_addr ipa; + + ipa.s_addr = *addr; + if (ntohl(ipa.s_addr) < 256) + printf("%lu", (u_long)ntohl(ipa.s_addr)); + else + printf("%s", inet_ntoa(ipa)); +} diff --git a/contrib/ipfilter/lib/printlog.c b/contrib/ipfilter/lib/printlog.c new file mode 100644 index 0000000..d14add4 --- /dev/null +++ b/contrib/ipfilter/lib/printlog.c @@ -0,0 +1,44 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printlog.c,v 1.6 2002/01/28 06:50:47 darrenr Exp + */ + +#include "ipf.h" + +#include <syslog.h> + + +void printlog(fp) +frentry_t *fp; +{ + char *s, *u; + + printf("log"); + if (fp->fr_flags & FR_LOGBODY) + printf(" body"); + if (fp->fr_flags & FR_LOGFIRST) + printf(" first"); + if (fp->fr_flags & FR_LOGORBLOCK) + printf(" or-block"); + if (fp->fr_loglevel != 0xffff) { + printf(" level "); + if (fp->fr_loglevel & LOG_FACMASK) { + s = fac_toname(fp->fr_loglevel); + if (s == NULL) + s = "!!!"; + } else + s = ""; + u = pri_toname(fp->fr_loglevel); + if (u == NULL) + u = "!!!"; + if (*s) + printf("%s.%s", s, u); + else + printf("%s", u); + } +} diff --git a/contrib/ipfilter/lib/printmask.c b/contrib/ipfilter/lib/printmask.c new file mode 100644 index 0000000..d3d9a6f --- /dev/null +++ b/contrib/ipfilter/lib/printmask.c @@ -0,0 +1,30 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printmask.c,v 1.5 2002/06/15 04:48:33 darrenr Exp + */ + +#include "ipf.h" + + +void printmask(mask) +u_32_t *mask; +{ + struct in_addr ipa; + int ones; + +#ifdef USE_INET6 + if (use_inet6) + printf("/%d", count6bits(mask)); + else +#endif + if ((ones = count4bits(*mask)) == -1) { + ipa.s_addr = *mask; + printf("/%s", inet_ntoa(ipa)); + } else + printf("/%d", ones); +} diff --git a/contrib/ipfilter/lib/printnat.c b/contrib/ipfilter/lib/printnat.c new file mode 100644 index 0000000..15a6886 --- /dev/null +++ b/contrib/ipfilter/lib/printnat.c @@ -0,0 +1,247 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" +#include "kmem.h" + + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: printnat.c,v 1.22.2.8 2005/01/12 03:39:04 darrenr Exp"; +#endif + +static void printproto __P((ipnat_t *, struct protoent *)); + +/* + * Print out a NAT rule + */ +void printnat(np, opts) +ipnat_t *np; +int opts; +{ + struct protoent *pr; + int bits; + + pr = getprotobynumber(np->in_p); + + switch (np->in_redir) + { + case NAT_REDIRECT : + printf("rdr"); + break; + case NAT_MAP : + printf("map"); + break; + case NAT_MAPBLK : + printf("map-block"); + break; + case NAT_BIMAP : + printf("bimap"); + break; + default : + fprintf(stderr, "unknown value for in_redir: %#x\n", + np->in_redir); + break; + } + + printf(" %s", np->in_ifnames[0]); + if ((np->in_ifnames[1][0] != '\0') && + (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) { + printf(",%s ", np->in_ifnames[1]); + } + putchar(' '); + + if (np->in_flags & IPN_FILTER) { + if (np->in_flags & IPN_NOTSRC) + printf("! "); + printf("from "); + if (np->in_redir == NAT_REDIRECT) { + printhostmask(4, (u_32_t *)&np->in_srcip, + (u_32_t *)&np->in_srcmsk); + } else { + printhostmask(4, (u_32_t *)&np->in_inip, + (u_32_t *)&np->in_inmsk); + } + if (np->in_scmp) + printportcmp(np->in_p, &np->in_tuc.ftu_src); + + if (np->in_flags & IPN_NOTDST) + printf(" !"); + printf(" to "); + if (np->in_redir == NAT_REDIRECT) { + printhostmask(4, (u_32_t *)&np->in_outip, + (u_32_t *)&np->in_outmsk); + } else { + printhostmask(4, (u_32_t *)&np->in_srcip, + (u_32_t *)&np->in_srcmsk); + } + if (np->in_dcmp) + printportcmp(np->in_p, &np->in_tuc.ftu_dst); + } + + if (np->in_redir == NAT_REDIRECT) { + if (!(np->in_flags & IPN_FILTER)) { + printf("%s", inet_ntoa(np->in_out[0].in4)); + bits = count4bits(np->in_outmsk); + if (bits != -1) + printf("/%d", bits); + else + printf("/%s", inet_ntoa(np->in_out[1].in4)); + if (np->in_flags & IPN_TCPUDP) { + printf(" port %d", ntohs(np->in_pmin)); + if (np->in_pmax != np->in_pmin) + printf("-%d", ntohs(np->in_pmax)); + } + } + printf(" -> %s", inet_ntoa(np->in_in[0].in4)); + if (np->in_flags & IPN_SPLIT) + printf(",%s", inet_ntoa(np->in_in[1].in4)); + if (np->in_flags & IPN_TCPUDP) { + if ((np->in_flags & IPN_FIXEDDPORT) != 0) + printf(" port = %d", ntohs(np->in_pnext)); + else + printf(" port %d", ntohs(np->in_pnext)); + } + printproto(np, pr); + if (np->in_flags & IPN_ROUNDR) + printf(" round-robin"); + if (np->in_flags & IPN_FRAG) + printf(" frag"); + if (np->in_age[0] != 0 || np->in_age[1] != 0) { + printf(" age %d/%d", np->in_age[0], np->in_age[1]); + } + if (np->in_flags & IPN_STICKY) + printf(" sticky"); + if (np->in_mssclamp != 0) + printf(" mssclamp %d", np->in_mssclamp); + if (*np->in_plabel != '\0') + printf(" proxy %.*s", (int)sizeof(np->in_plabel), + np->in_plabel); + if (np->in_tag.ipt_tag[0] != '\0') + printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); + printf("\n"); + if (opts & OPT_DEBUG) + printf("\tpmax %u\n", np->in_pmax); + } else { + if (!(np->in_flags & IPN_FILTER)) { + printf("%s/", inet_ntoa(np->in_in[0].in4)); + bits = count4bits(np->in_inmsk); + if (bits != -1) + printf("%d", bits); + else + printf("%s", inet_ntoa(np->in_in[1].in4)); + } + printf(" -> "); + if (np->in_flags & IPN_IPRANGE) { + printf("range %s-", inet_ntoa(np->in_out[0].in4)); + printf("%s", inet_ntoa(np->in_out[1].in4)); + } else { + printf("%s/", inet_ntoa(np->in_out[0].in4)); + bits = count4bits(np->in_outmsk); + if (bits != -1) + printf("%d", bits); + else + printf("%s", inet_ntoa(np->in_out[1].in4)); + } + if (*np->in_plabel != '\0') { + printf(" proxy port "); + if (np->in_dcmp != 0) + np->in_dport = htons(np->in_dport); + if (np->in_dport != 0) { + char *s; + + s = portname(np->in_p, ntohs(np->in_dport)); + if (s != NULL) + fputs(s, stdout); + else + fputs("???", stdout); + } + printf(" %.*s/", (int)sizeof(np->in_plabel), + np->in_plabel); + if (pr != NULL) + fputs(pr->p_name, stdout); + else + printf("%d", np->in_p); + } else if (np->in_redir == NAT_MAPBLK) { + if ((np->in_pmin == 0) && + (np->in_flags & IPN_AUTOPORTMAP)) + printf(" ports auto"); + else + printf(" ports %d", np->in_pmin); + if (opts & OPT_DEBUG) + printf("\n\tip modulous %d", np->in_pmax); + } else if (np->in_pmin || np->in_pmax) { + if (np->in_flags & IPN_ICMPQUERY) { + printf(" icmpidmap"); + } else { + printf(" portmap"); + } + printproto(np, pr); + if (np->in_flags & IPN_AUTOPORTMAP) { + printf(" auto"); + if (opts & OPT_DEBUG) + printf(" [%d:%d %d %d]", + ntohs(np->in_pmin), + ntohs(np->in_pmax), + np->in_ippip, np->in_ppip); + } else { + printf(" %d:%d", ntohs(np->in_pmin), + ntohs(np->in_pmax)); + } + } else if (np->in_flags & IPN_TCPUDP || np->in_p) + printproto(np, pr); + + if (np->in_flags & IPN_FRAG) + printf(" frag"); + if (np->in_age[0] != 0 || np->in_age[1] != 0) { + printf(" age %d/%d", np->in_age[0], np->in_age[1]); + } + if (np->in_mssclamp != 0) + printf(" mssclamp %d", np->in_mssclamp); + if (np->in_tag.ipt_tag[0] != '\0') + printf(" tag %s", np->in_tag.ipt_tag); + printf("\n"); + if (opts & OPT_DEBUG) { + struct in_addr nip; + + nip.s_addr = htonl(np->in_nextip.s_addr); + + printf("\tnextip %s pnext %d\n", + inet_ntoa(nip), np->in_pnext); + } + } + + if (opts & OPT_DEBUG) { + printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n", + np->in_space, np->in_use, np->in_hits, + np->in_flags, np->in_p, np->in_hv); + printf("\tifp[0] %p ifp[1] %p apr %p\n", + np->in_ifps[0], np->in_ifps[1], np->in_apr); + printf("\ttqehead %p/%p comment %p\n", + np->in_tqehead[0], np->in_tqehead[1], np->in_comment); + } +} + +static void printproto(np, pr) +ipnat_t *np; +struct protoent *pr; +{ + if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) + printf(" tcp/udp"); + else if (np->in_flags & IPN_TCP) + printf(" tcp"); + else if (np->in_flags & IPN_UDP) + printf(" udp"); + else if (np->in_flags & IPN_ICMPQUERY) + printf(" icmp"); + else if (pr != NULL) + printf(" %s", pr->p_name); + else + printf(" %d", np->in_p); +} diff --git a/contrib/ipfilter/lib/printpacket.c b/contrib/ipfilter/lib/printpacket.c new file mode 100644 index 0000000..58460be --- /dev/null +++ b/contrib/ipfilter/lib/printpacket.c @@ -0,0 +1,89 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printpacket.c,v 1.12.4.1 2005/02/21 05:09:24 darrenr Exp + */ + +#include "ipf.h" + +#ifndef IP_OFFMASK +# define IP_OFFMASK 0x3fff +#endif + + +void printpacket(ip) +struct ip *ip; +{ + struct tcphdr *tcp; + u_short len; + u_short off; + + if (IP_V(ip) == 6) { + off = 0; + len = ntohs(((u_short *)ip)[2]) + 40; + } else { + off = ntohs(ip->ip_off); + len = ntohs(ip->ip_len); + } + + if ((opts & OPT_HEX) == OPT_HEX) { + u_char *s; + int i; + + for (s = (u_char *)ip, i = 0; i < len; i++) { + printf("%02x", *s++ & 0xff); + if (len - i > 1) { + i++; + printf("%02x", *s++ & 0xff); + } + putchar(' '); + } + putchar('\n'); + return; + } + + if (IP_V(ip) == 6) { + printpacket6(ip); + return; + } + + tcp = (struct tcphdr *)((char *)ip + (IP_HL(ip) << 2)); + printf("ip %d(%d) %d", ntohs(ip->ip_len), IP_HL(ip) << 2, ip->ip_p); + if (off & IP_OFFMASK) + printf(" @%d", off << 3); + printf(" %s", inet_ntoa(ip->ip_src)); + if (!(off & IP_OFFMASK)) + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) + printf(",%d", ntohs(tcp->th_sport)); + printf(" > "); + printf("%s", inet_ntoa(ip->ip_dst)); + if (!(off & IP_OFFMASK)) { + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) + printf(",%d", ntohs(tcp->th_dport)); + if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) { + putchar(' '); + if (tcp->th_flags & TH_FIN) + putchar('F'); + if (tcp->th_flags & TH_SYN) + putchar('S'); + if (tcp->th_flags & TH_RST) + putchar('R'); + if (tcp->th_flags & TH_PUSH) + putchar('P'); + if (tcp->th_flags & TH_ACK) + putchar('A'); + if (tcp->th_flags & TH_URG) + putchar('U'); + if (tcp->th_flags & TH_ECN) + putchar('E'); + if (tcp->th_flags & TH_CWR) + putchar('C'); + } + } + + putchar('\n'); +} diff --git a/contrib/ipfilter/lib/printpacket6.c b/contrib/ipfilter/lib/printpacket6.c new file mode 100644 index 0000000..2f9ea1d --- /dev/null +++ b/contrib/ipfilter/lib/printpacket6.c @@ -0,0 +1,43 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +/* + * This is meant to work without the IPv6 header files being present or + * the inet_ntop() library. + */ +void printpacket6(ip) +struct ip *ip; +{ + u_char *buf, p; + u_short plen, *addrs; + tcphdr_t *tcp; + u_32_t flow; + + buf = (u_char *)ip; + tcp = (tcphdr_t *)(buf + 40); + p = buf[6]; + flow = ntohl(*(u_32_t *)buf); + flow &= 0xfffff; + plen = ntohs(*((u_short *)buf +2)); + addrs = (u_short *)buf + 4; + + printf("ip6/%d %d %#x %d", buf[0] & 0xf, plen, flow, p); + printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), + ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), + ntohs(addrs[6]), ntohs(addrs[7])); + if (plen >= 4) + if (p == IPPROTO_TCP || p == IPPROTO_UDP) + (void)printf(",%d", ntohs(tcp->th_sport)); + printf(" >"); + addrs += 8; + printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), + ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), + ntohs(addrs[6]), ntohs(addrs[7])); + if (plen >= 4) + if (p == IPPROTO_TCP || p == IPPROTO_UDP) + (void)printf(",%d", ntohs(tcp->th_dport)); + putchar('\n'); +} diff --git a/contrib/ipfilter/lib/printpool.c b/contrib/ipfilter/lib/printpool.c new file mode 100644 index 0000000..6291306 --- /dev/null +++ b/contrib/ipfilter/lib/printpool.c @@ -0,0 +1,108 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + +ip_pool_t *printpool(pp, copyfunc, name, opts) +ip_pool_t *pp; +copyfunc_t copyfunc; +char *name; +int opts; +{ + ip_pool_node_t *ipnp, *ipnpn, ipn; + ip_pool_t ipp; + + if ((*copyfunc)(pp, &ipp, sizeof(ipp))) + return NULL; + + if ((name != NULL) && strncmp(name, ipp.ipo_name, FR_GROUPLEN)) + return ipp.ipo_next; + + if ((opts & OPT_DEBUG) == 0) { + if ((ipp.ipo_flags & IPOOL_ANON) != 0) + PRINTF("# 'anonymous' tree %s\n", ipp.ipo_name); + PRINTF("table role = "); + } else { + PRINTF("Name: %s", ipp.ipo_name); + if ((ipp.ipo_flags & IPOOL_ANON) == IPOOL_ANON) + PRINTF("(anon)"); + putchar(' '); + PRINTF("Role: "); + } + + switch (ipp.ipo_unit) + { + case IPL_LOGIPF : + printf("ipf"); + break; + case IPL_LOGNAT : + printf("nat"); + break; + case IPL_LOGSTATE : + printf("state"); + break; + case IPL_LOGAUTH : + printf("auth"); + break; + case IPL_LOGSYNC : + printf("sync"); + break; + case IPL_LOGSCAN : + printf("scan"); + break; + case IPL_LOGLOOKUP : + printf("lookup"); + break; + case IPL_LOGCOUNT : + printf("count"); + break; + default : + printf("unknown(%d)", ipp.ipo_unit); + } + + if ((opts & OPT_DEBUG) == 0) { + PRINTF(" type = tree number = %s\n", ipp.ipo_name); + PRINTF("\t{"); + } else { + putchar(' '); + + PRINTF("\tReferences: %d\tHits: %lu\n", ipp.ipo_ref, + ipp.ipo_hits); + PRINTF("\tNodes Starting at %p\n", ipp.ipo_list); + } + + ipnpn = ipp.ipo_list; + ipp.ipo_list = NULL; + while (ipnpn != NULL) { + ipnp = (ip_pool_node_t *)malloc(sizeof(*ipnp)); + (*copyfunc)(ipnpn, ipnp, sizeof(ipn)); + ipnpn = ipnp->ipn_next; + ipnp->ipn_next = ipp.ipo_list; + ipp.ipo_list = ipnp; + } + + if (ipp.ipo_list == NULL) { + putchar(';'); + } else { + for (ipnp = ipp.ipo_list; ipnp != NULL; ) { + ipnp = printpoolnode(ipnp, opts); + + if ((opts & OPT_DEBUG) == 0) { + putchar(';'); + } + } + } + + if ((opts & OPT_DEBUG) == 0) + PRINTF(" };\n"); + + return ipp.ipo_next; +} diff --git a/contrib/ipfilter/lib/printpoolnode.c b/contrib/ipfilter/lib/printpoolnode.c new file mode 100644 index 0000000..dd0ef97 --- /dev/null +++ b/contrib/ipfilter/lib/printpoolnode.c @@ -0,0 +1,33 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + +ip_pool_node_t *printpoolnode(np, opts) +ip_pool_node_t *np; +int opts; +{ + + if ((opts & OPT_DEBUG) == 0) { + putchar(' '); + if (np->ipn_info == 1) + PRINTF("! "); + printip((u_32_t *)&np->ipn_addr.adf_addr.in4); + printmask((u_32_t *)&np->ipn_mask.adf_addr); + } else { + PRINTF("\t\t%s%s", np->ipn_info ? "! " : "", + inet_ntoa(np->ipn_addr.adf_addr.in4)); + printmask((u_32_t *)&np->ipn_mask.adf_addr); + PRINTF("\n\t\tHits %lu\tName %s\n", + np->ipn_hits, np->ipn_name); + } + return np->ipn_next; +} diff --git a/contrib/ipfilter/lib/printportcmp.c b/contrib/ipfilter/lib/printportcmp.c new file mode 100644 index 0000000..7ec0116 --- /dev/null +++ b/contrib/ipfilter/lib/printportcmp.c @@ -0,0 +1,29 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printportcmp.c,v 1.7 2003/02/16 02:31:05 darrenr Exp + */ + +#include "ipf.h" + + +void printportcmp(pr, frp) +int pr; +frpcmp_t *frp; +{ + static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=", + "<>", "><", ":" }; + + if (frp->frp_cmp == FR_INRANGE || frp->frp_cmp == FR_OUTRANGE) + printf(" port %d %s %d", frp->frp_port, + pcmp1[frp->frp_cmp], frp->frp_top); + else if (frp->frp_cmp == FR_INCRANGE) + printf(" port %d:%d", frp->frp_port, frp->frp_top); + else + printf(" port %s %s", pcmp1[frp->frp_cmp], + portname(pr, frp->frp_port)); +} diff --git a/contrib/ipfilter/lib/printsbuf.c b/contrib/ipfilter/lib/printsbuf.c new file mode 100644 index 0000000..805c03b --- /dev/null +++ b/contrib/ipfilter/lib/printsbuf.c @@ -0,0 +1,24 @@ +/* $NetBSD$ */ + +#ifdef IPFILTER_SCAN + +#include <ctype.h> +#include <stdio.h> +#include "ipf.h" +#include "netinet/ip_scan.h" + +void printsbuf(buf) +char *buf; +{ + u_char *s; + int i; + + for (s = (u_char *)buf, i = ISC_TLEN; i; i--, s++) { + if (ISPRINT(*s)) + putchar(*s); + else + printf("\\%o", *s); + } +} + +#endif diff --git a/contrib/ipfilter/lib/printstate.c b/contrib/ipfilter/lib/printstate.c new file mode 100644 index 0000000..9cfdc8a --- /dev/null +++ b/contrib/ipfilter/lib/printstate.c @@ -0,0 +1,189 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" +#include "kmem.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + +ipstate_t *printstate(sp, opts, now) +ipstate_t *sp; +int opts; +u_long now; +{ + ipstate_t ips; + synclist_t ipsync; + + if (kmemcpy((char *)&ips, (u_long)sp, sizeof(ips))) + return NULL; + + PRINTF("%s -> ", hostname(ips.is_v, &ips.is_src.in4)); + PRINTF("%s pass %#x pr %d state %d/%d bkt %d\n", + hostname(ips.is_v, &ips.is_dst.in4), ips.is_pass, ips.is_p, + ips.is_state[0], ips.is_state[1], ips.is_hv); + PRINTF("\ttag %u ttl %lu", ips.is_tag, ips.is_die - now); + + if (ips.is_p == IPPROTO_TCP) { + PRINTF("\n\t%hu -> %hu %x:%x %hu<<%d:%hu<<%d\n", + ntohs(ips.is_sport), ntohs(ips.is_dport), + ips.is_send, ips.is_dend, + ips.is_maxswin, ips.is_swinscale, + ips.is_maxdwin, ips.is_dwinscale); + PRINTF("\tcmsk %04x smsk %04x isc %p s0 %08x/%08x\n", + ips.is_smsk[0], ips.is_smsk[1], ips.is_isc, + ips.is_s0[0], ips.is_s0[1]); + PRINTF("\tFWD:ISN inc %x sumd %x\n", + ips.is_isninc[0], ips.is_sumd[0]); + PRINTF("\tREV:ISN inc %x sumd %x\n", + ips.is_isninc[1], ips.is_sumd[1]); +#ifdef IPFILTER_SCAN + PRINTF("\tsbuf[0] ["); + printsbuf(ips.is_sbuf[0]); + PRINTF("] sbuf[1] ["); + printsbuf(ips.is_sbuf[1]); + PRINTF("]\n"); +#endif + } else if (ips.is_p == IPPROTO_UDP) { + PRINTF(" %hu -> %hu\n", ntohs(ips.is_sport), + ntohs(ips.is_dport)); + } else if (ips.is_p == IPPROTO_GRE) { + PRINTF(" call %hx/%hx\n", ntohs(ips.is_gre.gs_call[0]), + ntohs(ips.is_gre.gs_call[1])); + } else if (ips.is_p == IPPROTO_ICMP +#ifdef USE_INET6 + || ips.is_p == IPPROTO_ICMPV6 +#endif + ) + PRINTF(" id %hu seq %hu type %d\n", ips.is_icmp.ici_id, + ips.is_icmp.ici_seq, ips.is_icmp.ici_type); + +#ifdef USE_QUAD_T + PRINTF("\tforward: pkts in %qd bytes in %qd pkts out %qd bytes out %qd\n\tbackward: pkts in %qd bytes in %qd pkts out %qd bytes out %qd\n", + ips.is_pkts[0], ips.is_bytes[0], + ips.is_pkts[1], ips.is_bytes[1], + ips.is_pkts[2], ips.is_bytes[2], + ips.is_pkts[3], ips.is_bytes[3]); +#else + PRINTF("\tforward: pkts in %ld bytes in %ld pkts out %ld bytes out %ld\n\tbackward: pkts in %ld bytes in %ld pkts out %ld bytes out %ld\n", + ips.is_pkts[0], ips.is_bytes[0], + ips.is_pkts[1], ips.is_bytes[1], + ips.is_pkts[2], ips.is_bytes[2], + ips.is_pkts[3], ips.is_bytes[3]); +#endif + + PRINTF("\t"); + + /* + * Print out bits set in the result code for the state being + * kept as they would for a rule. + */ + if (FR_ISPASS(ips.is_pass)) { + PRINTF("pass"); + } else if (FR_ISBLOCK(ips.is_pass)) { + PRINTF("block"); + switch (ips.is_pass & FR_RETMASK) + { + case FR_RETICMP : + PRINTF(" return-icmp"); + break; + case FR_FAKEICMP : + PRINTF(" return-icmp-as-dest"); + break; + case FR_RETRST : + PRINTF(" return-rst"); + break; + default : + break; + } + } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) { + PRINTF("log"); + if (ips.is_pass & FR_LOGBODY) + PRINTF(" body"); + if (ips.is_pass & FR_LOGFIRST) + PRINTF(" first"); + } else if (FR_ISACCOUNT(ips.is_pass)) { + PRINTF("count"); + } else if (FR_ISPREAUTH(ips.is_pass)) { + PRINTF("preauth"); + } else if (FR_ISAUTH(ips.is_pass)) + PRINTF("auth"); + + if (ips.is_pass & FR_OUTQUE) + PRINTF(" out"); + else + PRINTF(" in"); + + if ((ips.is_pass & FR_LOG) != 0) { + PRINTF(" log"); + if (ips.is_pass & FR_LOGBODY) + PRINTF(" body"); + if (ips.is_pass & FR_LOGFIRST) + PRINTF(" first"); + if (ips.is_pass & FR_LOGORBLOCK) + PRINTF(" or-block"); + } + if (ips.is_pass & FR_QUICK) + PRINTF(" quick"); + if (ips.is_pass & FR_KEEPFRAG) + PRINTF(" keep frags"); + /* a given; no? */ + if (ips.is_pass & FR_KEEPSTATE) { + PRINTF(" keep state"); + if (ips.is_pass & FR_STATESYNC) + PRINTF(" ( sync )"); + } + PRINTF("\tIPv%d", ips.is_v); + PRINTF("\n"); + + PRINTF("\tpkt_flags & %x(%x) = %x,\t", + ips.is_flags & 0xf, ips.is_flags, + ips.is_flags >> 4); + PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk, + ips.is_opt); + PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n", + ips.is_secmsk, ips.is_sec, ips.is_authmsk, + ips.is_auth); + PRINTF("\tis_flx %#x %#x %#x %#x\n", ips.is_flx[0][0], ips.is_flx[0][1], + ips.is_flx[1][0], ips.is_flx[1][1]); + PRINTF("\tinterfaces: in %s[%s", getifname(ips.is_ifp[0]), + ips.is_ifname[0]); + if (opts & OPT_DEBUG) + PRINTF("/%p", ips.is_ifp[0]); + putchar(']'); + PRINTF(",%s[%s", getifname(ips.is_ifp[1]), ips.is_ifname[1]); + if (opts & OPT_DEBUG) + PRINTF("/%p", ips.is_ifp[1]); + putchar(']'); + PRINTF(" out %s[%s", getifname(ips.is_ifp[2]), ips.is_ifname[2]); + if (opts & OPT_DEBUG) + PRINTF("/%p", ips.is_ifp[2]); + putchar(']'); + PRINTF(",%s[%s", getifname(ips.is_ifp[3]), ips.is_ifname[3]); + if (opts & OPT_DEBUG) + PRINTF("/%p", ips.is_ifp[3]); + PRINTF("]\n"); + + if (ips.is_sync != NULL) { + + if (kmemcpy((char *)&ipsync, (u_long)ips.is_sync, sizeof(ipsync))) { + + PRINTF("\tSync status: status could not be retrieved\n"); + return NULL; + } + + PRINTF("\tSync status: idx %d num %d v %d pr %d rev %d\n", + ipsync.sl_idx, ipsync.sl_num, ipsync.sl_v, + ipsync.sl_p, ipsync.sl_rev); + + } else { + PRINTF("\tSync status: not synchronized\n"); + } + + return ips.is_next; +} diff --git a/contrib/ipfilter/lib/printtunable.c b/contrib/ipfilter/lib/printtunable.c new file mode 100644 index 0000000..46e9f80 --- /dev/null +++ b/contrib/ipfilter/lib/printtunable.c @@ -0,0 +1,21 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +void printtunable(tup) +ipftune_t *tup; +{ + printf("%s\tmin %#lx\tmax %#lx\tcurrent ", + tup->ipft_name, tup->ipft_min, tup->ipft_max); + if (tup->ipft_sz == sizeof(u_long)) + printf("%lu\n", tup->ipft_vlong); + else if (tup->ipft_sz == sizeof(u_int)) + printf("%u\n", tup->ipft_vint); + else if (tup->ipft_sz == sizeof(u_short)) + printf("%hu\n", tup->ipft_vshort); + else if (tup->ipft_sz == sizeof(u_char)) + printf("%u\n", (u_int)tup->ipft_vchar); + else { + printf("sz = %d\n", tup->ipft_sz); + } +} diff --git a/contrib/ipfilter/lib/ratoi.c b/contrib/ipfilter/lib/ratoi.c new file mode 100644 index 0000000..31ee122 --- /dev/null +++ b/contrib/ipfilter/lib/ratoi.c @@ -0,0 +1,26 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ratoi.c,v 1.4 2001/06/09 17:09:25 darrenr Exp + */ + +#include "ipf.h" + + +int ratoi(ps, pi, min, max) +char *ps; +int *pi, min, max; +{ + int i; + char *pe; + + i = (int)strtol(ps, &pe, 0); + if (*pe != '\0' || i < min || i > max) + return 0; + *pi = i; + return 1; +} diff --git a/contrib/ipfilter/lib/ratoui.c b/contrib/ipfilter/lib/ratoui.c new file mode 100644 index 0000000..e4d0cbf --- /dev/null +++ b/contrib/ipfilter/lib/ratoui.c @@ -0,0 +1,26 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ratoui.c,v 1.4 2001/06/09 17:09:25 darrenr Exp + */ + +#include "ipf.h" + + +int ratoui(ps, pi, min, max) +char *ps; +u_int *pi, min, max; +{ + u_int i; + char *pe; + + i = (u_int)strtol(ps, &pe, 0); + if (*pe != '\0' || i < min || i > max) + return 0; + *pi = i; + return 1; +} diff --git a/contrib/ipfilter/lib/remove_hash.c b/contrib/ipfilter/lib/remove_hash.c new file mode 100644 index 0000000..256751f --- /dev/null +++ b/contrib/ipfilter/lib/remove_hash.c @@ -0,0 +1,53 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: remove_hash.c,v 1.1 2003/04/13 06:40:14 darrenr Exp + */ + +#include <fcntl.h> +#include <sys/ioctl.h> +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int hashfd = -1; + + +int remove_hash(iphp, iocfunc) +iphtable_t *iphp; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + iphtable_t iph; + + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + hashfd = open(IPLOOKUP_NAME, O_RDWR); + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_type = IPLT_HASH; + op.iplo_unit = iphp->iph_unit; + strncpy(op.iplo_name, iphp->iph_name, sizeof(op.iplo_name)); + if (*op.iplo_name == '\0') + op.iplo_arg = IPHASH_ANON; + op.iplo_size = sizeof(iph); + op.iplo_struct = &iph; + + bzero((char *)&iph, sizeof(iph)); + iph.iph_unit = iphp->iph_unit; + iph.iph_type = iphp->iph_type; + strncpy(iph.iph_name, iphp->iph_name, sizeof(iph.iph_name)); + iph.iph_flags = iphp->iph_flags; + + if ((*iocfunc)(hashfd, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("remove_hash:SIOCLOOKUPDELTABLE"); + return -1; + } + + return 0; +} diff --git a/contrib/ipfilter/lib/remove_hashnode.c b/contrib/ipfilter/lib/remove_hashnode.c new file mode 100644 index 0000000..5e5b634 --- /dev/null +++ b/contrib/ipfilter/lib/remove_hashnode.c @@ -0,0 +1,58 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: remove_hashnode.c,v 1.1 2003/04/13 06:40:14 darrenr Exp + */ + +#include <fcntl.h> +#include <sys/ioctl.h> +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int hashfd = -1; + + +int remove_hashnode(unit, name, node, iocfunc) +int unit; +char *name; +iphtent_t *node; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + iphtent_t ipe; + + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + hashfd = open(IPLOOKUP_NAME, O_RDWR); + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_type = IPLT_HASH; + op.iplo_unit = unit; + op.iplo_size = sizeof(ipe); + op.iplo_struct = &ipe; + op.iplo_arg = 0; + strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + + bzero((char *)&ipe, sizeof(ipe)); + bcopy((char *)&node->ipe_addr, (char *)&ipe.ipe_addr, + sizeof(ipe.ipe_addr)); + bcopy((char *)&node->ipe_mask, (char *)&ipe.ipe_mask, + sizeof(ipe.ipe_mask)); + + if (opts & OPT_DEBUG) { + printf("\t%s - ", inet_ntoa(ipe.ipe_addr.in4)); + printf("%s\n", inet_ntoa(ipe.ipe_mask.in4)); + } + + if ((*iocfunc)(hashfd, SIOCLOOKUPDELNODE, &op)) + if (!(opts & OPT_DONOTHING)) { + perror("remove_hash:SIOCLOOKUPDELNODE"); + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/remove_pool.c b/contrib/ipfilter/lib/remove_pool.c new file mode 100644 index 0000000..3f5e004 --- /dev/null +++ b/contrib/ipfilter/lib/remove_pool.c @@ -0,0 +1,50 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: remove_pool.c,v 1.1 2003/04/13 06:40:14 darrenr Exp + */ + +#include <fcntl.h> +#include <sys/ioctl.h> +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int poolfd = -1; + + +int remove_pool(poolp, iocfunc) +ip_pool_t *poolp; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + ip_pool_t pool; + + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_type = IPLT_POOL; + op.iplo_unit = poolp->ipo_unit; + strncpy(op.iplo_name, poolp->ipo_name, sizeof(op.iplo_name)); + op.iplo_size = sizeof(pool); + op.iplo_struct = &pool; + + bzero((char *)&pool, sizeof(pool)); + pool.ipo_unit = poolp->ipo_unit; + strncpy(pool.ipo_name, poolp->ipo_name, sizeof(pool.ipo_name)); + pool.ipo_flags = poolp->ipo_flags; + + if ((*iocfunc)(poolfd, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("remove_pool:SIOCLOOKUPDELTABLE"); + return -1; + } + + return 0; +} diff --git a/contrib/ipfilter/lib/remove_poolnode.c b/contrib/ipfilter/lib/remove_poolnode.c new file mode 100644 index 0000000..aff4694 --- /dev/null +++ b/contrib/ipfilter/lib/remove_poolnode.c @@ -0,0 +1,57 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: remove_poolnode.c,v 1.3 2003/11/22 10:14:36 darrenr Exp + */ + +#include <fcntl.h> +#include <sys/ioctl.h> +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" + +static int poolfd = -1; + + +int remove_poolnode(unit, name, node, iocfunc) +int unit; +char *name; +ip_pool_node_t *node; +ioctlfunc_t iocfunc; +{ + ip_pool_node_t pn; + iplookupop_t op; + + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_unit = unit; + op.iplo_type = IPLT_POOL; + op.iplo_arg = 0; + strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + op.iplo_struct = &pn; + op.iplo_size = sizeof(pn); + + bzero((char *)&pn, sizeof(pn)); + bcopy((char *)&node->ipn_addr, (char *)&pn.ipn_addr, + sizeof(pn.ipn_addr)); + bcopy((char *)&node->ipn_mask, (char *)&pn.ipn_mask, + sizeof(pn.ipn_mask)); + pn.ipn_info = node->ipn_info; + strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name)); + + if ((*iocfunc)(poolfd, SIOCLOOKUPDELNODE, &op)) { + if ((opts & OPT_DONOTHING) == 0) { + perror("remove_pool:SIOCLOOKUPDELNODE"); + return -1; + } + } + + return 0; +} diff --git a/contrib/ipfilter/lib/resetlexer.c b/contrib/ipfilter/lib/resetlexer.c new file mode 100644 index 0000000..0801242 --- /dev/null +++ b/contrib/ipfilter/lib/resetlexer.c @@ -0,0 +1,17 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +long string_start = -1; +long string_end = -1; +char *string_val = NULL; +long pos = 0; + + +void resetlexer() +{ + string_start = -1; + string_end = -1; + string_val = NULL; + pos = 0; +} diff --git a/contrib/ipfilter/lib/rwlock_emul.c b/contrib/ipfilter/lib/rwlock_emul.c new file mode 100644 index 0000000..64b807e --- /dev/null +++ b/contrib/ipfilter/lib/rwlock_emul.c @@ -0,0 +1,125 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#define EMM_MAGIC 0x97dd8b3a + +void eMrwlock_read_enter(rw, file, line) +eMrwlock_t *rw; +char *file; +int line; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_read_enter(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + if (rw->eMrw_read != 0 || rw->eMrw_write != 0) { + fprintf(stderr, + "%s:eMrwlock_read_enter(%p): already locked: %d/%d\n", + rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); + abort(); + } + rw->eMrw_read++; + rw->eMrw_heldin = file; + rw->eMrw_heldat = line; +} + + +void eMrwlock_write_enter(rw, file, line) +eMrwlock_t *rw; +char *file; +int line; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + if (rw->eMrw_read != 0 || rw->eMrw_write != 0) { + fprintf(stderr, + "%s:eMrwlock_write_enter(%p): already locked: %d/%d\n", + rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); + abort(); + } + rw->eMrw_write++; + rw->eMrw_heldin = file; + rw->eMrw_heldat = line; +} + + +void eMrwlock_downgrade(rw, file, line) +eMrwlock_t *rw; +char *file; +int line; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + if (rw->eMrw_read != 0 || rw->eMrw_write != 1) { + fprintf(stderr, + "%s:eMrwlock_write_enter(%p): already locked: %d/%d\n", + rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); + abort(); + } + rw->eMrw_write--; + rw->eMrw_read++; + rw->eMrw_heldin = file; + rw->eMrw_heldat = line; +} + + +void eMrwlock_exit(rw) +eMrwlock_t *rw; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_exit(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + if (rw->eMrw_read != 1 && rw->eMrw_write != 1) { + fprintf(stderr, "%s:eMrwlock_exit(%p): not locked: %d/%d\n", + rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); + abort(); + } + if (rw->eMrw_read == 1) + rw->eMrw_read--; + else if (rw->eMrw_write == 1) + rw->eMrw_write--; + rw->eMrw_heldin = NULL; + rw->eMrw_heldat = 0; +} + + +void eMrwlock_init(rw, who) +eMrwlock_t *rw; +char *who; +{ + if (rw->eMrw_magic == EMM_MAGIC) { /* safe bet ? */ + fprintf(stderr, + "%s:eMrwlock_init(%p): already initialised?: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + rw->eMrw_magic = EMM_MAGIC; + rw->eMrw_read = 0; + rw->eMrw_write = 0; + if (who != NULL) + rw->eMrw_owner = strdup(who); + else + rw->eMrw_owner = NULL; +} + + +void eMrwlock_destroy(rw) +eMrwlock_t *rw; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_destroy(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + memset(rw, 0xa5, sizeof(*rw)); +} diff --git a/contrib/ipfilter/lib/tcp_flags.c b/contrib/ipfilter/lib/tcp_flags.c new file mode 100644 index 0000000..314b9d2 --- /dev/null +++ b/contrib/ipfilter/lib/tcp_flags.c @@ -0,0 +1,50 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: tcp_flags.c,v 1.8 2004/02/07 18:15:54 darrenr Exp + */ + +#include "ipf.h" + +extern char flagset[]; +extern u_char flags[]; + + +u_char tcp_flags(flgs, mask, linenum) +char *flgs; +u_char *mask; +int linenum; +{ + u_char tcpf = 0, tcpfm = 0; + char *s; + + s = strchr(flgs, '/'); + if (s) + *s++ = '\0'; + + if (*flgs == '0') { + tcpf = strtol(flgs, NULL, 0); + } else { + tcpf = tcpflags(flgs); + } + + if (s != NULL) { + if (*s == '0') + tcpfm = strtol(s, NULL, 0); + else + tcpfm = tcpflags(s); + } + + if (!tcpfm) { + if (tcpf == TH_SYN) + tcpfm = 0xff & ~(TH_ECN|TH_CWR); + else + tcpfm = 0xff & ~(TH_ECN); + } + *mask = tcpfm; + return tcpf; +} diff --git a/contrib/ipfilter/lib/tcpflags.c b/contrib/ipfilter/lib/tcpflags.c new file mode 100644 index 0000000..b7ea4b8 --- /dev/null +++ b/contrib/ipfilter/lib/tcpflags.c @@ -0,0 +1,45 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: tcpflags.c,v 1.3 2002/11/02 07:18:01 darrenr Exp + */ + +#include "ipf.h" + + +/* + * ECN is a new addition to TCP - RFC 2481 + */ +#ifndef TH_ECN +# define TH_ECN 0x40 +#endif +#ifndef TH_CWR +# define TH_CWR 0x80 +#endif + +extern char flagset[]; +extern u_char flags[]; + + +u_char tcpflags(flgs) +char *flgs; +{ + u_char tcpf = 0; + char *s, *t; + + for (s = flgs; *s; s++) { + if (*s == 'W') + tcpf |= TH_CWR; + else { + if (!(t = strchr(flagset, *s))) { + return 0; + } + tcpf |= flags[t - flagset]; + } + } + return tcpf; +} diff --git a/contrib/ipfilter/lib/tcpoptnames.c b/contrib/ipfilter/lib/tcpoptnames.c new file mode 100644 index 0000000..b5e0cc7 --- /dev/null +++ b/contrib/ipfilter/lib/tcpoptnames.c @@ -0,0 +1,22 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: tcpoptnames.c,v 1.5 2002/01/28 06:50:48 darrenr Exp + */ + +#include "ipf.h" + + +struct ipopt_names tcpoptnames[] ={ + { TCPOPT_NOP, 0x000001, 1, "nop" }, + { TCPOPT_MAXSEG, 0x000002, 4, "maxseg" }, + { TCPOPT_WINDOW, 0x000004, 3, "wscale" }, + { TCPOPT_SACK_PERMITTED, 0x000008, 2, "sackok" }, + { TCPOPT_SACK, 0x000010, 3, "sack" }, + { TCPOPT_TIMESTAMP, 0x000020, 10, "tstamp" }, + { 0, 0, 0, (char *)NULL } /* must be last */ +}; diff --git a/contrib/ipfilter/lib/to_interface.c b/contrib/ipfilter/lib/to_interface.c new file mode 100644 index 0000000..50f9a70 --- /dev/null +++ b/contrib/ipfilter/lib/to_interface.c @@ -0,0 +1,31 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: to_interface.c,v 1.8 2002/01/28 06:50:48 darrenr Exp + */ + +#include "ipf.h" + + +int to_interface(fdp, to, linenum) +frdest_t *fdp; +char *to; +int linenum; +{ + char *s; + + s = strchr(to, ':'); + fdp->fd_ifp = NULL; + if (s) { + *s++ = '\0'; + if (hostnum((u_32_t *)&fdp->fd_ip, s, linenum, NULL) == -1) + return -1; + } + (void) strncpy(fdp->fd_ifname, to, sizeof(fdp->fd_ifname) - 1); + fdp->fd_ifname[sizeof(fdp->fd_ifname) - 1] = '\0'; + return 0; +} diff --git a/contrib/ipfilter/lib/v6ionames.c b/contrib/ipfilter/lib/v6ionames.c new file mode 100644 index 0000000..087da5d --- /dev/null +++ b/contrib/ipfilter/lib/v6ionames.c @@ -0,0 +1,27 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: v6ionames.c,v 1.1.4.1 2005/01/02 13:08:49 darrenr Exp + */ +#include "ipf.h" + + +#ifdef USE_INET6 + +struct ipopt_names v6ionames[] ={ + { IPPROTO_HOPOPTS, 0x000001, 0, "hopopts" }, + { IPPROTO_IPV6, 0x000002, 0, "ipv6" }, + { IPPROTO_ROUTING, 0x000004, 0, "routing" }, + { IPPROTO_FRAGMENT, 0x000008, 0, "frag" }, + { IPPROTO_ESP, 0x000010, 0, "esp" }, + { IPPROTO_AH, 0x000020, 0, "ah" }, + { IPPROTO_NONE, 0x000040, 0, "none" }, + { IPPROTO_DSTOPTS, 0x000080, 0, "dstopts" }, + { 0, 0, 0, (char *)NULL } +}; + +#endif diff --git a/contrib/ipfilter/lib/v6optvalue.c b/contrib/ipfilter/lib/v6optvalue.c new file mode 100644 index 0000000..57dc2fb --- /dev/null +++ b/contrib/ipfilter/lib/v6optvalue.c @@ -0,0 +1,39 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: v6optvalue.c,v 1.1 2003/04/26 04:55:58 darrenr Exp + */ +#include "ipf.h" + + + +u_32_t getv6optbyname(optname) +char *optname; +{ +#ifdef USE_INET6 + struct ipopt_names *io; + + for (io = v6ionames; io->on_name; io++) + if (!strcasecmp(optname, io->on_name)) + return io->on_bit; +#endif + return -1; +} + + +u_32_t getv6optbyvalue(optval) +int optval; +{ +#ifdef USE_INET6 + struct ipopt_names *io; + + for (io = v6ionames; io->on_name; io++) + if (io->on_value == optval) + return io->on_bit; +#endif + return -1; +} diff --git a/contrib/ipfilter/lib/var.c b/contrib/ipfilter/lib/var.c new file mode 100644 index 0000000..79b2517 --- /dev/null +++ b/contrib/ipfilter/lib/var.c @@ -0,0 +1,171 @@ +/* $NetBSD$ */ + +#include <ctype.h> + +#include "ipf.h" + +typedef struct variable { + struct variable *v_next; + char *v_name; + char *v_value; +} variable_t; + +static variable_t *vtop = NULL; + +static variable_t *find_var __P((char *)); +static char *expand_string __P((char *, int)); + + +static variable_t *find_var(name) +char *name; +{ + variable_t *v; + + for (v = vtop; v != NULL; v = v->v_next) + if (!strcmp(name, v->v_name)) + return v; + return NULL; +} + + +char *get_variable(string, after, line) +char *string, **after; +int line; +{ + char c, *s, *t, *value; + variable_t *v; + + s = string; + + if (*s == '{') { + s++; + for (t = s; *t != '\0'; t++) + if (*t == '}') + break; + if (*t == '\0') { + fprintf(stderr, "%d: { without }\n", line); + return NULL; + } + } else if (ISALPHA(*s)) { + for (t = s + 1; *t != '\0'; t++) + if (!ISALPHA(*t) && !ISDIGIT(*t) && (*t != '_')) + break; + } else { + fprintf(stderr, "%d: variables cannot start with '%c'\n", + line, *s); + return NULL; + } + + if (after != NULL) + *after = t; + c = *t; + *t = '\0'; + v = find_var(s); + *t = c; + if (v == NULL) { + fprintf(stderr, "%d: unknown variable '%s'\n", line, s); + return NULL; + } + + s = strdup(v->v_value); + value = expand_string(s, line); + if (value != s) + free(s); + return value; +} + + +static char *expand_string(oldstring, line) +char *oldstring; +int line; +{ + char c, *s, *p1, *p2, *p3, *newstring, *value; + int len; + + p3 = NULL; + newstring = oldstring; + + for (s = oldstring; *s != '\0'; s++) + if (*s == '$') { + *s = '\0'; + s++; + + switch (*s) + { + case '$' : + bcopy(s, s - 1, strlen(s)); + break; + default : + c = *s; + if (c == '\0') + return newstring; + + value = get_variable(s, &p3, line); + if (value == NULL) + return NULL; + + p2 = expand_string(value, line); + if (p2 == NULL) + return NULL; + + len = strlen(newstring) + strlen(p2); + if (p3 != NULL) { + if (c == '{' && *p3 == '}') + p3++; + len += strlen(p3); + } + p1 = malloc(len + 1); + if (p1 == NULL) + return NULL; + + *(s - 1) = '\0'; + strcpy(p1, newstring); + strcat(p1, p2); + if (p3 != NULL) + strcat(p1, p3); + + s = p1 + len - strlen(p3) - 1; + if (newstring != oldstring) + free(newstring); + newstring = p1; + break; + } + } + return newstring; +} + + +void set_variable(name, value) +char *name; +char *value; +{ + variable_t *v; + int len; + + if (name == NULL || value == NULL || *name == '\0') + return; + + v = find_var(name); + if (v != NULL) { + free(v->v_value); + v->v_value = strdup(value); + return; + } + + len = strlen(value); + + if ((*value == '"' && value[len - 1] == '"') || + (*value == '\'' && value[len - 1] == '\'')) { + value[len - 1] = '\0'; + value++; + len -=2; + } + + v = (variable_t *)malloc(sizeof(*v)); + if (v == NULL) + return; + v->v_name = strdup(name); + v->v_value = strdup(value); + v->v_next = vtop; + vtop = v; +} diff --git a/contrib/ipfilter/lib/verbose.c b/contrib/ipfilter/lib/verbose.c new file mode 100644 index 0000000..d4f3012 --- /dev/null +++ b/contrib/ipfilter/lib/verbose.c @@ -0,0 +1,37 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: verbose.c,v 1.6 2001/06/09 17:09:25 darrenr Exp + */ + +#if defined(__STDC__) +# include <stdarg.h> +#else +# include <varargs.h> +#endif +#include <stdio.h> + +#include "ipt.h" +#include "opts.h" + + +#if defined(__STDC__) +void verbose(char *fmt, ...) +#else +void verbose(fmt, va_alist) +char *fmt; +va_dcl +#endif +{ + va_list pvar; + + va_start(pvar, fmt); + + if (opts & OPT_VERBOSE) + vprintf(fmt, pvar); + va_end(pvar); +} |