1145519Sdarrenr/*	$FreeBSD$	*/
2145510Sdarrenr
3145510Sdarrenr/*
4255332Scy * Copyright (C) 2012 by Darren Reed.
5145510Sdarrenr *
6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
7145510Sdarrenr */
8145510Sdarrenr#if !defined(lint)
9145510Sdarrenrstatic const char sccsid[] = "@(#)ipft_hx.c	1.1 3/9/96 (C) 1996 Darren Reed";
10255332Scystatic const char rcsid[] = "@(#)$Id$";
11145510Sdarrenr#endif
12145510Sdarrenr
13145510Sdarrenr#include <ctype.h>
14145510Sdarrenr
15145510Sdarrenr#include "ipf.h"
16145510Sdarrenr#include "ipt.h"
17145510Sdarrenr
18145510Sdarrenr
19145510Sdarrenrextern	int	opts;
20145510Sdarrenr
21145510Sdarrenrstatic	int	hex_open __P((char *));
22145510Sdarrenrstatic	int	hex_close __P((void));
23255332Scystatic	int	hex_readip __P((mb_t *, char **, int *));
24145510Sdarrenrstatic	char	*readhex __P((char *, char *));
25145510Sdarrenr
26145510Sdarrenrstruct	ipread	iphex = { hex_open, hex_close, hex_readip, 0 };
27145510Sdarrenrstatic	FILE	*tfp = NULL;
28145510Sdarrenrstatic	int	tfd = -1;
29145510Sdarrenr
30145510Sdarrenrstatic	int	hex_open(fname)
31255332Scy	char	*fname;
32145510Sdarrenr{
33145510Sdarrenr	if (tfp && tfd != -1) {
34145510Sdarrenr		rewind(tfp);
35145510Sdarrenr		return tfd;
36145510Sdarrenr	}
37145510Sdarrenr
38145510Sdarrenr	if (!strcmp(fname, "-")) {
39145510Sdarrenr		tfd = 0;
40145510Sdarrenr		tfp = stdin;
41145510Sdarrenr	} else {
42145510Sdarrenr		tfd = open(fname, O_RDONLY);
43145510Sdarrenr		if (tfd != -1)
44145510Sdarrenr			tfp = fdopen(tfd, "r");
45145510Sdarrenr	}
46145510Sdarrenr	return tfd;
47145510Sdarrenr}
48145510Sdarrenr
49145510Sdarrenr
50145510Sdarrenrstatic	int	hex_close()
51145510Sdarrenr{
52145510Sdarrenr	int	cfd = tfd;
53145510Sdarrenr
54145510Sdarrenr	tfd = -1;
55145510Sdarrenr	return close(cfd);
56145510Sdarrenr}
57145510Sdarrenr
58145510Sdarrenr
59255332Scystatic	int	hex_readip(mb, ifn, dir)
60255332Scy	mb_t	*mb;
61255332Scy	char	**ifn;
62255332Scy	int	*dir;
63145510Sdarrenr{
64145510Sdarrenr	register char *s, *t, *u;
65145510Sdarrenr	char	line[513];
66145510Sdarrenr	ip_t	*ip;
67255332Scy	char	*buf;
68255332Scy	int	cnt;
69145510Sdarrenr
70255332Scy	buf = (char *)mb->mb_buf;
71255332Scy	cnt = sizeof(mb->mb_buf);
72145510Sdarrenr	/*
73145510Sdarrenr	 * interpret start of line as possibly "[ifname]" or
74145510Sdarrenr	 * "[in/out,ifname]".
75145510Sdarrenr	 */
76145510Sdarrenr	if (ifn)
77145510Sdarrenr		*ifn = NULL;
78145510Sdarrenr	if (dir)
79145510Sdarrenr		*dir = 0;
80145510Sdarrenr 	ip = (ip_t *)buf;
81145510Sdarrenr	while (fgets(line, sizeof(line)-1, tfp)) {
82145510Sdarrenr		if ((s = strchr(line, '\n'))) {
83255332Scy			if (s == line) {
84255332Scy				mb->mb_len = (char *)ip - buf;
85255332Scy				return mb->mb_len;
86255332Scy			}
87145510Sdarrenr			*s = '\0';
88145510Sdarrenr		}
89145510Sdarrenr		if ((s = strchr(line, '#')))
90145510Sdarrenr			*s = '\0';
91145510Sdarrenr		if (!*line)
92145510Sdarrenr			continue;
93153881Sguido		if ((opts & OPT_DEBUG) != 0) {
94145510Sdarrenr			printf("input: %s", line);
95145510Sdarrenr		}
96145510Sdarrenr
97145510Sdarrenr		if ((*line == '[') && (s = strchr(line, ']'))) {
98145510Sdarrenr			t = line + 1;
99145510Sdarrenr			if (s - t > 0) {
100145510Sdarrenr				*s++ = '\0';
101145510Sdarrenr				if ((u = strchr(t, ',')) && (u < s)) {
102145510Sdarrenr					u++;
103145510Sdarrenr					if (ifn)
104145510Sdarrenr						*ifn = strdup(u);
105145510Sdarrenr					if (dir) {
106145510Sdarrenr						if (*t == 'i')
107145510Sdarrenr							*dir = 0;
108145510Sdarrenr						else if (*t == 'o')
109145510Sdarrenr							*dir = 1;
110145510Sdarrenr					}
111145510Sdarrenr				} else if (ifn)
112145510Sdarrenr					*ifn = t;
113145510Sdarrenr			}
114255332Scy
115255332Scy			while (*s++ == '+') {
116255332Scy				if (!strncasecmp(s, "mcast", 5)) {
117255332Scy					mb->mb_flags |= M_MCAST;
118255332Scy					s += 5;
119255332Scy				}
120255332Scy				if (!strncasecmp(s, "bcast", 5)) {
121255332Scy					mb->mb_flags |= M_BCAST;
122255332Scy					s += 5;
123255332Scy				}
124255332Scy				if (!strncasecmp(s, "mbcast", 6)) {
125255332Scy					mb->mb_flags |= M_MBCAST;
126255332Scy					s += 6;
127255332Scy				}
128255332Scy			}
129255332Scy			while (ISSPACE(*s))
130255332Scy				s++;
131145510Sdarrenr		} else
132145510Sdarrenr			s = line;
133145510Sdarrenr		t = (char *)ip;
134145510Sdarrenr		ip = (ip_t *)readhex(s, (char *)ip);
135153881Sguido		if ((opts & OPT_DEBUG) != 0) {
136145510Sdarrenr			if (opts & OPT_ASCII) {
137255332Scy				int c = *t;
138145510Sdarrenr				if (t < (char *)ip)
139145510Sdarrenr					putchar('\t');
140145510Sdarrenr				while (t < (char *)ip) {
141255332Scy					if (isprint(c) && isascii(c))
142255332Scy						putchar(c);
143145510Sdarrenr					else
144145510Sdarrenr						putchar('.');
145145510Sdarrenr					t++;
146145510Sdarrenr				}
147145510Sdarrenr			}
148145510Sdarrenr			putchar('\n');
149145510Sdarrenr			fflush(stdout);
150145510Sdarrenr		}
151145510Sdarrenr	}
152153881Sguido	if (feof(tfp))
153153881Sguido		return 0;
154145510Sdarrenr	return -1;
155145510Sdarrenr}
156145510Sdarrenr
157145510Sdarrenr
158145510Sdarrenrstatic	char	*readhex(src, dst)
159145510Sdarrenrregister char	*src, *dst;
160145510Sdarrenr{
161145510Sdarrenr	int	state = 0;
162145510Sdarrenr	char	c;
163145510Sdarrenr
164145510Sdarrenr	while ((c = *src++)) {
165145510Sdarrenr		if (ISSPACE(c)) {
166145510Sdarrenr			if (state) {
167145510Sdarrenr				dst++;
168145510Sdarrenr				state = 0;
169145510Sdarrenr			}
170145510Sdarrenr			continue;
171145510Sdarrenr		} else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
172145510Sdarrenr			   (c >= 'A' && c <= 'F')) {
173145510Sdarrenr			c = ISDIGIT(c) ? (c - '0') : (TOUPPER(c) - 55);
174145510Sdarrenr			if (state == 0) {
175145510Sdarrenr				*dst = (c << 4);
176145510Sdarrenr				state++;
177145510Sdarrenr			} else {
178145510Sdarrenr				*dst++ |= c;
179145510Sdarrenr				state = 0;
180145510Sdarrenr			}
181145510Sdarrenr		} else
182145510Sdarrenr			break;
183145510Sdarrenr	}
184145510Sdarrenr	return dst;
185145510Sdarrenr}
186