1/*
2 * Copyright (C) 1993-2001 by Darren Reed.
3 *
4 * See the IPFILTER.LICENCE file for details on licencing.
5 *
6 * $Id: addicmp.c,v 1.10.2.1 2004/12/09 19:41:16 darrenr Exp $
7 */
8
9#include <ctype.h>
10
11#include "ipf.h"
12
13
14char	*icmptypes[MAX_ICMPTYPE + 1] = {
15	"echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
16	"redir", (char *)NULL, (char *)NULL, "echo", "routerad",
17	"routersol", "timex", "paramprob", "timest", "timestrep",
18	"inforeq", "inforep", "maskreq", "maskrep", "END"
19};
20
21/*
22 * set the icmp field to the correct type if "icmp" word is found
23 */
24int	addicmp(cp, fp, linenum)
25char	***cp;
26struct	frentry	*fp;
27int     linenum;
28{
29	char	**t;
30	int	i;
31
32	(*cp)++;
33	if (!**cp)
34		return -1;
35	if (!fp->fr_proto)	/* to catch lusers */
36		fp->fr_proto = IPPROTO_ICMP;
37	if (ISDIGIT(***cp)) {
38		if (!ratoi(**cp, &i, 0, 255)) {
39			fprintf(stderr,
40				"%d: Invalid icmp-type (%s) specified\n",
41				linenum, **cp);
42			return -1;
43		}
44	} else {
45		for (t = icmptypes, i = 0; ; t++, i++) {
46			if (!*t)
47				continue;
48			if (!strcasecmp("END", *t)) {
49				i = -1;
50				break;
51			}
52			if (!strcasecmp(*t, **cp))
53				break;
54		}
55		if (i == -1) {
56			fprintf(stderr,
57				"%d: Unknown icmp-type (%s) specified\n",
58				linenum, **cp);
59			return -1;
60		}
61	}
62	fp->fr_icmp = (u_short)(i << 8);
63	fp->fr_icmpm = (u_short)0xff00;
64	(*cp)++;
65	if (!**cp)
66		return 0;
67
68	if (**cp && strcasecmp("code", **cp))
69		return 0;
70	(*cp)++;
71	if (ISDIGIT(***cp)) {
72		if (!ratoi(**cp, &i, 0, 255)) {
73			fprintf(stderr,
74				"%d: Invalid icmp code (%s) specified\n",
75				linenum, **cp);
76			return -1;
77		}
78	} else {
79		i = icmpcode(**cp);
80		if (i == -1) {
81			fprintf(stderr,
82				"%d: Unknown icmp code (%s) specified\n",
83				linenum, **cp);
84			return -1;
85		}
86	}
87	i &= 0xff;
88	fp->fr_icmp |= (u_short)i;
89	fp->fr_icmpm = (u_short)0xffff;
90	(*cp)++;
91	return 0;
92}
93