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