addicmp.c revision 145510
1145510Sdarrenr/*	$NetBSD$	*/
2145510Sdarrenr
3145510Sdarrenr/*
4145510Sdarrenr * Copyright (C) 1993-2001 by Darren Reed.
5145510Sdarrenr *
6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
7145510Sdarrenr *
8145510Sdarrenr * Id: addicmp.c,v 1.10.2.1 2004/12/09 19:41:16 darrenr Exp
9145510Sdarrenr */
10145510Sdarrenr
11145510Sdarrenr#include <ctype.h>
12145510Sdarrenr
13145510Sdarrenr#include "ipf.h"
14145510Sdarrenr
15145510Sdarrenr
16145510Sdarrenrchar	*icmptypes[MAX_ICMPTYPE + 1] = {
17145510Sdarrenr	"echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
18145510Sdarrenr	"redir", (char *)NULL, (char *)NULL, "echo", "routerad",
19145510Sdarrenr	"routersol", "timex", "paramprob", "timest", "timestrep",
20145510Sdarrenr	"inforeq", "inforep", "maskreq", "maskrep", "END"
21145510Sdarrenr};
22145510Sdarrenr
23145510Sdarrenr/*
24145510Sdarrenr * set the icmp field to the correct type if "icmp" word is found
25145510Sdarrenr */
26145510Sdarrenrint	addicmp(cp, fp, linenum)
27145510Sdarrenrchar	***cp;
28145510Sdarrenrstruct	frentry	*fp;
29145510Sdarrenrint     linenum;
30145510Sdarrenr{
31145510Sdarrenr	char	**t;
32145510Sdarrenr	int	i;
33145510Sdarrenr
34145510Sdarrenr	(*cp)++;
35145510Sdarrenr	if (!**cp)
36145510Sdarrenr		return -1;
37145510Sdarrenr	if (!fp->fr_proto)	/* to catch lusers */
38145510Sdarrenr		fp->fr_proto = IPPROTO_ICMP;
39145510Sdarrenr	if (ISDIGIT(***cp)) {
40145510Sdarrenr		if (!ratoi(**cp, &i, 0, 255)) {
41145510Sdarrenr			fprintf(stderr,
42145510Sdarrenr				"%d: Invalid icmp-type (%s) specified\n",
43145510Sdarrenr				linenum, **cp);
44145510Sdarrenr			return -1;
45145510Sdarrenr		}
46145510Sdarrenr	} else {
47145510Sdarrenr		for (t = icmptypes, i = 0; ; t++, i++) {
48145510Sdarrenr			if (!*t)
49145510Sdarrenr				continue;
50145510Sdarrenr			if (!strcasecmp("END", *t)) {
51145510Sdarrenr				i = -1;
52145510Sdarrenr				break;
53145510Sdarrenr			}
54145510Sdarrenr			if (!strcasecmp(*t, **cp))
55145510Sdarrenr				break;
56145510Sdarrenr		}
57145510Sdarrenr		if (i == -1) {
58145510Sdarrenr			fprintf(stderr,
59145510Sdarrenr				"%d: Unknown icmp-type (%s) specified\n",
60145510Sdarrenr				linenum, **cp);
61145510Sdarrenr			return -1;
62145510Sdarrenr		}
63145510Sdarrenr	}
64145510Sdarrenr	fp->fr_icmp = (u_short)(i << 8);
65145510Sdarrenr	fp->fr_icmpm = (u_short)0xff00;
66145510Sdarrenr	(*cp)++;
67145510Sdarrenr	if (!**cp)
68145510Sdarrenr		return 0;
69145510Sdarrenr
70145510Sdarrenr	if (**cp && strcasecmp("code", **cp))
71145510Sdarrenr		return 0;
72145510Sdarrenr	(*cp)++;
73145510Sdarrenr	if (ISDIGIT(***cp)) {
74145510Sdarrenr		if (!ratoi(**cp, &i, 0, 255)) {
75145510Sdarrenr			fprintf(stderr,
76145510Sdarrenr				"%d: Invalid icmp code (%s) specified\n",
77145510Sdarrenr				linenum, **cp);
78145510Sdarrenr			return -1;
79145510Sdarrenr		}
80145510Sdarrenr	} else {
81145510Sdarrenr		i = icmpcode(**cp);
82145510Sdarrenr		if (i == -1) {
83145510Sdarrenr			fprintf(stderr,
84145510Sdarrenr				"%d: Unknown icmp code (%s) specified\n",
85145510Sdarrenr				linenum, **cp);
86145510Sdarrenr			return -1;
87145510Sdarrenr		}
88145510Sdarrenr	}
89145510Sdarrenr	i &= 0xff;
90145510Sdarrenr	fp->fr_icmp |= (u_short)i;
91145510Sdarrenr	fp->fr_icmpm = (u_short)0xffff;
92145510Sdarrenr	(*cp)++;
93145510Sdarrenr	return 0;
94145510Sdarrenr}
95