mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-05 01:30:43 +00:00
Remove files no longer required to build IPFilter
This commit is contained in:
parent
d7eeb25225
commit
c485ab2d8d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=170269
@ -1,114 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,730 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,754 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user