2 ###############################################################################
4 # collecty - A system statistics collection daemon for IPFire #
5 # Copyright (C) 2015 IPFire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
28 CONNTRACK_FILE
= "/proc/net/nf_conntrack"
30 class ConntrackTable(object):
48 _stateful_layer4_protocols
= {
85 def __init__(self
, filename
):
86 with
open(filename
) as f
:
87 self
.layer3_protocols
= {}
88 for proto
in self
._layer
3_protocols
:
89 self
.layer3_protocols
[proto
] = 0
91 self
.layer4_protocols
= {}
92 for proto
in self
._layer
4_protocols
:
93 self
.layer4_protocols
[proto
] = 0
95 self
.protocol_states
= {}
96 for proto
, states
in self
._stateful
_layer
4_protocols
.items():
97 self
.protocol_states
[proto
] = dict((state
, 0) for state
in states
)
99 for line
in f
.readlines():
103 layer3_protocol
= line
[0]
106 self
.layer3_protocols
[layer3_protocol
] += 1
108 self
.layer3_protocols
["other"] += 1
111 layer4_protocol
= line
[2]
114 self
.layer4_protocols
[layer4_protocol
] += 1
116 self
.layer4_protocols
["other"] += 1
117 layer4_protocol
= "other"
119 # Count connection states
120 if self
.protocol_states
.has_key(layer4_protocol
):
124 self
.protocol_states
[layer4_protocol
][state
] += 1
129 class ConntrackLayer3ProtocolsGraphTemplate(base
.GraphTemplate
):
130 name
= "conntrack-layer3-protocols"
132 protocols
= ConntrackTable
._layer
3_protocols
139 protocol_descriptions
= {
142 "other" : _("Other"),
146 def graph_title(self
):
147 return _("Connections by Layer 3 Protocols")
150 def graph_vertical_label(self
):
151 return _("Number of open connections")
153 def get_object_table(self
, object_id
):
155 "file" : self
.plugin
.get_object("layer3-protocols"),
162 for proto
in reversed(self
.protocols
):
164 "colour" : self
.protocol_colours
.get(proto
, "#000000"),
165 "description" : self
.protocol_descriptions
.get(proto
, proto
),
169 "legend_min" : "%10s\: %%8.0lf" % _("Minimum"),
170 "legend_max" : "%10s\: %%8.0lf" % _("Maximum"),
171 "legend_avg" : "%10s\: %%8.0lf" % _("Average"),
172 "legend_cur" : "%10s\: %%8.0lf" % _("Current"),
176 "DEF:%(proto)s=%%(file)s:%(proto)s:AVERAGE" % i
,
177 "AREA:%(proto)s%(colour)s:%(description)-15s:STACK" % i
,
178 "VDEF:%(proto)s_cur=%(proto)s,LAST" % i
,
179 "GPRINT:%(proto)s_cur:%(legend_cur)s" % i
,
180 "VDEF:%(proto)s_avg=%(proto)s,AVERAGE" % i
,
181 "GPRINT:%(proto)s_avg:%(legend_avg)s" % i
,
182 "VDEF:%(proto)s_min=%(proto)s,MINIMUM" % i
,
183 "GPRINT:%(proto)s_min:%(legend_min)s" % i
,
184 "VDEF:%(proto)s_max=%(proto)s,MAXIMUM" % i
,
185 "GPRINT:%(proto)s_max:%(legend_max)s\\n" % i
,
191 def rrd_graph_args(self
):
193 "--legend-direction=bottomup",
197 class ConntrackLayer4ProtocolsGraphTemplate(ConntrackLayer3ProtocolsGraphTemplate
):
198 name
= "conntrack-layer4-protocols"
205 "udplite" : "#3366cc",
210 protocol_descriptions
= {
215 "udplite" : _("UDP Lite"),
218 "other" : _("Other"),
221 protocol_sortorder
= {
232 def graph_title(self
):
233 return _("Connections by IP Protocols")
237 return sorted(ConntrackTable
._layer
4_protocols
,
238 key
=lambda x
: self
.protocol_sortorder
.get(x
, 99))
240 def get_object_table(self
, object_id
):
242 "file" : self
.plugin
.get_object("layer4-protocols"),
247 class ConntrackProtocolWithStatesGraphTemplate(base
.GraphTemplate
):
248 name
= "conntrack-protocol-states"
254 "CLOSEREQ" : "#000000",
255 "CLOSING" : "#111111",
256 "IGNORE" : "#222222",
257 "INVALID" : "#333333",
260 "PARTOPEN" : "#666666",
261 "REQUEST" : "#777777",
262 "RESPOND" : "#888888",
263 "TIME_WAIT" : "#999999",
266 "CLOSED" : "#000000",
267 "COOKIE_ECHOED" : "#111111",
268 "COOKIE_WAIT" : "#222222",
269 "ESTABLISHED" : "#333333",
271 "SHUTDOWN_ACK_SENT" : "#555555",
272 "SHUTDOWN_RECD" : "#666666",
273 "SHUTDOWN_SENT" : "#777777",
277 "CLOSE_WAIT" : "#999999",
278 "ESTABLISHED" : "#000000",
279 "FIN_WAIT" : "#888888",
280 "LAST_ACK" : "#777777",
282 "SYN_RECV" : "#111111",
283 "SYN_SENT" : "#222222",
284 "SYN_SENT2" : "#333333",
285 "TIME_WAIT" : "#444444",
289 states_descriptions
= {
314 "SHUTDOWN_ACK_SENT" : 0,
333 def graph_title(self
):
334 return _("Protocol States of all %s connections") % self
.protocol
.upper()
337 def graph_vertical_label(self
):
338 return _("Number of open connections")
342 return self
.object.protocol
346 return sorted(ConntrackTable
._stateful
_layer
4_protocols
[self
.protocol
],
347 key
=lambda x
: self
.states_sortorder
[self
.protocol
].get(x
, 99))
353 for state
in reversed(self
.states
):
355 "colour" : self
.states_colours
[self
.protocol
].get(state
, "#000000"),
356 "description" : self
.states_descriptions
[self
.protocol
].get(state
, state
),
357 "proto" : self
.protocol
,
360 "legend_min" : "%10s\: %%8.0lf" % _("Minimum"),
361 "legend_max" : "%10s\: %%8.0lf" % _("Maximum"),
362 "legend_avg" : "%10s\: %%8.0lf" % _("Average"),
363 "legend_cur" : "%10s\: %%8.0lf" % _("Current"),
367 "DEF:%(state)s=%%(file)s:%(state)s:AVERAGE" % i
,
368 "AREA:%(state)s%(colour)s:%(description)-15s:STACK" % i
,
369 "VDEF:%(state)s_cur=%(state)s,LAST" % i
,
370 "GPRINT:%(state)s_cur:%(legend_cur)s" % i
,
371 "VDEF:%(state)s_avg=%(state)s,AVERAGE" % i
,
372 "GPRINT:%(state)s_avg:%(legend_avg)s" % i
,
373 "VDEF:%(state)s_min=%(state)s,MINIMUM" % i
,
374 "GPRINT:%(state)s_min:%(legend_min)s" % i
,
375 "VDEF:%(state)s_max=%(state)s,MAXIMUM" % i
,
376 "GPRINT:%(state)s_max:%(legend_max)s\\n" % i
,
382 def rrd_graph_args(self
):
384 "--legend-direction=bottomup",
388 class ConntrackObject(base
.Object
):
391 def init(self
, conntrack_table
):
392 self
.conntrack_table
= conntrack_table
399 class ConntrackLayer3ProtocolsObject(ConntrackObject
):
400 protocols
= ConntrackTable
._layer
3_protocols
403 "DS:%s:GAUGE:0:U" % p
for p
in protocols
408 return "layer3-protocols"
413 for proto
in self
.protocols
:
414 r
= self
.conntrack_table
.layer3_protocols
.get(proto
, 0)
415 results
.append("%s" % r
)
420 class ConntrackLayer4ProtocolsObject(ConntrackObject
):
421 protocols
= ConntrackTable
._layer
4_protocols
424 "DS:%s:GAUGE:0:U" % p
for p
in protocols
429 return "layer4-protocols"
434 for proto
in self
.protocols
:
435 r
= self
.conntrack_table
.layer4_protocols
.get(proto
, 0)
436 results
.append("%s" % r
)
441 class ConntrackProtocolWithStatesObject(ConntrackObject
):
442 def init(self
, conntrack_table
, protocol
):
443 ConntrackObject
.init(self
, conntrack_table
)
444 self
.protocol
= protocol
447 return "<%s %s>" % (self
.__class
__.__name
__, self
.protocol
)
451 return ConntrackTable
._stateful
_layer
4_protocols
.get(self
.protocol
)
454 def rrd_schema(self
):
455 return ["DS:%s:GAUGE:0:U" % state
for state
in self
.states
]
457 def get_states(self
):
460 for state
in self
.states
:
461 r
= self
.conntrack_table
.protocol_states
[self
.protocol
].get(state
, 0)
462 results
.append("%s" % r
)
467 return self
.get_states()
470 class ConntrackPlugin(base
.Plugin
):
472 description
= "Conntrack Plugin"
475 ConntrackLayer3ProtocolsGraphTemplate
,
476 ConntrackLayer4ProtocolsGraphTemplate
,
477 ConntrackProtocolWithStatesGraphTemplate
,
482 ct
= self
.get_conntrack_table()
485 yield ConntrackLayer3ProtocolsObject(self
, ct
)
486 yield ConntrackLayer4ProtocolsObject(self
, ct
)
488 for protocol
in ConntrackTable
._stateful
_layer
4_protocols
:
489 yield ConntrackProtocolWithStatesObject(self
, ct
, protocol
)
491 def get_conntrack_table(self
):
492 if not os
.path
.exists(CONNTRACK_FILE
):
495 return ConntrackTable(CONNTRACK_FILE
)