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