diff --git a/plugins/display/ip_type.py b/plugins/display/ip_type.py
new file mode 100644
index 0000000..abaa17c
--- /dev/null
+++ b/plugins/display/ip_type.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright Grégory Soutadé 2023
+
+# This file is part of iwla
+
+# iwla is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# iwla is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with iwla. If not, see .
+#
+
+from iwla import IWLA
+from iplugin import IPlugin
+from display import *
+
+"""
+Display hook
+
+Add IPv4/IPv6 statistics
+
+Plugin requirements :
+ post_analysis/ip_type
+
+Conf values needed :
+ None
+
+Output files :
+ OUTPUT_ROOT/year/month/index.html
+
+Statistics creation :
+ None
+
+Statistics update :
+ None
+
+Statistics deletion :
+ None
+"""
+
+class IWLADisplayIPType(IPlugin):
+ def __init__(self, iwla):
+ super(IWLADisplayIPType, self).__init__(iwla)
+ self.requires = ['IWLAPostAnalysisIPType']
+
+ def hook(self):
+ display = self.iwla.getDisplay()
+ ip_types = self.iwla.getMonthStats()['ip_type']
+
+ # Subdomains in index
+ title = self.iwla._(u'IP types')
+
+ index = self.iwla.getDisplayIndex()
+
+ table = display.createBlock(DisplayHTMLBlockTable, title, [self.iwla._('Type'), self.iwla._(u'Entrance')])
+ table.setColsCSSClass(['', 'iwla_hit'])
+ types = sorted(ip_types.items(), key=lambda t: t[0])
+ for (_type, count) in types:
+ table.appendRow([_type, count])
+ table.computeRatio(1)
+ index.appendBlock(table)
diff --git a/plugins/post_analysis/ip_type.py b/plugins/post_analysis/ip_type.py
new file mode 100644
index 0000000..fe8640d
--- /dev/null
+++ b/plugins/post_analysis/ip_type.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright Grégory Soutadé 2023
+
+# This file is part of iwla
+
+# iwla is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# iwla is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with iwla. If not, see .
+#
+
+import re
+
+from iwla import IWLA
+from iplugin import IPlugin
+
+"""
+Post analysis hook
+
+Detect if IP is IPv4 or IPv6
+
+Plugin requirements :
+ None
+
+Conf values needed :
+ None
+
+Output files :
+ None
+
+Statistics creation :
+visits :
+ remote_addr =>
+ ip_type
+
+month_stats :
+ ip_type : {4: XXX, 6: XXX}
+
+Statistics update :
+ None
+
+Statistics deletion :
+ None
+"""
+
+class IWLAPostAnalysisIPType(IPlugin):
+
+ def load(self):
+ self.v4_re = re.compile('[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
+ return True
+
+ def hook(self):
+ stats = self.iwla.getValidVisitors()
+ month_stats = self.iwla.getMonthStats()
+
+ if month_stats.get('ip_type', None) is None:
+ month_stats['ip_type'] = {4:0, 6:0}
+
+ for (k, super_hit) in stats.items():
+ if super_hit.get('ip_type', None) is None:
+ if self.v4_re.match(super_hit['remote_ip']):
+ _type = 4
+ else:
+ _type = 6
+ super_hit['ip_type'] = _type
+ month_stats['ip_type'][_type] += 1