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