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
hex_open(char * fname)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
hex_close(void)50 hex_close(void)
51 {
52 int cfd = tfd;
53
54 tfd = -1;
55 return (close(cfd));
56 }
57
58
59 static int
hex_readip(mb_t * mb,char ** ifn,int * dir)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
readhex(register char * src,register char * dst)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