|
| 1 | +# SNMP::Info::Layer7::Stormshield |
| 2 | +# |
| 3 | +# Copyright (c) 2025 snmp-info Developers |
| 4 | +# All rights reserved. |
| 5 | +# |
| 6 | +# Redistribution and use in source and binary forms, with or without |
| 7 | +# modification, are permitted provided that the following conditions are met: |
| 8 | +# |
| 9 | +# * Redistributions of source code must retain the above copyright notice, |
| 10 | +# this list of conditions and the following disclaimer. |
| 11 | +# * Redistributions in binary form must reproduce the above copyright |
| 12 | +# notice, this list of conditions and the following disclaimer in the |
| 13 | +# documentation and/or other materials provided with the distribution. |
| 14 | +# * Neither the name of the University of California, Santa Cruz nor the |
| 15 | +# names of its contributors may be used to endorse or promote products |
| 16 | +# derived from this software without specific prior written permission. |
| 17 | +# |
| 18 | +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 19 | +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 20 | +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 21 | +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| 22 | +# LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 23 | +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 24 | +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 25 | +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 26 | +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 27 | +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 28 | +# POSSIBILITY OF SUCH DAMAGE. |
| 29 | + |
| 30 | +package SNMP::Info::Layer7::Stormshield; |
| 31 | + |
| 32 | +use strict; |
| 33 | +use warnings; |
| 34 | +use Exporter; |
| 35 | +use SNMP::Info::Layer7; |
| 36 | +use Data::Dumper; |
| 37 | + |
| 38 | +@SNMP::Info::Layer7::Stormshield::ISA = qw/SNMP::Info::Layer7 Exporter/; |
| 39 | +@SNMP::Info::Layer7::Stormshield::EXPORT_OK = qw//; |
| 40 | + |
| 41 | +our ($VERSION, %GLOBALS, %MIBS, %FUNCS, %MUNGE); |
| 42 | + |
| 43 | +$VERSION = '3.972002'; |
| 44 | + |
| 45 | +%MIBS = ( |
| 46 | + %SNMP::Info::Layer7::MIBS, |
| 47 | + 'STORMSHIELD-HA-MIB' => 'snsFwSerial', |
| 48 | + 'STORMSHIELD-PROPERTY-MIB' => 'snsSerialNumber', |
| 49 | +); |
| 50 | + |
| 51 | + |
| 52 | +# use qualified names to avoid leaf conflicts. There is PROPERTY, HA and some DEPRECATED mibs |
| 53 | +# with identical symbols |
| 54 | + |
| 55 | +%GLOBALS = ( |
| 56 | + %SNMP::Info::Layer7::GLOBALS, |
| 57 | + 'propmib_serial' => 'STORMSHIELD_PROPERTY_MIB__snsSerialNumber', |
| 58 | + 'propmib_model' => 'STORMSHIELD_PROPERTY_MIB__snsModel', |
| 59 | + 'propmib_version' => 'STORMSHIELD_PROPERTY_MIB__snsVersion', |
| 60 | +); |
| 61 | + |
| 62 | +%FUNCS = ( |
| 63 | + %SNMP::Info::Layer7::FUNCS, |
| 64 | + # HA MIB |
| 65 | + 'hamib_serial' => 'STORMSHIELD_HA_MIB__snsFwSerial', |
| 66 | + 'hamib_model' => 'STORMSHIELD_HA_MIB__snsModel', |
| 67 | + 'hamib_version' => 'STORMSHIELD_HA_MIB__snsVersion', |
| 68 | + ); |
| 69 | + |
| 70 | +%MUNGE = ( |
| 71 | + %SNMP::Info::Layer7::MUNGE, |
| 72 | + ); |
| 73 | + |
| 74 | +sub vendor { |
| 75 | + return 'stormshield'; |
| 76 | +} |
| 77 | + |
| 78 | +sub os { |
| 79 | + return 'SNS'; |
| 80 | +} |
| 81 | + |
| 82 | +sub serial { |
| 83 | + |
| 84 | + my $Stormshield = shift; |
| 85 | + my $hamib_serial = $Stormshield->hamib_serial(); |
| 86 | + my $propmib_serial = $Stormshield->propmib_serial(); |
| 87 | + |
| 88 | + # Collect serials preserving HA MIB order |
| 89 | + my %unique_serials; |
| 90 | + my @serials; |
| 91 | + my %seen; |
| 92 | + |
| 93 | + if (ref($hamib_serial) eq 'HASH') { |
| 94 | + foreach my $key (sort keys %$hamib_serial) { |
| 95 | + my $value = $hamib_serial->{$key}; |
| 96 | + push @serials, $value unless $seen{$value}++; |
| 97 | + } |
| 98 | + } else { |
| 99 | + push @serials, $hamib_serial unless $seen{$hamib_serial}++; |
| 100 | + } |
| 101 | + |
| 102 | + # Add Property MIB serials (avoiding duplicates) |
| 103 | + if (ref($propmib_serial) eq 'HASH') { |
| 104 | + foreach my $value (values %$propmib_serial) { |
| 105 | + push @serials, $value unless $seen{$value}++; |
| 106 | + } |
| 107 | + } else { |
| 108 | + push @serials, $propmib_serial unless $seen{$propmib_serial}++; |
| 109 | + } |
| 110 | + |
| 111 | + my $serial = join(' ', grep { defined && length } @serials); |
| 112 | + return $serial; |
| 113 | +} |
| 114 | + |
| 115 | + |
| 116 | + |
| 117 | +sub model { |
| 118 | + |
| 119 | + my $Stormshield = shift; |
| 120 | + my $hamib_model = $Stormshield->hamib_model(); |
| 121 | + my $propmib_model = $Stormshield->propmib_model(); |
| 122 | + |
| 123 | + my @models; |
| 124 | + my %seen; |
| 125 | + |
| 126 | + # Collect unique models preserving HA MIB order |
| 127 | + if (ref($hamib_model) eq 'HASH') { |
| 128 | + foreach my $key (sort keys %$hamib_model) { |
| 129 | + my $value = $hamib_model->{$key}; |
| 130 | + push @models, $value unless $seen{$value}++; |
| 131 | + } |
| 132 | + } else { |
| 133 | + push @models, $hamib_model unless $seen{$hamib_model}++; |
| 134 | + } |
| 135 | + |
| 136 | + # Add Property MIB model |
| 137 | + if (ref($propmib_model) eq 'HASH') { |
| 138 | + foreach my $value (values %$propmib_model) { |
| 139 | + push @models, $value unless $seen{$value}++; |
| 140 | + } |
| 141 | + } else { |
| 142 | + push @models, $propmib_model unless $seen{$propmib_model}++; |
| 143 | + } |
| 144 | + |
| 145 | + my $model = join(' ', grep { defined && length } @models); |
| 146 | + return $model; |
| 147 | +} |
| 148 | + |
| 149 | +sub os_ver { |
| 150 | + |
| 151 | + my $Stormshield = shift; |
| 152 | + my $hamib_version = $Stormshield->hamib_version(); |
| 153 | + my $propmib_version = $Stormshield->propmib_version(); |
| 154 | + |
| 155 | + my @versions; |
| 156 | + my %seen; |
| 157 | + |
| 158 | + # Collect unique versions preserving HA MIB order |
| 159 | + if (ref($hamib_version) eq 'HASH') { |
| 160 | + foreach my $key (sort keys %$hamib_version) { |
| 161 | + my $value = $hamib_version->{$key}; |
| 162 | + push @versions, $value unless $seen{$value}++; |
| 163 | + } |
| 164 | + } else { |
| 165 | + push @versions, $hamib_version unless $seen{$hamib_version}++; |
| 166 | + } |
| 167 | + |
| 168 | + # Add Property MIB version |
| 169 | + if (ref($propmib_version) eq 'HASH') { |
| 170 | + foreach my $value (values %$propmib_version) { |
| 171 | + push @versions, $value unless $seen{$value}++; |
| 172 | + } |
| 173 | + } else { |
| 174 | + push @versions, $propmib_version unless $seen{$propmib_version}++; |
| 175 | + } |
| 176 | + |
| 177 | + my $os_ver = join(' ', grep { defined && length } @versions); |
| 178 | + return $os_ver; |
| 179 | +} |
| 180 | + |
| 181 | + |
| 182 | + |
| 183 | +1; |
| 184 | + |
| 185 | +__END__ |
| 186 | +
|
| 187 | +=head1 NAME |
| 188 | +
|
| 189 | +SNMP::Info::Layer7::Stormshield - SNMP Interface to Stormshield Network Security appliances |
| 190 | +
|
| 191 | +=head1 AUTHORS |
| 192 | +
|
| 193 | +Rob Woodward |
| 194 | +
|
| 195 | +=head1 SYNOPSIS |
| 196 | +
|
| 197 | + # Let SNMP::Info determine the correct subclass for you. |
| 198 | + my $Stormshield = new SNMP::Info( |
| 199 | + AutoSpecify => 1, |
| 200 | + Debug => 1, |
| 201 | + DestHost => 'myfirewall', |
| 202 | + Community => 'public', |
| 203 | + Version => 2 |
| 204 | + ) |
| 205 | + or die "Can't connect to DestHost.\n"; |
| 206 | +
|
| 207 | + my $class = $Stormshield->class(); |
| 208 | + print "SNMP::Info determined this device to fall under subclass : $class\n"; |
| 209 | +
|
| 210 | +=head1 DESCRIPTION |
| 211 | +
|
| 212 | +Subclass for Stormshield Network Security (SNS) appliances |
| 213 | +
|
| 214 | +The module supports both High Availability (HA) and non-HA Stormshield appliances. The information retrieved can be different based on whether the device is a HA or non-HA device. |
| 215 | +
|
| 216 | +=head2 High Availability (HA) Devices |
| 217 | +
|
| 218 | +For HA devices, the module uses the STORMSHIELD-HA-MIB: |
| 219 | +
|
| 220 | +=over |
| 221 | +
|
| 222 | +=item Serial Number: C<snsFwSerial> (.1.3.6.1.4.1.11256.1.11.7.1.2) |
| 223 | +
|
| 224 | +=item Model: C<snsModel> (.1.3.6.1.4.1.11256.1.11.7.1.4) |
| 225 | +
|
| 226 | +=item Version: C<snsVersion> (.1.3.6.1.4.1.11256.1.11.7.1.5) |
| 227 | +
|
| 228 | +=back |
| 229 | +
|
| 230 | +Example SNMP walk for model: |
| 231 | + snmpwalk -v2c -On .1.3.6.1.4.1.11256.1.11.7.1.4 |
| 232 | + .1.3.6.1.4.1.11256.1.11.7.1.4.0 = STRING: "SN-S-Series-220" |
| 233 | + .1.3.6.1.4.1.11256.1.11.7.1.4.1 = STRING: "SN-S-Series-220" |
| 234 | +
|
| 235 | +=head2 Non-HA Devices |
| 236 | +
|
| 237 | +For non-HA devices, the module uses the STORMSHIELD-PROPERTY-MIB: |
| 238 | +
|
| 239 | +=over |
| 240 | +
|
| 241 | +=item Serial Number: C<snsSerialNumber> (.1.3.6.1.4.1.11256.1.18.3) |
| 242 | +
|
| 243 | +=item Model: C<snsModel> (.1.3.6.1.4.1.11256.1.18.1) |
| 244 | +
|
| 245 | +=item Version: C<snsVersion> (.1.3.6.1.4.1.11256.1.18.2) |
| 246 | +
|
| 247 | +=back |
| 248 | +
|
| 249 | +Example SNMP walk for model: |
| 250 | + snmpwalk -v2c -On .1.3.6.1.4.1.11256.1.18 |
| 251 | + .1.3.6.1.4.1.11256.1.18.1.0 = STRING: "SN-S-Series-220" |
| 252 | +
|
| 253 | +=head2 Inherited Classes |
| 254 | +
|
| 255 | +=over |
| 256 | +
|
| 257 | +=item SNMP::Info::Layer7 |
| 258 | +
|
| 259 | +=back |
| 260 | +
|
| 261 | +=head2 Required MIBs |
| 262 | +
|
| 263 | +=over |
| 264 | +
|
| 265 | +=item Inherited Classes' MIBs |
| 266 | +
|
| 267 | +See L<SNMP::Info::Layer7> for its own MIB requirements. |
| 268 | +
|
| 269 | +=item STORMSHIELD-HA-MIB |
| 270 | +
|
| 271 | +Required for High Availability (HA) Stormshield appliances. |
| 272 | +
|
| 273 | +=item STORMSHIELD-PROPERTY-MIB |
| 274 | +
|
| 275 | +Required for non-HA Stormshield appliances. |
| 276 | +
|
| 277 | +=back |
| 278 | +
|
| 279 | +=head1 GLOBALS |
| 280 | +
|
| 281 | +These are methods that return scalar value from SNMP |
| 282 | +
|
| 283 | +=over |
| 284 | +
|
| 285 | +=item $Stormshield->vendor() |
| 286 | +
|
| 287 | +Returns 'stormshield'. |
| 288 | +
|
| 289 | +=item $Stormshield->os() |
| 290 | +
|
| 291 | +Returns 'SNS'. |
| 292 | +
|
| 293 | +=item $Stormshield->os_ver() |
| 294 | +
|
| 295 | +Release extracted from Stormshield MIBs (HA or Property MIB). |
| 296 | +
|
| 297 | +=item $Stormshield->model() |
| 298 | +
|
| 299 | +Model extracted from Stormshield MIBs (HA or Property MIB). |
| 300 | +
|
| 301 | +=item $Stormshield->serial() |
| 302 | +
|
| 303 | +Returns serial number extracted from Stormshield MIBs (HA or Property MIB). |
| 304 | +
|
| 305 | +=back |
| 306 | +
|
| 307 | +=head2 Globals imported from SNMP::Info::Layer7 |
| 308 | +
|
| 309 | +See documentation in L<SNMP::Info::Layer7> for details. |
| 310 | +
|
| 311 | +=head1 TABLE ENTRIES |
| 312 | +
|
| 313 | +These are methods that return tables of information in the form of a reference |
| 314 | +to a hash. |
| 315 | +
|
| 316 | +=head2 Table Methods imported from SNMP::Info::Layer7 |
| 317 | +
|
| 318 | +See documentation in L<SNMP::Info::Layer7> for details. |
| 319 | +
|
| 320 | +=cut |
0 commit comments