From 424ebbe5288f2ce3ef4b89f22ff7545fc23c53ce Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Sun, 7 Apr 2024 14:12:36 +0200
Subject: [PATCH] update project

---
 README.md                              |   2 +-
 mkp/inv_ipv4_routes-0.0.2-20240407.mkp | Bin 0 -> 2787 bytes
 source/agent_based/inv_ipv4_routes.py  |  50 +++++++++++++++++--------
 source/packages/inv_ipv4_routes        |   4 +-
 4 files changed, 38 insertions(+), 18 deletions(-)
 create mode 100644 mkp/inv_ipv4_routes-0.0.2-20240407.mkp

diff --git a/README.md b/README.md
index d42dc73..240c521 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[PACKAGE]: ../../raw/master/mkp/inv_ipv4_routes-0.0.1-20231227.mkp "inv_ipv4_routes-0.0.1-20231227.mkp"
+[PACKAGE]: ../../raw/master/mkp/inv_ipv4_routes-0.0.2-20240407.mkp "inv_ipv4_routes-0.0.2-20240407.mkp"
 # Inventory of IPv4 routes
 
 The plugin adds the IPv4 routes of a device monitored via SNMP to the inventory.
diff --git a/mkp/inv_ipv4_routes-0.0.2-20240407.mkp b/mkp/inv_ipv4_routes-0.0.2-20240407.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..5ffca2ef8e9f8231f0bef316ac67bcbede95bfb2
GIT binary patch
literal 2787
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
YwKd%+XNUj4Bf?km0Va>kmdM8TKcB8)Z~y=R

literal 0
HcmV?d00001

diff --git a/source/agent_based/inv_ipv4_routes.py b/source/agent_based/inv_ipv4_routes.py
index 81c85ee..a302379 100644
--- a/source/agent_based/inv_ipv4_routes.py
+++ b/source/agent_based/inv_ipv4_routes.py
@@ -9,10 +9,13 @@
 # File  : inv_ipv4_route.py
 #
 # inventory of IPv4 routing information
+#
+# 2024.04.07: fixed missing/bad netmask (ThX bitwiz@froum.checkmk.com)
+#             improved validation if SNMP input data
 
 
-import ipaddress
 from dataclasses import dataclass
+from ipaddress import AddressValueError, IPv4Address, IPv4Network, NetmaskValueError
 from typing import List
 
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
@@ -71,7 +74,7 @@ class Ipv4Route:
     age: int | None
     cidr: int
     destination: str
-    if_index: int
+    if_index: int | None
     if_name: str
     netmask: str
     next_hop: str
@@ -80,23 +83,42 @@ class Ipv4Route:
     type: str
 
 
-def parse_inv_ipv4_routes(string_table: List[StringTable]) -> List[Ipv4Route]:
-    routes, if_info = string_table
+def parse_inv_ipv4_routes(string_table: List[StringTable]) -> List[Ipv4Route] | None:
+    try:
+        routes, if_info = string_table
+    except ValueError:
+        return
 
-    interface_by_index = {if_index: if_name for if_index, if_name in if_info}
+    try:
+        interface_by_index = {if_index: if_name for if_index, if_name in if_info}
+    except ValueError:
+        interface_by_index = {}
 
     ipv4_routes = []
-    for destination, netmask, next_hop, if_index, route_type, protocol, age, status in routes:
-        ipv4 = ipaddress.IPv4Network(address=f'{destination}/{netmask}', strict=False)
+
+    for entry in routes:
+        try:
+            destination, netmask, next_hop, if_index, route_type, protocol, age, status = entry
+        except ValueError:
+            continue
+        try:
+            ipv4 = IPv4Network(address=f'{destination}/{netmask}', strict=True)
+        except (AddressValueError, NetmaskValueError, ValueError):
+            continue
+        try:
+            next_hop = IPv4Address(next_hop)
+        except AddressValueError:
+            continue
+
         ipv4_routes.append(
             Ipv4Route(
                 age=int(age) if age.isdigit() else None,
                 cidr=int(ipv4.prefixlen),
-                destination=str(destination),
-                if_index=int(if_index),
-                if_name=str(interface_by_index.get(if_index, f'unknown ({if_index})')),
-                netmask=str(netmask),
-                next_hop=str(next_hop),
+                destination=str(ipv4.network_address),
+                if_index=int(if_index) if if_index.isdigit() else None,
+                if_name=str(interface_by_index.get(if_index, if_index)),
+                netmask=str(ipv4.netmask),
+                next_hop=str(next_hop.exploded),
                 protocol=_route_protocol.get(protocol, f'unknown ({protocol})'),
                 status=_route_status.get(status, f'unknown ({status})'),
                 type=_route_type.get(route_type, f'unknown ({route_type})'),
@@ -115,14 +137,12 @@ def inventory_ipv4_routes(section: List[Ipv4Route]) -> InventoryResult:
             'gateway': ipv4_route.next_hop,
         }
         inventory_columns = {
-            # 'age': render.timespan(ipv4_route.age),
+            **({"age": render.timespan(ipv4_route.age)} if ipv4_route.age else {}),
             'device': ipv4_route.if_name,
             'protocol': ipv4_route.protocol,
             'status': ipv4_route.status,
             'type': ipv4_route.type,
         }
-        if ipv4_route.age:
-            inventory_columns['age'] = render.timespan(ipv4_route.age)
 
         yield TableRow(
             path=path,
diff --git a/source/packages/inv_ipv4_routes b/source/packages/inv_ipv4_routes
index 136e1b1..6225df1 100644
--- a/source/packages/inv_ipv4_routes
+++ b/source/packages/inv_ipv4_routes
@@ -6,7 +6,7 @@
            'web': ['plugins/views/inv_ipv4_routes.py']},
  'name': 'inv_ipv4_routes',
  'title': 'Inventory of IPv4 routes',
- 'version': '0.0.1-20231227',
+ 'version': '0.0.2-20240407',
  'version.min_required': '2.2.0b1',
- 'version.packaged': '2.2.0p17',
+ 'version.packaged': '2.2.0p24',
  'version.usable_until': '2.3.0p1'}
-- 
GitLab