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