xref: /freebsd/sbin/ipf/libipf/ipft_hx.c (revision 8f76bb7dad48538c6832c2fb466a433d2a3f8cd5)
1 
2 /*
3  * Copyright (C) 2012 by Darren Reed.
4  *
5  * See the IPFILTER.LICENCE file for details on licencing.
6  */
7 #if !defined(lint)
8 static const char sccsid[] = "@(#)ipft_hx.c	1.1 3/9/96 (C) 1996 Darren Reed";
9 static const char rcsid[] = "@(#)$Id$";
10 #endif
11 
12 #include <ctype.h>
13 
14 #include "ipf.h"
15 #include "ipt.h"
16 
17 
18 extern	int	opts;
19 
20 static	int	hex_open(char *);
21 static	int	hex_close(void);
22 static	int	hex_readip(mb_t *, char **, int *);
23 static	char	*readhex(char *, char *);
24 
25 struct	ipread	iphex = { hex_open, hex_close, hex_readip, 0 };
26 static	FILE	*tfp = NULL;
27 static	int	tfd = -1;
28 
29 static int
30 hex_open(char *fname)
31 {
32 	if (tfp && tfd != -1) {
33 		rewind(tfp);
34 		return (tfd);
35 	}
36 
37 	if (!strcmp(fname, "-")) {
38 		tfd = 0;
39 		tfp = stdin;
40 	} else {
41 		tfd = open(fname, O_RDONLY);
42 		if (tfd != -1)
43 			tfp = fdopen(tfd, "r");
44 	}
45 	return (tfd);
46 }
47 
48 
49 static int
50 hex_close(void)
51 {
52 	int	cfd = tfd;
53 
54 	tfd = -1;
55 	return (close(cfd));
56 }
57 
58 
59 static int
60 hex_readip(mb_t *mb, char **ifn, int *dir)
61 {
62 	register char *s, *t, *u;
63 	char	line[513];
64 	ip_t	*ip;
65 	char	*buf;
66 
67 	buf = (char *)mb->mb_buf;
68 	/*
69 	 * interpret start of line as possibly "[ifname]" or
70 	 * "[in/out,ifname]".
71 	 */
72 	if (ifn)
73 		*ifn = NULL;
74 	if (dir)
75 		*dir = 0;
76  	ip = (ip_t *)buf;
77 	while (fgets(line, sizeof(line)-1, tfp)) {
78 		if ((s = strchr(line, '\n'))) {
79 			if (s == line) {
80 				mb->mb_len = (char *)ip - buf;
81 				return (mb->mb_len);
82 			}
83 			*s = '\0';
84 		}
85 		if ((s = strchr(line, '#')))
86 			*s = '\0';
87 		if (!*line)
88 			continue;
89 		if ((opts & OPT_DEBUG) != 0) {
90 			printf("input: %s", line);
91 		}
92 
93 		if ((*line == '[') && (s = strchr(line, ']'))) {
94 			t = line + 1;
95 			if (s - t > 0) {
96 				*s++ = '\0';
97 				if ((u = strchr(t, ',')) && (u < s)) {
98 					u++;
99 					if (ifn)
100 						*ifn = strdup(u);
101 					if (dir) {
102 						if (*t == 'i')
103 							*dir = 0;
104 						else if (*t == 'o')
105 							*dir = 1;
106 					}
107 				} else if (ifn)
108 					*ifn = t;
109 			}
110 
111 			while (*s++ == '+') {
112 				if (!strncasecmp(s, "mcast", 5)) {
113 					mb->mb_flags |= M_MCAST;
114 					s += 5;
115 				}
116 				if (!strncasecmp(s, "bcast", 5)) {
117 					mb->mb_flags |= M_BCAST;
118 					s += 5;
119 				}
120 				if (!strncasecmp(s, "mbcast", 6)) {
121 					mb->mb_flags |= M_MBCAST;
122 					s += 6;
123 				}
124 			}
125 			while (ISSPACE(*s))
126 				s++;
127 		} else
128 			s = line;
129 		t = (char *)ip;
130 		ip = (ip_t *)readhex(s, (char *)ip);
131 		if ((opts & OPT_DEBUG) != 0) {
132 			if (opts & OPT_ASCII) {
133 				int c = *t;
134 				if (t < (char *)ip)
135 					putchar('\t');
136 				while (t < (char *)ip) {
137 					if (isprint(c) && isascii(c))
138 						putchar(c);
139 					else
140 						putchar('.');
141 					t++;
142 				}
143 			}
144 			putchar('\n');
145 			fflush(stdout);
146 		}
147 	}
148 	if (feof(tfp))
149 		return (0);
150 	return (-1);
151 }
152 
153 
154 static char
155 *readhex(register char *src, register char *dst)
156 {
157 	int	state = 0;
158 	char	c;
159 
160 	while ((c = *src++)) {
161 		if (ISSPACE(c)) {
162 			if (state) {
163 				dst++;
164 				state = 0;
165 			}
166 			continue;
167 		} else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
168 			   (c >= 'A' && c <= 'F')) {
169 			c = ISDIGIT(c) ? (c - '0') : (TOUPPER(c) - 55);
170 			if (state == 0) {
171 				*dst = (c << 4);
172 				state++;
173 			} else {
174 				*dst++ |= c;
175 				state = 0;
176 			}
177 		} else
178 			break;
179 	}
180 	return (dst);
181 }
182