├── .github
├── dependabot.yml
├── integration
│ ├── configuration.yaml
│ ├── example1.walk
│ └── ios.yaml
└── workflows
│ ├── codeql.yml
│ ├── docker.yml
│ ├── integration.yml
│ ├── maven-release.yml
│ └── maven.yml
├── .gitignore
├── .suppressions.xml
├── Dockerfile
├── LICENSE.txt
├── MAINTAINERS
├── README.md
├── docker
└── docker-entrypoint.sh
├── pom.xml
├── snmpman-cli
├── pom.xml
└── src
│ ├── main
│ ├── assembly
│ │ ├── dist.xml
│ │ └── snmpman.sh
│ ├── config
│ │ ├── configuration.yaml
│ │ ├── devices
│ │ │ ├── catos.yaml
│ │ │ ├── finesse.yaml
│ │ │ ├── foundry.yaml
│ │ │ ├── ios.yaml
│ │ │ ├── iosxr.yaml
│ │ │ ├── junos.yaml
│ │ │ └── nxos.yaml
│ │ └── walk
│ │ │ └── example1.walk
│ ├── java
│ │ └── com
│ │ │ └── oneandone
│ │ │ └── snmpman
│ │ │ ├── CommandLineOptions.java
│ │ │ ├── Main.java
│ │ │ └── package-info.java
│ └── resources
│ │ └── log4j2.xml
│ └── test
│ ├── java
│ └── com
│ │ └── oneandone
│ │ └── snmpman
│ │ └── CommandLineOptionsTest.java
│ └── resources
│ ├── configuration
│ ├── cisco.yaml
│ ├── configuration.yaml
│ ├── differentStartingOID.txt
│ ├── empty.yaml
│ └── example.txt
│ └── log4j2.xml
└── snmpman
├── pom.xml
└── src
├── main
├── config
│ ├── configuration.yaml
│ ├── devices
│ │ ├── catos.yaml
│ │ ├── finesse.yaml
│ │ ├── foundry.yaml
│ │ ├── ios.yaml
│ │ ├── iosxr.yaml
│ │ ├── junos.yaml
│ │ └── nxos.yaml
│ ├── log4j2.xml
│ └── walk
│ │ └── example1.walk
└── java
│ └── com
│ └── oneandone
│ └── snmpman
│ ├── Snmpman.java
│ ├── SnmpmanAgent.java
│ ├── configuration
│ ├── AgentConfiguration.java
│ ├── Device.java
│ ├── Walks.java
│ ├── modifier
│ │ ├── AbstractIntegerModifier.java
│ │ ├── CommunityContextModifier.java
│ │ ├── CommunityIndexCounter32Modifier.java
│ │ ├── Counter32Modifier.java
│ │ ├── Counter64Modifier.java
│ │ ├── Gauge32Modifier.java
│ │ ├── Integer32Modifier.java
│ │ ├── ModifiedVariable.java
│ │ ├── Modifier.java
│ │ ├── TimeTicksModifier.java
│ │ ├── UnsignedInteger32Modifier.java
│ │ ├── VariableModifier.java
│ │ └── package-info.java
│ ├── package-info.java
│ └── type
│ │ ├── ModifierProperties.java
│ │ ├── WildcardOID.java
│ │ └── package-info.java
│ ├── exception
│ ├── InitializationException.java
│ └── package-info.java
│ ├── package-info.java
│ └── snmp
│ └── MOGroup.java
└── test
├── java
└── com
│ └── oneandone
│ └── snmpman
│ ├── AbstractSnmpmanTest.java
│ ├── SnmpmanAgentTest.java
│ ├── SnmpmanSetTest.java
│ ├── SnmpmanTest.java
│ ├── configuration
│ ├── AgentConfigurationTest.java
│ ├── DeviceFactoryTest.java
│ ├── DeviceTest.java
│ ├── WalksTest.java
│ ├── modifier
│ │ ├── AbstractIntegerModifierTest.java
│ │ ├── CommunityIndexCounter32ModifierTest.java
│ │ ├── Counter32ModifierTest.java
│ │ ├── Counter64ModifierTest.java
│ │ ├── Gauge32ModifierTest.java
│ │ ├── Integer32ModifierTest.java
│ │ ├── ModifiedVariableTest.java
│ │ ├── ModifierTest.java
│ │ ├── TimeTicksModifierTest.java
│ │ └── UnsignedInteger32ModifierTest.java
│ └── type
│ │ ├── ModifierPropertiesTest.java
│ │ └── WildcardOIDTest.java
│ └── integration
│ └── SnmpmanIntegrationTest.java
└── resources
├── configuration
├── cisco.yaml
├── configuration.yaml
├── differentStartingOID.txt
├── empty.yaml
└── example.txt
└── log4j2.xml
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "maven" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "daily"
12 |
--------------------------------------------------------------------------------
/.github/integration/configuration.yaml:
--------------------------------------------------------------------------------
1 | - name: "example1"
2 | device: "ios.yaml"
3 | walk: "example1.walk"
4 | ip: "127.0.0.1"
5 | port: 10000
--------------------------------------------------------------------------------
/.github/integration/example1.walk:
--------------------------------------------------------------------------------
1 | .1.3.6.1.2.1.1.5.0 = STRING: "device"
2 | .1.3.6.1.2.1.2.2.1.7.10101 = INTEGER: 1
3 | .1.3.6.1.2.1.31.1.1.1.6.10101 = Counter64: 389172331
4 | .1.3.6.1.2.1.31.1.1.1.7.10101 = Counter64: 5470259
5 | .1.3.6.1.2.1.31.1.1.1.8.10101 = Counter64: 19
6 | .1.3.6.1.2.1.31.1.1.1.9.10101 = Counter64: 743
7 | .1.3.6.1.2.1.2.2.1.13.10101 = Counter32: 0
8 | .1.3.6.1.2.1.2.2.1.14.10101 = Counter32: 0
9 | .1.3.6.1.2.1.2.2.1.15.10101 = Counter32: 0
10 | .1.3.6.1.2.1.31.1.1.1.10.10101 = Counter64: 48648257581
11 | .1.3.6.1.2.1.31.1.1.1.11.10101 = Counter64: 32038868
12 | .1.3.6.1.2.1.31.1.1.1.12.10101 = Counter64: 141915228
13 | .1.3.6.1.2.1.31.1.1.1.13.10101 = Counter64: 44011328
14 | .1.3.6.1.2.1.2.2.1.19.10101 = Counter32: 0
15 | .1.3.6.1.2.1.2.2.1.2.10101 = STRING: "GigabitEthernet0/1"
16 | .1.3.6.1.2.1.31.1.1.1.1.10101 = STRING: "Gi0/1"
17 | .1.3.6.1.2.1.31.1.1.1.10.10101 = Counter64: 48648257581
18 | .1.3.6.1.2.1.31.1.1.1.11.10101 = Counter64: 32038868
19 | .1.3.6.1.2.1.31.1.1.1.12.10101 = Counter64: 141915228
20 | .1.3.6.1.2.1.31.1.1.1.13.10101 = Counter64: 44011328
21 | .1.3.6.1.2.1.31.1.1.1.15.10101 = Gauge32: 1000
22 | .1.3.6.1.2.1.2.2.1.5.10101 = Gauge32: 1000000000
23 | .1.3.6.1.2.1.17.2.4.0 = Counter32: 0
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ "master" ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ "master" ]
20 | schedule:
21 | - cron: '18 19 * * 0'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
27 | timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
28 | permissions:
29 | actions: read
30 | contents: read
31 | security-events: write
32 |
33 | strategy:
34 | fail-fast: false
35 | matrix:
36 | language: [ 'java' ]
37 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
38 | # Use only 'java' to analyze code written in Java, Kotlin or both
39 | # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
40 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
41 |
42 | steps:
43 | - name: Checkout repository
44 | uses: actions/checkout@v3
45 |
46 | # Initializes the CodeQL tools for scanning.
47 | - name: Initialize CodeQL
48 | uses: github/codeql-action/init@v2
49 | with:
50 | languages: ${{ matrix.language }}
51 | # If you wish to specify custom queries, you can do so here or in a config file.
52 | # By default, queries listed here will override any specified in a config file.
53 | # Prefix the list here with "+" to use these queries and those in the config file.
54 |
55 | # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
56 | # queries: security-extended,security-and-quality
57 |
58 |
59 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
60 | # If this step fails, then you should remove it and run the build manually (see below)
61 | - name: Autobuild
62 | uses: github/codeql-action/autobuild@v2
63 |
64 | # ℹ️ Command-line programs to run using the OS shell.
65 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
66 |
67 | # If the Autobuild fails above, remove it and uncomment the following three lines.
68 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
69 |
70 | # - run: |
71 | # echo "Run, Build Application using script"
72 | # ./location_of_script_within_repo/buildscript.sh
73 |
74 | - name: Perform CodeQL Analysis
75 | uses: github/codeql-action/analyze@v2
76 | with:
77 | category: "/language:${{matrix.language}}"
78 |
--------------------------------------------------------------------------------
/.github/workflows/docker.yml:
--------------------------------------------------------------------------------
1 | name: Docker
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 |
7 | jobs:
8 | docker:
9 | runs-on: ubuntu-latest
10 | steps:
11 | -
12 | name: Set up QEMU
13 | uses: docker/setup-qemu-action@v2
14 | -
15 | name: Set up Docker Buildx
16 | uses: docker/setup-buildx-action@v2
17 | -
18 | name: Login to DockerHub
19 | uses: docker/login-action@v2
20 | with:
21 | username: ${{ secrets.DOCKERHUB_USERNAME }}
22 | password: ${{ secrets.DOCKERHUB_TOKEN }}
23 | -
24 | name: Build and push
25 | uses: docker/build-push-action@v3
26 | with:
27 | push: true
28 | tags: stephanfuhrmannionos/snmpman:latest
29 |
--------------------------------------------------------------------------------
/.github/workflows/integration.yml:
--------------------------------------------------------------------------------
1 | name: Integration Test
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | integration:
11 | runs-on: ubuntu-latest
12 | strategy:
13 | matrix:
14 | java: [ 11, 17, 21 ]
15 | steps:
16 |
17 | - uses: actions/checkout@v3
18 |
19 | - name: Set up JDK ${{ matrix.java }}
20 | uses: actions/setup-java@v3
21 | with:
22 | distribution: 'adopt'
23 | java-version: ${{ matrix.java }}
24 |
25 | - name: Build with Maven
26 | run: mvn -B package --file pom.xml
27 |
28 | - name: Run snmpman
29 | run: |
30 | ../../snmpman-cli/target/snmpman-cli-*-SNAPSHOT-bin/bin/snmpman.sh -c configuration.yaml &
31 | SNMPMAN_PID=$!
32 | echo "Pid: $SNMPMAN_PID"
33 | sleep 5
34 | working-directory: ./.github/integration
35 |
36 | - name: snmpget a single OID
37 | run: |
38 | ACTUAL=$(snmpget -On -v2c -c public 127.0.0.1:10000 iso.3.6.1.2.1.2.2.1.2.10101)
39 | DESIRED=".1.3.6.1.2.1.2.2.1.2.10101 = STRING: \"GigabitEthernet0/1\""
40 | if [ "$ACTUAL" != "$DESIRED" ]; then
41 | echo "Actual is: $ACTUAL"
42 | echo "Desired is: $DESIRED"
43 | exit 1
44 | fi
45 |
46 | - name: snmpset a single OID
47 | run: |
48 | snmpset -On -v2c -c public 127.0.0.1:10000 iso.3.6.1.2.1.2.2.1.2.10101 s "GigabitEthernet0/2"
49 | ACTUAL=$(snmpget -On -v2c -c public 127.0.0.1:10000 iso.3.6.1.2.1.2.2.1.2.10101)
50 | DESIRED=".1.3.6.1.2.1.2.2.1.2.10101 = STRING: \"GigabitEthernet0/2\""
51 | if [ "$ACTUAL" != "$DESIRED" ]; then
52 | echo "Actual is: $ACTUAL"
53 | echo "Desired is: $DESIRED"
54 | exit 1
55 | fi
56 |
--------------------------------------------------------------------------------
/.github/workflows/maven-release.yml:
--------------------------------------------------------------------------------
1 | # This release process looks for tags and produces releases.
2 | name: Release
3 |
4 | on:
5 | push:
6 | tags:
7 | - 'snmpman-parent-[0-9]+*'
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | outputs:
13 | version: ${{ steps.version.outputs.version }}
14 | md5sum: ${{ steps.md5sum.outputs.md5sum }}
15 | sha256sum: ${{ steps.sha256sum.outputs.sha256sum }}
16 | env:
17 | DEBIAN_FRONTEND: noninteractive
18 |
19 | steps:
20 | - uses: actions/checkout@v3
21 |
22 | - name: Set up JDK 21
23 | uses: actions/setup-java@v3
24 | with:
25 | distribution: 'adopt'
26 | java-version: 21
27 |
28 | - name: Build with Maven
29 | run: mvn -B package --file pom.xml
30 |
31 | - name: Extract current maven version
32 | run: echo "::set-output name=version::$(mvn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version -q -DforceStdout)"
33 | id: version
34 | shell: bash
35 |
36 | - name: Calculate MD5
37 | run: echo "::set-output name=md5sum::$(md5sum -b snmpman-cli/target/snmpman-cli-${{ steps.version.outputs.version }}-bin.tar.gz | cut -f1 -d" ")"
38 | id: md5sum
39 | shell: bash
40 |
41 | - name: Calculate SHA256
42 | run: echo "::set-output name=sha256sum::$(sha256sum -b snmpman-cli/target/snmpman-cli-${{ steps.version.outputs.version }}-bin.tar.gz | cut -f1 -d" ")"
43 | id: sha256sum
44 | shell: bash
45 |
46 | - uses: actions/upload-artifact@v3
47 | with:
48 | name: snmpman-cli-${{ steps.version.outputs.version }}-bin.tar.gz
49 | path: snmpman-cli/target/snmpman-cli-${{ steps.version.outputs.version }}-bin.tar.gz
50 |
51 | - uses: actions/create-release@v1
52 | id: create_release
53 | env:
54 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
55 | with:
56 | tag_name: ${{ github.ref }}
57 | release_name: ${{ github.ref }}
58 | draft: true
59 | body: |
60 | # Release ${{ steps.version.outputs.version }}
61 | ## Changes
62 |
63 | * 1
64 | * 2
65 | * 3
66 |
67 | ## Checksums
68 | |Type|Message digest|
69 | |----|--------------|
70 | |MD5|`${{ steps.md5sum.outputs.md5sum }}`|
71 | |SHA256|`${{ steps.sha256sum.outputs.sha256sum }}`|
72 |
73 | - uses: actions/upload-release-asset@v1
74 | env:
75 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76 | with:
77 | upload_url: ${{ steps.create_release.outputs.upload_url }}
78 | asset_path: snmpman-cli/target/snmpman-cli-${{ steps.version.outputs.version }}-bin.tar.gz
79 | asset_name: snmpman-cli-${{ steps.version.outputs.version }}-bin.tar.gz
80 | asset_content_type: application/tar+gzip
81 |
--------------------------------------------------------------------------------
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Java CI with Maven
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 | strategy:
16 | matrix:
17 | java: [ 11, 17, 21 ]
18 | steps:
19 | - uses: actions/checkout@v2
20 | - name: Set up JDK ${{ matrix.java }}
21 | uses: actions/setup-java@v1
22 | with:
23 | java-version: ${{ matrix.java }}
24 | - name: Build with Maven
25 | run: mvn -B package --file pom.xml
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Maven
2 | target/
3 |
4 | # Eclipse
5 | .project
6 | .settings/
7 | .classpath
8 | .metadata
9 |
10 | # IntelliJ
11 | .idea/
12 | *.iml
13 | *.iws
14 |
15 | # MAC
16 | .DS_Store
17 |
18 | # Gradle properties
19 | gradle.properties
20 | *.gpg
21 | build
22 | .gradle
23 |
24 | # Temporary execution files
25 | *.BC.cfg
26 | *.Config.cfg
--------------------------------------------------------------------------------
/.suppressions.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 | * A mandatory argument for execution of the {@link #main(String...)} method is the path to the configuration file.
12 | * See {@link com.oneandone.snmpman.CommandLineOptions} for information on available command line options.
13 | *
14 | * Each configuration list item represents an instance of the {@link com.oneandone.snmpman.configuration.AgentConfiguration}.
15 | * The constructor {@link com.oneandone.snmpman.configuration.AgentConfiguration#AgentConfiguration(String, java.io.File, java.io.File, String, int, String)}
16 | * lists all available properties, which may or may not be required.
17 | *
18 | * An entry may look like the following:
19 | *
20 | * {@code 21 | * - name: "example1" 22 | * device: "src/test/resources/configuration/cisco.yaml" 23 | * walk: "src/test/resources/configuration/example.txt" 24 | * ip: "127.0.0.1" 25 | * port: 10000 26 | * } 27 | *28 | * You can find more example within the test resources of this project. 29 | *
28 | * {@code 29 | * - name: "example1" 30 | * device: "src/test/resources/configuration/cisco.yaml" 31 | * walk: "src/test/resources/configuration/example.txt" 32 | * ip: "127.0.0.1" 33 | * port: 10000 34 | * } 35 | *36 | * You can find more example within the test resources of this project. 37 | *
38 | * An overflow can occur and will be considered in the minimum and maximum interval.
39 | *
40 | * @param currentValue the current value to modify
41 | * @param minimum {@link #minimum}
42 | * @param maximum {@link #maximum}
43 | * @param minimumStep {@link #minimumStep}
44 | * @param maximumStep {@link #maximumStep}
45 | * @return the modified variable value
46 | */
47 | protected int modify(final int currentValue, final int minimum, final int maximum, final int minimumStep, final int maximumStep) {
48 | int currentValidValue = currentValue;
49 | if (currentValue < minimum || currentValue > maximum) {
50 | currentValidValue = minimum;
51 | }
52 | int step = (int) (Math.round(Math.random() * (maximumStep - minimumStep)) + minimumStep);
53 |
54 | int stepUntilMaximum = maximum - currentValidValue;
55 | int newValue;
56 | if (Math.abs(step) > Math.abs(stepUntilMaximum)) {
57 | newValue = minimum + (step - stepUntilMaximum - 1);
58 | } else {
59 | newValue = currentValidValue + step;
60 | }
61 |
62 | if (newValue < minimum) {
63 | newValue = minimum;
64 | } else if (newValue > maximum) {
65 | newValue = maximum;
66 | }
67 |
68 | return newValue;
69 | }
70 |
71 | @Override
72 | public Integer32 modify(final Integer32 variable) {
73 | final int newValue = this.modify(variable.getValue(), minimum, maximum, minimumStep, maximumStep);
74 | log.trace("Counter32 variable {} will be tuned to {}", variable.getValue(), newValue);
75 | return new Integer32(newValue);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/snmpman/src/main/java/com/oneandone/snmpman/configuration/modifier/ModifiedVariable.java:
--------------------------------------------------------------------------------
1 | package com.oneandone.snmpman.configuration.modifier;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.snmp4j.asn1.BERInputStream;
5 | import org.snmp4j.smi.OID;
6 | import org.snmp4j.smi.Variable;
7 |
8 | import java.io.IOException;
9 | import java.io.OutputStream;
10 | import java.util.Collections;
11 | import java.util.List;
12 |
13 | /**
14 | * A modified variable will change it's value on every value call.
15 | */
16 | @Slf4j
17 | public class ModifiedVariable implements Variable, Cloneable {
18 |
19 | /** The list of modifiers that modify the {@link #variable}. */
20 | private final List
28 | * A modified variable will dynamically change it's value on each value call.
29 | *
30 | * @param variable the initial variable to modify
31 | * @param modifiers the list of modifiers that should modify this variable
32 | */
33 | public ModifiedVariable(final Variable variable, final List
16 | * See also {@link com.oneandone.snmpman.configuration.modifier.VariableModifier}.
17 | *
18 | * @param
8 | * This method will return a new {@link TimeTicks} instance with the current timestamp.
9 | */
10 | public class TimeTicksModifier implements VariableModifier
4 | * In this context the so called modified variables are those which value change with every prompt.
5 | *
6 | * Every implementation of the {@link com.oneandone.snmpman.configuration.modifier.VariableModifier} can be used as a binding
7 | * modifier in a device configuration.
8 | *
9 | * @see com.oneandone.snmpman.configuration.Device
10 | */
11 | package com.oneandone.snmpman.configuration.modifier;
--------------------------------------------------------------------------------
/snmpman/src/main/java/com/oneandone/snmpman/configuration/package-info.java:
--------------------------------------------------------------------------------
1 | /** This package contains all classes as used for the configuration of the {@code Snmpman} application. */
2 | package com.oneandone.snmpman.configuration;
--------------------------------------------------------------------------------
/snmpman/src/main/java/com/oneandone/snmpman/configuration/type/ModifierProperties.java:
--------------------------------------------------------------------------------
1 | package com.oneandone.snmpman.configuration.type;
2 |
3 | import com.google.common.primitives.UnsignedLong;
4 |
5 | import java.util.Optional;
6 | import java.util.Properties;
7 |
8 | /** The modifier properties as used in {@link com.oneandone.snmpman.configuration.Device} for initialization. */
9 | public class ModifierProperties extends Properties {
10 |
11 | /**
12 | * Returns the integer value for the specified property {@code key}.
13 | *
14 | * @param key the property key
15 | * @return the integer value for the specified key or {@code null} if not existing.
16 | * @throws java.lang.ClassCastException thrown if the value for the specified key could not be casted
17 | */
18 | public Integer getInteger(final String key) {
19 | final Optional
13 | * The wildcard will be considered for matching request in the function {@link #matches(org.snmp4j.smi.OID)}.
14 | * Every sequence of {@code int} array chains can be considered for the wildcard character.
15 | *
16 | * Only one wildcard is allowed for the wildcard {@code OID}.
17 | */
18 | @EqualsAndHashCode
19 | public class WildcardOID {
20 |
21 | /** The wildcard OID pattern. */
22 | private static final Pattern WILDCARD_OID_PATTERN = Pattern.compile("((\\.)?[0-9]+(\\.[0-9]+)*)(\\.\\*)?((\\.[0-9]+)*)");
23 |
24 | /** The first part of the wildcard {@code OID} (before the "{@code *}" character). */
25 | private final OID startsWith;
26 |
27 | /** The second part of the wildcard {@code OID} (after the "{@code *}" character). Can be {@code null}. */
28 | private final OID endsWith;
29 |
30 | /**
31 | * Constructs a new instance of this class.
32 | *
33 | * @param oid the {@code OID} that potentially contains a wildcard
34 | * @throws NullPointerException if the specified {@code OID} is null
35 | * @throws IllegalArgumentException if the specified {@code OID} contains more than one wildcard character
36 | */
37 | public WildcardOID(final String oid) {
38 | Preconditions.checkNotNull(oid, "oid may not be null");
39 |
40 | final Matcher matcher = WILDCARD_OID_PATTERN.matcher(oid);
41 | if (matcher.matches()) {
42 | this.startsWith = new OID(matcher.group(1));
43 | if (matcher.group(5).isEmpty()) {
44 | this.endsWith = null;
45 | } else {
46 | this.endsWith = new OID(matcher.group(5));
47 | }
48 | } else {
49 | throw new IllegalArgumentException("specified oid \"" + oid + "\" is not a valid wildcard");
50 | }
51 | }
52 |
53 | /**
54 | * Returns {@code true} if this wildcard {@code OID} matches with the specified {@code OID}.
55 | *
56 | * Here some examples for matching {@code OID}s:
57 | *
58 | *
62 | *
63 | * @param oid the {@code OID} to test
64 | * @return {@code true} if the {@code OID}s are matching, otherwise {@code false}
65 | */
66 | public boolean matches(final OID oid) {
67 | return oid.startsWith(startsWith) && (endsWith == null || oid.size() >= endsWith.size() && oid.rightMostCompare(endsWith.size(), endsWith) == 0);
68 | }
69 |
70 | @Override
71 | public String toString() {
72 | if (endsWith == null) {
73 | return startsWith.toDottedString() + ".*";
74 | } else {
75 | return startsWith.toDottedString() + ".*." + endsWith.toDottedString();
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/snmpman/src/main/java/com/oneandone/snmpman/configuration/type/package-info.java:
--------------------------------------------------------------------------------
1 | /** Types as used by other configuration representations. */
2 | package com.oneandone.snmpman.configuration.type;
--------------------------------------------------------------------------------
/snmpman/src/main/java/com/oneandone/snmpman/exception/InitializationException.java:
--------------------------------------------------------------------------------
1 | package com.oneandone.snmpman.exception;
2 |
3 | /** Exception type defines the failed initialization of the application. */
4 | public class InitializationException extends RuntimeException {
5 |
6 | /** The version number of this class. */
7 | private static final long serialVersionUID = 1L;
8 |
9 | /**
10 | * Constructs a new exception.
11 | *
12 | * @param message the detail message
13 | */
14 | public InitializationException(final String message) {
15 | super(message);
16 | }
17 |
18 | /**
19 | * Constructs a new exception.
20 | *
21 | * @param message the detail message
22 | * @param cause the exception cause
23 | */
24 | public InitializationException(final String message, final Throwable cause) {
25 | super(message, cause);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/snmpman/src/main/java/com/oneandone/snmpman/exception/package-info.java:
--------------------------------------------------------------------------------
1 | /** Application specific exception types. */
2 | package com.oneandone.snmpman.exception;
--------------------------------------------------------------------------------
/snmpman/src/main/java/com/oneandone/snmpman/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The {@code Snmpman} is a command-line application that simulates {@code SNMP}-capable devices.
3 | *
4 | * It also can be used within Unit tests which require the usage of SNMP devices. You can start and stop all agents
5 | * with pre- and post unit-test execution methods, which are available in probably every Unit-Test framework.
6 | *
7 | * Check the documentation of {@link com.oneandone.snmpman.Snmpman} to get more information on the execution.
8 | */
9 | package com.oneandone.snmpman;
--------------------------------------------------------------------------------
/snmpman/src/main/java/com/oneandone/snmpman/snmp/MOGroup.java:
--------------------------------------------------------------------------------
1 | package com.oneandone.snmpman.snmp;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.snmp4j.agent.DefaultMOScope;
5 | import org.snmp4j.agent.MOScope;
6 | import org.snmp4j.agent.ManagedObject;
7 | import org.snmp4j.agent.request.SubRequest;
8 | import org.snmp4j.mp.SnmpConstants;
9 | import org.snmp4j.smi.Null;
10 | import org.snmp4j.smi.OID;
11 | import org.snmp4j.smi.Variable;
12 |
13 | import java.util.Iterator;
14 | import java.util.SortedMap;
15 | import java.util.TreeMap;
16 |
17 | @Slf4j
18 | public class MOGroup implements ManagedObject {
19 |
20 | /**
21 | * Sorted map of the variable bindings for this group.
22 | */
23 | private final SortedMap
38 | * The specified {@code OID} and variable will be set as the only data stored
39 | * in the map of {@link #variableBindings}.
40 | *
41 | * @param root the root {@code OID}
42 | * @param oid the {@code OID} for a variable binding
43 | * @param variable the variable of the variable binding
44 | */
45 | public MOGroup(final OID root, final OID oid, final Variable variable) {
46 | this.root = root;
47 | this.scope = new DefaultMOScope(root, true, root.nextPeer(), false);
48 | this.variableBindings = new TreeMap<>();
49 | this.variableBindings.put(oid, variable);
50 | }
51 |
52 | /**
53 | * Constructs a new instance of this class.
54 | *
55 | * @param root the root {@code OID}
56 | * @param variableBindings the map of variable bindings for this instance
57 | */
58 | public MOGroup(final OID root, final SortedMap