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