1 %{ 2 #include <sys/types.h> 3 #include <sys/time.h> 4 #include <sys/param.h> 5 #include <sys/socket.h> 6 #if defined(BSD) && (BSD >= 199306) 7 # include <sys/cdefs.h> 8 #endif 9 #include <sys/ioctl.h> 10 11 #include <net/if.h> 12 #if __FreeBSD_version >= 300000 13 # include <net/if_var.h> 14 #endif 15 #include <netinet/in.h> 16 17 #include <arpa/inet.h> 18 19 #include <stdio.h> 20 #include <fcntl.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <netdb.h> 24 #include <ctype.h> 25 #include <unistd.h> 26 27 #include "ipf.h" 28 #if SOLARIS2 >= 10 29 #include "ip_lookup.h" 30 #include "ip_pool.h" 31 #include "ip_htable.h" 32 #else 33 #include "netinet/ip_lookup.h" 34 #include "netinet/ip_pool.h" 35 #include "netinet/ip_htable.h" 36 #endif 37 #include "ippool_l.h" 38 #include "kmem.h" 39 40 #define YYDEBUG 1 41 42 extern int yyparse __P((void)); 43 extern int yydebug; 44 extern FILE *yyin; 45 46 static iphtable_t ipht; 47 static iphtent_t iphte; 48 static ip_pool_t iplo; 49 static ioctlfunc_t poolioctl = NULL; 50 static char poolname[FR_GROUPLEN]; 51 52 %} 53 54 %union { 55 char *str; 56 u_32_t num; 57 struct in_addr addr; 58 struct alist_s *alist; 59 struct in_addr adrmsk[2]; 60 iphtent_t *ipe; 61 ip_pool_node_t *ipp; 62 union i6addr ip6; 63 } 64 65 %token <num> YY_NUMBER YY_HEX 66 %token <str> YY_STR 67 %token YY_COMMENT 68 %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 69 %token YY_RANGE_OUT YY_RANGE_IN 70 %token <ip6> YY_IPV6 71 72 %token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT 73 %token IPT_TABLE IPT_GROUPMAP IPT_HASH 74 %token IPT_ROLE IPT_TYPE IPT_TREE 75 %token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME 76 %type <num> role table inout 77 %type <ipp> ipftree range addrlist 78 %type <adrmsk> addrmask 79 %type <ipe> ipfgroup ipfhash hashlist hashentry 80 %type <ipe> groupentry setgrouplist grouplist 81 %type <addr> ipaddr mask ipv4 82 %type <str> number setgroup 83 84 %% 85 file: line 86 | assign 87 | file line 88 | file assign 89 ; 90 91 line: table role ipftree eol { iplo.ipo_unit = $2; 92 iplo.ipo_list = $3; 93 load_pool(&iplo, poolioctl); 94 resetlexer(); 95 } 96 | table role ipfhash eol { ipht.iph_unit = $2; 97 ipht.iph_type = IPHASH_LOOKUP; 98 load_hash(&ipht, $3, poolioctl); 99 resetlexer(); 100 } 101 | groupmap role number ipfgroup eol 102 { ipht.iph_unit = $2; 103 strncpy(ipht.iph_name, $3, 104 sizeof(ipht.iph_name)); 105 ipht.iph_type = IPHASH_GROUPMAP; 106 load_hash(&ipht, $4, poolioctl); 107 resetlexer(); 108 } 109 | YY_COMMENT 110 ; 111 112 eol: ';' 113 ; 114 115 assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 116 resetlexer(); 117 free($1); 118 free($3); 119 } 120 ; 121 122 assigning: 123 '=' { yyvarnext = 1; } 124 ; 125 126 table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); 127 bzero((char *)&iphte, sizeof(iphte)); 128 bzero((char *)&iplo, sizeof(iplo)); 129 *ipht.iph_name = '\0'; 130 iplo.ipo_flags = IPHASH_ANON; 131 iplo.ipo_name[0] = '\0'; 132 } 133 ; 134 135 groupmap: 136 IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht)); 137 bzero((char *)&iphte, sizeof(iphte)); 138 *ipht.iph_name = '\0'; 139 ipht.iph_unit = IPHASH_GROUPMAP; 140 ipht.iph_flags = $2; 141 } 142 ; 143 144 inout: IPT_IN { $$ = FR_INQUE; } 145 | IPT_OUT { $$ = FR_OUTQUE; } 146 ; 147 role: 148 IPT_ROLE '=' IPT_IPF { $$ = IPL_LOGIPF; } 149 | IPT_ROLE '=' IPT_NAT { $$ = IPL_LOGNAT; } 150 | IPT_ROLE '=' IPT_AUTH { $$ = IPL_LOGAUTH; } 151 | IPT_ROLE '=' IPT_COUNT { $$ = IPL_LOGCOUNT; } 152 ; 153 154 ipftree: 155 IPT_TYPE '=' IPT_TREE number '{' addrlist '}' 156 { strncpy(iplo.ipo_name, $4, 157 sizeof(iplo.ipo_name)); 158 $$ = $6; 159 } 160 ; 161 162 ipfhash: 163 IPT_TYPE '=' IPT_HASH number hashopts '{' hashlist '}' 164 { strncpy(ipht.iph_name, $4, 165 sizeof(ipht.iph_name)); 166 $$ = $7; 167 } 168 ; 169 170 ipfgroup: 171 setgroup hashopts '{' grouplist '}' 172 { iphtent_t *e; 173 for (e = $4; e != NULL; 174 e = e->ipe_next) 175 if (e->ipe_group[0] == '\0') 176 strncpy(e->ipe_group, 177 $1, 178 FR_GROUPLEN); 179 $$ = $4; 180 } 181 | hashopts '{' setgrouplist '}' { $$ = $3; } 182 ; 183 184 number: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3); 185 $$ = poolname; 186 } 187 | IPT_NAME '=' YY_STR { $$ = $3; } 188 | { $$ = ""; } 189 ; 190 191 setgroup: 192 IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; 193 strncpy(tmp, $3, FR_GROUPLEN); 194 $$ = strdup(tmp); 195 } 196 | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; 197 sprintf(tmp, "%u", $3); 198 $$ = strdup(tmp); 199 } 200 ; 201 202 hashopts: 203 | size 204 | seed 205 | size seed 206 ; 207 208 addrlist: 209 range ',' addrlist { $1->ipn_next = $3; $$ = $1; } 210 | range { $$ = $1; } 211 ; 212 213 grouplist: 214 groupentry ';' grouplist { $$ = $1; $1->ipe_next = $3; } 215 | addrmask ';' grouplist { $$ = calloc(1, sizeof(iphtent_t)); 216 bcopy((char *)&($1[0]), 217 (char *)&($$->ipe_addr), 218 sizeof($$->ipe_addr)); 219 bcopy((char *)&($1[1]), 220 (char *)&($$->ipe_mask), 221 sizeof($$->ipe_mask)); 222 $$->ipe_next = $3; 223 } 224 | groupentry ';' { $$ = $1; } 225 | addrmask ';' { $$ = calloc(1, sizeof(iphtent_t)); 226 bcopy((char *)&($1[0]), 227 (char *)&($$->ipe_addr), 228 sizeof($$->ipe_addr)); 229 bcopy((char *)&($1[1]), 230 (char *)&($$->ipe_mask), 231 sizeof($$->ipe_mask)); 232 } 233 ; 234 235 setgrouplist: 236 groupentry ';' { $$ = $1; } 237 | groupentry ';' setgrouplist { $1->ipe_next = $3; $$ = $1; } 238 ; 239 240 groupentry: 241 addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); 242 bcopy((char *)&($1[0]), 243 (char *)&($$->ipe_addr), 244 sizeof($$->ipe_addr)); 245 bcopy((char *)&($1[1]), 246 (char *)&($$->ipe_mask), 247 sizeof($$->ipe_mask)); 248 strncpy($$->ipe_group, $3, 249 FR_GROUPLEN); 250 free($3); 251 } 252 ; 253 254 range: addrmask { $$ = calloc(1, sizeof(*$$)); 255 $$->ipn_info = 0; 256 $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr; 257 $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr; 258 } 259 | '!' addrmask { $$ = calloc(1, sizeof(*$$)); 260 $$->ipn_info = 1; 261 $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr; 262 $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr; 263 } 264 265 hashlist: 266 hashentry ';' { $$ = $1; } 267 | hashentry ';' hashlist { $1->ipe_next = $3; $$ = $1; } 268 ; 269 270 hashentry: 271 addrmask { $$ = calloc(1, sizeof(iphtent_t)); 272 bcopy((char *)&($1[0]), 273 (char *)&($$->ipe_addr), 274 sizeof($$->ipe_addr)); 275 bcopy((char *)&($1[1]), 276 (char *)&($$->ipe_mask), 277 sizeof($$->ipe_mask)); 278 } 279 ; 280 281 addrmask: 282 ipaddr '/' mask { $$[0] = $1; $$[1].s_addr = $3.s_addr; } 283 | ipaddr { $$[0] = $1; $$[1].s_addr = 0xffffffff; } 284 ; 285 286 ipaddr: ipv4 { $$ = $1; } 287 | YY_NUMBER { $$.s_addr = htonl($1); } 288 ; 289 290 mask: YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$.s_addr); } 291 | ipv4 { $$ = $1; } 292 ; 293 294 size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } 295 ; 296 297 seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } 298 ; 299 300 ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 301 { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 302 yyerror("Invalid octet string for IP address"); 303 return 0; 304 } 305 $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 306 $$.s_addr = htonl($$.s_addr); 307 } 308 ; 309 %% 310 static wordtab_t yywords[] = { 311 { "auth", IPT_AUTH }, 312 { "count", IPT_COUNT }, 313 { "group", IPT_GROUP }, 314 { "group-map", IPT_GROUPMAP }, 315 { "hash", IPT_HASH }, 316 { "in", IPT_IN }, 317 { "ipf", IPT_IPF }, 318 { "name", IPT_NAME }, 319 { "nat", IPT_NAT }, 320 { "number", IPT_NUM }, 321 { "out", IPT_OUT }, 322 { "role", IPT_ROLE }, 323 { "seed", IPT_SEED }, 324 { "size", IPT_SIZE }, 325 { "table", IPT_TABLE }, 326 { "tree", IPT_TREE }, 327 { "type", IPT_TYPE }, 328 { NULL, 0 } 329 }; 330 331 332 int ippool_parsefile(fd, filename, iocfunc) 333 int fd; 334 char *filename; 335 ioctlfunc_t iocfunc; 336 { 337 FILE *fp = NULL; 338 char *s; 339 340 yylineNum = 1; 341 (void) yysettab(yywords); 342 343 s = getenv("YYDEBUG"); 344 if (s) 345 yydebug = atoi(s); 346 else 347 yydebug = 0; 348 349 if (strcmp(filename, "-")) { 350 fp = fopen(filename, "r"); 351 if (!fp) { 352 fprintf(stderr, "fopen(%s) failed: %s\n", filename, 353 STRERROR(errno)); 354 return -1; 355 } 356 } else 357 fp = stdin; 358 359 while (ippool_parsesome(fd, fp, iocfunc) == 1) 360 ; 361 if (fp != NULL) 362 fclose(fp); 363 return 0; 364 } 365 366 367 int ippool_parsesome(fd, fp, iocfunc) 368 int fd; 369 FILE *fp; 370 ioctlfunc_t iocfunc; 371 { 372 char *s; 373 int i; 374 375 poolioctl = iocfunc; 376 377 if (feof(fp)) 378 return 0; 379 i = fgetc(fp); 380 if (i == EOF) 381 return 0; 382 if (ungetc(i, fp) == EOF) 383 return 0; 384 if (feof(fp)) 385 return 0; 386 s = getenv("YYDEBUG"); 387 if (s) 388 yydebug = atoi(s); 389 else 390 yydebug = 0; 391 392 yyin = fp; 393 yyparse(); 394 return 1; 395 } 396