825 lines
17 KiB
Plaintext
825 lines
17 KiB
Plaintext
/* $FreeBSD$ */
|
|
|
|
/*
|
|
* Copyright (C) 2012 by Darren Reed.
|
|
*
|
|
* See the IPFILTER.LICENCE file for details on licencing.
|
|
*/
|
|
%{
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
#include <sys/param.h>
|
|
#include <sys/socket.h>
|
|
# include <sys/cdefs.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <net/if.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <netdb.h>
|
|
#include <ctype.h>
|
|
#include <unistd.h>
|
|
|
|
#include "ipf.h"
|
|
#include "netinet/ip_lookup.h"
|
|
#include "netinet/ip_pool.h"
|
|
#include "netinet/ip_htable.h"
|
|
#include "netinet/ip_dstlist.h"
|
|
#include "ippool_l.h"
|
|
#include "kmem.h"
|
|
|
|
#define YYDEBUG 1
|
|
#define YYSTACKSIZE 0x00ffffff
|
|
|
|
extern int yyparse(void);
|
|
extern int yydebug;
|
|
extern FILE *yyin;
|
|
|
|
static iphtable_t ipht;
|
|
static iphtent_t iphte;
|
|
static ip_pool_t iplo;
|
|
static ippool_dst_t ipld;
|
|
static ioctlfunc_t poolioctl = NULL;
|
|
static char poolname[FR_GROUPLEN];
|
|
|
|
static iphtent_t *add_htablehosts(char *);
|
|
static ip_pool_node_t *add_poolhosts(char *);
|
|
static ip_pool_node_t *read_whoisfile(char *);
|
|
static void setadflen(addrfamily_t *);
|
|
|
|
%}
|
|
|
|
%union {
|
|
char *str;
|
|
u_32_t num;
|
|
struct in_addr ip4;
|
|
struct alist_s *alist;
|
|
addrfamily_t adrmsk[2];
|
|
iphtent_t *ipe;
|
|
ip_pool_node_t *ipp;
|
|
ipf_dstnode_t *ipd;
|
|
addrfamily_t ipa;
|
|
i6addr_t ip6;
|
|
}
|
|
|
|
%token <num> YY_NUMBER YY_HEX
|
|
%token <str> YY_STR
|
|
%token <ip6> YY_IPV6
|
|
%token YY_COMMENT
|
|
%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
|
|
%token YY_RANGE_OUT YY_RANGE_IN
|
|
%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT IPT_ALL
|
|
%token IPT_TABLE IPT_GROUPMAP IPT_HASH IPT_SRCHASH IPT_DSTHASH
|
|
%token IPT_ROLE IPT_TYPE IPT_TREE
|
|
%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME IPT_POLICY
|
|
%token IPT_POOL IPT_DSTLIST IPT_ROUNDROBIN
|
|
%token IPT_WEIGHTED IPT_RANDOM IPT_CONNECTION
|
|
%token IPT_WHOIS IPT_FILE
|
|
%type <num> role table inout unit dstopts weighting
|
|
%type <ipp> ipftree range addrlist
|
|
%type <adrmsk> addrmask
|
|
%type <ipe> ipfgroup ipfhash hashlist hashentry
|
|
%type <ipe> groupentry setgrouplist grouplist
|
|
%type <ipa> ipaddr mask
|
|
%type <ip4> ipv4
|
|
%type <str> number setgroup name
|
|
%type <ipd> dstentry dstentries dstlist
|
|
|
|
%%
|
|
file: line
|
|
| assign
|
|
| file line
|
|
| file assign
|
|
;
|
|
|
|
line: table role ipftree eol { ip_pool_node_t *n;
|
|
iplo.ipo_unit = $2;
|
|
iplo.ipo_list = $3;
|
|
load_pool(&iplo, poolioctl);
|
|
while ((n = $3) != NULL) {
|
|
$3 = n->ipn_next;
|
|
free(n);
|
|
}
|
|
resetlexer();
|
|
use_inet6 = 0;
|
|
}
|
|
| table role ipfhash eol { iphtent_t *h;
|
|
ipht.iph_unit = $2;
|
|
ipht.iph_type = IPHASH_LOOKUP;
|
|
load_hash(&ipht, $3, poolioctl);
|
|
while ((h = $3) != NULL) {
|
|
$3 = h->ipe_next;
|
|
free(h);
|
|
}
|
|
resetlexer();
|
|
use_inet6 = 0;
|
|
}
|
|
| groupmap role number ipfgroup eol
|
|
{ iphtent_t *h;
|
|
ipht.iph_unit = $2;
|
|
strncpy(ipht.iph_name, $3,
|
|
sizeof(ipht.iph_name));
|
|
ipht.iph_type = IPHASH_GROUPMAP;
|
|
load_hash(&ipht, $4, poolioctl);
|
|
while ((h = $4) != NULL) {
|
|
$4 = h->ipe_next;
|
|
free(h);
|
|
}
|
|
resetlexer();
|
|
use_inet6 = 0;
|
|
}
|
|
| YY_COMMENT
|
|
| poolline eol
|
|
;
|
|
|
|
eol: ';'
|
|
;
|
|
|
|
assign: YY_STR assigning YY_STR ';' { set_variable($1, $3);
|
|
resetlexer();
|
|
free($1);
|
|
free($3);
|
|
yyvarnext = 0;
|
|
}
|
|
;
|
|
|
|
assigning:
|
|
'=' { yyvarnext = 1; }
|
|
;
|
|
|
|
table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht));
|
|
bzero((char *)&iphte, sizeof(iphte));
|
|
bzero((char *)&iplo, sizeof(iplo));
|
|
bzero((char *)&ipld, sizeof(ipld));
|
|
*ipht.iph_name = '\0';
|
|
iplo.ipo_flags = IPHASH_ANON;
|
|
iplo.ipo_name[0] = '\0';
|
|
}
|
|
;
|
|
|
|
groupmap:
|
|
IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht));
|
|
bzero((char *)&iphte, sizeof(iphte));
|
|
*ipht.iph_name = '\0';
|
|
ipht.iph_unit = IPHASH_GROUPMAP;
|
|
ipht.iph_flags = $2;
|
|
}
|
|
;
|
|
|
|
inout: IPT_IN { $$ = FR_INQUE; }
|
|
| IPT_OUT { $$ = FR_OUTQUE; }
|
|
;
|
|
|
|
role: IPT_ROLE '=' unit { $$ = $3; }
|
|
;
|
|
|
|
unit: IPT_IPF { $$ = IPL_LOGIPF; }
|
|
| IPT_NAT { $$ = IPL_LOGNAT; }
|
|
| IPT_AUTH { $$ = IPL_LOGAUTH; }
|
|
| IPT_COUNT { $$ = IPL_LOGCOUNT; }
|
|
| IPT_ALL { $$ = IPL_LOGALL; }
|
|
;
|
|
|
|
ipftree:
|
|
IPT_TYPE '=' IPT_TREE number start addrlist end
|
|
{ strncpy(iplo.ipo_name, $4,
|
|
sizeof(iplo.ipo_name));
|
|
$$ = $6;
|
|
}
|
|
;
|
|
|
|
ipfhash:
|
|
IPT_TYPE '=' IPT_HASH number hashopts start hashlist end
|
|
{ strncpy(ipht.iph_name, $4,
|
|
sizeof(ipht.iph_name));
|
|
$$ = $7;
|
|
}
|
|
;
|
|
|
|
ipfgroup:
|
|
setgroup hashopts start grouplist end
|
|
{ iphtent_t *e;
|
|
for (e = $4; e != NULL;
|
|
e = e->ipe_next)
|
|
if (e->ipe_group[0] == '\0')
|
|
strncpy(e->ipe_group,
|
|
$1,
|
|
FR_GROUPLEN);
|
|
$$ = $4;
|
|
free($1);
|
|
}
|
|
| hashopts start setgrouplist end
|
|
{ $$ = $3; }
|
|
;
|
|
|
|
number: IPT_NUM '=' YY_NUMBER { snprintf(poolname, sizeof(poolname), "%u", $3);
|
|
$$ = poolname;
|
|
}
|
|
| IPT_NAME '=' YY_STR { strncpy(poolname, $3,
|
|
FR_GROUPLEN);
|
|
poolname[FR_GROUPLEN-1]='\0';
|
|
free($3);
|
|
$$ = poolname;
|
|
}
|
|
| { $$ = ""; }
|
|
;
|
|
|
|
setgroup:
|
|
IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1];
|
|
strncpy(tmp, $3, FR_GROUPLEN);
|
|
$$ = strdup(tmp);
|
|
free($3);
|
|
}
|
|
| IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1];
|
|
snprintf(tmp, sizeof(tmp), "%u", $3);
|
|
$$ = strdup(tmp);
|
|
}
|
|
;
|
|
|
|
hashopts:
|
|
| size
|
|
| seed
|
|
| size seed
|
|
;
|
|
|
|
addrlist:
|
|
';' { $$ = NULL; }
|
|
| range next addrlist { $$ = $1;
|
|
while ($1->ipn_next != NULL)
|
|
$1 = $1->ipn_next;
|
|
$1->ipn_next = $3;
|
|
}
|
|
| range next { $$ = $1; }
|
|
;
|
|
|
|
grouplist:
|
|
';' { $$ = NULL; }
|
|
| groupentry next grouplist { $$ = $1; $1->ipe_next = $3; }
|
|
| addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t));
|
|
$$->ipe_addr = $1[0].adf_addr;
|
|
$$->ipe_mask = $1[1].adf_addr;
|
|
$$->ipe_family = $1[0].adf_family;
|
|
$$->ipe_next = $3;
|
|
}
|
|
| groupentry next { $$ = $1; }
|
|
| addrmask next { $$ = calloc(1, sizeof(iphtent_t));
|
|
$$->ipe_addr = $1[0].adf_addr;
|
|
$$->ipe_mask = $1[1].adf_addr;
|
|
#ifdef USE_INET6
|
|
if (use_inet6)
|
|
$$->ipe_family = AF_INET6;
|
|
else
|
|
#endif
|
|
$$->ipe_family = AF_INET;
|
|
}
|
|
| YY_STR { $$ = add_htablehosts($1);
|
|
free($1);
|
|
}
|
|
;
|
|
|
|
setgrouplist:
|
|
';' { $$ = NULL; }
|
|
| groupentry next { $$ = $1; }
|
|
| groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; }
|
|
;
|
|
|
|
groupentry:
|
|
addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t));
|
|
$$->ipe_addr = $1[0].adf_addr;
|
|
$$->ipe_mask = $1[1].adf_addr;
|
|
strncpy($$->ipe_group, $3,
|
|
FR_GROUPLEN);
|
|
#ifdef USE_INET6
|
|
if (use_inet6)
|
|
$$->ipe_family = AF_INET6;
|
|
else
|
|
#endif
|
|
$$->ipe_family = AF_INET;
|
|
free($3);
|
|
}
|
|
;
|
|
|
|
range: addrmask { $$ = calloc(1, sizeof(*$$));
|
|
$$->ipn_info = 0;
|
|
$$->ipn_addr = $1[0];
|
|
$$->ipn_mask = $1[1];
|
|
#ifdef USE_INET6
|
|
if (use_inet6)
|
|
$$->ipn_addr.adf_family =
|
|
AF_INET6;
|
|
else
|
|
#endif
|
|
$$->ipn_addr.adf_family =
|
|
AF_INET;
|
|
}
|
|
| '!' addrmask { $$ = calloc(1, sizeof(*$$));
|
|
$$->ipn_info = 1;
|
|
$$->ipn_addr = $2[0];
|
|
$$->ipn_mask = $2[1];
|
|
#ifdef USE_INET6
|
|
if (use_inet6)
|
|
$$->ipn_addr.adf_family =
|
|
AF_INET6;
|
|
else
|
|
#endif
|
|
$$->ipn_addr.adf_family =
|
|
AF_INET;
|
|
}
|
|
| YY_STR { $$ = add_poolhosts($1);
|
|
free($1);
|
|
}
|
|
| IPT_WHOIS IPT_FILE YY_STR { $$ = read_whoisfile($3);
|
|
free($3);
|
|
}
|
|
;
|
|
|
|
hashlist:
|
|
';' { $$ = NULL; }
|
|
| hashentry next { $$ = $1; }
|
|
| hashentry next hashlist { $1->ipe_next = $3; $$ = $1; }
|
|
;
|
|
|
|
hashentry:
|
|
addrmask { $$ = calloc(1, sizeof(iphtent_t));
|
|
$$->ipe_addr = $1[0].adf_addr;
|
|
$$->ipe_mask = $1[1].adf_addr;
|
|
#ifdef USE_INET6
|
|
if (use_inet6)
|
|
$$->ipe_family = AF_INET6;
|
|
else
|
|
#endif
|
|
$$->ipe_family = AF_INET;
|
|
}
|
|
| YY_STR { $$ = add_htablehosts($1);
|
|
free($1);
|
|
}
|
|
;
|
|
|
|
addrmask:
|
|
ipaddr '/' mask { $$[0] = $1;
|
|
setadflen(&$$[0]);
|
|
$$[1] = $3;
|
|
$$[1].adf_len = $$[0].adf_len;
|
|
}
|
|
| ipaddr { $$[0] = $1;
|
|
setadflen(&$$[1]);
|
|
$$[1].adf_len = $$[0].adf_len;
|
|
#ifdef USE_INET6
|
|
if (use_inet6)
|
|
memset(&$$[1].adf_addr, 0xff,
|
|
sizeof($$[1].adf_addr.in6));
|
|
else
|
|
#endif
|
|
memset(&$$[1].adf_addr, 0xff,
|
|
sizeof($$[1].adf_addr.in4));
|
|
}
|
|
;
|
|
|
|
ipaddr: ipv4 { $$.adf_addr.in4 = $1;
|
|
$$.adf_family = AF_INET;
|
|
setadflen(&$$);
|
|
use_inet6 = 0;
|
|
}
|
|
| YY_NUMBER { $$.adf_addr.in4.s_addr = htonl($1);
|
|
$$.adf_family = AF_INET;
|
|
setadflen(&$$);
|
|
use_inet6 = 0;
|
|
}
|
|
| YY_IPV6 { $$.adf_addr = $1;
|
|
$$.adf_family = AF_INET6;
|
|
setadflen(&$$);
|
|
use_inet6 = 1;
|
|
}
|
|
;
|
|
|
|
mask: YY_NUMBER { bzero(&$$, sizeof($$));
|
|
if (use_inet6) {
|
|
if (ntomask(AF_INET6, $1,
|
|
(u_32_t *)&$$.adf_addr) == -1)
|
|
yyerror("bad bitmask");
|
|
} else {
|
|
if (ntomask(AF_INET, $1,
|
|
(u_32_t *)&$$.adf_addr.in4) == -1)
|
|
yyerror("bad bitmask");
|
|
}
|
|
}
|
|
| ipv4 { bzero(&$$, sizeof($$));
|
|
$$.adf_addr.in4 = $1;
|
|
}
|
|
| YY_IPV6 { bzero(&$$, sizeof($$));
|
|
$$.adf_addr = $1;
|
|
}
|
|
;
|
|
|
|
size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; }
|
|
;
|
|
|
|
seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; }
|
|
;
|
|
|
|
ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
|
|
{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
|
|
yyerror("Invalid octet string for IP address");
|
|
return(0);
|
|
}
|
|
$$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
|
|
$$.s_addr = htonl($$.s_addr);
|
|
}
|
|
;
|
|
|
|
next: ';' { yyexpectaddr = 1; }
|
|
;
|
|
|
|
start: '{' { yyexpectaddr = 1; }
|
|
;
|
|
|
|
end: '}' { yyexpectaddr = 0; }
|
|
;
|
|
|
|
poolline:
|
|
IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')'
|
|
start dstlist end
|
|
{ bzero((char *)&ipld, sizeof(ipld));
|
|
strncpy(ipld.ipld_name, $6,
|
|
sizeof(ipld.ipld_name));
|
|
ipld.ipld_unit = $2;
|
|
ipld.ipld_policy = $8;
|
|
load_dstlist(&ipld, poolioctl, $11);
|
|
resetlexer();
|
|
use_inet6 = 0;
|
|
free($6);
|
|
}
|
|
| IPT_POOL unit '/' IPT_TREE '(' name ';' ')'
|
|
start addrlist end
|
|
{ bzero((char *)&iplo, sizeof(iplo));
|
|
strncpy(iplo.ipo_name, $6,
|
|
sizeof(iplo.ipo_name));
|
|
iplo.ipo_list = $10;
|
|
iplo.ipo_unit = $2;
|
|
load_pool(&iplo, poolioctl);
|
|
resetlexer();
|
|
use_inet6 = 0;
|
|
free($6);
|
|
}
|
|
| IPT_POOL '(' name ';' ')' start addrlist end
|
|
{ bzero((char *)&iplo, sizeof(iplo));
|
|
strncpy(iplo.ipo_name, $3,
|
|
sizeof(iplo.ipo_name));
|
|
iplo.ipo_list = $7;
|
|
iplo.ipo_unit = IPL_LOGALL;
|
|
load_pool(&iplo, poolioctl);
|
|
resetlexer();
|
|
use_inet6 = 0;
|
|
free($3);
|
|
}
|
|
| IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')'
|
|
start hashlist end
|
|
{ iphtent_t *h;
|
|
bzero((char *)&ipht, sizeof(ipht));
|
|
strncpy(ipht.iph_name, $6,
|
|
sizeof(ipht.iph_name));
|
|
ipht.iph_unit = $2;
|
|
load_hash(&ipht, $11, poolioctl);
|
|
while ((h = ipht.iph_list) != NULL) {
|
|
ipht.iph_list = h->ipe_next;
|
|
free(h);
|
|
}
|
|
resetlexer();
|
|
use_inet6 = 0;
|
|
free($6);
|
|
}
|
|
| IPT_GROUPMAP '(' name ';' inout ';' ')'
|
|
start setgrouplist end
|
|
{ iphtent_t *h;
|
|
bzero((char *)&ipht, sizeof(ipht));
|
|
strncpy(ipht.iph_name, $3,
|
|
sizeof(ipht.iph_name));
|
|
ipht.iph_type = IPHASH_GROUPMAP;
|
|
ipht.iph_unit = IPL_LOGIPF;
|
|
ipht.iph_flags = $5;
|
|
load_hash(&ipht, $9, poolioctl);
|
|
while ((h = ipht.iph_list) != NULL) {
|
|
ipht.iph_list = h->ipe_next;
|
|
free(h);
|
|
}
|
|
resetlexer();
|
|
use_inet6 = 0;
|
|
free($3);
|
|
}
|
|
;
|
|
|
|
name: IPT_NAME YY_STR { $$ = $2; }
|
|
| IPT_NUM YY_NUMBER { char name[80];
|
|
snprintf(name, sizeof(name), "%d", $2);
|
|
$$ = strdup(name);
|
|
}
|
|
;
|
|
|
|
hashoptlist:
|
|
| hashopt ';'
|
|
| hashoptlist ';' hashopt ';'
|
|
;
|
|
hashopt:
|
|
IPT_SIZE YY_NUMBER
|
|
| IPT_SEED YY_NUMBER
|
|
;
|
|
|
|
dstlist:
|
|
dstentries { $$ = $1; }
|
|
| ';' { $$ = NULL; }
|
|
;
|
|
|
|
dstentries:
|
|
dstentry next { $$ = $1; }
|
|
| dstentry next dstentries { $1->ipfd_next = $3; $$ = $1; }
|
|
;
|
|
|
|
dstentry:
|
|
YY_STR ':' ipaddr { int size = sizeof(*$$) + strlen($1) + 1;
|
|
$$ = calloc(1, size);
|
|
if ($$ != NULL) {
|
|
$$->ipfd_dest.fd_name = strlen($1) + 1;
|
|
bcopy($1, $$->ipfd_names,
|
|
$$->ipfd_dest.fd_name);
|
|
$$->ipfd_dest.fd_addr = $3;
|
|
$$->ipfd_size = size;
|
|
}
|
|
free($1);
|
|
}
|
|
| ipaddr { $$ = calloc(1, sizeof(*$$));
|
|
if ($$ != NULL) {
|
|
$$->ipfd_dest.fd_name = -1;
|
|
$$->ipfd_dest.fd_addr = $1;
|
|
$$->ipfd_size = sizeof(*$$);
|
|
}
|
|
}
|
|
;
|
|
|
|
dstopts:
|
|
{ $$ = IPLDP_NONE; }
|
|
| IPT_POLICY IPT_ROUNDROBIN ';' { $$ = IPLDP_ROUNDROBIN; }
|
|
| IPT_POLICY IPT_WEIGHTED weighting ';' { $$ = $3; }
|
|
| IPT_POLICY IPT_RANDOM ';' { $$ = IPLDP_RANDOM; }
|
|
| IPT_POLICY IPT_HASH ';' { $$ = IPLDP_HASHED; }
|
|
| IPT_POLICY IPT_SRCHASH ';' { $$ = IPLDP_SRCHASH; }
|
|
| IPT_POLICY IPT_DSTHASH ';' { $$ = IPLDP_DSTHASH; }
|
|
;
|
|
|
|
weighting:
|
|
IPT_CONNECTION { $$ = IPLDP_CONNECTION; }
|
|
;
|
|
%%
|
|
static wordtab_t yywords[] = {
|
|
{ "all", IPT_ALL },
|
|
{ "auth", IPT_AUTH },
|
|
{ "connection", IPT_CONNECTION },
|
|
{ "count", IPT_COUNT },
|
|
{ "dst-hash", IPT_DSTHASH },
|
|
{ "dstlist", IPT_DSTLIST },
|
|
{ "file", IPT_FILE },
|
|
{ "group", IPT_GROUP },
|
|
{ "group-map", IPT_GROUPMAP },
|
|
{ "hash", IPT_HASH },
|
|
{ "in", IPT_IN },
|
|
{ "ipf", IPT_IPF },
|
|
{ "name", IPT_NAME },
|
|
{ "nat", IPT_NAT },
|
|
{ "number", IPT_NUM },
|
|
{ "out", IPT_OUT },
|
|
{ "policy", IPT_POLICY },
|
|
{ "pool", IPT_POOL },
|
|
{ "random", IPT_RANDOM },
|
|
{ "round-robin", IPT_ROUNDROBIN },
|
|
{ "role", IPT_ROLE },
|
|
{ "seed", IPT_SEED },
|
|
{ "size", IPT_SIZE },
|
|
{ "src-hash", IPT_SRCHASH },
|
|
{ "table", IPT_TABLE },
|
|
{ "tree", IPT_TREE },
|
|
{ "type", IPT_TYPE },
|
|
{ "weighted", IPT_WEIGHTED },
|
|
{ "whois", IPT_WHOIS },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
|
|
int
|
|
ippool_parsefile(int fd, char *filename, ioctlfunc_t iocfunc)
|
|
{
|
|
FILE *fp = NULL;
|
|
char *s;
|
|
|
|
yylineNum = 1;
|
|
(void) yysettab(yywords);
|
|
|
|
s = getenv("YYDEBUG");
|
|
if (s)
|
|
yydebug = atoi(s);
|
|
else
|
|
yydebug = 0;
|
|
|
|
if (strcmp(filename, "-")) {
|
|
fp = fopen(filename, "r");
|
|
if (!fp) {
|
|
fprintf(stderr, "fopen(%s) failed: %s\n", filename,
|
|
STRERROR(errno));
|
|
return(-1);
|
|
}
|
|
} else
|
|
fp = stdin;
|
|
|
|
while (ippool_parsesome(fd, fp, iocfunc) == 1)
|
|
;
|
|
if (fp != NULL)
|
|
fclose(fp);
|
|
return(0);
|
|
}
|
|
|
|
|
|
int
|
|
ippool_parsesome(int fd, FILE *fp, ioctlfunc_t iocfunc)
|
|
{
|
|
char *s;
|
|
int i;
|
|
|
|
poolioctl = iocfunc;
|
|
|
|
if (feof(fp))
|
|
return(0);
|
|
i = fgetc(fp);
|
|
if (i == EOF)
|
|
return(0);
|
|
if (ungetc(i, fp) == EOF)
|
|
return(0);
|
|
if (feof(fp))
|
|
return(0);
|
|
s = getenv("YYDEBUG");
|
|
if (s)
|
|
yydebug = atoi(s);
|
|
else
|
|
yydebug = 0;
|
|
|
|
yyin = fp;
|
|
yyparse();
|
|
return(1);
|
|
}
|
|
|
|
|
|
static iphtent_t *
|
|
add_htablehosts(char *url)
|
|
{
|
|
iphtent_t *htop, *hbot, *h;
|
|
alist_t *a, *hlist;
|
|
|
|
if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
|
|
hlist = load_url(url);
|
|
} else {
|
|
use_inet6 = 0;
|
|
|
|
hlist = calloc(1, sizeof(*hlist));
|
|
if (hlist == NULL)
|
|
return(NULL);
|
|
|
|
if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) {
|
|
yyerror("Unknown hostname");
|
|
}
|
|
}
|
|
|
|
hbot = NULL;
|
|
htop = NULL;
|
|
|
|
for (a = hlist; a != NULL; a = a->al_next) {
|
|
h = calloc(1, sizeof(*h));
|
|
if (h == NULL)
|
|
break;
|
|
|
|
h->ipe_family = a->al_family;
|
|
h->ipe_addr = a->al_i6addr;
|
|
h->ipe_mask = a->al_i6mask;
|
|
|
|
if (hbot != NULL)
|
|
hbot->ipe_next = h;
|
|
else
|
|
htop = h;
|
|
hbot = h;
|
|
}
|
|
|
|
alist_free(hlist);
|
|
|
|
return(htop);
|
|
}
|
|
|
|
|
|
static ip_pool_node_t *
|
|
add_poolhosts(char *url)
|
|
{
|
|
ip_pool_node_t *ptop, *pbot, *p;
|
|
alist_t *a, *hlist;
|
|
|
|
if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
|
|
hlist = load_url(url);
|
|
} else {
|
|
use_inet6 = 0;
|
|
|
|
hlist = calloc(1, sizeof(*hlist));
|
|
if (hlist == NULL)
|
|
return(NULL);
|
|
|
|
if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) {
|
|
yyerror("Unknown hostname");
|
|
}
|
|
}
|
|
|
|
pbot = NULL;
|
|
ptop = NULL;
|
|
|
|
for (a = hlist; a != NULL; a = a->al_next) {
|
|
p = calloc(1, sizeof(*p));
|
|
if (p == NULL)
|
|
break;
|
|
p->ipn_mask.adf_addr = a->al_i6mask;
|
|
|
|
if (a->al_family == AF_INET) {
|
|
p->ipn_addr.adf_family = AF_INET;
|
|
#ifdef USE_INET6
|
|
} else if (a->al_family == AF_INET6) {
|
|
p->ipn_addr.adf_family = AF_INET6;
|
|
#endif
|
|
}
|
|
setadflen(&p->ipn_addr);
|
|
p->ipn_addr.adf_addr = a->al_i6addr;
|
|
p->ipn_info = a->al_not;
|
|
p->ipn_mask.adf_len = p->ipn_addr.adf_len;
|
|
|
|
if (pbot != NULL)
|
|
pbot->ipn_next = p;
|
|
else
|
|
ptop = p;
|
|
pbot = p;
|
|
}
|
|
|
|
alist_free(hlist);
|
|
|
|
return(ptop);
|
|
}
|
|
|
|
|
|
ip_pool_node_t *
|
|
read_whoisfile(char *file)
|
|
{
|
|
ip_pool_node_t *ntop, *ipn, node, *last;
|
|
char line[1024];
|
|
FILE *fp;
|
|
|
|
fp = fopen(file, "r");
|
|
if (fp == NULL)
|
|
return(NULL);
|
|
|
|
last = NULL;
|
|
ntop = NULL;
|
|
while (fgets(line, sizeof(line) - 1, fp) != NULL) {
|
|
line[sizeof(line) - 1] = '\0';
|
|
|
|
if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask))
|
|
continue;
|
|
ipn = calloc(1, sizeof(*ipn));
|
|
if (ipn == NULL)
|
|
continue;
|
|
ipn->ipn_addr = node.ipn_addr;
|
|
ipn->ipn_mask = node.ipn_mask;
|
|
if (last == NULL)
|
|
ntop = ipn;
|
|
else
|
|
last->ipn_next = ipn;
|
|
last = ipn;
|
|
}
|
|
fclose(fp);
|
|
return(ntop);
|
|
}
|
|
|
|
|
|
static void
|
|
setadflen(addrfamily_t *afp)
|
|
{
|
|
afp->adf_len = offsetof(addrfamily_t, adf_addr);
|
|
switch (afp->adf_family)
|
|
{
|
|
case AF_INET :
|
|
afp->adf_len += sizeof(struct in_addr);
|
|
break;
|
|
#ifdef USE_INET6
|
|
case AF_INET6 :
|
|
afp->adf_len += sizeof(struct in6_addr);
|
|
break;
|
|
#endif
|
|
default :
|
|
break;
|
|
}
|
|
}
|