-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathds_create.pl
executable file
·199 lines (161 loc) · 5.33 KB
/
ds_create.pl
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/perl -w
#######################################################################
#
# userconfig_create (C) 2001-2006 by Markus Schade
#
# license: General Public License version 2
#
#######################################################################
use strict;
use DBI;
use CSN;
sub dsconfig();
sub replace_file($$);
my $DSCONF="/etc/dynshaper/dynshaper.conf";
# begin
#######################################################################
dsconfig();
# end
#######################################################################
# begin subroutines
sub dsconfig() {
my $dbh = db_connect("traffic_shaper");
my (%fwconf, %dsallg, %group_info, %excepts);
my ($sql, $sth, $out);
# Allgemeine Dynshaper Parameter holen
$sql = qq{SELECT * from ds_allgemein_v2};
$sth = db_call($dbh,$sql);
while (my $r = $sth->fetchrow_hashref()) {
$dsallg{$r->{parameter}} = $r->{wert};
}
$sth->finish;
# Gruppenparameter holen
$sql = qq{SELECT * from ds_gruppen_v2};
$sth = db_call($dbh,$sql);
while (my $r = $sth->fetchrow_hashref()) {
$group_info{$r->{gruppe}}{$r->{parameter}} = $r->{wert};
}
$sth->finish;
$sql = qq{SELECT * from ds_ausnahmen_v2};
$sth = db_call($dbh,$sql);
while (my $r = $sth->fetchrow_hashref()) {
$excepts{$r->{ausnahme}}{$r->{parameter}} = $r->{wert};
}
$sth->finish;
# IPs einer zu einer person_id holen (auch für die fw)
$sql = qq{SELECT * FROM firewall_config
WHERE person_id IS NOT NULL
AND manglemask IS NOT NULL};
$sth = db_call($dbh,$sql);
while (my $r = $sth->fetchrow_hashref()) {
# fwmark aus person_id und Netzklassenbitmaske berechnen
my $mark = int($r->{person_id}) | int($r->{manglemask});
# shaping gruppe der person_id
$fwconf{$r->{person_id}}{gruppe} = $r->{gruppe};
# fwmark per IP
$fwconf{$r->{person_id}}{$r->{ip_adr}} = $mark;
# fwmarks einer person_id
push(@{$fwconf{$r->{person_id}}{mark}},$mark);
# IP Adressen einer person_id
push(@{$fwconf{$r->{person_id}}{ip}},$r->{ip_adr});
};
$sth->finish();
$dbh->disconnect();
#################### Shaper Config File generieren ################
$out = "#\n# !!! WARNING !!!\n" .
"# This file is generated automatically by $0\n" .
"# Modification is futile!\n#\n";
$out .= "VERSION=\"Dynamic Traffic Shaper v0.70\"\n";
$out .= "DEVINT=\"" . $dsallg{conf_devint} . "\"\n";
$out .= "BWINT=\"" . format_bits($dsallg{conf_bwint}) . "\"\n";
$out .= "DEVEXT=\"" . $dsallg{conf_devext} . "\"\n";
$out .= "BWEXT=\"" . format_bits($dsallg{conf_bwext}) . "\"\n";
$out .= "DYNSHAPER=\"" . $dsallg{conf_dspath} . "\"\n";
$out .= "TC=\"" . $dsallg{conf_tcpath} . "\"\n";
$out .= "MODPROBE=\"" . $dsallg{conf_mppath} . "\"\n";
#Gruppenliste
$out .= "UGROUPS=\"";
foreach my $group (sort {$a <=> $b} keys %group_info)
{
$out .= "$group "
}
chop $out; $out .= "\"\n";
foreach my $group (sort {$a <=> $b} keys %group_info)
{
my $rate = $group_info{$group}{conf_rate} * $group_info{$group}{conf_factor};
# BB jeder Gruppe
$out .= "RATE[$group]=\"" . format_bits_fine($rate) ."\"\n";
# FIXME: Minimum BB der beiden Interfaces zum Vergleich nutzen
# Perl hat keinen Min/Max Operator
# To shape or not to shape (incoming)
if ($rate > $dsallg{conf_noshape} || $rate > $dsallg{conf_bwint} || !$group_info{$group}{conf_in})
{
$out .= "IN[$group]=\"\"\n";
} else {
$out .= "IN[$group]=\"on\"\n";
}
# to shape or not to shape (outgoing)
if ($rate > $dsallg{conf_noshape} || $rate > $dsallg{conf_bwext} || !$group_info{$group}{conf_out})
{
$out .= "OUT[$group]=\"\"\n";
} else {
$out .= "OUT[$group]=\"on\"\n";
}
# Pro Gruppe die FW-Marks schreiben
$out .= "MARKS[$group]=\"";
foreach my $uid (keys %fwconf) {
if ($fwconf{$uid}{gruppe} == $group) {
$out .= "$uid:";
$out .= join (",", @{$fwconf{$uid}{mark}});
$out .= ";";
}
}
chop $out; $out .= "\"\n";
}
# und zum schluss die Ausnahmen
$out .= "EXCEPTS=\"";
foreach my $case (sort {$a <=> $b} keys %excepts) {
$out .= "$case "
}
chop $out; $out .= "\"\n";
foreach my $case (sort {$a <=> $b} keys %excepts) {
$out .= "ERATE[$case]=\"" . format_bits($excepts{$case}{conf_rate}) ."\"\n";
$out .= "EPRIO[$case]=\"" . $excepts{$case}{conf_prio} ."\"\n";
# Mehrere Matches stehen in der DB mit , getrennt
# Der tc filter will aber ; haben
$excepts{$case}{conf_in} =~ s/,/;/g;
$out .= "EIN[$case]=\"" . $excepts{$case}{conf_in} ."\"\n";
# Mehrere Matches stehen in der DB mit , getrennt
# Der tc filter will aber ; haben
$excepts{$case}{conf_out} =~ s/,/;/g;
$out .= "EOUT[$case]=\"" . $excepts{$case}{conf_out} ."\"\n";
$out .= "EBOUND[$case]=\"" . $excepts{$case}{conf_bound} ."\"\n";
}
replace_file($DSCONF, $out);
# chown shaper.root $DSCONF
#my ($login,$pass,$userid,$gid) = getpwnam('shaper')
# or die "User 'shaper' not in passwd file";
#chown $userid, $gid, $DSCONF;
}
#
# Library functions
#
sub replace_file($$) {
my $file = shift;
my $data = shift;
my $tmpl_file = "$file.tmpl";
my $out_file = "$file.new";
open OUT, ">$out_file" or die "Cannot open $out_file for writing: $!";
if (-f $tmpl_file) {
open TMPL, "<$tmpl_file" or die "Cannot open $tmpl_file for reading: $!";
while (<TMPL>) {
/^#RULES#/ or print OUT and next;
print OUT $data;
}
close TMPL;
} else {
print OUT $data;
}
close OUT;
rename "$file.new", "$file" or die "Cannot rename $file.new to $file: $!";
}