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