File: action.IfEvent

package info (click to toggle)
shorewall 5.0.15.6-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 4,716 kB
  • ctags: 961
  • sloc: perl: 26,144; sh: 2,043; makefile: 50
file content (142 lines) | stat: -rw-r--r-- 4,914 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#
# Shorewall -- /usr/share/shorewall/action.IfEvent
#
# Perform an Action based on a Event
#
# Parameters:
#
# Event        - Must start with a letter and be composed of letters, digits,
#                '-', and '_'.
# Action       - Anything that can appear in the ACTION column of a rule.
# Duration     - Duration in seconds over which the event is to be tested.
# Hit Count    - Number of packets seen within the duration -- default is 1
# Src or Dest  - 'src' (default) or 'dst'. Determines if the event is
#                associated with the source address (src) or destination
#                address (dst)
# Command      - 'check' (default) 'reset', or 'update'. If 'reset',
#                the event will be reset before the Action is taken.
#                If 'update', the timestamp associated with the event will
#                be updated and the action taken if the time limit/hitcount
#                are matched.
#                If '-', the action will be taken if the limit/hitcount are
#                matched but the event's timestamp will not be updated.
#
#                If a duration is specified, then 'checkreap' and 'updatereap'
#                may also be used. These are like 'check' and 'update'
#                respectively, but they also remove any event entries for
#                the IP address that are older than <duration> seconds.
# Disposition  - Disposition for any event generated.
#
# For additional information, see http://www.shorewall.net/Events.html
#
###############################################################################
#                                         DO NOT REMOVE THE FOLLOWING LINE
###############################################################################
#ACTION		SOURCE		DEST		PROTO	DPORT	SPORT

DEFAULTS -,ACCEPT,-,1,src,check,-

?begin perl

use Shorewall::Config qw(:DEFAULT :internal);
use Shorewall::Chains;
use Shorewall::Rules;
use strict;

my ( $event, $action, $duration, $hitcount, $destination, $command, $disposition ) = get_action_params( 7 );

fatal_error "An event name is required"           unless supplied $event;
fatal_error "Invalid event name ($event)"         unless $event =~ /^[a-zA-z][-\w]*$/;

if ( supplied $duration ) {
    fatal_error "Invalid time limit ($duration)"  unless $duration =~ /^\d+$/;
    $duration = "--seconds $duration ";
} else {
    $duration = '';
}

fatal_error "Invalid hit count ($hitcount)"       unless $hitcount =~ /^\d+$/;
fatal_error "Invalid Src or Dest ($destination)"  unless $destination =~ /^(?:src|dst)$/;

my $srcdst = $destination eq 'src'? '--rsource' : '--rdest';

our $commands_defined;

#
# Can't 'use constant' here
#
my ( $UPDATE_CMD, $CHECK_CMD, $RESET_CMD, $REAP_OPT, $TTL_OPT ) = ( 1, 2, 4, 8, 16 );

my %command = ( check =>  $CHECK_CMD,
		update => $UPDATE_CMD,
		reset  => $RESET_CMD
	      );

my %commandopts = ( 
		    reap   => $REAP_OPT,
		    ttl    => $TTL_OPT
		  );

my @command = split(':', $command);

$command = $command{shift @command} || 0;

fatal_error "Command must be 'check', 'update' or 'reset" unless $command & ( $CHECK_CMD | $UPDATE_CMD | $RESET_CMD); 

for ( @command ) {
    fatal_error "Invalid command option ($_)" unless $commandopts{$_};
    if ( $command & $commandopts{$_} ) {
	warning_message "Duplicate command ($_)";
    } else {
	$command |= $commandopts{$_};
    }
}

my $duplicate;

set_action_disposition( $disposition) if supplied $disposition;
set_action_name_to_caller;

require_capability 'RECENT_MATCH', 'Use of events', 's';

if ( $command & $REAP_OPT ) {
    require_capability( 'REAP_OPTION', q(The 'reap' option), 's' );
    fatal_error "${command}reap requires a time limit" unless $duration;
    $duration .= '--reap ';
}

$duration .= '--rttl ' if $command & $TTL_OPT;

if ( $command & $RESET_CMD ) {
    require_capability 'MARK_ANYWHERE', '"reset"', 's';

    print "Resetting....\n";
    
    my $mark = $globals{EVENT_MARK};
    #
    # The event mark bit must be within 32 bits
    #
    fatal_error "The mark layout does not permit resetting of events" unless $mark & 0xffffffff;
    #
    # Reset the event mark bit
    #
    perl_action_helper( 'INLINE', '-j MARK --and-mark '. in_hex( (~ $mark ) & 0xffffffff ) );

    $mark = in_hex $mark;
    #
    # Mark the packet if event is armed
    #
    perl_action_helper( 'INLINE', "-m recent --rcheck ${duration}--hitcount $hitcount --name $event $srcdst -j MARK --or-mark $mark" );
    #
    # if the event is armed, remove it and perform the action
    #
    perl_action_helper( $action , "-m mark --mark $mark/$mark -m recent --remove --name $event" );
} elsif ( $command & $UPDATE_CMD ) {
    perl_action_helper( $action, "-m recent --update ${duration}--hitcount $hitcount --name $event $srcdst" );
} else {
    perl_action_helper( $action, "-m recent --rcheck ${duration}--hitcount $hitcount --name $event $srcdst" );
}

1;

?end perl