141edb306SCy Schubert
241edb306SCy Schubert /*
341edb306SCy Schubert * Copyright (C) 2012 by Darren Reed.
441edb306SCy Schubert *
541edb306SCy Schubert * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert */
741edb306SCy Schubert
841edb306SCy Schubert #include <ctype.h>
941edb306SCy Schubert
1041edb306SCy Schubert #include "ipf.h"
1141edb306SCy Schubert #include "ipt.h"
1241edb306SCy Schubert
1341edb306SCy Schubert
1441edb306SCy Schubert extern int opts;
1541edb306SCy Schubert
1641edb306SCy Schubert static int hex_open(char *);
1741edb306SCy Schubert static int hex_close(void);
1841edb306SCy Schubert static int hex_readip(mb_t *, char **, int *);
1941edb306SCy Schubert static char *readhex(char *, char *);
2041edb306SCy Schubert
2141edb306SCy Schubert struct ipread iphex = { hex_open, hex_close, hex_readip, 0 };
2241edb306SCy Schubert static FILE *tfp = NULL;
2341edb306SCy Schubert static int tfd = -1;
2441edb306SCy Schubert
25efeb8bffSCy Schubert static int
hex_open(char * fname)26efeb8bffSCy Schubert hex_open(char *fname)
2741edb306SCy Schubert {
2841edb306SCy Schubert if (tfp && tfd != -1) {
2941edb306SCy Schubert rewind(tfp);
30*2582ae57SCy Schubert return (tfd);
3141edb306SCy Schubert }
3241edb306SCy Schubert
3341edb306SCy Schubert if (!strcmp(fname, "-")) {
3441edb306SCy Schubert tfd = 0;
3541edb306SCy Schubert tfp = stdin;
3641edb306SCy Schubert } else {
3741edb306SCy Schubert tfd = open(fname, O_RDONLY);
3841edb306SCy Schubert if (tfd != -1)
3941edb306SCy Schubert tfp = fdopen(tfd, "r");
4041edb306SCy Schubert }
41*2582ae57SCy Schubert return (tfd);
4241edb306SCy Schubert }
4341edb306SCy Schubert
4441edb306SCy Schubert
45efeb8bffSCy Schubert static int
hex_close(void)46efeb8bffSCy Schubert hex_close(void)
4741edb306SCy Schubert {
4841edb306SCy Schubert int cfd = tfd;
4941edb306SCy Schubert
5041edb306SCy Schubert tfd = -1;
51*2582ae57SCy Schubert return (close(cfd));
5241edb306SCy Schubert }
5341edb306SCy Schubert
5441edb306SCy Schubert
55efeb8bffSCy Schubert static int
hex_readip(mb_t * mb,char ** ifn,int * dir)56efeb8bffSCy Schubert hex_readip(mb_t *mb, char **ifn, int *dir)
5741edb306SCy Schubert {
5841edb306SCy Schubert register char *s, *t, *u;
5941edb306SCy Schubert char line[513];
6041edb306SCy Schubert ip_t *ip;
6141edb306SCy Schubert char *buf;
6241edb306SCy Schubert
6341edb306SCy Schubert buf = (char *)mb->mb_buf;
6441edb306SCy Schubert /*
6541edb306SCy Schubert * interpret start of line as possibly "[ifname]" or
6641edb306SCy Schubert * "[in/out,ifname]".
6741edb306SCy Schubert */
6841edb306SCy Schubert if (ifn)
6941edb306SCy Schubert *ifn = NULL;
7041edb306SCy Schubert if (dir)
7141edb306SCy Schubert *dir = 0;
7241edb306SCy Schubert ip = (ip_t *)buf;
7341edb306SCy Schubert while (fgets(line, sizeof(line)-1, tfp)) {
7441edb306SCy Schubert if ((s = strchr(line, '\n'))) {
7541edb306SCy Schubert if (s == line) {
7641edb306SCy Schubert mb->mb_len = (char *)ip - buf;
77*2582ae57SCy Schubert return (mb->mb_len);
7841edb306SCy Schubert }
7941edb306SCy Schubert *s = '\0';
8041edb306SCy Schubert }
8141edb306SCy Schubert if ((s = strchr(line, '#')))
8241edb306SCy Schubert *s = '\0';
8341edb306SCy Schubert if (!*line)
8441edb306SCy Schubert continue;
8541edb306SCy Schubert if ((opts & OPT_DEBUG) != 0) {
8641edb306SCy Schubert printf("input: %s", line);
8741edb306SCy Schubert }
8841edb306SCy Schubert
8941edb306SCy Schubert if ((*line == '[') && (s = strchr(line, ']'))) {
9041edb306SCy Schubert t = line + 1;
9141edb306SCy Schubert if (s - t > 0) {
9241edb306SCy Schubert *s++ = '\0';
9341edb306SCy Schubert if ((u = strchr(t, ',')) && (u < s)) {
9441edb306SCy Schubert u++;
9541edb306SCy Schubert if (ifn)
9641edb306SCy Schubert *ifn = strdup(u);
9741edb306SCy Schubert if (dir) {
9841edb306SCy Schubert if (*t == 'i')
9941edb306SCy Schubert *dir = 0;
10041edb306SCy Schubert else if (*t == 'o')
10141edb306SCy Schubert *dir = 1;
10241edb306SCy Schubert }
10341edb306SCy Schubert } else if (ifn)
10441edb306SCy Schubert *ifn = t;
10541edb306SCy Schubert }
10641edb306SCy Schubert
10741edb306SCy Schubert while (*s++ == '+') {
10841edb306SCy Schubert if (!strncasecmp(s, "mcast", 5)) {
10941edb306SCy Schubert mb->mb_flags |= M_MCAST;
11041edb306SCy Schubert s += 5;
11141edb306SCy Schubert }
11241edb306SCy Schubert if (!strncasecmp(s, "bcast", 5)) {
11341edb306SCy Schubert mb->mb_flags |= M_BCAST;
11441edb306SCy Schubert s += 5;
11541edb306SCy Schubert }
11641edb306SCy Schubert if (!strncasecmp(s, "mbcast", 6)) {
11741edb306SCy Schubert mb->mb_flags |= M_MBCAST;
11841edb306SCy Schubert s += 6;
11941edb306SCy Schubert }
12041edb306SCy Schubert }
12141edb306SCy Schubert while (ISSPACE(*s))
12241edb306SCy Schubert s++;
12341edb306SCy Schubert } else
12441edb306SCy Schubert s = line;
12541edb306SCy Schubert t = (char *)ip;
12641edb306SCy Schubert ip = (ip_t *)readhex(s, (char *)ip);
12741edb306SCy Schubert if ((opts & OPT_DEBUG) != 0) {
12841edb306SCy Schubert if (opts & OPT_ASCII) {
12941edb306SCy Schubert int c = *t;
13041edb306SCy Schubert if (t < (char *)ip)
13141edb306SCy Schubert putchar('\t');
13241edb306SCy Schubert while (t < (char *)ip) {
13341edb306SCy Schubert if (isprint(c) && isascii(c))
13441edb306SCy Schubert putchar(c);
13541edb306SCy Schubert else
13641edb306SCy Schubert putchar('.');
13741edb306SCy Schubert t++;
13841edb306SCy Schubert }
13941edb306SCy Schubert }
14041edb306SCy Schubert putchar('\n');
14141edb306SCy Schubert fflush(stdout);
14241edb306SCy Schubert }
14341edb306SCy Schubert }
14441edb306SCy Schubert if (feof(tfp))
145*2582ae57SCy Schubert return (0);
146*2582ae57SCy Schubert return (-1);
14741edb306SCy Schubert }
14841edb306SCy Schubert
14941edb306SCy Schubert
150efeb8bffSCy Schubert static char
readhex(register char * src,register char * dst)151efeb8bffSCy Schubert *readhex(register char *src, register char *dst)
15241edb306SCy Schubert {
15341edb306SCy Schubert int state = 0;
15441edb306SCy Schubert char c;
15541edb306SCy Schubert
15641edb306SCy Schubert while ((c = *src++)) {
15741edb306SCy Schubert if (ISSPACE(c)) {
15841edb306SCy Schubert if (state) {
15941edb306SCy Schubert dst++;
16041edb306SCy Schubert state = 0;
16141edb306SCy Schubert }
16241edb306SCy Schubert continue;
16341edb306SCy Schubert } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
16441edb306SCy Schubert (c >= 'A' && c <= 'F')) {
16541edb306SCy Schubert c = ISDIGIT(c) ? (c - '0') : (TOUPPER(c) - 55);
16641edb306SCy Schubert if (state == 0) {
16741edb306SCy Schubert *dst = (c << 4);
16841edb306SCy Schubert state++;
16941edb306SCy Schubert } else {
17041edb306SCy Schubert *dst++ |= c;
17141edb306SCy Schubert state = 0;
17241edb306SCy Schubert }
17341edb306SCy Schubert } else
17441edb306SCy Schubert break;
17541edb306SCy Schubert }
176*2582ae57SCy Schubert return (dst);
17741edb306SCy Schubert }
178