1/*
2 * Copyright (C) 1993-2001 by Darren Reed.
3 *
4 * See the IPFILTER.LICENCE file for details on licencing.
5 *
6 * $Id: extras.c,v 1.12 2002/07/13 12:06:49 darrenr Exp $
7 */
8
9#include "ipf.h"
10
11
12/*
13 * deal with extra bits on end of the line
14 */
15int	extras(cp, fr, linenum)
16char	***cp;
17struct	frentry	*fr;
18int     linenum;
19{
20	u_short	secmsk;
21	u_long	opts;
22	int	notopt;
23
24	opts = 0;
25	secmsk = 0;
26	notopt = 0;
27	(*cp)++;
28	if (!**cp)
29		return -1;
30
31	while (**cp) {
32		if (!strcasecmp(**cp, "not") || !strcasecmp(**cp, "no")) {
33			notopt = 1;
34			(*cp)++;
35			continue;
36		} else if (!strncasecmp(**cp, "ipopt", 5)) {
37			if (!notopt)
38				fr->fr_flx |= FI_OPTIONS;
39			fr->fr_mflx |= FI_OPTIONS;
40			goto nextopt;
41		} else if (!strcasecmp(**cp, "lowttl")) {
42			if (!notopt)
43				fr->fr_flx |= FI_LOWTTL;
44			fr->fr_mflx |= FI_LOWTTL;
45			goto nextopt;
46		} else if (!strcasecmp(**cp, "bad-src")) {
47			if (!notopt)
48				fr->fr_flx |= FI_BADSRC;
49			fr->fr_mflx |= FI_BADSRC;
50			goto nextopt;
51		} else if (!strncasecmp(**cp, "mbcast", 6)) {
52			if (!notopt)
53				fr->fr_flx |= FI_MBCAST;
54			fr->fr_mflx |= FI_MBCAST;
55			goto nextopt;
56		} else if (!strncasecmp(**cp, "nat", 3)) {
57			if (!notopt)
58				fr->fr_flx |= FI_NATED;
59			fr->fr_mflx |= FI_NATED;
60			goto nextopt;
61		} else if (!strncasecmp(**cp, "frag", 4)) {
62			if (!notopt)
63				fr->fr_flx |= FI_FRAG;
64			fr->fr_mflx |= FI_FRAG;
65			goto nextopt;
66		} else if (!strncasecmp(**cp, "opt", 3)) {
67			if (!*(*cp + 1)) {
68				fprintf(stderr, "%d: opt missing arguements\n",
69					linenum);
70				return -1;
71			}
72			(*cp)++;
73			if (!(opts = optname(cp, &secmsk, linenum)))
74				return -1;
75
76			if (notopt) {
77				if (!secmsk) {
78					fr->fr_optmask |= opts;
79				} else {
80					fr->fr_optmask |= (opts & ~0x0100);
81					fr->fr_secmask |= secmsk;
82				}
83				fr->fr_secbits &= ~secmsk;
84				fr->fr_optbits &= ~opts;
85			} else {
86				fr->fr_optmask |= opts;
87				fr->fr_secmask |= secmsk;
88				fr->fr_optbits |= opts;
89				fr->fr_secbits |= secmsk;
90			}
91		} else if (!strncasecmp(**cp, "short", 5)) {
92			if (fr->fr_tcpf) {
93				fprintf(stderr,
94				"%d: short cannot be used with TCP flags\n",
95					linenum);
96				return -1;
97			}
98
99			if (!notopt)
100				fr->fr_flx |= FI_SHORT;
101			fr->fr_mflx |= FI_SHORT;
102			goto nextopt;
103		} else
104			return -1;
105nextopt:
106		notopt = 0;
107		opts = 0;
108		secmsk = 0;
109		(*cp)++;
110	}
111	return 0;
112}
113