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