diff --git a/agent_based/ospfv3_area.py b/agent_based/ospfv3_area.py
index bbf909a02647f7f330bb55e9d306c4dfd791cd74..fc87fa8e505ee2de5c410591f3111fc381747c93 100644
--- a/agent_based/ospfv3_area.py
+++ b/agent_based/ospfv3_area.py
@@ -43,7 +43,7 @@
 # .1.3.6.1.2.1.191.1.2.1.16.0 = INTEGER: 2
 # .1.3.6.1.2.1.191.1.2.1.16.3 = INTEGER: 2
 #
-# sample info
+# sample string_table
 # [
 #  ['0', '1', '17', '4', '0', '18', '646544', '2', '1', '2', '3', '0', '0', '1', '2'],
 #  ['1', '1', '3', '1', '0', '7', '317410', '2', '1', '2', '3', '0', '0', '1', '2']
@@ -69,6 +69,16 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     StringTable,
 )
 
+from cmk.base.plugins.agent_based.utils.ospfv3 import (
+    ospf_area_impotasextern,
+    ospf_area_summary,
+    ospf_area_translatorrole,
+    ospf_area_translatorrolestate,
+    ospf_area_submetrictype,
+    ospf_area_teeenabled,
+    get_area_type
+)
+
 
 @dataclass
 class OspfV3Area:
@@ -90,61 +100,6 @@ class OspfV3Area:
 
 
 def parse_ospfv3_area(string_table: StringTable) -> Dict[str, OspfV3Area]:
-    def ospf_area_impotasextern(st: str) -> str:
-        names = {'1': 'import External',
-                 '2': 'import no External',
-                 '3': 'import Nssa',
-                 }
-        return names.get(st, st)
-
-    def ospf_area_summary(st: str) -> str:
-        names = {'1': 'no Area Summary',
-                 '2': 'send Area Summary'}
-        return names.get(st, st)
-
-    def ospf_area_translatorrole(st: str) -> str:
-        names = {
-            '1': 'always',
-            '2': 'candidate',
-        }
-        return names.get(st, st)
-
-    def ospf_area_translatorrolestate(st: str) -> str:
-        names = {
-            '1': 'enabled',
-            '2': 'elected',
-            '3': 'disabled',
-        }
-        return names.get(st, st)
-
-    def ospf_area_submetrictype(st: str) -> str:
-        names = {
-            '1': 'ospfv3 Metric',
-            '2': 'comparable Cost',
-            '3': 'non Comparable',
-        }
-        return names.get(st, st)
-
-    def ospf_area_teeenabled(st: str) -> str:
-        names = {
-            '1': 'enabled',
-        }
-        return names.get(st, 'disabled')
-
-    def get_area_type(AreaImportAsExtern: str, AreaSummary: str) -> str:
-        areatype = 'UNKNOWN'
-        if int(AreaImportAsExtern) == 1 and int(AreaSummary) == 2:
-            areatype = 'normal'
-        if int(AreaImportAsExtern) == 2 and int(AreaSummary) == 1:
-            areatype = 'totaly subby'
-        if int(AreaImportAsExtern) == 2 and int(AreaSummary) == 2:
-            areatype = 'stubby'
-        if int(AreaImportAsExtern) == 3 and int(AreaSummary) == 2:
-            areatype = 'NSSA'
-        if int(AreaImportAsExtern) == 3 and int(AreaSummary) == 1:
-            areatype = 'totaly NSSA'
-        return areatype
-
     areas = {}
     for area in string_table:
         AreaId, AreaImportAsExtern, AreaSpfRuns, AreaBdrRtrCount, AreaAsBdrRtrCount, AreaScopeLsaCount, \
@@ -194,12 +149,10 @@ def check_ospfv3_area(item, params, section: Dict[str, OspfV3Area]) -> CheckResu
             value=value,
             label=label,
             metric_name=f'ospfv3_area_{metric}',
+            render_func=lambda v: f'{v:.0f}'
         )
-    yield Result(state=State.OK, summary=f'Area type: {area.AreaType}')
-    yield Result(state=State.OK, summary=f'area scope LSA checksum: {area.AreaScopeLsaCksumSum}')
-
-    yield Metric(name='ospfv3_area_nssatranslatorevents', value=area.AreaNssaTranslatorEvents)
-
+    yield Result(state=State.OK, notice=f'Area type: {area.AreaType}')
+    yield Result(state=State.OK, notice=f'Area scope LSA checksum: {area.AreaScopeLsaCksumSum}')
     yield Result(state=State.OK, notice=f'Area import as extern: {area.AreaImportAsExtern}')
     yield Result(state=State.OK, notice=f'Area summary: {area.AreaSummary}')
     yield Result(state=State.OK, notice=f'Area stub metric: {area.AreaStubMetric}')
@@ -209,6 +162,8 @@ def check_ospfv3_area(item, params, section: Dict[str, OspfV3Area]) -> CheckResu
     yield Result(state=State.OK, notice=f'Area NSSA stub metric type: {area.AreaStubMetricType}')
     yield Result(state=State.OK, notice=f'Area Traffic engineering  {area.AreaTEEnabled}')
 
+    yield Metric(name='ospfv3_area_nssatranslatorevents', value=area.AreaNssaTranslatorEvents)
+
 
 register.snmp_section(
     name='ospfv3_area',
diff --git a/agent_based/ospfv3_general.py b/agent_based/ospfv3_general.py
index 7e0594bc33bd95b3adfe69f55ea5ebefebd501ba..c6f909e54f9d8625119bf20dc6231a5be5880869 100644
--- a/agent_based/ospfv3_general.py
+++ b/agent_based/ospfv3_general.py
@@ -38,7 +38,7 @@
 # .1.3.6.1.2.1.191.1.1.24.0 = 0
 # .1.3.6.1.2.1.191.1.1.25.0 = 0
 #
-# sample info
+# sample string_table
 # [['0', '16843038', '1', '3', '1', '2', '0', '0', '256', '51', '0', '100000', '1', '1']]
 
 from dataclasses import dataclass
@@ -53,7 +53,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     exists,
     Metric,
     OIDEnd,
-    check_levels,
 )
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -61,6 +60,14 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     StringTable,
 )
 
+from cmk.base.plugins.agent_based.utils.ospfv3 import (
+    ospf_stub_router_advertisement,
+    ospf_admin_status,
+    ospf_abr_asbr_status,
+    ospf_stub_router_support,
+    render_ipv4_neighbor_id,
+)
+
 
 @dataclass
 class OspfV3General:
@@ -80,69 +87,6 @@ class OspfV3General:
 
 
 def parse_ospfv3_general(string_table: StringTable) -> Optional[OspfV3General]:
-    def ospf_stub_router_advertisement(st: str) -> str:
-        names = {'1': 'do Not Advertise',
-                 '2': 'advertise'}
-        return names.get(st, st)
-
-    def ospf_exit_reason(st: str) -> str:
-        names = {
-            '1': 'none',
-            '2': 'in Progress',
-            '3': 'completed',
-            '4': 'timed Out',
-            '5': 'topology Changed',
-        }
-        return names.get(st, st)
-
-    def ospf_restart_status(st: str) -> str:
-        names = {
-            '1': 'not Restarting',
-            '2': 'planned Restart',
-            '3': 'unplanned Restart',
-        }
-        return names.get(st, st)
-
-    def ospf_restart_support(st: str) -> str:
-        names = {
-            '1': 'none',
-            '2': 'planned Only',
-            '3': 'planned And Unplanned',
-        }
-        return names.get(st, st)
-
-    def ospf_admin_status(st: str) -> str:
-        names = {
-            '1': 'enabled',
-            '2': 'disabled',
-        }
-        return names.get(st, st)
-
-    def ospf_abr_asbr_status(st: str) -> str:
-        names = {
-            '1': 'yes',
-            '2': 'no',
-        }
-        return names.get(st, st)
-
-    def ospf_stub_router_support(st: str) -> str:
-        names = {
-            '1': 'yes',
-            '2': 'no',
-        }
-        return names.get(st, st)
-
-    def render_ipv4_router_id(nbrRtrId: str) -> str:
-        nbrRtrId = int(nbrRtrId)
-        firstoctet = nbrRtrId / (256 * 256 * 256)
-        nbrRtrId = nbrRtrId - (firstoctet * 256 * 256 * 256)
-        secondocted = nbrRtrId / (256 * 256)
-        nbrRtrId = nbrRtrId - (secondocted * 256 * 256)
-        thirdorted = nbrRtrId / 256
-        nbrRtrId = nbrRtrId - (thirdorted * 256)
-        nbrRtrId = '%d.%d.%d.%d' % (firstoctet, secondocted, thirdorted, nbrRtrId)
-        return nbrRtrId
-
     try:
         OID_END, RouterId, AdminStatus, VersionNumber, AreaBdrRtrStatus, ASBdrRtrStatus, AsScopeLsaCount, \
         AsScopeLsaCksumSum, OriginateNewLsas, RxNewLsas, ExtLsaCount, ExtAreaLsdbLimit, \
@@ -151,7 +95,7 @@ def parse_ospfv3_general(string_table: StringTable) -> Optional[OspfV3General]:
         return
 
     return OspfV3General(
-        RouterId=render_ipv4_router_id(RouterId),
+        RouterId=render_ipv4_neighbor_id(RouterId),
         AdminStatus=ospf_admin_status(AdminStatus),
         VersionNumber=int(VersionNumber),
         AreaBdrRtrStatus=ospf_abr_asbr_status(AreaBdrRtrStatus),
@@ -173,23 +117,23 @@ def discovery_ospfv3_general(section: OspfV3General) -> DiscoveryResult:
 
 def check_ospfv3_general(params, section: OspfV3General) -> CheckResult:
     yield Result(state=State.OK, summary=f'Router ID: {section.RouterId}')
-    yield Result(state=State.OK, summary=f'Area border router: {section.AreaBdrRtrStatus}')
-    yield Result(state=State.OK, summary=f'Autonomous system border router: {section.ASBdrRtrStatus}')
-
-    yield Metric(name='ospf_general_lsacount', value=section.AsScopeLsaCount)
-    yield Metric(name='ospf_general_rxnewlsas', value=section.RxNewLsas)
-    yield Metric(name='ospf_general_extlsacount', value=section.ExtLsaCount)
+    yield Result(state=State.OK, summary=f'ABR: {section.AreaBdrRtrStatus}')
+    yield Result(state=State.OK, summary=f'ASBR: {section.ASBdrRtrStatus}')
 
     yield Result(state=State.OK, notice=f'Version number: {section.VersionNumber}')
     yield Result(state=State.OK, notice=f'AS scope LSA checksum: {section.AsScopeLsaCksumSum}')
     yield Result(state=State.OK, notice=f'max # of non-default AS-external-LSAs: {section.ExtAreaLsdbLimit}')
-    yield Result(state=State.OK, notice=f'Reference bandwidth: %s KBPS' % section.ReferenceBandwidth)
+    yield Result(state=State.OK, notice=f'Reference bandwidth: {section.ReferenceBandwidth} KBPS')
     yield Result(state=State.OK, notice=f'Stub router support: {section.StubRouterSupport}')
     yield Result(state=State.OK, notice=f'Stub router advertisement: {section.StubRouterAdvertisement}')
 
     if section.AdminStatus == 'disabled':
         yield Result(state=State.WARN, notice='Admin disabled')
 
+    yield Metric(name='ospf3_general_lsacount', value=section.AsScopeLsaCount)
+    yield Metric(name='ospf3_general_rxnewlsas', value=section.RxNewLsas)
+    yield Metric(name='ospf3_general_extlsacount', value=section.ExtLsaCount)
+
 
 register.snmp_section(
     name='ospfv3_general',
@@ -230,7 +174,7 @@ register.snmp_section(
 
 register.check_plugin(
     name='ospfv3_general',
-    service_name='OSPFv3',
+    service_name='OSPFv3 general',
     discovery_function=discovery_ospfv3_general,
     check_function=check_ospfv3_general,
     check_default_parameters={
diff --git a/agent_based/ospfv3_interface.py b/agent_based/ospfv3_interface.py
index 2c135ada935ba88b687a1cd23a34f5e7d2f61147..9e01868f4a44c24e784b2c71a09868a9bf4dbbd0 100644
--- a/agent_based/ospfv3_interface.py
+++ b/agent_based/ospfv3_interface.py
@@ -60,7 +60,7 @@
 # .1.3.6.1.2.1.191.1.7.1.25.18.0 = INTEGER: 2
 # .1.3.6.1.2.1.191.1.7.1.25.23.0 = INTEGER: 2
 #
-# sample info
+# sample string_table
 # [
 #  [
 #   ['1.0', '0', '1', '1', '1', '1', '4', '120', '6', '50529055', '16843038', '6', '1', '4', '104400'],
@@ -101,7 +101,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     exists,
     Metric,
     OIDEnd,
-    check_levels,
 )
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -109,6 +108,14 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     StringTable,
 )
 
+from cmk.base.plugins.agent_based.utils.ospfv3 import (
+    ospf_if_type,
+    ospf_if_admin_status,
+    ospf_if_state,
+    render_ipv4_neighbor_id,
+    get_short_if_name,
+)
+
 
 @dataclass
 class OspfV3Interface:
@@ -129,59 +136,6 @@ class OspfV3Interface:
 
 
 def parse_ospfv3_interface(string_table: List[StringTable]) -> Optional[Dict[str, OspfV3Interface]]:
-    def ospf_if_type(st: str) -> str:
-        names = {'1': 'broadcast',
-                 '2': 'nbma',
-                 '3': 'pointToPoint',
-                 '5': 'pointToMultipoint',
-                 }
-        return names.get(st, st)
-
-    def ospf_if_admin_status(st: str) -> str:
-        names = {'1': 'enabled',
-                 '2': 'disabled'}
-        return names.get(st, st)
-
-    def ospf_if_state(st: str) -> str:
-        names = {
-            '1': 'down',
-            '2': 'loopback',
-            '3': 'waiting',
-            '4': 'P2P',
-            '5': 'DR',
-            '6': 'BDR',
-            '7': 'other DR',
-            '8': 'standby',
-        }
-        return names.get(st, st)
-
-    def render_ipv4_neighbor_id(nbrRtrId: str) -> str:
-        nbrRtrId = int(nbrRtrId)
-        firstoctet = nbrRtrId / (256 * 256 * 256)
-        nbrRtrId = nbrRtrId - (firstoctet * 256 * 256 * 256)
-        secondocted = nbrRtrId / (256 * 256)
-        nbrRtrId = nbrRtrId - (secondocted * 256 * 256)
-        thirdorted = nbrRtrId / 256
-        nbrRtrId = nbrRtrId - (thirdorted * 256)
-        nbrRtrId = '%d.%d.%d.%d' % (firstoctet, secondocted, thirdorted, nbrRtrId)
-        return nbrRtrId
-
-    def get_short_if_name(st: str) -> str:
-        names = {'ethernet': 'Eth',
-                 'fastethernet': 'Fa',
-                 'gigabitethernet': 'Gi',
-                 'tengigabitethernet': 'Te',
-                 'fortygigabitethernet': 'Fo',
-                 'hundredgigabitethernet': 'H',
-                 'port-channel': 'Po',
-                 'tunnel': 'T',
-                 'loopback': 'Lo',
-                 }
-        for item in names.keys():
-            if st.lower().startswith(item):
-                st = st.lower().replace(item, names.get(item))
-        return st
-
     ospf_interfaces = {}
     interfaceinfo, interfaces = string_table
 
@@ -233,11 +187,8 @@ def check_ospfv3_interface(item, params, section: Dict[str, OspfV3Interface]) ->
     yield Result(state=State.OK, summary=f'DR: {interface.IfDesignatedRouter}')
     yield Result(state=State.OK, summary=f'BDR: {interface.IfBackupDesignatedRouter}')
     yield Result(state=State.OK, summary=f'State: {interface.IfState}')
-    yield Result(state=State.OK, summary=f'link scope LSA checksum: {interface.IfLinkLsaCksumSum}')
-
-    yield Metric(name='ospfv3_interface_events', value=interface.IfEvents)
-    yield Metric(name='ospfv3_interface_linkscopelsacount', value=interface.IfLinkScopeLsaCount)
 
+    yield Result(state=State.OK, notice=f'Link scope LSA checksum: {interface.IfLinkLsaCksumSum}')
     yield Result(state=State.OK, notice=f'Interface type: {interface.IfType}')
     yield Result(state=State.OK, notice=f'Interface priority: {interface.IfRtrPriority}')
     yield Result(state=State.OK, notice=f'Interface hello interval: {interface.IfHelloInterval}')
@@ -254,6 +205,9 @@ def check_ospfv3_interface(item, params, section: Dict[str, OspfV3Interface]) ->
     if interface.IfState in ['waiting', 'standby']:
         yield Result(state=State.WARN, notice=f'state is {interface.IfState}')
 
+    yield Metric(name='ospfv3_interface_events', value=interface.IfEvents)
+    yield Metric(name='ospfv3_interface_linkscopelsacount', value=interface.IfLinkScopeLsaCount)
+
 
 register.snmp_section(
     name='ospfv3_interface',
diff --git a/agent_based/ospfv3_neighbor.py b/agent_based/ospfv3_neighbor.py
index f75eda696753b11b9823c89e0fa7282ec7da267d..f074333c2a50910bb513ef3058d465cc74b4e21b 100644
--- a/agent_based/ospfv3_neighbor.py
+++ b/agent_based/ospfv3_neighbor.py
@@ -37,6 +37,8 @@
 # OSPFV3-MIB::ospfv3NbrRestartHelperAge.1.0.50529054 = Gauge32: 0 seconds
 # OSPFV3-MIB::ospfv3NbrRestartHelperExitReason.1.0.50529054 = INTEGER: none(1)
 #
+#
+# sample string_table
 # [
 #  [
 #   ['1.0.50529054', '2', '\xfe\x80\x00\x00\x00\x00\x00\x00\x01\x92\x01h\x00\x00\x00\x03',
@@ -67,9 +69,8 @@
 
 #
 
-import re
 from dataclasses import dataclass
-from typing import Optional, Dict, List
+from typing import Dict, List
 
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     register,
@@ -80,7 +81,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     exists,
     Metric,
     OIDEnd,
-    check_levels,
 )
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -88,6 +88,17 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     StringTable,
 )
 
+from cmk.base.plugins.agent_based.utils.ospfv3 import (
+    ospf_nbr_addresstype,
+    ospf_nbr_hellosuppressed,
+    ospf_nbr_helperstatus,
+    ospf_nbr_helperexitreason,
+    render_ipv6_address,
+    render_ipv4_neighbor_id,
+    get_short_if_name,
+    ospf_nbr_state,
+)
+
 
 @dataclass
 class OspfV3Neighbor:
@@ -107,85 +118,6 @@ class OspfV3Neighbor:
 
 
 def parse_ospfv3_neighbor(string_table: List[StringTable]) -> Dict[str, OspfV3Neighbor]:
-    def ospf_nbr_addresstype(st: str) -> str:
-        names = {'0': 'unknown',
-                 '1': 'ipv4',
-                 '2': 'ipv6',
-                 '3': 'ipv4z',
-                 '4': 'ipv6z',
-                 '16': 'dns', }
-        return names.get(st, st)
-
-    def ospf_nbr_hellosuppressed(st: str) -> str:
-        names = {'1': 'true',
-                 '2': 'false'}
-        return names.get(st, st)
-
-    def ospf_nbr_helperstatus(st: str) -> str:
-        names = {'1': 'not Helping',
-                 '2': 'helping'}
-        return names.get(st, st)
-
-    def ospf_nbr_helperexitreason(st: str) -> str:
-        names = {'1': 'none',
-                 '2': 'inProgress',
-                 '3': 'completed',
-                 '4': 'timedOut',
-                 '5': 'topologyChanged'}
-        return names.get(st, st)
-
-    def shorten_ipv6_adress(address: str) -> str:
-        address = address.split(':')
-        span = 2
-        address = [''.join(address[i:i + span]) for i in range(0, len(address), span)]
-        for m in range(0, len(address)):
-            address[m] = re.sub(r'^0{1,3}', r'', address[m])
-        address = ':'.join(address)
-        zeros = ':0:0:0:0:0:0:'
-        while not zeros == '':
-            if zeros in address:
-                address = re.sub(r'%s' % zeros, r'::', address)
-                zeros = ''
-            else:
-                zeros = zeros[:-2]
-        if address == '0::0':
-            address = '::'
-
-        return address
-
-    def render_ipv6_address(bytestring) -> str:
-        address = ':'.join(['%02s' % hex(ord(m))[2:] for m in bytestring]).replace(' ', '0').upper()
-        address = shorten_ipv6_adress(address)
-
-        return address
-
-    def render_ipv4_neighbor_id(nbrRtrId: str) -> str:
-        nbrRtrId = int(nbrRtrId)
-        firstoctet = nbrRtrId / (256 * 256 * 256)
-        nbrRtrId = nbrRtrId - (firstoctet * 256 * 256 * 256)
-        secondocted = nbrRtrId / (256 * 256)
-        nbrRtrId = nbrRtrId - (secondocted * 256 * 256)
-        thirdorted = nbrRtrId / 256
-        nbrRtrId = nbrRtrId - (thirdorted * 256)
-        nbrRtrId = '%d.%d.%d.%d' % (firstoctet, secondocted, thirdorted, nbrRtrId)
-        return nbrRtrId
-
-    def get_short_if_name(st: str) -> str:
-        names = {'ethernet': 'Eth',
-                 'fastethernet': 'Fa',
-                 'gigabitethernet': 'Gi',
-                 'tengigabitethernet': 'Te',
-                 'fortygigabitethernet': 'Fo',
-                 'hundredgigabitethernet': 'H',
-                 'port-channel': 'Po',
-                 'tunnel': 'T',
-                 'loopback': 'Lo',
-                 }
-        for item in names.keys():
-            if st.lower().startswith(item):
-                st = st.lower().replace(item, names.get(item))
-        return st
-
     neighbors = {}
     neighborinfo, interfaces = string_table
 
@@ -228,17 +160,6 @@ def discovery_ospfv3_neighbor(section: Dict[str, OspfV3Neighbor]) -> DiscoveryRe
 
 
 def check_ospfv3_neighbor(item, params, section: Dict[str, OspfV3Neighbor]) -> CheckResult:
-    def ospf_nbr_state(st: int) -> str:
-        names = {1: 'down',
-                 2: 'attempt',
-                 3: 'init',
-                 4: 'twoWay',
-                 5: 'exchangeStart',
-                 6: 'exchange',
-                 7: 'loading',
-                 8: 'full'}
-        return names.get(st, st)
-
     try:
         neighbor = section[item]
     except KeyError:
@@ -261,9 +182,6 @@ def check_ospfv3_neighbor(item, params, section: Dict[str, OspfV3Neighbor]) -> C
     else:
         yield Result(state=State.UNKNOWN, notice='Invalid Output from Agent')
 
-    yield Metric(name='ospfv3_events', value=neighbor.nbrEvents)
-    yield Metric(name='ospfv3_lsretransqlen', value=neighbor.nbrLsRetransQLen)
-
     yield Result(state=State.OK, notice=f'Neighbor options: {neighbor.nbrOptions}')
     yield Result(state=State.OK, notice=f'Neighbor priority: {neighbor.nbrPriority}')
     yield Result(state=State.OK, notice=f'Neighbor hello suppressed: {neighbor.nbrHelloSuppressed}')
@@ -271,6 +189,9 @@ def check_ospfv3_neighbor(item, params, section: Dict[str, OspfV3Neighbor]) -> C
     yield Result(state=State.OK, notice=f'Neighbor helper age: {neighbor.nbrRestartHelperAge}')
     yield Result(state=State.OK, notice=f'Neighbor helper exit reason: {neighbor.nbrRestartHelperExitReason}')
 
+    yield Metric(name='ospfv3_events', value=neighbor.nbrEvents)
+    yield Metric(name='ospfv3_lsretransqlen', value=neighbor.nbrLsRetransQLen)
+
 
 register.snmp_section(
     name='ospfv3_neighbor',
diff --git a/agent_based/ospfv3_virtuallink.py b/agent_based/ospfv3_virtuallink.py
index df2af49f62e549c28c7f0144df0e68b585a299f7..f78aeb3854aca5940e2326524eed10b1e223d9b5 100644
--- a/agent_based/ospfv3_virtuallink.py
+++ b/agent_based/ospfv3_virtuallink.py
@@ -39,10 +39,11 @@
 # OSPFV3-MIB::ospfv3VirtNbrRestartHelperAge.3.50529054 = Gauge32: 0 seconds
 # OSPFV3-MIB::ospfv3VirtNbrRestartHelperExitReason.3.50529054 = INTEGER: none(1)
 #
-#
+# sample string_table
 # [
 #  [
-#   ['3.50529054', '0', '0', '2', '0\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x03\x000', '51', '8', '6', '0', '1', '26', '1', '0', '1']
+#   ['3.50529054', '0', '0', '2', '0\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x03\x000',
+#    '51', '8', '6', '0', '1', '26', '1', '0', '1']
 #  ],
 #  [
 #   ['1', 'Vlan1'],
@@ -66,9 +67,8 @@
 # ]
 #
 
-import re
 from dataclasses import dataclass
-from typing import Optional, Dict, List
+from typing import Dict, List
 
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     register,
@@ -79,7 +79,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     exists,
     Metric,
     OIDEnd,
-    check_levels,
 )
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -87,6 +86,17 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     StringTable,
 )
 
+from cmk.base.plugins.agent_based.utils.ospfv3 import (
+    ospf_nbr_addresstype,
+    ospf_nbr_hellosuppressed,
+    ospf_nbr_helperstatus,
+    ospf_nbr_helperexitreason,
+    render_ipv6_address,
+    render_ipv4_neighbor_id,
+    get_short_if_name,
+    ospf_nbr_state,
+)
+
 
 @dataclass
 class OspfV3VirtualLink:
@@ -100,88 +110,9 @@ class OspfV3VirtualLink:
     VirtNbrRestartHelperStatus: str
     VirtNbrRestartHelperAge: int
     VirtNbrRestartHelperExitReason: str
-    
-    
-def parse_ospfv3_virtuallink(string_table: List[StringTable]) -> Dict[str, OspfV3VirtualLink]:
-    def ospf_nbr_addresstype(st):
-        names = { '0': 'unknown',
-                      '1': 'ipv4',
-                      '2': 'ipv6',
-                      '3': 'ipv4z',
-                      '4': 'ipv6z',
-                      '16':'dns',}
-        return names.get(st, st)
-
-    def ospf_nbr_hellosuppressed(st):
-        names = {'1': 'true',
-                 '2': 'false'}
-        return names.get(st, st)
-
-    def ospf_nbr_helperstatus(st):
-        names = {'1': 'not Helping',
-                 '2': 'helping'}
-        return names.get(st, st)
-
-    def ospf_nbr_helperexitreason(st):
-        names = {'1': 'none',
-                 '2': 'inProgress',
-                 '3': 'completed',
-                 '4': 'timedOut',
-                 '5': 'topologyChanged'}
-        return names.get(st, st)
-
-    def shorten_ipv6_adress(address):
-        address = address.split(':')
-        span = 2
-        address = [''.join(address[i:i + span]) for i in range(0, len(address), span)]
-        for m in range(0, len(address)):
-            address[m] = re.sub(r'^0{1,3}', r'', address[m])
-        address = ':'.join(address)
-        zeros = ':0:0:0:0:0:0:'
-        while not zeros == '':
-            if zeros in address:
-                address = re.sub(r'%s' % zeros, r'::', address)
-                zeros = ''
-            else:
-                zeros = zeros[:-2]
-        if address == '0::0':
-            address = '::'
-
-        return address
-
-    def render_ipv6_address(bytestring):
-        address = ":".join(["%02s" % hex(ord(m))[2:] for m in bytestring]).replace(' ', '0').upper()
-        address = shorten_ipv6_adress(address)
-
-        return address
-
-    def render_ipv4_neighbor_id(nbrRtrId: str)-> str:
-        nbrRtrId = int(nbrRtrId)
-        firstoctet = nbrRtrId / (256*256*256)
-        nbrRtrId = nbrRtrId - (firstoctet *256*256*256)
-        secondocted = nbrRtrId / (256*256)
-        nbrRtrId = nbrRtrId - (secondocted * 256 * 256)
-        thirdorted = nbrRtrId / 256
-        nbrRtrId = nbrRtrId - (thirdorted * 256)
-        nbrRtrId = '%d.%d.%d.%d' % (firstoctet, secondocted, thirdorted, nbrRtrId)
-        return nbrRtrId
 
-    def get_short_if_name(st):
-        names = {'ethernet': 'Eth',
-                 'fastethernet': 'Fa',
-                 'gigabitethernet': 'Gi',
-                 'tengigabitethernet': 'Te',
-                 'fortygigabitethernet': 'Fo',
-                 'hundredgigabitethernet': 'H',
-                 'port-channel': 'Po',
-                 'tunnel': 'T',
-                 'loopback': 'Lo',
-                 }
-        for item in names.keys():
-            if st.lower().startswith(item):
-                st = st.lower().replace(item, names.get(item))
-        return st
 
+def parse_ospfv3_virtuallink(string_table: List[StringTable]) -> Dict[str, OspfV3VirtualLink]:
     virtual_links = {}
     virtual_links_info, interfaces = string_table
 
@@ -202,7 +133,7 @@ def parse_ospfv3_virtuallink(string_table: List[StringTable]) -> Dict[str, OspfV
                     nbrLocalInterface = get_short_if_name(ifName)
 
             # virtual_links[f'{VirtNbrAddress} on {nbrLocalInterface}']= OspfV3VirtualLink(
-            virtual_links[VirtNbrAddress]= OspfV3VirtualLink(
+            virtual_links[VirtNbrAddress] = OspfV3VirtualLink(
                 VirtNbrId=render_ipv4_neighbor_id(VirtNbrId),
                 VirtNbrArea=int(VirtNbrArea),
                 VirtNbrOptions=VirtNbrOptions,
@@ -224,31 +155,19 @@ def discovery_ospfv3_virtuallink(section: Dict[str, OspfV3VirtualLink]) -> Disco
 
 
 def check_ospfv3_virtuallink(item, params, section: Dict[str, OspfV3VirtualLink]) -> CheckResult:
-
-    def ospf_nbr_state(st: int)-> str:
-        names = {1: 'down',
-                 2: 'attempt',
-                 3: 'init',
-                 4: 'twoWay',
-                 5: 'exchangeStart',
-                 6: 'exchange',
-                 7: 'loading',
-                 8: 'full'}
-        return names.get(st, st)
-
     try:
         virtual_link = section[item]
     except KeyError:
         yield Result(state=State.UNKNOWN, notice='Item not found in SNMP data')
         return
-    
+
     nbrstatus = ospf_nbr_state(virtual_link.VirtNbrState)
 
     yield Result(state=State.OK, summary=f'Neighbor ID: {virtual_link.VirtNbrId}')
-    yield Result(state=State.OK, summary=f', Area: {virtual_link.VirtNbrArea}')
+    yield Result(state=State.OK, summary=f'Area: {virtual_link.VirtNbrArea}')
 
     nbrstate = virtual_link.VirtNbrState
-            
+
     if nbrstate in params['critical_states']:
         yield Result(state=State.CRIT, notice='State: {nbrstatus}')
     elif nbrstate in params['warning_states']:
@@ -258,14 +177,15 @@ def check_ospfv3_virtuallink(item, params, section: Dict[str, OspfV3VirtualLink]
     else:
         yield Result(state=State.UNKNOWN, notice='Invalid Output from Agent')
 
-    yield Metric(name='ospfv3_events', value=virtual_link.VirtNbrEvents)
-    yield Metric(name='ospfv3_lsretransqlen', value=virtual_link.VirtNbrLsRetransQLen)
-
     yield Result(state=State.OK, notice=f'Virtual link options: {virtual_link.VirtNbrOptions}')
     yield Result(state=State.OK, notice=f'Virtual link hello suppressed: {virtual_link.VirtNbrHelloSuppressed}')
     yield Result(state=State.OK, notice=f'Virtual link helper status: {virtual_link.VirtNbrRestartHelperStatus}')
     yield Result(state=State.OK, notice=f'Virtual link helper age: {virtual_link.VirtNbrRestartHelperAge}')
-    yield Result(state=State.OK, notice=f'Virtual link helper exit reason: {virtual_link.VirtNbrRestartHelperExitReason}')
+    yield Result(state=State.OK,
+                 notice=f'Virtual link helper exit reason: {virtual_link.VirtNbrRestartHelperExitReason}')
+
+    yield Metric(name='ospfv3_events', value=virtual_link.VirtNbrEvents)
+    yield Metric(name='ospfv3_lsretransqlen', value=virtual_link.VirtNbrLsRetransQLen)
 
 
 register.snmp_section(
diff --git a/agent_based/utils/ospfv3.py b/agent_based/utils/ospfv3.py
new file mode 100644
index 0000000000000000000000000000000000000000..832cf90a73904364b51e6aa71c830edbf55e4108
--- /dev/null
+++ b/agent_based/utils/ospfv3.py
@@ -0,0 +1,306 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2021-09-17
+#
+# include file, will be used with ospfv3_area, ospfv3_general, ospfv3_interface, ospfv3_neighbor, ospfv3_virtuallink
+#
+import re
+
+
+def get_area_type(area_import_as_extern: str, area_summary: str) -> str:
+    areatype = 'UNKNOWN'
+    if int(area_import_as_extern) == 1 and int(area_summary) == 2:
+        areatype = 'normal'
+    if int(area_import_as_extern) == 2 and int(area_summary) == 1:
+        areatype = 'totaly subby'
+    if int(area_import_as_extern) == 2 and int(area_summary) == 2:
+        areatype = 'stubby'
+    if int(area_import_as_extern) == 3 and int(area_summary) == 2:
+        areatype = 'NSSA'
+    if int(area_import_as_extern) == 3 and int(area_summary) == 1:
+        areatype = 'totaly NSSA'
+    return areatype
+
+
+def render_ipv4_neighbor_id(router_id: str) -> str:
+    """
+    >>> from pprint import pprint
+    >>> pprint(render_ipv4_neighbor_id('50529054'))
+    3.3.3.30
+    """
+    router_id = int(router_id)
+    firstoctet = router_id // (256 * 256 * 256)
+    router_id = router_id - (firstoctet * 256 * 256 * 256)
+    secondocted = router_id // (256 * 256)
+    router_id = router_id - (secondocted * 256 * 256)
+    thirdorted = router_id // 256
+    router_id = router_id - (thirdorted * 256)
+    router_id = f'{firstoctet}.{secondocted}.{thirdorted}.{router_id}'
+    return router_id
+
+
+_interface_displayhints = {
+    'ethernet': 'eth',
+    'fastethernet': 'Fa',
+    'gigabitethernet': 'Gi',
+    'tengigabitethernet': 'Te',
+    'fortygigabitethernet': 'Fo',
+    'hundredgigabitethernet': 'Hu',
+    'port-channel': 'Po',
+    'tunnel': 'Tu',
+    'loopback': 'Lo',
+    'cellular': 'Cel',
+    'vlan': 'Vlan',
+    'management': 'Ma',
+}
+
+
+def get_short_if_name(ifname: str) -> str:
+    """
+    returns short interface name from long interface name
+    ifname: is the long interface name
+    :type ifname: str
+    """
+
+    for ifname_prefix in _interface_displayhints.keys():
+        if ifname.lower().startswith(ifname_prefix.lower()):
+            ifname_short = _interface_displayhints[ifname_prefix]
+            return ifname.lower().replace(ifname_prefix.lower(), ifname_short, 1)
+    return ifname
+
+
+def _shorten_ipv6_adress(address: str) -> str:
+    """
+    >>> from pprint import pprint
+    >>> pprint(_shorten_ipv6_adress('20:03:00:00:00:00:00:00:01:92:01:68:00:00:00:01'))
+    2003::192:168:0:1
+    """
+    # '20:03:00:00:00:00:00:00:01:92:01:68:00:00:00:01'
+    address = address.split(':')
+    span = 2
+    address = [''.join(address[i:i + span]) for i in range(0, len(address), span)]
+    # ['2003', '0000', '0000', '0000', '0192', '0168', '0000', '0001']
+    for m in range(0, len(address)):
+        address[m] = re.sub(r'^0{1,3}', r'', address[m])
+    # ['2003', '0', '0', '0', '192', '168', '0', '1']
+    address = ':'.join(address)
+    # '2003:0:0:0:192:168:0:1'
+    zeros = ':0:0:0:0:0:0:'
+    while not zeros == '':
+        if zeros in address:
+            address = address.replace(zeros, '::', 1)
+            zeros = ''
+        else:
+            zeros = zeros[:-2]
+    if address == '0::0':
+        address = '::'
+    # '2003::192:168:0:1'
+    return address
+
+
+def render_ipv6_address(bytestring) -> str:
+    address = ':'.join([f'{hex(ord(m))[2:]:0>2}' for m in bytestring]).replace(' ', '0').upper()
+    address = _shorten_ipv6_adress(address)
+
+    return address
+
+
+def ospf_stub_router_advertisement(st: str) -> str:
+    names = {
+        '1': 'do Not Advertise',
+        '2': 'advertise',
+    }
+    return names.get(st, st)
+
+
+def ospf_exit_reason(st: str) -> str:
+    names = {
+        '1': 'none',
+        '2': 'in Progress',
+        '3': 'completed',
+        '4': 'timed Out',
+        '5': 'topology Changed',
+    }
+    return names.get(st, st)
+
+
+def ospf_restart_status(st: str) -> str:
+    names = {
+        '1': 'not Restarting',
+        '2': 'planned Restart',
+        '3': 'unplanned Restart',
+    }
+    return names.get(st, st)
+
+
+def ospf_restart_support(st: str) -> str:
+    names = {
+        '1': 'none',
+        '2': 'planned Only',
+        '3': 'planned And Unplanned',
+    }
+    return names.get(st, st)
+
+
+def ospf_admin_status(st: str) -> str:
+    names = {
+        '1': 'enabled',
+        '2': 'disabled',
+    }
+    return names.get(st, st)
+
+
+def ospf_abr_asbr_status(st: str) -> str:
+    names = {
+        '1': 'yes',
+        '2': 'no',
+    }
+    return names.get(st, st)
+
+
+def ospf_stub_router_support(st: str) -> str:
+    names = {
+        '1': 'yes',
+        '2': 'no',
+    }
+    return names.get(st, st)
+
+
+def ospf_area_impotasextern(st: str) -> str:
+    names = {
+        '1': 'import External',
+        '2': 'import no External',
+        '3': 'import Nssa',
+    }
+    return names.get(st, st)
+
+
+def ospf_area_summary(st: str) -> str:
+    names = {
+        '1': 'no Area Summary',
+        '2': 'send Area Summary',
+    }
+    return names.get(st, st)
+
+
+def ospf_area_translatorrole(st: str) -> str:
+    names = {
+        '1': 'always',
+        '2': 'candidate',
+    }
+    return names.get(st, st)
+
+
+def ospf_area_translatorrolestate(st: str) -> str:
+    names = {
+        '1': 'enabled',
+        '2': 'elected',
+        '3': 'disabled',
+    }
+    return names.get(st, st)
+
+
+def ospf_area_submetrictype(st: str) -> str:
+    names = {
+        '1': 'ospfv3 Metric',
+        '2': 'comparable Cost',
+        '3': 'non Comparable',
+    }
+    return names.get(st, st)
+
+
+def ospf_area_teeenabled(st: str) -> str:
+    names = {
+        '1': 'enabled',
+    }
+    return names.get(st, 'disabled')
+
+
+def ospf_if_type(st: str) -> str:
+    names = {
+        '1': 'broadcast',
+        '2': 'nbma',
+        '3': 'pointToPoint',
+        '5': 'pointToMultipoint',
+    }
+    return names.get(st, st)
+
+
+def ospf_if_admin_status(st: str) -> str:
+    names = {
+        '1': 'enabled',
+        '2': 'disabled',
+    }
+    return names.get(st, st)
+
+
+def ospf_if_state(st: str) -> str:
+    names = {
+        '1': 'down',
+        '2': 'loopback',
+        '3': 'waiting',
+        '4': 'P2P',
+        '5': 'DR',
+        '6': 'BDR',
+        '7': 'other DR',
+        '8': 'standby',
+    }
+    return names.get(st, st)
+
+
+def ospf_nbr_state(st: int) -> str:
+    names = {
+        1: 'down',
+        2: 'attempt',
+        3: 'init',
+        4: 'twoWay',
+        5: 'exchangeStart',
+        6: 'exchange',
+        7: 'loading',
+        8: 'full',
+    }
+    return names.get(st, st)
+
+
+def ospf_nbr_addresstype(st: str) -> str:
+    names = {
+        '0': 'unknown',
+        '1': 'ipv4',
+        '2': 'ipv6',
+        '3': 'ipv4z',
+        '4': 'ipv6z',
+        '16': 'dns',
+    }
+    return names.get(st, st)
+
+
+def ospf_nbr_hellosuppressed(st: str) -> str:
+    names = {
+        '1': 'true',
+        '2': 'false',
+    }
+    return names.get(st, st)
+
+
+def ospf_nbr_helperstatus(st: str) -> str:
+    names = {
+        '1': 'not Helping',
+        '2': 'helping',
+    }
+    return names.get(st, st)
+
+
+def ospf_nbr_helperexitreason(st: str) -> str:
+    names = {
+        '1': 'none',
+        '2': 'inProgress',
+        '3': 'completed',
+        '4': 'timedOut',
+        '5': 'topologyChanged',
+    }
+    return names.get(st, st)
diff --git a/ospfv3.mkp b/ospfv3.mkp
index 8fef4840fb4ed39cef766c46040cb98b66d7b03a..e46832ab2faabdf1ed8b4d742e190900e05650fa 100644
Binary files a/ospfv3.mkp and b/ospfv3.mkp differ
diff --git a/packages/ospfv3 b/packages/ospfv3
index 5747a4d43c495823a20f07a5acfc6e0fe6e8a343..5ac9a2f96fac658de96e3b922bb343794d219c6c 100644
--- a/packages/ospfv3
+++ b/packages/ospfv3
@@ -5,10 +5,11 @@
                            'ospfv3_general.py',
                            'ospfv3_interface.py',
                            'ospfv3_neighbor.py',
-                           'ospfv3_virtuallink.py'],
+                           'ospfv3_virtuallink.py',
+                           'utils/ospfv3.py'],
            'web': ['plugins/metrics/ospfv3.py']},
  'name': 'ospfv3',
- 'num_files': 6,
+ 'num_files': 7,
  'title': 'Collection of OSPFv3 checks',
  'version': '20210917.v0.2',
  'version.min_required': '2.0.0',
diff --git a/web/plugins/metrics/ospfv3.py b/web/plugins/metrics/ospfv3.py
index 75b5e6a6e220f12a89911c98703e4b0139e56107..58e9e6c1a9b267bb1691554075eb4072a139cb28 100644
--- a/web/plugins/metrics/ospfv3.py
+++ b/web/plugins/metrics/ospfv3.py
@@ -7,7 +7,7 @@
 # URL   : https://thl-cmk.hopto.org
 # Date  : 2019-11-02
 #
-# Cisco OSPFv3 metrics plugin
+# OSPFv3 metrics plugin
 #
 from cmk.gui.i18n import _