__PACKAGE__->cgBuildIndices;
our
$VERSION
=
'1.00'
;
sub
_load {
my
$self
=
shift
;
my
(
$file
) =
@_
;
my
$csv
=
$self
->state->value(
'csv'
,
$self
->idx);
my
$match_fields
=
$self
->state->value(
'match_fields'
,
$self
->idx);
my
$lookup_field
=
$self
->state->value(
'lookup_field'
,
$self
->idx);
unless
(
defined
(
$csv
)) {
my
$csvxs
= Text::CSV_XS->new({
binary
=> 1,
sep_char
=>
','
,
allow_loose_quotes
=> 1,
allow_loose_escapes
=> 1,
escape_char
=>
'"'
,
}) or
die
(
"lookup: cannot initiate Text::CSV_XS\n"
);
open
(
my
$fd
,
'<'
,
$file
) or
die
(
"lookup: cannot open file: $file\n"
);
my
$header
=
$csvxs
->getline(
$fd
) or
die
(
"lookup: cannot get header\n"
);
die
(
"lookup: no line found\n"
)
unless
defined
$header
;
my
$lookup
=
pop
@$header
;
$lookup_field
=
$lookup
;
$match_fields
= [
sort
{
$a
cmp
$b
}
@$header
];
$header
=
join
(
'+'
,
sort
{
$a
cmp
$b
}
@$header
);
while
(
my
$line
=
$csvxs
->getline(
$fd
)) {
my
$last
=
pop
@$line
;
my
$key
=
join
(
'+'
,
sort
{
$a
cmp
$b
}
@$line
);
$csv
->{
$header
}{
lc
(
$key
)} = {
$lookup_field
=>
$last
};
}
$self
->state->add(
'csv'
,
$csv
,
$self
->idx);
$self
->state->add(
'match_fields'
,
$match_fields
,
$self
->idx);
$self
->state->add(
'lookup_field'
,
$lookup_field
,
$self
->idx);
}
return
[
$csv
,
$match_fields
,
$lookup_field
];
}
sub
process {
my
$self
=
shift
;
my
(
$input
) =
@_
;
my
$options
=
$self
->options;
my
$file
=
$options
->{0};
die
(
"lookup: file not given\n"
)
unless
defined
$file
;
die
(
"lookup: file not found: $file\n"
)
unless
-f
$file
;
my
$cidr
=
$options
->{cidr} ||
'ip'
;
my
$r
=
$self
->_load(
$file
);
my
$csv
=
$r
->[0];
my
$match_fields
=
$r
->[1];
my
$lookup_field
=
$r
->[2];
for
my
$field
(
@$match_fields
) {
my
$values
=
$self
->value(
$input
,
$field
);
unless
(
defined
(
$values
)) {
$self
->output->add(
$input
);
return
1;
}
}
for
my
$field
(
@$match_fields
) {
my
$values
=
$self
->value(
$input
,
$field
) or
next
;
if
(
$field
eq
$cidr
) {
for
my
$v
(
@$values
) {
for
my
$this
(
keys
%{
$csv
->{
$cidr
}}) {
if
(ipv4_in_network(
$this
,
$v
)) {
for
my
$k
(
keys
%{
$csv
->{
$field
}{
$this
}}) {
$self
->set(
$input
,
$k
,
$csv
->{
$field
}{
$this
}{
$k
}, 1);
}
}
}
}
}
else
{
for
my
$v
(
@$values
) {
if
(
defined
(
$csv
->{
$field
}) &&
defined
(
$csv
->{
$field
}{
lc
(
$v
)})) {
for
my
$k
(
keys
%{
$csv
->{
$field
}{
lc
(
$v
)}}) {
$self
->set(
$input
,
$k
,
$csv
->{
$field
}{
lc
(
$v
)}{
$k
}, 1);
}
}
}
}
}
$self
->output->add(
$input
);
return
1;
}
1;